e9a6aa7f4afbe2037517fb392d4b4416d6e63562
[deliverable/linux.git] / drivers / staging / wilc1000 / host_interface.c
1 #include <linux/slab.h>
2 #include <linux/time.h>
3 #include <linux/kthread.h>
4 #include <linux/delay.h>
5 #include "host_interface.h"
6 #include "coreconfigurator.h"
7 #include "wilc_wlan.h"
8 #include "wilc_wlan_if.h"
9 #include "wilc_msgqueue.h"
10 #include <linux/etherdevice.h>
11 #include "wilc_wfi_netdevice.h"
12
13 #define HOST_IF_MSG_SCAN 0
14 #define HOST_IF_MSG_CONNECT 1
15 #define HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO 2
16 #define HOST_IF_MSG_KEY 3
17 #define HOST_IF_MSG_RCVD_NTWRK_INFO 4
18 #define HOST_IF_MSG_RCVD_SCAN_COMPLETE 5
19 #define HOST_IF_MSG_CFG_PARAMS 6
20 #define HOST_IF_MSG_SET_CHANNEL 7
21 #define HOST_IF_MSG_DISCONNECT 8
22 #define HOST_IF_MSG_GET_RSSI 9
23 #define HOST_IF_MSG_GET_CHNL 10
24 #define HOST_IF_MSG_ADD_BEACON 11
25 #define HOST_IF_MSG_DEL_BEACON 12
26 #define HOST_IF_MSG_ADD_STATION 13
27 #define HOST_IF_MSG_DEL_STATION 14
28 #define HOST_IF_MSG_EDIT_STATION 15
29 #define HOST_IF_MSG_SCAN_TIMER_FIRED 16
30 #define HOST_IF_MSG_CONNECT_TIMER_FIRED 17
31 #define HOST_IF_MSG_POWER_MGMT 18
32 #define HOST_IF_MSG_GET_INACTIVETIME 19
33 #define HOST_IF_MSG_REMAIN_ON_CHAN 20
34 #define HOST_IF_MSG_REGISTER_FRAME 21
35 #define HOST_IF_MSG_LISTEN_TIMER_FIRED 22
36 #define HOST_IF_MSG_GET_LINKSPEED 23
37 #define HOST_IF_MSG_SET_WFIDRV_HANDLER 24
38 #define HOST_IF_MSG_SET_MAC_ADDRESS 25
39 #define HOST_IF_MSG_GET_MAC_ADDRESS 26
40 #define HOST_IF_MSG_SET_OPERATION_MODE 27
41 #define HOST_IF_MSG_SET_IPADDRESS 28
42 #define HOST_IF_MSG_GET_IPADDRESS 29
43 #define HOST_IF_MSG_FLUSH_CONNECT 30
44 #define HOST_IF_MSG_GET_STATISTICS 31
45 #define HOST_IF_MSG_SET_MULTICAST_FILTER 32
46 #define HOST_IF_MSG_DEL_BA_SESSION 34
47 #define HOST_IF_MSG_Q_IDLE 35
48 #define HOST_IF_MSG_DEL_ALL_STA 36
49 #define HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS 37
50 #define HOST_IF_MSG_SET_TX_POWER 38
51 #define HOST_IF_MSG_GET_TX_POWER 39
52 #define HOST_IF_MSG_EXIT 100
53
54 #define HOST_IF_SCAN_TIMEOUT 4000
55 #define HOST_IF_CONNECT_TIMEOUT 9500
56
57 #define BA_SESSION_DEFAULT_BUFFER_SIZE 16
58 #define BA_SESSION_DEFAULT_TIMEOUT 1000
59 #define BLOCK_ACK_REQ_SIZE 0x14
60 #define FALSE_FRMWR_CHANNEL 100
61
62 #define TCP_ACK_FILTER_LINK_SPEED_THRESH 54
63 #define DEFAULT_LINK_SPEED 72
64
65 struct cfg_param_attr {
66 struct cfg_param_val cfg_attr_info;
67 };
68
69 struct host_if_wpa_attr {
70 u8 *key;
71 const u8 *mac_addr;
72 u8 *seq;
73 u8 seq_len;
74 u8 index;
75 u8 key_len;
76 u8 mode;
77 };
78
79 struct host_if_wep_attr {
80 u8 *key;
81 u8 key_len;
82 u8 index;
83 u8 mode;
84 enum AUTHTYPE auth_type;
85 };
86
87 union host_if_key_attr {
88 struct host_if_wep_attr wep;
89 struct host_if_wpa_attr wpa;
90 struct host_if_pmkid_attr pmkid;
91 };
92
93 struct key_attr {
94 enum KEY_TYPE type;
95 u8 action;
96 union host_if_key_attr attr;
97 };
98
99 struct scan_attr {
100 u8 src;
101 u8 type;
102 u8 *ch_freq_list;
103 u8 ch_list_len;
104 u8 *ies;
105 size_t ies_len;
106 wilc_scan_result result;
107 void *arg;
108 struct hidden_network hidden_network;
109 };
110
111 struct connect_attr {
112 u8 *bssid;
113 u8 *ssid;
114 size_t ssid_len;
115 u8 *ies;
116 size_t ies_len;
117 u8 security;
118 wilc_connect_result result;
119 void *arg;
120 enum AUTHTYPE auth_type;
121 u8 ch;
122 void *params;
123 };
124
125 struct rcvd_async_info {
126 u8 *buffer;
127 u32 len;
128 };
129
130 struct channel_attr {
131 u8 set_ch;
132 };
133
134 struct beacon_attr {
135 u32 interval;
136 u32 dtim_period;
137 u32 head_len;
138 u8 *head;
139 u32 tail_len;
140 u8 *tail;
141 };
142
143 struct set_multicast {
144 bool enabled;
145 u32 cnt;
146 };
147
148 struct del_all_sta {
149 u8 del_all_sta[MAX_NUM_STA][ETH_ALEN];
150 u8 assoc_sta;
151 };
152
153 struct del_sta {
154 u8 mac_addr[ETH_ALEN];
155 };
156
157 struct power_mgmt_param {
158 bool enabled;
159 u32 timeout;
160 };
161
162 struct set_ip_addr {
163 u8 *ip_addr;
164 u8 idx;
165 };
166
167 struct sta_inactive_t {
168 u8 mac[6];
169 };
170
171 struct tx_power {
172 u8 tx_pwr;
173 };
174
175 union message_body {
176 struct scan_attr scan_info;
177 struct connect_attr con_info;
178 struct rcvd_net_info net_info;
179 struct rcvd_async_info async_info;
180 struct key_attr key_info;
181 struct cfg_param_attr cfg_info;
182 struct channel_attr channel_info;
183 struct beacon_attr beacon_info;
184 struct add_sta_param add_sta_info;
185 struct del_sta del_sta_info;
186 struct add_sta_param edit_sta_info;
187 struct power_mgmt_param pwr_mgmt_info;
188 struct sta_inactive_t mac_info;
189 struct set_ip_addr ip_info;
190 struct drv_handler drv;
191 struct set_multicast multicast_info;
192 struct op_mode mode;
193 struct set_mac_addr set_mac_info;
194 struct get_mac_addr get_mac_info;
195 struct ba_session_info session_info;
196 struct remain_ch remain_on_ch;
197 struct reg_frame reg_frame;
198 char *data;
199 struct del_all_sta del_all_sta_info;
200 struct tx_power tx_power;
201 };
202
203 struct host_if_msg {
204 u16 id;
205 union message_body body;
206 struct wilc_vif *vif;
207 };
208
209 struct join_bss_param {
210 BSSTYPE_T bss_type;
211 u8 dtim_period;
212 u16 beacon_period;
213 u16 cap_info;
214 u8 bssid[6];
215 char ssid[MAX_SSID_LEN];
216 u8 ssid_len;
217 u8 supp_rates[MAX_RATES_SUPPORTED + 1];
218 u8 ht_capable;
219 u8 wmm_cap;
220 u8 uapsd_cap;
221 bool rsn_found;
222 u8 rsn_grp_policy;
223 u8 mode_802_11i;
224 u8 rsn_pcip_policy[3];
225 u8 rsn_auth_policy[3];
226 u8 rsn_cap[2];
227 u32 tsf;
228 u8 noa_enabled;
229 u8 opp_enabled;
230 u8 ct_window;
231 u8 cnt;
232 u8 idx;
233 u8 duration[4];
234 u8 interval[4];
235 u8 start_time[4];
236 };
237
238 static struct host_if_drv *terminated_handle;
239 bool wilc_optaining_ip;
240 static u8 P2P_LISTEN_STATE;
241 static struct task_struct *hif_thread_handler;
242 static struct message_queue hif_msg_q;
243 static struct semaphore hif_sema_thread;
244 static struct semaphore hif_sema_driver;
245 static struct semaphore hif_sema_wait_response;
246 static struct semaphore hif_sema_deinit;
247 static struct timer_list periodic_rssi;
248
249 u8 wilc_multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN];
250
251 static u8 rcv_assoc_resp[MAX_ASSOC_RESP_FRAME_SIZE];
252
253 static bool scan_while_connected;
254
255 static s8 rssi;
256 static s8 link_speed;
257 static u8 ch_no;
258 static u8 set_ip[2][4];
259 static u8 get_ip[2][4];
260 static u32 inactive_time;
261 static u8 del_beacon;
262 static u32 clients_count;
263
264 static u8 *join_req;
265 static u8 *info_element;
266 static u8 mode_11i;
267 static u8 auth_type;
268 static u32 join_req_size;
269 static u32 info_element_size;
270 static struct wilc_vif *join_req_vif;
271 #define REAL_JOIN_REQ 0
272 #define FLUSHED_JOIN_REQ 1
273 #define FLUSHED_BYTE_POS 79
274
275 static void *host_int_ParseJoinBssParam(struct network_info *ptstrNetworkInfo);
276 static int host_int_get_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx);
277
278 /* The u8IfIdx starts from 0 to NUM_CONCURRENT_IFC -1, but 0 index used as
279 * special purpose in wilc device, so we add 1 to the index to starts from 1.
280 * As a result, the returned index will be 1 to NUM_CONCURRENT_IFC.
281 */
282 int wilc_get_vif_idx(struct wilc_vif *vif)
283 {
284 return vif->idx + 1;
285 }
286
287 /* We need to minus 1 from idx which is from wilc device to get real index
288 * of wilc->vif[], because we add 1 when pass to wilc device in the function
289 * wilc_get_vif_idx.
290 * As a result, the index should be between 0 and NUM_CONCURRENT_IFC -1.
291 */
292 static struct wilc_vif *wilc_get_vif_from_idx(struct wilc *wilc, int idx)
293 {
294 int index = idx - 1;
295
296 if (index < 0 || index >= NUM_CONCURRENT_IFC)
297 return NULL;
298
299 return wilc->vif[index];
300 }
301
302 static s32 handle_set_channel(struct wilc_vif *vif,
303 struct channel_attr *hif_set_ch)
304 {
305 s32 result = 0;
306 struct wid wid;
307
308 wid.id = (u16)WID_CURRENT_CHANNEL;
309 wid.type = WID_CHAR;
310 wid.val = (char *)&hif_set_ch->set_ch;
311 wid.size = sizeof(char);
312
313 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
314 wilc_get_vif_idx(vif));
315
316 if (result) {
317 PRINT_ER("Failed to set channel\n");
318 return -EINVAL;
319 }
320
321 return result;
322 }
323
324 static s32 handle_set_wfi_drv_handler(struct wilc_vif *vif,
325 struct drv_handler *hif_drv_handler)
326 {
327 s32 result = 0;
328 struct wid wid;
329
330 wid.id = (u16)WID_SET_DRV_HANDLER;
331 wid.type = WID_STR;
332 wid.val = (s8 *)hif_drv_handler;
333 wid.size = sizeof(*hif_drv_handler);
334
335 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
336 hif_drv_handler->handler);
337
338 if (!hif_drv_handler->handler)
339 up(&hif_sema_driver);
340
341 if (result) {
342 PRINT_ER("Failed to set driver handler\n");
343 return -EINVAL;
344 }
345
346 return result;
347 }
348
349 static s32 handle_set_operation_mode(struct wilc_vif *vif,
350 struct op_mode *hif_op_mode)
351 {
352 s32 result = 0;
353 struct wid wid;
354
355 wid.id = (u16)WID_SET_OPERATION_MODE;
356 wid.type = WID_INT;
357 wid.val = (s8 *)&hif_op_mode->mode;
358 wid.size = sizeof(u32);
359
360 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
361 wilc_get_vif_idx(vif));
362
363 if ((hif_op_mode->mode) == IDLE_MODE)
364 up(&hif_sema_driver);
365
366 if (result) {
367 PRINT_ER("Failed to set driver handler\n");
368 return -EINVAL;
369 }
370
371 return result;
372 }
373
374 static s32 handle_set_ip_address(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
375 {
376 s32 result = 0;
377 struct wid wid;
378 char firmware_ip_addr[4] = {0};
379
380 if (ip_addr[0] < 192)
381 ip_addr[0] = 0;
382
383 memcpy(set_ip[idx], ip_addr, IP_ALEN);
384
385 wid.id = (u16)WID_IP_ADDRESS;
386 wid.type = WID_STR;
387 wid.val = (u8 *)ip_addr;
388 wid.size = IP_ALEN;
389
390 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
391 wilc_get_vif_idx(vif));
392
393 host_int_get_ipaddress(vif, firmware_ip_addr, idx);
394
395 if (result) {
396 PRINT_ER("Failed to set IP address\n");
397 return -EINVAL;
398 }
399
400 return result;
401 }
402
403 static s32 handle_get_ip_address(struct wilc_vif *vif, u8 idx)
404 {
405 s32 result = 0;
406 struct wid wid;
407
408 wid.id = (u16)WID_IP_ADDRESS;
409 wid.type = WID_STR;
410 wid.val = kmalloc(IP_ALEN, GFP_KERNEL);
411 wid.size = IP_ALEN;
412
413 result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
414 wilc_get_vif_idx(vif));
415
416 memcpy(get_ip[idx], wid.val, IP_ALEN);
417
418 kfree(wid.val);
419
420 if (memcmp(get_ip[idx], set_ip[idx], IP_ALEN) != 0)
421 wilc_setup_ipaddress(vif, set_ip[idx], idx);
422
423 if (result != 0) {
424 PRINT_ER("Failed to get IP address\n");
425 return -EINVAL;
426 }
427
428 return result;
429 }
430
431 static s32 handle_set_mac_address(struct wilc_vif *vif,
432 struct set_mac_addr *set_mac_addr)
433 {
434 s32 result = 0;
435 struct wid wid;
436 u8 *mac_buf = kmalloc(ETH_ALEN, GFP_KERNEL);
437
438 if (!mac_buf) {
439 PRINT_ER("No buffer to send mac address\n");
440 return -EFAULT;
441 }
442 memcpy(mac_buf, set_mac_addr->mac_addr, ETH_ALEN);
443
444 wid.id = (u16)WID_MAC_ADDR;
445 wid.type = WID_STR;
446 wid.val = mac_buf;
447 wid.size = ETH_ALEN;
448
449 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
450 wilc_get_vif_idx(vif));
451 if (result) {
452 PRINT_ER("Failed to set mac address\n");
453 result = -EFAULT;
454 }
455
456 kfree(mac_buf);
457 return result;
458 }
459
460 static s32 handle_get_mac_address(struct wilc_vif *vif,
461 struct get_mac_addr *get_mac_addr)
462 {
463 s32 result = 0;
464 struct wid wid;
465
466 wid.id = (u16)WID_MAC_ADDR;
467 wid.type = WID_STR;
468 wid.val = get_mac_addr->mac_addr;
469 wid.size = ETH_ALEN;
470
471 result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
472 wilc_get_vif_idx(vif));
473
474 if (result) {
475 PRINT_ER("Failed to get mac address\n");
476 result = -EFAULT;
477 }
478 up(&hif_sema_wait_response);
479
480 return result;
481 }
482
483 static s32 handle_cfg_param(struct wilc_vif *vif,
484 struct cfg_param_attr *cfg_param_attr)
485 {
486 s32 result = 0;
487 struct wid wid_list[32];
488 struct host_if_drv *hif_drv = vif->hif_drv;
489 u8 wid_cnt = 0;
490
491 down(&hif_drv->sem_cfg_values);
492
493 if (cfg_param_attr->cfg_attr_info.flag & BSS_TYPE) {
494 if (cfg_param_attr->cfg_attr_info.bss_type < 6) {
495 wid_list[wid_cnt].id = WID_BSS_TYPE;
496 wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.bss_type;
497 wid_list[wid_cnt].type = WID_CHAR;
498 wid_list[wid_cnt].size = sizeof(char);
499 hif_drv->cfg_values.bss_type = (u8)cfg_param_attr->cfg_attr_info.bss_type;
500 } else {
501 PRINT_ER("check value 6 over\n");
502 result = -EINVAL;
503 goto ERRORHANDLER;
504 }
505 wid_cnt++;
506 }
507 if (cfg_param_attr->cfg_attr_info.flag & AUTH_TYPE) {
508 if (cfg_param_attr->cfg_attr_info.auth_type == 1 ||
509 cfg_param_attr->cfg_attr_info.auth_type == 2 ||
510 cfg_param_attr->cfg_attr_info.auth_type == 5) {
511 wid_list[wid_cnt].id = WID_AUTH_TYPE;
512 wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.auth_type;
513 wid_list[wid_cnt].type = WID_CHAR;
514 wid_list[wid_cnt].size = sizeof(char);
515 hif_drv->cfg_values.auth_type = (u8)cfg_param_attr->cfg_attr_info.auth_type;
516 } else {
517 PRINT_ER("Impossible value \n");
518 result = -EINVAL;
519 goto ERRORHANDLER;
520 }
521 wid_cnt++;
522 }
523 if (cfg_param_attr->cfg_attr_info.flag & AUTHEN_TIMEOUT) {
524 if (cfg_param_attr->cfg_attr_info.auth_timeout > 0 &&
525 cfg_param_attr->cfg_attr_info.auth_timeout < 65536) {
526 wid_list[wid_cnt].id = WID_AUTH_TIMEOUT;
527 wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.auth_timeout;
528 wid_list[wid_cnt].type = WID_SHORT;
529 wid_list[wid_cnt].size = sizeof(u16);
530 hif_drv->cfg_values.auth_timeout = cfg_param_attr->cfg_attr_info.auth_timeout;
531 } else {
532 PRINT_ER("Range(1 ~ 65535) over\n");
533 result = -EINVAL;
534 goto ERRORHANDLER;
535 }
536 wid_cnt++;
537 }
538 if (cfg_param_attr->cfg_attr_info.flag & POWER_MANAGEMENT) {
539 if (cfg_param_attr->cfg_attr_info.power_mgmt_mode < 5) {
540 wid_list[wid_cnt].id = WID_POWER_MANAGEMENT;
541 wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.power_mgmt_mode;
542 wid_list[wid_cnt].type = WID_CHAR;
543 wid_list[wid_cnt].size = sizeof(char);
544 hif_drv->cfg_values.power_mgmt_mode = (u8)cfg_param_attr->cfg_attr_info.power_mgmt_mode;
545 } else {
546 PRINT_ER("Invalid power mode\n");
547 result = -EINVAL;
548 goto ERRORHANDLER;
549 }
550 wid_cnt++;
551 }
552 if (cfg_param_attr->cfg_attr_info.flag & RETRY_SHORT) {
553 if (cfg_param_attr->cfg_attr_info.short_retry_limit > 0 &&
554 cfg_param_attr->cfg_attr_info.short_retry_limit < 256) {
555 wid_list[wid_cnt].id = WID_SHORT_RETRY_LIMIT;
556 wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.short_retry_limit;
557 wid_list[wid_cnt].type = WID_SHORT;
558 wid_list[wid_cnt].size = sizeof(u16);
559 hif_drv->cfg_values.short_retry_limit = cfg_param_attr->cfg_attr_info.short_retry_limit;
560 } else {
561 PRINT_ER("Range(1~256) over\n");
562 result = -EINVAL;
563 goto ERRORHANDLER;
564 }
565 wid_cnt++;
566 }
567 if (cfg_param_attr->cfg_attr_info.flag & RETRY_LONG) {
568 if (cfg_param_attr->cfg_attr_info.long_retry_limit > 0 &&
569 cfg_param_attr->cfg_attr_info.long_retry_limit < 256) {
570 wid_list[wid_cnt].id = WID_LONG_RETRY_LIMIT;
571 wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.long_retry_limit;
572 wid_list[wid_cnt].type = WID_SHORT;
573 wid_list[wid_cnt].size = sizeof(u16);
574 hif_drv->cfg_values.long_retry_limit = cfg_param_attr->cfg_attr_info.long_retry_limit;
575 } else {
576 PRINT_ER("Range(1~256) over\n");
577 result = -EINVAL;
578 goto ERRORHANDLER;
579 }
580 wid_cnt++;
581 }
582 if (cfg_param_attr->cfg_attr_info.flag & FRAG_THRESHOLD) {
583 if (cfg_param_attr->cfg_attr_info.frag_threshold > 255 &&
584 cfg_param_attr->cfg_attr_info.frag_threshold < 7937) {
585 wid_list[wid_cnt].id = WID_FRAG_THRESHOLD;
586 wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.frag_threshold;
587 wid_list[wid_cnt].type = WID_SHORT;
588 wid_list[wid_cnt].size = sizeof(u16);
589 hif_drv->cfg_values.frag_threshold = cfg_param_attr->cfg_attr_info.frag_threshold;
590 } else {
591 PRINT_ER("Threshold Range fail\n");
592 result = -EINVAL;
593 goto ERRORHANDLER;
594 }
595 wid_cnt++;
596 }
597 if (cfg_param_attr->cfg_attr_info.flag & RTS_THRESHOLD) {
598 if (cfg_param_attr->cfg_attr_info.rts_threshold > 255 &&
599 cfg_param_attr->cfg_attr_info.rts_threshold < 65536) {
600 wid_list[wid_cnt].id = WID_RTS_THRESHOLD;
601 wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.rts_threshold;
602 wid_list[wid_cnt].type = WID_SHORT;
603 wid_list[wid_cnt].size = sizeof(u16);
604 hif_drv->cfg_values.rts_threshold = cfg_param_attr->cfg_attr_info.rts_threshold;
605 } else {
606 PRINT_ER("Threshold Range fail\n");
607 result = -EINVAL;
608 goto ERRORHANDLER;
609 }
610 wid_cnt++;
611 }
612 if (cfg_param_attr->cfg_attr_info.flag & PREAMBLE) {
613 if (cfg_param_attr->cfg_attr_info.preamble_type < 3) {
614 wid_list[wid_cnt].id = WID_PREAMBLE;
615 wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.preamble_type;
616 wid_list[wid_cnt].type = WID_CHAR;
617 wid_list[wid_cnt].size = sizeof(char);
618 hif_drv->cfg_values.preamble_type = cfg_param_attr->cfg_attr_info.preamble_type;
619 } else {
620 PRINT_ER("Preamle Range(0~2) over\n");
621 result = -EINVAL;
622 goto ERRORHANDLER;
623 }
624 wid_cnt++;
625 }
626 if (cfg_param_attr->cfg_attr_info.flag & SHORT_SLOT_ALLOWED) {
627 if (cfg_param_attr->cfg_attr_info.short_slot_allowed < 2) {
628 wid_list[wid_cnt].id = WID_SHORT_SLOT_ALLOWED;
629 wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.short_slot_allowed;
630 wid_list[wid_cnt].type = WID_CHAR;
631 wid_list[wid_cnt].size = sizeof(char);
632 hif_drv->cfg_values.short_slot_allowed = (u8)cfg_param_attr->cfg_attr_info.short_slot_allowed;
633 } else {
634 PRINT_ER("Short slot(2) over\n");
635 result = -EINVAL;
636 goto ERRORHANDLER;
637 }
638 wid_cnt++;
639 }
640 if (cfg_param_attr->cfg_attr_info.flag & TXOP_PROT_DISABLE) {
641 if (cfg_param_attr->cfg_attr_info.txop_prot_disabled < 2) {
642 wid_list[wid_cnt].id = WID_11N_TXOP_PROT_DISABLE;
643 wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.txop_prot_disabled;
644 wid_list[wid_cnt].type = WID_CHAR;
645 wid_list[wid_cnt].size = sizeof(char);
646 hif_drv->cfg_values.txop_prot_disabled = (u8)cfg_param_attr->cfg_attr_info.txop_prot_disabled;
647 } else {
648 PRINT_ER("TXOP prot disable\n");
649 result = -EINVAL;
650 goto ERRORHANDLER;
651 }
652 wid_cnt++;
653 }
654 if (cfg_param_attr->cfg_attr_info.flag & BEACON_INTERVAL) {
655 if (cfg_param_attr->cfg_attr_info.beacon_interval > 0 &&
656 cfg_param_attr->cfg_attr_info.beacon_interval < 65536) {
657 wid_list[wid_cnt].id = WID_BEACON_INTERVAL;
658 wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.beacon_interval;
659 wid_list[wid_cnt].type = WID_SHORT;
660 wid_list[wid_cnt].size = sizeof(u16);
661 hif_drv->cfg_values.beacon_interval = cfg_param_attr->cfg_attr_info.beacon_interval;
662 } else {
663 PRINT_ER("Beacon interval(1~65535) fail\n");
664 result = -EINVAL;
665 goto ERRORHANDLER;
666 }
667 wid_cnt++;
668 }
669 if (cfg_param_attr->cfg_attr_info.flag & DTIM_PERIOD) {
670 if (cfg_param_attr->cfg_attr_info.dtim_period > 0 &&
671 cfg_param_attr->cfg_attr_info.dtim_period < 256) {
672 wid_list[wid_cnt].id = WID_DTIM_PERIOD;
673 wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.dtim_period;
674 wid_list[wid_cnt].type = WID_CHAR;
675 wid_list[wid_cnt].size = sizeof(char);
676 hif_drv->cfg_values.dtim_period = cfg_param_attr->cfg_attr_info.dtim_period;
677 } else {
678 PRINT_ER("DTIM range(1~255) fail\n");
679 result = -EINVAL;
680 goto ERRORHANDLER;
681 }
682 wid_cnt++;
683 }
684 if (cfg_param_attr->cfg_attr_info.flag & SITE_SURVEY) {
685 if (cfg_param_attr->cfg_attr_info.site_survey_enabled < 3) {
686 wid_list[wid_cnt].id = WID_SITE_SURVEY;
687 wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.site_survey_enabled;
688 wid_list[wid_cnt].type = WID_CHAR;
689 wid_list[wid_cnt].size = sizeof(char);
690 hif_drv->cfg_values.site_survey_enabled = (u8)cfg_param_attr->cfg_attr_info.site_survey_enabled;
691 } else {
692 PRINT_ER("Site survey disable\n");
693 result = -EINVAL;
694 goto ERRORHANDLER;
695 }
696 wid_cnt++;
697 }
698 if (cfg_param_attr->cfg_attr_info.flag & SITE_SURVEY_SCAN_TIME) {
699 if (cfg_param_attr->cfg_attr_info.site_survey_scan_time > 0 &&
700 cfg_param_attr->cfg_attr_info.site_survey_scan_time < 65536) {
701 wid_list[wid_cnt].id = WID_SITE_SURVEY_SCAN_TIME;
702 wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.site_survey_scan_time;
703 wid_list[wid_cnt].type = WID_SHORT;
704 wid_list[wid_cnt].size = sizeof(u16);
705 hif_drv->cfg_values.site_survey_scan_time = cfg_param_attr->cfg_attr_info.site_survey_scan_time;
706 } else {
707 PRINT_ER("Site survey scan time(1~65535) over\n");
708 result = -EINVAL;
709 goto ERRORHANDLER;
710 }
711 wid_cnt++;
712 }
713 if (cfg_param_attr->cfg_attr_info.flag & ACTIVE_SCANTIME) {
714 if (cfg_param_attr->cfg_attr_info.active_scan_time > 0 &&
715 cfg_param_attr->cfg_attr_info.active_scan_time < 65536) {
716 wid_list[wid_cnt].id = WID_ACTIVE_SCAN_TIME;
717 wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.active_scan_time;
718 wid_list[wid_cnt].type = WID_SHORT;
719 wid_list[wid_cnt].size = sizeof(u16);
720 hif_drv->cfg_values.active_scan_time = cfg_param_attr->cfg_attr_info.active_scan_time;
721 } else {
722 PRINT_ER("Active scan time(1~65535) over\n");
723 result = -EINVAL;
724 goto ERRORHANDLER;
725 }
726 wid_cnt++;
727 }
728 if (cfg_param_attr->cfg_attr_info.flag & PASSIVE_SCANTIME) {
729 if (cfg_param_attr->cfg_attr_info.passive_scan_time > 0 &&
730 cfg_param_attr->cfg_attr_info.passive_scan_time < 65536) {
731 wid_list[wid_cnt].id = WID_PASSIVE_SCAN_TIME;
732 wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.passive_scan_time;
733 wid_list[wid_cnt].type = WID_SHORT;
734 wid_list[wid_cnt].size = sizeof(u16);
735 hif_drv->cfg_values.passive_scan_time = cfg_param_attr->cfg_attr_info.passive_scan_time;
736 } else {
737 PRINT_ER("Passive scan time(1~65535) over\n");
738 result = -EINVAL;
739 goto ERRORHANDLER;
740 }
741 wid_cnt++;
742 }
743 if (cfg_param_attr->cfg_attr_info.flag & CURRENT_TX_RATE) {
744 enum CURRENT_TXRATE curr_tx_rate = cfg_param_attr->cfg_attr_info.curr_tx_rate;
745
746 if (curr_tx_rate == AUTORATE || curr_tx_rate == MBPS_1
747 || curr_tx_rate == MBPS_2 || curr_tx_rate == MBPS_5_5
748 || curr_tx_rate == MBPS_11 || curr_tx_rate == MBPS_6
749 || curr_tx_rate == MBPS_9 || curr_tx_rate == MBPS_12
750 || curr_tx_rate == MBPS_18 || curr_tx_rate == MBPS_24
751 || curr_tx_rate == MBPS_36 || curr_tx_rate == MBPS_48 || curr_tx_rate == MBPS_54) {
752 wid_list[wid_cnt].id = WID_CURRENT_TX_RATE;
753 wid_list[wid_cnt].val = (s8 *)&curr_tx_rate;
754 wid_list[wid_cnt].type = WID_SHORT;
755 wid_list[wid_cnt].size = sizeof(u16);
756 hif_drv->cfg_values.curr_tx_rate = (u8)curr_tx_rate;
757 } else {
758 PRINT_ER("out of TX rate\n");
759 result = -EINVAL;
760 goto ERRORHANDLER;
761 }
762 wid_cnt++;
763 }
764
765 result = wilc_send_config_pkt(vif, SET_CFG, wid_list,
766 wid_cnt, wilc_get_vif_idx(vif));
767
768 if (result)
769 PRINT_ER("Error in setting CFG params\n");
770
771 ERRORHANDLER:
772 up(&hif_drv->sem_cfg_values);
773 return result;
774 }
775
776 static void Handle_wait_msg_q_empty(void)
777 {
778 wilc_initialized = 0;
779 up(&hif_sema_wait_response);
780 }
781
782 static s32 Handle_ScanDone(struct wilc_vif *vif,
783 enum scan_event enuEvent);
784
785 static s32 Handle_Scan(struct wilc_vif *vif,
786 struct scan_attr *pstrHostIFscanAttr)
787 {
788 s32 result = 0;
789 struct wid strWIDList[5];
790 u32 u32WidsCount = 0;
791 u32 i;
792 u8 *pu8Buffer;
793 u8 valuesize = 0;
794 u8 *pu8HdnNtwrksWidVal = NULL;
795 struct host_if_drv *hif_drv = vif->hif_drv;
796
797 hif_drv->usr_scan_req.scan_result = pstrHostIFscanAttr->result;
798 hif_drv->usr_scan_req.arg = pstrHostIFscanAttr->arg;
799
800 if ((hif_drv->hif_state >= HOST_IF_SCANNING) &&
801 (hif_drv->hif_state < HOST_IF_CONNECTED)) {
802 PRINT_ER("Already scan\n");
803 result = -EBUSY;
804 goto ERRORHANDLER;
805 }
806
807 if (wilc_optaining_ip || wilc_connecting) {
808 PRINT_ER("Don't do obss scan\n");
809 result = -EBUSY;
810 goto ERRORHANDLER;
811 }
812
813 hif_drv->usr_scan_req.rcvd_ch_cnt = 0;
814
815 strWIDList[u32WidsCount].id = (u16)WID_SSID_PROBE_REQ;
816 strWIDList[u32WidsCount].type = WID_STR;
817
818 for (i = 0; i < pstrHostIFscanAttr->hidden_network.n_ssids; i++)
819 valuesize += ((pstrHostIFscanAttr->hidden_network.net_info[i].ssid_len) + 1);
820 pu8HdnNtwrksWidVal = kmalloc(valuesize + 1, GFP_KERNEL);
821 strWIDList[u32WidsCount].val = pu8HdnNtwrksWidVal;
822 if (strWIDList[u32WidsCount].val) {
823 pu8Buffer = strWIDList[u32WidsCount].val;
824
825 *pu8Buffer++ = pstrHostIFscanAttr->hidden_network.n_ssids;
826
827 for (i = 0; i < pstrHostIFscanAttr->hidden_network.n_ssids; i++) {
828 *pu8Buffer++ = pstrHostIFscanAttr->hidden_network.net_info[i].ssid_len;
829 memcpy(pu8Buffer, pstrHostIFscanAttr->hidden_network.net_info[i].ssid, pstrHostIFscanAttr->hidden_network.net_info[i].ssid_len);
830 pu8Buffer += pstrHostIFscanAttr->hidden_network.net_info[i].ssid_len;
831 }
832
833 strWIDList[u32WidsCount].size = (s32)(valuesize + 1);
834 u32WidsCount++;
835 }
836
837 {
838 strWIDList[u32WidsCount].id = WID_INFO_ELEMENT_PROBE;
839 strWIDList[u32WidsCount].type = WID_BIN_DATA;
840 strWIDList[u32WidsCount].val = pstrHostIFscanAttr->ies;
841 strWIDList[u32WidsCount].size = pstrHostIFscanAttr->ies_len;
842 u32WidsCount++;
843 }
844
845 strWIDList[u32WidsCount].id = WID_SCAN_TYPE;
846 strWIDList[u32WidsCount].type = WID_CHAR;
847 strWIDList[u32WidsCount].size = sizeof(char);
848 strWIDList[u32WidsCount].val = (s8 *)&pstrHostIFscanAttr->type;
849 u32WidsCount++;
850
851 strWIDList[u32WidsCount].id = WID_SCAN_CHANNEL_LIST;
852 strWIDList[u32WidsCount].type = WID_BIN_DATA;
853
854 if (pstrHostIFscanAttr->ch_freq_list &&
855 pstrHostIFscanAttr->ch_list_len > 0) {
856 int i;
857
858 for (i = 0; i < pstrHostIFscanAttr->ch_list_len; i++) {
859 if (pstrHostIFscanAttr->ch_freq_list[i] > 0)
860 pstrHostIFscanAttr->ch_freq_list[i] = pstrHostIFscanAttr->ch_freq_list[i] - 1;
861 }
862 }
863
864 strWIDList[u32WidsCount].val = pstrHostIFscanAttr->ch_freq_list;
865 strWIDList[u32WidsCount].size = pstrHostIFscanAttr->ch_list_len;
866 u32WidsCount++;
867
868 strWIDList[u32WidsCount].id = WID_START_SCAN_REQ;
869 strWIDList[u32WidsCount].type = WID_CHAR;
870 strWIDList[u32WidsCount].size = sizeof(char);
871 strWIDList[u32WidsCount].val = (s8 *)&pstrHostIFscanAttr->src;
872 u32WidsCount++;
873
874 if (hif_drv->hif_state == HOST_IF_CONNECTED)
875 scan_while_connected = true;
876 else if (hif_drv->hif_state == HOST_IF_IDLE)
877 scan_while_connected = false;
878
879 result = wilc_send_config_pkt(vif, SET_CFG, strWIDList,
880 u32WidsCount,
881 wilc_get_vif_idx(vif));
882
883 if (result)
884 PRINT_ER("Failed to send scan parameters config packet\n");
885
886 ERRORHANDLER:
887 if (result) {
888 del_timer(&hif_drv->scan_timer);
889 Handle_ScanDone(vif, SCAN_EVENT_ABORTED);
890 }
891
892 kfree(pstrHostIFscanAttr->ch_freq_list);
893 pstrHostIFscanAttr->ch_freq_list = NULL;
894
895 kfree(pstrHostIFscanAttr->ies);
896 pstrHostIFscanAttr->ies = NULL;
897 kfree(pstrHostIFscanAttr->hidden_network.net_info);
898 pstrHostIFscanAttr->hidden_network.net_info = NULL;
899
900 kfree(pu8HdnNtwrksWidVal);
901
902 return result;
903 }
904
905 static s32 Handle_ScanDone(struct wilc_vif *vif,
906 enum scan_event enuEvent)
907 {
908 s32 result = 0;
909 u8 u8abort_running_scan;
910 struct wid wid;
911 struct host_if_drv *hif_drv = vif->hif_drv;
912
913 if (enuEvent == SCAN_EVENT_ABORTED) {
914 u8abort_running_scan = 1;
915 wid.id = (u16)WID_ABORT_RUNNING_SCAN;
916 wid.type = WID_CHAR;
917 wid.val = (s8 *)&u8abort_running_scan;
918 wid.size = sizeof(char);
919
920 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
921 wilc_get_vif_idx(vif));
922
923 if (result) {
924 PRINT_ER("Failed to set abort running scan\n");
925 result = -EFAULT;
926 }
927 }
928
929 if (!hif_drv) {
930 PRINT_ER("Driver handler is NULL\n");
931 return result;
932 }
933
934 if (hif_drv->usr_scan_req.scan_result) {
935 hif_drv->usr_scan_req.scan_result(enuEvent, NULL,
936 hif_drv->usr_scan_req.arg, NULL);
937 hif_drv->usr_scan_req.scan_result = NULL;
938 }
939
940 return result;
941 }
942
943 u8 wilc_connected_ssid[6] = {0};
944 static s32 Handle_Connect(struct wilc_vif *vif,
945 struct connect_attr *pstrHostIFconnectAttr)
946 {
947 s32 result = 0;
948 struct wid strWIDList[8];
949 u32 u32WidsCount = 0, dummyval = 0;
950 u8 *pu8CurrByte = NULL;
951 struct join_bss_param *ptstrJoinBssParam;
952 struct host_if_drv *hif_drv = vif->hif_drv;
953
954 if (memcmp(pstrHostIFconnectAttr->bssid, wilc_connected_ssid, ETH_ALEN) == 0) {
955 result = 0;
956 PRINT_ER("Trying to connect to an already connected AP, Discard connect request\n");
957 return result;
958 }
959
960 ptstrJoinBssParam = (struct join_bss_param *)pstrHostIFconnectAttr->params;
961 if (!ptstrJoinBssParam) {
962 PRINT_ER("Required BSSID not found\n");
963 result = -ENOENT;
964 goto ERRORHANDLER;
965 }
966
967 if (pstrHostIFconnectAttr->bssid) {
968 hif_drv->usr_conn_req.bssid = kmalloc(6, GFP_KERNEL);
969 memcpy(hif_drv->usr_conn_req.bssid, pstrHostIFconnectAttr->bssid, 6);
970 }
971
972 hif_drv->usr_conn_req.ssid_len = pstrHostIFconnectAttr->ssid_len;
973 if (pstrHostIFconnectAttr->ssid) {
974 hif_drv->usr_conn_req.ssid = kmalloc(pstrHostIFconnectAttr->ssid_len + 1, GFP_KERNEL);
975 memcpy(hif_drv->usr_conn_req.ssid,
976 pstrHostIFconnectAttr->ssid,
977 pstrHostIFconnectAttr->ssid_len);
978 hif_drv->usr_conn_req.ssid[pstrHostIFconnectAttr->ssid_len] = '\0';
979 }
980
981 hif_drv->usr_conn_req.ies_len = pstrHostIFconnectAttr->ies_len;
982 if (pstrHostIFconnectAttr->ies) {
983 hif_drv->usr_conn_req.ies = kmalloc(pstrHostIFconnectAttr->ies_len, GFP_KERNEL);
984 memcpy(hif_drv->usr_conn_req.ies,
985 pstrHostIFconnectAttr->ies,
986 pstrHostIFconnectAttr->ies_len);
987 }
988
989 hif_drv->usr_conn_req.security = pstrHostIFconnectAttr->security;
990 hif_drv->usr_conn_req.auth_type = pstrHostIFconnectAttr->auth_type;
991 hif_drv->usr_conn_req.conn_result = pstrHostIFconnectAttr->result;
992 hif_drv->usr_conn_req.arg = pstrHostIFconnectAttr->arg;
993
994 strWIDList[u32WidsCount].id = WID_SUCCESS_FRAME_COUNT;
995 strWIDList[u32WidsCount].type = WID_INT;
996 strWIDList[u32WidsCount].size = sizeof(u32);
997 strWIDList[u32WidsCount].val = (s8 *)(&(dummyval));
998 u32WidsCount++;
999
1000 strWIDList[u32WidsCount].id = WID_RECEIVED_FRAGMENT_COUNT;
1001 strWIDList[u32WidsCount].type = WID_INT;
1002 strWIDList[u32WidsCount].size = sizeof(u32);
1003 strWIDList[u32WidsCount].val = (s8 *)(&(dummyval));
1004 u32WidsCount++;
1005
1006 strWIDList[u32WidsCount].id = WID_FAILED_COUNT;
1007 strWIDList[u32WidsCount].type = WID_INT;
1008 strWIDList[u32WidsCount].size = sizeof(u32);
1009 strWIDList[u32WidsCount].val = (s8 *)(&(dummyval));
1010 u32WidsCount++;
1011
1012 {
1013 strWIDList[u32WidsCount].id = WID_INFO_ELEMENT_ASSOCIATE;
1014 strWIDList[u32WidsCount].type = WID_BIN_DATA;
1015 strWIDList[u32WidsCount].val = hif_drv->usr_conn_req.ies;
1016 strWIDList[u32WidsCount].size = hif_drv->usr_conn_req.ies_len;
1017 u32WidsCount++;
1018
1019 if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
1020 info_element_size = hif_drv->usr_conn_req.ies_len;
1021 info_element = kmalloc(info_element_size, GFP_KERNEL);
1022 memcpy(info_element, hif_drv->usr_conn_req.ies,
1023 info_element_size);
1024 }
1025 }
1026 strWIDList[u32WidsCount].id = (u16)WID_11I_MODE;
1027 strWIDList[u32WidsCount].type = WID_CHAR;
1028 strWIDList[u32WidsCount].size = sizeof(char);
1029 strWIDList[u32WidsCount].val = (s8 *)&hif_drv->usr_conn_req.security;
1030 u32WidsCount++;
1031
1032 if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7))
1033 mode_11i = hif_drv->usr_conn_req.security;
1034
1035 strWIDList[u32WidsCount].id = (u16)WID_AUTH_TYPE;
1036 strWIDList[u32WidsCount].type = WID_CHAR;
1037 strWIDList[u32WidsCount].size = sizeof(char);
1038 strWIDList[u32WidsCount].val = (s8 *)&hif_drv->usr_conn_req.auth_type;
1039 u32WidsCount++;
1040
1041 if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7))
1042 auth_type = (u8)hif_drv->usr_conn_req.auth_type;
1043
1044 strWIDList[u32WidsCount].id = (u16)WID_JOIN_REQ_EXTENDED;
1045 strWIDList[u32WidsCount].type = WID_STR;
1046 strWIDList[u32WidsCount].size = 112;
1047 strWIDList[u32WidsCount].val = kmalloc(strWIDList[u32WidsCount].size, GFP_KERNEL);
1048
1049 if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
1050 join_req_size = strWIDList[u32WidsCount].size;
1051 join_req = kmalloc(join_req_size, GFP_KERNEL);
1052 }
1053 if (!strWIDList[u32WidsCount].val) {
1054 result = -EFAULT;
1055 goto ERRORHANDLER;
1056 }
1057
1058 pu8CurrByte = strWIDList[u32WidsCount].val;
1059
1060 if (pstrHostIFconnectAttr->ssid) {
1061 memcpy(pu8CurrByte, pstrHostIFconnectAttr->ssid, pstrHostIFconnectAttr->ssid_len);
1062 pu8CurrByte[pstrHostIFconnectAttr->ssid_len] = '\0';
1063 }
1064 pu8CurrByte += MAX_SSID_LEN;
1065 *(pu8CurrByte++) = INFRASTRUCTURE;
1066
1067 if ((pstrHostIFconnectAttr->ch >= 1) && (pstrHostIFconnectAttr->ch <= 14)) {
1068 *(pu8CurrByte++) = pstrHostIFconnectAttr->ch;
1069 } else {
1070 PRINT_ER("Channel out of range\n");
1071 *(pu8CurrByte++) = 0xFF;
1072 }
1073 *(pu8CurrByte++) = (ptstrJoinBssParam->cap_info) & 0xFF;
1074 *(pu8CurrByte++) = ((ptstrJoinBssParam->cap_info) >> 8) & 0xFF;
1075
1076 if (pstrHostIFconnectAttr->bssid)
1077 memcpy(pu8CurrByte, pstrHostIFconnectAttr->bssid, 6);
1078 pu8CurrByte += 6;
1079
1080 if (pstrHostIFconnectAttr->bssid)
1081 memcpy(pu8CurrByte, pstrHostIFconnectAttr->bssid, 6);
1082 pu8CurrByte += 6;
1083
1084 *(pu8CurrByte++) = (ptstrJoinBssParam->beacon_period) & 0xFF;
1085 *(pu8CurrByte++) = ((ptstrJoinBssParam->beacon_period) >> 8) & 0xFF;
1086 *(pu8CurrByte++) = ptstrJoinBssParam->dtim_period;
1087
1088 memcpy(pu8CurrByte, ptstrJoinBssParam->supp_rates, MAX_RATES_SUPPORTED + 1);
1089 pu8CurrByte += (MAX_RATES_SUPPORTED + 1);
1090
1091 *(pu8CurrByte++) = ptstrJoinBssParam->wmm_cap;
1092 *(pu8CurrByte++) = ptstrJoinBssParam->uapsd_cap;
1093
1094 *(pu8CurrByte++) = ptstrJoinBssParam->ht_capable;
1095 hif_drv->usr_conn_req.ht_capable = ptstrJoinBssParam->ht_capable;
1096
1097 *(pu8CurrByte++) = ptstrJoinBssParam->rsn_found;
1098 *(pu8CurrByte++) = ptstrJoinBssParam->rsn_grp_policy;
1099 *(pu8CurrByte++) = ptstrJoinBssParam->mode_802_11i;
1100
1101 memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_pcip_policy, sizeof(ptstrJoinBssParam->rsn_pcip_policy));
1102 pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_pcip_policy);
1103
1104 memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_auth_policy, sizeof(ptstrJoinBssParam->rsn_auth_policy));
1105 pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_auth_policy);
1106
1107 memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_cap, sizeof(ptstrJoinBssParam->rsn_cap));
1108 pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_cap);
1109
1110 *(pu8CurrByte++) = REAL_JOIN_REQ;
1111 *(pu8CurrByte++) = ptstrJoinBssParam->noa_enabled;
1112
1113 if (ptstrJoinBssParam->noa_enabled) {
1114 *(pu8CurrByte++) = (ptstrJoinBssParam->tsf) & 0xFF;
1115 *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 8) & 0xFF;
1116 *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 16) & 0xFF;
1117 *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 24) & 0xFF;
1118
1119 *(pu8CurrByte++) = ptstrJoinBssParam->opp_enabled;
1120 *(pu8CurrByte++) = ptstrJoinBssParam->idx;
1121
1122 if (ptstrJoinBssParam->opp_enabled)
1123 *(pu8CurrByte++) = ptstrJoinBssParam->ct_window;
1124
1125 *(pu8CurrByte++) = ptstrJoinBssParam->cnt;
1126
1127 memcpy(pu8CurrByte, ptstrJoinBssParam->duration, sizeof(ptstrJoinBssParam->duration));
1128 pu8CurrByte += sizeof(ptstrJoinBssParam->duration);
1129
1130 memcpy(pu8CurrByte, ptstrJoinBssParam->interval, sizeof(ptstrJoinBssParam->interval));
1131 pu8CurrByte += sizeof(ptstrJoinBssParam->interval);
1132
1133 memcpy(pu8CurrByte, ptstrJoinBssParam->start_time, sizeof(ptstrJoinBssParam->start_time));
1134 pu8CurrByte += sizeof(ptstrJoinBssParam->start_time);
1135 }
1136
1137 pu8CurrByte = strWIDList[u32WidsCount].val;
1138 u32WidsCount++;
1139
1140 if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
1141 memcpy(join_req, pu8CurrByte, join_req_size);
1142 join_req_vif = vif;
1143 }
1144
1145 if (pstrHostIFconnectAttr->bssid)
1146 memcpy(wilc_connected_ssid,
1147 pstrHostIFconnectAttr->bssid, ETH_ALEN);
1148
1149 result = wilc_send_config_pkt(vif, SET_CFG, strWIDList,
1150 u32WidsCount,
1151 wilc_get_vif_idx(vif));
1152 if (result) {
1153 PRINT_ER("failed to send config packet\n");
1154 result = -EFAULT;
1155 goto ERRORHANDLER;
1156 } else {
1157 hif_drv->hif_state = HOST_IF_WAITING_CONN_RESP;
1158 }
1159
1160 ERRORHANDLER:
1161 if (result) {
1162 tstrConnectInfo strConnectInfo;
1163
1164 del_timer(&hif_drv->connect_timer);
1165
1166 memset(&strConnectInfo, 0, sizeof(tstrConnectInfo));
1167
1168 if (pstrHostIFconnectAttr->result) {
1169 if (pstrHostIFconnectAttr->bssid)
1170 memcpy(strConnectInfo.au8bssid, pstrHostIFconnectAttr->bssid, 6);
1171
1172 if (pstrHostIFconnectAttr->ies) {
1173 strConnectInfo.ReqIEsLen = pstrHostIFconnectAttr->ies_len;
1174 strConnectInfo.pu8ReqIEs = kmalloc(pstrHostIFconnectAttr->ies_len, GFP_KERNEL);
1175 memcpy(strConnectInfo.pu8ReqIEs,
1176 pstrHostIFconnectAttr->ies,
1177 pstrHostIFconnectAttr->ies_len);
1178 }
1179
1180 pstrHostIFconnectAttr->result(CONN_DISCONN_EVENT_CONN_RESP,
1181 &strConnectInfo,
1182 MAC_DISCONNECTED,
1183 NULL,
1184 pstrHostIFconnectAttr->arg);
1185 hif_drv->hif_state = HOST_IF_IDLE;
1186 kfree(strConnectInfo.pu8ReqIEs);
1187 strConnectInfo.pu8ReqIEs = NULL;
1188
1189 } else {
1190 PRINT_ER("Connect callback function pointer is NULL\n");
1191 }
1192 }
1193
1194 kfree(pstrHostIFconnectAttr->bssid);
1195 pstrHostIFconnectAttr->bssid = NULL;
1196
1197 kfree(pstrHostIFconnectAttr->ssid);
1198 pstrHostIFconnectAttr->ssid = NULL;
1199
1200 kfree(pstrHostIFconnectAttr->ies);
1201 pstrHostIFconnectAttr->ies = NULL;
1202
1203 kfree(pu8CurrByte);
1204 return result;
1205 }
1206
1207 static s32 Handle_FlushConnect(struct wilc_vif *vif)
1208 {
1209 s32 result = 0;
1210 struct wid strWIDList[5];
1211 u32 u32WidsCount = 0;
1212 u8 *pu8CurrByte = NULL;
1213
1214 strWIDList[u32WidsCount].id = WID_INFO_ELEMENT_ASSOCIATE;
1215 strWIDList[u32WidsCount].type = WID_BIN_DATA;
1216 strWIDList[u32WidsCount].val = info_element;
1217 strWIDList[u32WidsCount].size = info_element_size;
1218 u32WidsCount++;
1219
1220 strWIDList[u32WidsCount].id = (u16)WID_11I_MODE;
1221 strWIDList[u32WidsCount].type = WID_CHAR;
1222 strWIDList[u32WidsCount].size = sizeof(char);
1223 strWIDList[u32WidsCount].val = (s8 *)(&(mode_11i));
1224 u32WidsCount++;
1225
1226 strWIDList[u32WidsCount].id = (u16)WID_AUTH_TYPE;
1227 strWIDList[u32WidsCount].type = WID_CHAR;
1228 strWIDList[u32WidsCount].size = sizeof(char);
1229 strWIDList[u32WidsCount].val = (s8 *)(&auth_type);
1230 u32WidsCount++;
1231
1232 strWIDList[u32WidsCount].id = (u16)WID_JOIN_REQ_EXTENDED;
1233 strWIDList[u32WidsCount].type = WID_STR;
1234 strWIDList[u32WidsCount].size = join_req_size;
1235 strWIDList[u32WidsCount].val = (s8 *)join_req;
1236 pu8CurrByte = strWIDList[u32WidsCount].val;
1237
1238 pu8CurrByte += FLUSHED_BYTE_POS;
1239 *(pu8CurrByte) = FLUSHED_JOIN_REQ;
1240
1241 u32WidsCount++;
1242
1243 result = wilc_send_config_pkt(vif, SET_CFG, strWIDList,
1244 u32WidsCount,
1245 wilc_get_vif_idx(join_req_vif));
1246 if (result) {
1247 PRINT_ER("failed to send config packet\n");
1248 result = -EINVAL;
1249 }
1250
1251 return result;
1252 }
1253
1254 static s32 Handle_ConnectTimeout(struct wilc_vif *vif)
1255 {
1256 s32 result = 0;
1257 tstrConnectInfo strConnectInfo;
1258 struct wid wid;
1259 u16 u16DummyReasonCode = 0;
1260 struct host_if_drv *hif_drv = vif->hif_drv;
1261
1262 if (!hif_drv) {
1263 PRINT_ER("Driver handler is NULL\n");
1264 return result;
1265 }
1266
1267 hif_drv->hif_state = HOST_IF_IDLE;
1268
1269 scan_while_connected = false;
1270
1271 memset(&strConnectInfo, 0, sizeof(tstrConnectInfo));
1272
1273 if (hif_drv->usr_conn_req.conn_result) {
1274 if (hif_drv->usr_conn_req.bssid) {
1275 memcpy(strConnectInfo.au8bssid,
1276 hif_drv->usr_conn_req.bssid, 6);
1277 }
1278
1279 if (hif_drv->usr_conn_req.ies) {
1280 strConnectInfo.ReqIEsLen = hif_drv->usr_conn_req.ies_len;
1281 strConnectInfo.pu8ReqIEs = kmalloc(hif_drv->usr_conn_req.ies_len, GFP_KERNEL);
1282 memcpy(strConnectInfo.pu8ReqIEs,
1283 hif_drv->usr_conn_req.ies,
1284 hif_drv->usr_conn_req.ies_len);
1285 }
1286
1287 hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_CONN_RESP,
1288 &strConnectInfo,
1289 MAC_DISCONNECTED,
1290 NULL,
1291 hif_drv->usr_conn_req.arg);
1292
1293 kfree(strConnectInfo.pu8ReqIEs);
1294 strConnectInfo.pu8ReqIEs = NULL;
1295 } else {
1296 PRINT_ER("Connect callback function pointer is NULL\n");
1297 }
1298
1299 wid.id = (u16)WID_DISCONNECT;
1300 wid.type = WID_CHAR;
1301 wid.val = (s8 *)&u16DummyReasonCode;
1302 wid.size = sizeof(char);
1303
1304 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
1305 wilc_get_vif_idx(vif));
1306 if (result)
1307 PRINT_ER("Failed to send dissconect config packet\n");
1308
1309 hif_drv->usr_conn_req.ssid_len = 0;
1310 kfree(hif_drv->usr_conn_req.ssid);
1311 hif_drv->usr_conn_req.ssid = NULL;
1312 kfree(hif_drv->usr_conn_req.bssid);
1313 hif_drv->usr_conn_req.bssid = NULL;
1314 hif_drv->usr_conn_req.ies_len = 0;
1315 kfree(hif_drv->usr_conn_req.ies);
1316 hif_drv->usr_conn_req.ies = NULL;
1317
1318 eth_zero_addr(wilc_connected_ssid);
1319
1320 if (join_req && join_req_vif == vif) {
1321 kfree(join_req);
1322 join_req = NULL;
1323 }
1324
1325 if (info_element && join_req_vif == vif) {
1326 kfree(info_element);
1327 info_element = NULL;
1328 }
1329
1330 return result;
1331 }
1332
1333 static s32 Handle_RcvdNtwrkInfo(struct wilc_vif *vif,
1334 struct rcvd_net_info *pstrRcvdNetworkInfo)
1335 {
1336 u32 i;
1337 bool bNewNtwrkFound;
1338 s32 result = 0;
1339 struct network_info *pstrNetworkInfo = NULL;
1340 void *pJoinParams = NULL;
1341 struct host_if_drv *hif_drv = vif->hif_drv;
1342
1343 bNewNtwrkFound = true;
1344
1345 if (hif_drv->usr_scan_req.scan_result) {
1346 wilc_parse_network_info(pstrRcvdNetworkInfo->buffer, &pstrNetworkInfo);
1347 if ((!pstrNetworkInfo) ||
1348 (!hif_drv->usr_scan_req.scan_result)) {
1349 PRINT_ER("driver is null\n");
1350 result = -EINVAL;
1351 goto done;
1352 }
1353
1354 for (i = 0; i < hif_drv->usr_scan_req.rcvd_ch_cnt; i++) {
1355 if ((hif_drv->usr_scan_req.net_info[i].bssid) &&
1356 (pstrNetworkInfo->bssid)) {
1357 if (memcmp(hif_drv->usr_scan_req.net_info[i].bssid,
1358 pstrNetworkInfo->bssid, 6) == 0) {
1359 if (pstrNetworkInfo->rssi <= hif_drv->usr_scan_req.net_info[i].rssi) {
1360 goto done;
1361 } else {
1362 hif_drv->usr_scan_req.net_info[i].rssi = pstrNetworkInfo->rssi;
1363 bNewNtwrkFound = false;
1364 break;
1365 }
1366 }
1367 }
1368 }
1369
1370 if (bNewNtwrkFound) {
1371 if (hif_drv->usr_scan_req.rcvd_ch_cnt < MAX_NUM_SCANNED_NETWORKS) {
1372 hif_drv->usr_scan_req.net_info[hif_drv->usr_scan_req.rcvd_ch_cnt].rssi = pstrNetworkInfo->rssi;
1373
1374 if (hif_drv->usr_scan_req.net_info[hif_drv->usr_scan_req.rcvd_ch_cnt].bssid &&
1375 pstrNetworkInfo->bssid) {
1376 memcpy(hif_drv->usr_scan_req.net_info[hif_drv->usr_scan_req.rcvd_ch_cnt].bssid,
1377 pstrNetworkInfo->bssid, 6);
1378
1379 hif_drv->usr_scan_req.rcvd_ch_cnt++;
1380
1381 pstrNetworkInfo->new_network = true;
1382 pJoinParams = host_int_ParseJoinBssParam(pstrNetworkInfo);
1383
1384 hif_drv->usr_scan_req.scan_result(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo,
1385 hif_drv->usr_scan_req.arg,
1386 pJoinParams);
1387 }
1388 }
1389 } else {
1390 pstrNetworkInfo->new_network = false;
1391 hif_drv->usr_scan_req.scan_result(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo,
1392 hif_drv->usr_scan_req.arg, NULL);
1393 }
1394 }
1395
1396 done:
1397 kfree(pstrRcvdNetworkInfo->buffer);
1398 pstrRcvdNetworkInfo->buffer = NULL;
1399
1400 if (pstrNetworkInfo) {
1401 kfree(pstrNetworkInfo->ies);
1402 kfree(pstrNetworkInfo);
1403 }
1404
1405 return result;
1406 }
1407
1408 static s32 host_int_get_assoc_res_info(struct wilc_vif *vif,
1409 u8 *pu8AssocRespInfo,
1410 u32 u32MaxAssocRespInfoLen,
1411 u32 *pu32RcvdAssocRespInfoLen);
1412
1413 static s32 Handle_RcvdGnrlAsyncInfo(struct wilc_vif *vif,
1414 struct rcvd_async_info *pstrRcvdGnrlAsyncInfo)
1415 {
1416 s32 result = 0;
1417 u8 u8MsgType = 0;
1418 u8 u8MsgID = 0;
1419 u16 u16MsgLen = 0;
1420 u16 u16WidID = (u16)WID_NIL;
1421 u8 u8WidLen = 0;
1422 u8 u8MacStatus;
1423 u8 u8MacStatusReasonCode;
1424 u8 u8MacStatusAdditionalInfo;
1425 tstrConnectInfo strConnectInfo;
1426 tstrDisconnectNotifInfo strDisconnectNotifInfo;
1427 s32 s32Err = 0;
1428 struct host_if_drv *hif_drv = vif->hif_drv;
1429
1430 if (!hif_drv) {
1431 PRINT_ER("Driver handler is NULL\n");
1432 return -ENODEV;
1433 }
1434
1435 if ((hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) ||
1436 (hif_drv->hif_state == HOST_IF_CONNECTED) ||
1437 hif_drv->usr_scan_req.scan_result) {
1438 if (!pstrRcvdGnrlAsyncInfo->buffer ||
1439 !hif_drv->usr_conn_req.conn_result) {
1440 PRINT_ER("driver is null\n");
1441 return -EINVAL;
1442 }
1443
1444 u8MsgType = pstrRcvdGnrlAsyncInfo->buffer[0];
1445
1446 if ('I' != u8MsgType) {
1447 PRINT_ER("Received Message format incorrect.\n");
1448 return -EFAULT;
1449 }
1450
1451 u8MsgID = pstrRcvdGnrlAsyncInfo->buffer[1];
1452 u16MsgLen = MAKE_WORD16(pstrRcvdGnrlAsyncInfo->buffer[2], pstrRcvdGnrlAsyncInfo->buffer[3]);
1453 u16WidID = MAKE_WORD16(pstrRcvdGnrlAsyncInfo->buffer[4], pstrRcvdGnrlAsyncInfo->buffer[5]);
1454 u8WidLen = pstrRcvdGnrlAsyncInfo->buffer[6];
1455 u8MacStatus = pstrRcvdGnrlAsyncInfo->buffer[7];
1456 u8MacStatusReasonCode = pstrRcvdGnrlAsyncInfo->buffer[8];
1457 u8MacStatusAdditionalInfo = pstrRcvdGnrlAsyncInfo->buffer[9];
1458 if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) {
1459 u32 u32RcvdAssocRespInfoLen = 0;
1460 struct connect_resp_info *pstrConnectRespInfo = NULL;
1461
1462 memset(&strConnectInfo, 0, sizeof(tstrConnectInfo));
1463
1464 if (u8MacStatus == MAC_CONNECTED) {
1465 memset(rcv_assoc_resp, 0, MAX_ASSOC_RESP_FRAME_SIZE);
1466
1467 host_int_get_assoc_res_info(vif,
1468 rcv_assoc_resp,
1469 MAX_ASSOC_RESP_FRAME_SIZE,
1470 &u32RcvdAssocRespInfoLen);
1471
1472 if (u32RcvdAssocRespInfoLen != 0) {
1473 s32Err = wilc_parse_assoc_resp_info(rcv_assoc_resp, u32RcvdAssocRespInfoLen,
1474 &pstrConnectRespInfo);
1475 if (s32Err) {
1476 PRINT_ER("wilc_parse_assoc_resp_info() returned error %d\n", s32Err);
1477 } else {
1478 strConnectInfo.u16ConnectStatus = pstrConnectRespInfo->status;
1479
1480 if (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE) {
1481 if (pstrConnectRespInfo->ies) {
1482 strConnectInfo.u16RespIEsLen = pstrConnectRespInfo->ies_len;
1483 strConnectInfo.pu8RespIEs = kmalloc(pstrConnectRespInfo->ies_len, GFP_KERNEL);
1484 memcpy(strConnectInfo.pu8RespIEs, pstrConnectRespInfo->ies,
1485 pstrConnectRespInfo->ies_len);
1486 }
1487 }
1488
1489 if (pstrConnectRespInfo) {
1490 kfree(pstrConnectRespInfo->ies);
1491 kfree(pstrConnectRespInfo);
1492 }
1493 }
1494 }
1495 }
1496
1497 if ((u8MacStatus == MAC_CONNECTED) &&
1498 (strConnectInfo.u16ConnectStatus != SUCCESSFUL_STATUSCODE)) {
1499 PRINT_ER("Received MAC status is MAC_CONNECTED while the received status code in Asoc Resp is not SUCCESSFUL_STATUSCODE\n");
1500 eth_zero_addr(wilc_connected_ssid);
1501 } else if (u8MacStatus == MAC_DISCONNECTED) {
1502 PRINT_ER("Received MAC status is MAC_DISCONNECTED\n");
1503 eth_zero_addr(wilc_connected_ssid);
1504 }
1505
1506 if (hif_drv->usr_conn_req.bssid) {
1507 memcpy(strConnectInfo.au8bssid, hif_drv->usr_conn_req.bssid, 6);
1508
1509 if ((u8MacStatus == MAC_CONNECTED) &&
1510 (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
1511 memcpy(hif_drv->assoc_bssid,
1512 hif_drv->usr_conn_req.bssid, ETH_ALEN);
1513 }
1514 }
1515
1516 if (hif_drv->usr_conn_req.ies) {
1517 strConnectInfo.ReqIEsLen = hif_drv->usr_conn_req.ies_len;
1518 strConnectInfo.pu8ReqIEs = kmalloc(hif_drv->usr_conn_req.ies_len, GFP_KERNEL);
1519 memcpy(strConnectInfo.pu8ReqIEs,
1520 hif_drv->usr_conn_req.ies,
1521 hif_drv->usr_conn_req.ies_len);
1522 }
1523
1524 del_timer(&hif_drv->connect_timer);
1525 hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_CONN_RESP,
1526 &strConnectInfo,
1527 u8MacStatus,
1528 NULL,
1529 hif_drv->usr_conn_req.arg);
1530
1531 if ((u8MacStatus == MAC_CONNECTED) &&
1532 (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
1533 wilc_set_power_mgmt(vif, 0, 0);
1534
1535 hif_drv->hif_state = HOST_IF_CONNECTED;
1536
1537 wilc_optaining_ip = true;
1538 mod_timer(&wilc_during_ip_timer,
1539 jiffies + msecs_to_jiffies(10000));
1540 } else {
1541 hif_drv->hif_state = HOST_IF_IDLE;
1542 scan_while_connected = false;
1543 }
1544
1545 kfree(strConnectInfo.pu8RespIEs);
1546 strConnectInfo.pu8RespIEs = NULL;
1547
1548 kfree(strConnectInfo.pu8ReqIEs);
1549 strConnectInfo.pu8ReqIEs = NULL;
1550 hif_drv->usr_conn_req.ssid_len = 0;
1551 kfree(hif_drv->usr_conn_req.ssid);
1552 hif_drv->usr_conn_req.ssid = NULL;
1553 kfree(hif_drv->usr_conn_req.bssid);
1554 hif_drv->usr_conn_req.bssid = NULL;
1555 hif_drv->usr_conn_req.ies_len = 0;
1556 kfree(hif_drv->usr_conn_req.ies);
1557 hif_drv->usr_conn_req.ies = NULL;
1558 } else if ((u8MacStatus == MAC_DISCONNECTED) &&
1559 (hif_drv->hif_state == HOST_IF_CONNECTED)) {
1560 memset(&strDisconnectNotifInfo, 0, sizeof(tstrDisconnectNotifInfo));
1561
1562 if (hif_drv->usr_scan_req.scan_result) {
1563 del_timer(&hif_drv->scan_timer);
1564 Handle_ScanDone(vif, SCAN_EVENT_ABORTED);
1565 }
1566
1567 strDisconnectNotifInfo.u16reason = 0;
1568 strDisconnectNotifInfo.ie = NULL;
1569 strDisconnectNotifInfo.ie_len = 0;
1570
1571 if (hif_drv->usr_conn_req.conn_result) {
1572 wilc_optaining_ip = false;
1573 wilc_set_power_mgmt(vif, 0, 0);
1574
1575 hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF,
1576 NULL,
1577 0,
1578 &strDisconnectNotifInfo,
1579 hif_drv->usr_conn_req.arg);
1580 } else {
1581 PRINT_ER("Connect result callback function is NULL\n");
1582 }
1583
1584 eth_zero_addr(hif_drv->assoc_bssid);
1585
1586 hif_drv->usr_conn_req.ssid_len = 0;
1587 kfree(hif_drv->usr_conn_req.ssid);
1588 hif_drv->usr_conn_req.ssid = NULL;
1589 kfree(hif_drv->usr_conn_req.bssid);
1590 hif_drv->usr_conn_req.bssid = NULL;
1591 hif_drv->usr_conn_req.ies_len = 0;
1592 kfree(hif_drv->usr_conn_req.ies);
1593 hif_drv->usr_conn_req.ies = NULL;
1594
1595 if (join_req && join_req_vif == vif) {
1596 kfree(join_req);
1597 join_req = NULL;
1598 }
1599
1600 if (info_element && join_req_vif == vif) {
1601 kfree(info_element);
1602 info_element = NULL;
1603 }
1604
1605 hif_drv->hif_state = HOST_IF_IDLE;
1606 scan_while_connected = false;
1607
1608 } else if ((u8MacStatus == MAC_DISCONNECTED) &&
1609 (hif_drv->usr_scan_req.scan_result)) {
1610 del_timer(&hif_drv->scan_timer);
1611 if (hif_drv->usr_scan_req.scan_result)
1612 Handle_ScanDone(vif, SCAN_EVENT_ABORTED);
1613 }
1614 }
1615
1616 kfree(pstrRcvdGnrlAsyncInfo->buffer);
1617 pstrRcvdGnrlAsyncInfo->buffer = NULL;
1618
1619 return result;
1620 }
1621
1622 static int Handle_Key(struct wilc_vif *vif,
1623 struct key_attr *pstrHostIFkeyAttr)
1624 {
1625 s32 result = 0;
1626 struct wid wid;
1627 struct wid strWIDList[5];
1628 u8 i;
1629 u8 *pu8keybuf;
1630 s8 s8idxarray[1];
1631 s8 ret = 0;
1632 struct host_if_drv *hif_drv = vif->hif_drv;
1633
1634 switch (pstrHostIFkeyAttr->type) {
1635 case WEP:
1636
1637 if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
1638 strWIDList[0].id = (u16)WID_11I_MODE;
1639 strWIDList[0].type = WID_CHAR;
1640 strWIDList[0].size = sizeof(char);
1641 strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wep.mode;
1642
1643 strWIDList[1].id = WID_AUTH_TYPE;
1644 strWIDList[1].type = WID_CHAR;
1645 strWIDList[1].size = sizeof(char);
1646 strWIDList[1].val = (s8 *)&pstrHostIFkeyAttr->attr.wep.auth_type;
1647
1648 pu8keybuf = kmalloc(pstrHostIFkeyAttr->attr.wep.key_len + 2,
1649 GFP_KERNEL);
1650
1651 if (pu8keybuf == NULL) {
1652 PRINT_ER("No buffer to send Key\n");
1653 return -ENOMEM;
1654 }
1655
1656 pu8keybuf[0] = pstrHostIFkeyAttr->attr.wep.index;
1657 pu8keybuf[1] = pstrHostIFkeyAttr->attr.wep.key_len;
1658
1659 memcpy(&pu8keybuf[2], pstrHostIFkeyAttr->attr.wep.key,
1660 pstrHostIFkeyAttr->attr.wep.key_len);
1661
1662 kfree(pstrHostIFkeyAttr->attr.wep.key);
1663
1664 strWIDList[2].id = (u16)WID_WEP_KEY_VALUE;
1665 strWIDList[2].type = WID_STR;
1666 strWIDList[2].size = pstrHostIFkeyAttr->attr.wep.key_len + 2;
1667 strWIDList[2].val = (s8 *)pu8keybuf;
1668
1669 result = wilc_send_config_pkt(vif, SET_CFG,
1670 strWIDList, 3,
1671 wilc_get_vif_idx(vif));
1672 kfree(pu8keybuf);
1673 } else if (pstrHostIFkeyAttr->action & ADDKEY) {
1674 pu8keybuf = kmalloc(pstrHostIFkeyAttr->attr.wep.key_len + 2, GFP_KERNEL);
1675 if (!pu8keybuf) {
1676 PRINT_ER("No buffer to send Key\n");
1677 return -ENOMEM;
1678 }
1679 pu8keybuf[0] = pstrHostIFkeyAttr->attr.wep.index;
1680 memcpy(pu8keybuf + 1, &pstrHostIFkeyAttr->attr.wep.key_len, 1);
1681 memcpy(pu8keybuf + 2, pstrHostIFkeyAttr->attr.wep.key,
1682 pstrHostIFkeyAttr->attr.wep.key_len);
1683 kfree(pstrHostIFkeyAttr->attr.wep.key);
1684
1685 wid.id = (u16)WID_ADD_WEP_KEY;
1686 wid.type = WID_STR;
1687 wid.val = (s8 *)pu8keybuf;
1688 wid.size = pstrHostIFkeyAttr->attr.wep.key_len + 2;
1689
1690 result = wilc_send_config_pkt(vif, SET_CFG,
1691 &wid, 1,
1692 wilc_get_vif_idx(vif));
1693 kfree(pu8keybuf);
1694 } else if (pstrHostIFkeyAttr->action & REMOVEKEY) {
1695 wid.id = (u16)WID_REMOVE_WEP_KEY;
1696 wid.type = WID_STR;
1697
1698 s8idxarray[0] = (s8)pstrHostIFkeyAttr->attr.wep.index;
1699 wid.val = s8idxarray;
1700 wid.size = 1;
1701
1702 result = wilc_send_config_pkt(vif, SET_CFG,
1703 &wid, 1,
1704 wilc_get_vif_idx(vif));
1705 } else if (pstrHostIFkeyAttr->action & DEFAULTKEY) {
1706 wid.id = (u16)WID_KEY_ID;
1707 wid.type = WID_CHAR;
1708 wid.val = (s8 *)&pstrHostIFkeyAttr->attr.wep.index;
1709 wid.size = sizeof(char);
1710
1711 result = wilc_send_config_pkt(vif, SET_CFG,
1712 &wid, 1,
1713 wilc_get_vif_idx(vif));
1714 }
1715 up(&hif_drv->sem_test_key_block);
1716 break;
1717
1718 case WPA_RX_GTK:
1719 if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
1720 pu8keybuf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
1721 if (!pu8keybuf) {
1722 PRINT_ER("No buffer to send RxGTK Key\n");
1723 ret = -ENOMEM;
1724 goto _WPARxGtk_end_case_;
1725 }
1726
1727 if (pstrHostIFkeyAttr->attr.wpa.seq)
1728 memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->attr.wpa.seq, 8);
1729
1730 memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->attr.wpa.index, 1);
1731 memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
1732 memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->attr.wpa.key,
1733 pstrHostIFkeyAttr->attr.wpa.key_len);
1734
1735 strWIDList[0].id = (u16)WID_11I_MODE;
1736 strWIDList[0].type = WID_CHAR;
1737 strWIDList[0].size = sizeof(char);
1738 strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wpa.mode;
1739
1740 strWIDList[1].id = (u16)WID_ADD_RX_GTK;
1741 strWIDList[1].type = WID_STR;
1742 strWIDList[1].val = (s8 *)pu8keybuf;
1743 strWIDList[1].size = RX_MIC_KEY_MSG_LEN;
1744
1745 result = wilc_send_config_pkt(vif, SET_CFG,
1746 strWIDList, 2,
1747 wilc_get_vif_idx(vif));
1748
1749 kfree(pu8keybuf);
1750 up(&hif_drv->sem_test_key_block);
1751 } else if (pstrHostIFkeyAttr->action & ADDKEY) {
1752 pu8keybuf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
1753 if (pu8keybuf == NULL) {
1754 PRINT_ER("No buffer to send RxGTK Key\n");
1755 ret = -ENOMEM;
1756 goto _WPARxGtk_end_case_;
1757 }
1758
1759 if (hif_drv->hif_state == HOST_IF_CONNECTED)
1760 memcpy(pu8keybuf, hif_drv->assoc_bssid, ETH_ALEN);
1761 else
1762 PRINT_ER("Couldn't handle WPARxGtk while state is not HOST_IF_CONNECTED\n");
1763
1764 memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->attr.wpa.seq, 8);
1765 memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->attr.wpa.index, 1);
1766 memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
1767 memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->attr.wpa.key,
1768 pstrHostIFkeyAttr->attr.wpa.key_len);
1769
1770 wid.id = (u16)WID_ADD_RX_GTK;
1771 wid.type = WID_STR;
1772 wid.val = (s8 *)pu8keybuf;
1773 wid.size = RX_MIC_KEY_MSG_LEN;
1774
1775 result = wilc_send_config_pkt(vif, SET_CFG,
1776 &wid, 1,
1777 wilc_get_vif_idx(vif));
1778
1779 kfree(pu8keybuf);
1780 up(&hif_drv->sem_test_key_block);
1781 }
1782 _WPARxGtk_end_case_:
1783 kfree(pstrHostIFkeyAttr->attr.wpa.key);
1784 kfree(pstrHostIFkeyAttr->attr.wpa.seq);
1785 if (ret)
1786 return ret;
1787
1788 break;
1789
1790 case WPA_PTK:
1791 if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
1792 pu8keybuf = kmalloc(PTK_KEY_MSG_LEN + 1, GFP_KERNEL);
1793 if (!pu8keybuf) {
1794 PRINT_ER("No buffer to send PTK Key\n");
1795 ret = -ENOMEM;
1796 goto _WPAPtk_end_case_;
1797 }
1798
1799 memcpy(pu8keybuf, pstrHostIFkeyAttr->attr.wpa.mac_addr, 6);
1800 memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->attr.wpa.index, 1);
1801 memcpy(pu8keybuf + 7, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
1802 memcpy(pu8keybuf + 8, pstrHostIFkeyAttr->attr.wpa.key,
1803 pstrHostIFkeyAttr->attr.wpa.key_len);
1804
1805 strWIDList[0].id = (u16)WID_11I_MODE;
1806 strWIDList[0].type = WID_CHAR;
1807 strWIDList[0].size = sizeof(char);
1808 strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wpa.mode;
1809
1810 strWIDList[1].id = (u16)WID_ADD_PTK;
1811 strWIDList[1].type = WID_STR;
1812 strWIDList[1].val = (s8 *)pu8keybuf;
1813 strWIDList[1].size = PTK_KEY_MSG_LEN + 1;
1814
1815 result = wilc_send_config_pkt(vif, SET_CFG,
1816 strWIDList, 2,
1817 wilc_get_vif_idx(vif));
1818 kfree(pu8keybuf);
1819 up(&hif_drv->sem_test_key_block);
1820 } else if (pstrHostIFkeyAttr->action & ADDKEY) {
1821 pu8keybuf = kmalloc(PTK_KEY_MSG_LEN, GFP_KERNEL);
1822 if (!pu8keybuf) {
1823 PRINT_ER("No buffer to send PTK Key\n");
1824 ret = -ENOMEM;
1825 goto _WPAPtk_end_case_;
1826 }
1827
1828 memcpy(pu8keybuf, pstrHostIFkeyAttr->attr.wpa.mac_addr, 6);
1829 memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
1830 memcpy(pu8keybuf + 7, pstrHostIFkeyAttr->attr.wpa.key,
1831 pstrHostIFkeyAttr->attr.wpa.key_len);
1832
1833 wid.id = (u16)WID_ADD_PTK;
1834 wid.type = WID_STR;
1835 wid.val = (s8 *)pu8keybuf;
1836 wid.size = PTK_KEY_MSG_LEN;
1837
1838 result = wilc_send_config_pkt(vif, SET_CFG,
1839 &wid, 1,
1840 wilc_get_vif_idx(vif));
1841 kfree(pu8keybuf);
1842 up(&hif_drv->sem_test_key_block);
1843 }
1844
1845 _WPAPtk_end_case_:
1846 kfree(pstrHostIFkeyAttr->attr.wpa.key);
1847 if (ret)
1848 return ret;
1849
1850 break;
1851
1852 case PMKSA:
1853 pu8keybuf = kmalloc((pstrHostIFkeyAttr->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1, GFP_KERNEL);
1854 if (!pu8keybuf) {
1855 PRINT_ER("No buffer to send PMKSA Key\n");
1856 return -ENOMEM;
1857 }
1858
1859 pu8keybuf[0] = pstrHostIFkeyAttr->attr.pmkid.numpmkid;
1860
1861 for (i = 0; i < pstrHostIFkeyAttr->attr.pmkid.numpmkid; i++) {
1862 memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + 1), pstrHostIFkeyAttr->attr.pmkid.pmkidlist[i].bssid, ETH_ALEN);
1863 memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + ETH_ALEN + 1), pstrHostIFkeyAttr->attr.pmkid.pmkidlist[i].pmkid, PMKID_LEN);
1864 }
1865
1866 wid.id = (u16)WID_PMKID_INFO;
1867 wid.type = WID_STR;
1868 wid.val = (s8 *)pu8keybuf;
1869 wid.size = (pstrHostIFkeyAttr->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1;
1870
1871 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
1872 wilc_get_vif_idx(vif));
1873
1874 kfree(pu8keybuf);
1875 break;
1876 }
1877
1878 if (result)
1879 PRINT_ER("Failed to send key config packet\n");
1880
1881 return result;
1882 }
1883
1884 static void Handle_Disconnect(struct wilc_vif *vif)
1885 {
1886 struct wid wid;
1887 struct host_if_drv *hif_drv = vif->hif_drv;
1888
1889 s32 result = 0;
1890 u16 u16DummyReasonCode = 0;
1891
1892 wid.id = (u16)WID_DISCONNECT;
1893 wid.type = WID_CHAR;
1894 wid.val = (s8 *)&u16DummyReasonCode;
1895 wid.size = sizeof(char);
1896
1897 wilc_optaining_ip = false;
1898 wilc_set_power_mgmt(vif, 0, 0);
1899
1900 eth_zero_addr(wilc_connected_ssid);
1901
1902 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
1903 wilc_get_vif_idx(vif));
1904
1905 if (result) {
1906 PRINT_ER("Failed to send dissconect config packet\n");
1907 } else {
1908 tstrDisconnectNotifInfo strDisconnectNotifInfo;
1909
1910 memset(&strDisconnectNotifInfo, 0, sizeof(tstrDisconnectNotifInfo));
1911
1912 strDisconnectNotifInfo.u16reason = 0;
1913 strDisconnectNotifInfo.ie = NULL;
1914 strDisconnectNotifInfo.ie_len = 0;
1915
1916 if (hif_drv->usr_scan_req.scan_result) {
1917 del_timer(&hif_drv->scan_timer);
1918 hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED,
1919 NULL,
1920 hif_drv->usr_scan_req.arg,
1921 NULL);
1922 hif_drv->usr_scan_req.scan_result = NULL;
1923 }
1924
1925 if (hif_drv->usr_conn_req.conn_result) {
1926 if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP)
1927 del_timer(&hif_drv->connect_timer);
1928
1929 hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF,
1930 NULL,
1931 0,
1932 &strDisconnectNotifInfo,
1933 hif_drv->usr_conn_req.arg);
1934 } else {
1935 PRINT_ER("usr_conn_req.conn_result = NULL\n");
1936 }
1937
1938 scan_while_connected = false;
1939
1940 hif_drv->hif_state = HOST_IF_IDLE;
1941
1942 eth_zero_addr(hif_drv->assoc_bssid);
1943
1944 hif_drv->usr_conn_req.ssid_len = 0;
1945 kfree(hif_drv->usr_conn_req.ssid);
1946 hif_drv->usr_conn_req.ssid = NULL;
1947 kfree(hif_drv->usr_conn_req.bssid);
1948 hif_drv->usr_conn_req.bssid = NULL;
1949 hif_drv->usr_conn_req.ies_len = 0;
1950 kfree(hif_drv->usr_conn_req.ies);
1951 hif_drv->usr_conn_req.ies = NULL;
1952
1953 if (join_req && join_req_vif == vif) {
1954 kfree(join_req);
1955 join_req = NULL;
1956 }
1957
1958 if (info_element && join_req_vif == vif) {
1959 kfree(info_element);
1960 info_element = NULL;
1961 }
1962 }
1963
1964 up(&hif_drv->sem_test_disconn_block);
1965 }
1966
1967 void wilc_resolve_disconnect_aberration(struct wilc_vif *vif)
1968 {
1969 if (!vif->hif_drv)
1970 return;
1971 if ((vif->hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) ||
1972 (vif->hif_drv->hif_state == HOST_IF_CONNECTING))
1973 wilc_disconnect(vif, 1);
1974 }
1975
1976 static s32 Handle_GetChnl(struct wilc_vif *vif)
1977 {
1978 s32 result = 0;
1979 struct wid wid;
1980 struct host_if_drv *hif_drv = vif->hif_drv;
1981
1982 wid.id = (u16)WID_CURRENT_CHANNEL;
1983 wid.type = WID_CHAR;
1984 wid.val = (s8 *)&ch_no;
1985 wid.size = sizeof(char);
1986
1987 result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
1988 wilc_get_vif_idx(vif));
1989
1990 if (result) {
1991 PRINT_ER("Failed to get channel number\n");
1992 result = -EFAULT;
1993 }
1994
1995 up(&hif_drv->sem_get_chnl);
1996
1997 return result;
1998 }
1999
2000 static void Handle_GetRssi(struct wilc_vif *vif)
2001 {
2002 s32 result = 0;
2003 struct wid wid;
2004
2005 wid.id = (u16)WID_RSSI;
2006 wid.type = WID_CHAR;
2007 wid.val = &rssi;
2008 wid.size = sizeof(char);
2009
2010 result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
2011 wilc_get_vif_idx(vif));
2012 if (result) {
2013 PRINT_ER("Failed to get RSSI value\n");
2014 result = -EFAULT;
2015 }
2016
2017 up(&vif->hif_drv->sem_get_rssi);
2018 }
2019
2020 static void Handle_GetLinkspeed(struct wilc_vif *vif)
2021 {
2022 s32 result = 0;
2023 struct wid wid;
2024 struct host_if_drv *hif_drv = vif->hif_drv;
2025
2026 link_speed = 0;
2027
2028 wid.id = (u16)WID_LINKSPEED;
2029 wid.type = WID_CHAR;
2030 wid.val = &link_speed;
2031 wid.size = sizeof(char);
2032
2033 result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
2034 wilc_get_vif_idx(vif));
2035 if (result) {
2036 PRINT_ER("Failed to get LINKSPEED value\n");
2037 result = -EFAULT;
2038 }
2039
2040 up(&hif_drv->sem_get_link_speed);
2041 }
2042
2043 static s32 Handle_GetStatistics(struct wilc_vif *vif,
2044 struct rf_info *pstrStatistics)
2045 {
2046 struct wid strWIDList[5];
2047 u32 u32WidsCount = 0, result = 0;
2048
2049 strWIDList[u32WidsCount].id = WID_LINKSPEED;
2050 strWIDList[u32WidsCount].type = WID_CHAR;
2051 strWIDList[u32WidsCount].size = sizeof(char);
2052 strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->link_speed;
2053 u32WidsCount++;
2054
2055 strWIDList[u32WidsCount].id = WID_RSSI;
2056 strWIDList[u32WidsCount].type = WID_CHAR;
2057 strWIDList[u32WidsCount].size = sizeof(char);
2058 strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->rssi;
2059 u32WidsCount++;
2060
2061 strWIDList[u32WidsCount].id = WID_SUCCESS_FRAME_COUNT;
2062 strWIDList[u32WidsCount].type = WID_INT;
2063 strWIDList[u32WidsCount].size = sizeof(u32);
2064 strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->tx_cnt;
2065 u32WidsCount++;
2066
2067 strWIDList[u32WidsCount].id = WID_RECEIVED_FRAGMENT_COUNT;
2068 strWIDList[u32WidsCount].type = WID_INT;
2069 strWIDList[u32WidsCount].size = sizeof(u32);
2070 strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->rx_cnt;
2071 u32WidsCount++;
2072
2073 strWIDList[u32WidsCount].id = WID_FAILED_COUNT;
2074 strWIDList[u32WidsCount].type = WID_INT;
2075 strWIDList[u32WidsCount].size = sizeof(u32);
2076 strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->tx_fail_cnt;
2077 u32WidsCount++;
2078
2079 result = wilc_send_config_pkt(vif, GET_CFG, strWIDList,
2080 u32WidsCount,
2081 wilc_get_vif_idx(vif));
2082
2083 if (result)
2084 PRINT_ER("Failed to send scan parameters config packet\n");
2085
2086 if (pstrStatistics->link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH &&
2087 pstrStatistics->link_speed != DEFAULT_LINK_SPEED)
2088 wilc_enable_tcp_ack_filter(true);
2089 else if (pstrStatistics->link_speed != DEFAULT_LINK_SPEED)
2090 wilc_enable_tcp_ack_filter(false);
2091
2092 if (pstrStatistics != &vif->wilc->dummy_statistics)
2093 up(&hif_sema_wait_response);
2094 return 0;
2095 }
2096
2097 static s32 Handle_Get_InActiveTime(struct wilc_vif *vif,
2098 struct sta_inactive_t *strHostIfStaInactiveT)
2099 {
2100 s32 result = 0;
2101 u8 *stamac;
2102 struct wid wid;
2103 struct host_if_drv *hif_drv = vif->hif_drv;
2104
2105 wid.id = (u16)WID_SET_STA_MAC_INACTIVE_TIME;
2106 wid.type = WID_STR;
2107 wid.size = ETH_ALEN;
2108 wid.val = kmalloc(wid.size, GFP_KERNEL);
2109
2110 stamac = wid.val;
2111 memcpy(stamac, strHostIfStaInactiveT->mac, ETH_ALEN);
2112
2113 PRINT_D(CFG80211_DBG, "SETING STA inactive time\n");
2114
2115 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2116 wilc_get_vif_idx(vif));
2117
2118 if (result) {
2119 PRINT_ER("Failed to SET incative time\n");
2120 return -EFAULT;
2121 }
2122
2123 wid.id = (u16)WID_GET_INACTIVE_TIME;
2124 wid.type = WID_INT;
2125 wid.val = (s8 *)&inactive_time;
2126 wid.size = sizeof(u32);
2127
2128 result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
2129 wilc_get_vif_idx(vif));
2130
2131 if (result) {
2132 PRINT_ER("Failed to get incative time\n");
2133 return -EFAULT;
2134 }
2135
2136 PRINT_D(CFG80211_DBG, "Getting inactive time : %d\n", inactive_time);
2137
2138 up(&hif_drv->sem_inactive_time);
2139
2140 return result;
2141 }
2142
2143 static void Handle_AddBeacon(struct wilc_vif *vif,
2144 struct beacon_attr *pstrSetBeaconParam)
2145 {
2146 s32 result = 0;
2147 struct wid wid;
2148 u8 *pu8CurrByte;
2149
2150 wid.id = (u16)WID_ADD_BEACON;
2151 wid.type = WID_BIN;
2152 wid.size = pstrSetBeaconParam->head_len + pstrSetBeaconParam->tail_len + 16;
2153 wid.val = kmalloc(wid.size, GFP_KERNEL);
2154 if (!wid.val)
2155 goto ERRORHANDLER;
2156
2157 pu8CurrByte = wid.val;
2158 *pu8CurrByte++ = (pstrSetBeaconParam->interval & 0xFF);
2159 *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 8) & 0xFF);
2160 *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 16) & 0xFF);
2161 *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 24) & 0xFF);
2162
2163 *pu8CurrByte++ = (pstrSetBeaconParam->dtim_period & 0xFF);
2164 *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 8) & 0xFF);
2165 *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 16) & 0xFF);
2166 *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 24) & 0xFF);
2167
2168 *pu8CurrByte++ = (pstrSetBeaconParam->head_len & 0xFF);
2169 *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 8) & 0xFF);
2170 *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 16) & 0xFF);
2171 *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 24) & 0xFF);
2172
2173 memcpy(pu8CurrByte, pstrSetBeaconParam->head, pstrSetBeaconParam->head_len);
2174 pu8CurrByte += pstrSetBeaconParam->head_len;
2175
2176 *pu8CurrByte++ = (pstrSetBeaconParam->tail_len & 0xFF);
2177 *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 8) & 0xFF);
2178 *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 16) & 0xFF);
2179 *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 24) & 0xFF);
2180
2181 if (pstrSetBeaconParam->tail)
2182 memcpy(pu8CurrByte, pstrSetBeaconParam->tail, pstrSetBeaconParam->tail_len);
2183 pu8CurrByte += pstrSetBeaconParam->tail_len;
2184
2185 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2186 wilc_get_vif_idx(vif));
2187 if (result)
2188 PRINT_ER("Failed to send add beacon config packet\n");
2189
2190 ERRORHANDLER:
2191 kfree(wid.val);
2192 kfree(pstrSetBeaconParam->head);
2193 kfree(pstrSetBeaconParam->tail);
2194 }
2195
2196 static void Handle_DelBeacon(struct wilc_vif *vif)
2197 {
2198 s32 result = 0;
2199 struct wid wid;
2200 u8 *pu8CurrByte;
2201
2202 wid.id = (u16)WID_DEL_BEACON;
2203 wid.type = WID_CHAR;
2204 wid.size = sizeof(char);
2205 wid.val = &del_beacon;
2206
2207 if (!wid.val)
2208 return;
2209
2210 pu8CurrByte = wid.val;
2211
2212 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2213 wilc_get_vif_idx(vif));
2214 if (result)
2215 PRINT_ER("Failed to send delete beacon config packet\n");
2216 }
2217
2218 static u32 WILC_HostIf_PackStaParam(u8 *pu8Buffer,
2219 struct add_sta_param *pstrStationParam)
2220 {
2221 u8 *pu8CurrByte;
2222
2223 pu8CurrByte = pu8Buffer;
2224
2225 memcpy(pu8CurrByte, pstrStationParam->bssid, ETH_ALEN);
2226 pu8CurrByte += ETH_ALEN;
2227
2228 *pu8CurrByte++ = pstrStationParam->aid & 0xFF;
2229 *pu8CurrByte++ = (pstrStationParam->aid >> 8) & 0xFF;
2230
2231 *pu8CurrByte++ = pstrStationParam->rates_len;
2232 if (pstrStationParam->rates_len > 0)
2233 memcpy(pu8CurrByte, pstrStationParam->rates,
2234 pstrStationParam->rates_len);
2235 pu8CurrByte += pstrStationParam->rates_len;
2236
2237 *pu8CurrByte++ = pstrStationParam->ht_supported;
2238 *pu8CurrByte++ = pstrStationParam->ht_capa_info & 0xFF;
2239 *pu8CurrByte++ = (pstrStationParam->ht_capa_info >> 8) & 0xFF;
2240
2241 *pu8CurrByte++ = pstrStationParam->ht_ampdu_params;
2242 memcpy(pu8CurrByte, pstrStationParam->ht_supp_mcs_set,
2243 WILC_SUPP_MCS_SET_SIZE);
2244 pu8CurrByte += WILC_SUPP_MCS_SET_SIZE;
2245
2246 *pu8CurrByte++ = pstrStationParam->ht_ext_params & 0xFF;
2247 *pu8CurrByte++ = (pstrStationParam->ht_ext_params >> 8) & 0xFF;
2248
2249 *pu8CurrByte++ = pstrStationParam->ht_tx_bf_cap & 0xFF;
2250 *pu8CurrByte++ = (pstrStationParam->ht_tx_bf_cap >> 8) & 0xFF;
2251 *pu8CurrByte++ = (pstrStationParam->ht_tx_bf_cap >> 16) & 0xFF;
2252 *pu8CurrByte++ = (pstrStationParam->ht_tx_bf_cap >> 24) & 0xFF;
2253
2254 *pu8CurrByte++ = pstrStationParam->ht_ante_sel;
2255
2256 *pu8CurrByte++ = pstrStationParam->flags_mask & 0xFF;
2257 *pu8CurrByte++ = (pstrStationParam->flags_mask >> 8) & 0xFF;
2258
2259 *pu8CurrByte++ = pstrStationParam->flags_set & 0xFF;
2260 *pu8CurrByte++ = (pstrStationParam->flags_set >> 8) & 0xFF;
2261
2262 return pu8CurrByte - pu8Buffer;
2263 }
2264
2265 static void Handle_AddStation(struct wilc_vif *vif,
2266 struct add_sta_param *pstrStationParam)
2267 {
2268 s32 result = 0;
2269 struct wid wid;
2270 u8 *pu8CurrByte;
2271
2272 wid.id = (u16)WID_ADD_STA;
2273 wid.type = WID_BIN;
2274 wid.size = WILC_ADD_STA_LENGTH + pstrStationParam->rates_len;
2275
2276 wid.val = kmalloc(wid.size, GFP_KERNEL);
2277 if (!wid.val)
2278 goto ERRORHANDLER;
2279
2280 pu8CurrByte = wid.val;
2281 pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam);
2282
2283 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2284 wilc_get_vif_idx(vif));
2285 if (result != 0)
2286 PRINT_ER("Failed to send add station config packet\n");
2287
2288 ERRORHANDLER:
2289 kfree(pstrStationParam->rates);
2290 kfree(wid.val);
2291 }
2292
2293 static void Handle_DelAllSta(struct wilc_vif *vif,
2294 struct del_all_sta *pstrDelAllStaParam)
2295 {
2296 s32 result = 0;
2297 struct wid wid;
2298 u8 *pu8CurrByte;
2299 u8 i;
2300 u8 au8Zero_Buff[6] = {0};
2301
2302 wid.id = (u16)WID_DEL_ALL_STA;
2303 wid.type = WID_STR;
2304 wid.size = (pstrDelAllStaParam->assoc_sta * ETH_ALEN) + 1;
2305
2306 wid.val = kmalloc((pstrDelAllStaParam->assoc_sta * ETH_ALEN) + 1, GFP_KERNEL);
2307 if (!wid.val)
2308 goto ERRORHANDLER;
2309
2310 pu8CurrByte = wid.val;
2311
2312 *(pu8CurrByte++) = pstrDelAllStaParam->assoc_sta;
2313
2314 for (i = 0; i < MAX_NUM_STA; i++) {
2315 if (memcmp(pstrDelAllStaParam->del_all_sta[i], au8Zero_Buff, ETH_ALEN))
2316 memcpy(pu8CurrByte, pstrDelAllStaParam->del_all_sta[i], ETH_ALEN);
2317 else
2318 continue;
2319
2320 pu8CurrByte += ETH_ALEN;
2321 }
2322
2323 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2324 wilc_get_vif_idx(vif));
2325 if (result)
2326 PRINT_ER("Failed to send add station config packet\n");
2327
2328 ERRORHANDLER:
2329 kfree(wid.val);
2330
2331 up(&hif_sema_wait_response);
2332 }
2333
2334 static void Handle_DelStation(struct wilc_vif *vif,
2335 struct del_sta *pstrDelStaParam)
2336 {
2337 s32 result = 0;
2338 struct wid wid;
2339 u8 *pu8CurrByte;
2340
2341 wid.id = (u16)WID_REMOVE_STA;
2342 wid.type = WID_BIN;
2343 wid.size = ETH_ALEN;
2344
2345 wid.val = kmalloc(wid.size, GFP_KERNEL);
2346 if (!wid.val)
2347 goto ERRORHANDLER;
2348
2349 pu8CurrByte = wid.val;
2350
2351 memcpy(pu8CurrByte, pstrDelStaParam->mac_addr, ETH_ALEN);
2352
2353 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2354 wilc_get_vif_idx(vif));
2355 if (result)
2356 PRINT_ER("Failed to send add station config packet\n");
2357
2358 ERRORHANDLER:
2359 kfree(wid.val);
2360 }
2361
2362 static void Handle_EditStation(struct wilc_vif *vif,
2363 struct add_sta_param *pstrStationParam)
2364 {
2365 s32 result = 0;
2366 struct wid wid;
2367 u8 *pu8CurrByte;
2368
2369 wid.id = (u16)WID_EDIT_STA;
2370 wid.type = WID_BIN;
2371 wid.size = WILC_ADD_STA_LENGTH + pstrStationParam->rates_len;
2372
2373 wid.val = kmalloc(wid.size, GFP_KERNEL);
2374 if (!wid.val)
2375 goto ERRORHANDLER;
2376
2377 pu8CurrByte = wid.val;
2378 pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam);
2379
2380 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2381 wilc_get_vif_idx(vif));
2382 if (result)
2383 PRINT_ER("Failed to send edit station config packet\n");
2384
2385 ERRORHANDLER:
2386 kfree(pstrStationParam->rates);
2387 kfree(wid.val);
2388 }
2389
2390 static int Handle_RemainOnChan(struct wilc_vif *vif,
2391 struct remain_ch *pstrHostIfRemainOnChan)
2392 {
2393 s32 result = 0;
2394 u8 u8remain_on_chan_flag;
2395 struct wid wid;
2396 struct host_if_drv *hif_drv = vif->hif_drv;
2397
2398 if (!hif_drv->remain_on_ch_pending) {
2399 hif_drv->remain_on_ch.arg = pstrHostIfRemainOnChan->arg;
2400 hif_drv->remain_on_ch.expired = pstrHostIfRemainOnChan->expired;
2401 hif_drv->remain_on_ch.ready = pstrHostIfRemainOnChan->ready;
2402 hif_drv->remain_on_ch.ch = pstrHostIfRemainOnChan->ch;
2403 hif_drv->remain_on_ch.id = pstrHostIfRemainOnChan->id;
2404 } else {
2405 pstrHostIfRemainOnChan->ch = hif_drv->remain_on_ch.ch;
2406 }
2407
2408 if (hif_drv->usr_scan_req.scan_result) {
2409 hif_drv->remain_on_ch_pending = 1;
2410 result = -EBUSY;
2411 goto ERRORHANDLER;
2412 }
2413 if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) {
2414 result = -EBUSY;
2415 goto ERRORHANDLER;
2416 }
2417
2418 if (wilc_optaining_ip || wilc_connecting) {
2419 result = -EBUSY;
2420 goto ERRORHANDLER;
2421 }
2422
2423 u8remain_on_chan_flag = true;
2424 wid.id = (u16)WID_REMAIN_ON_CHAN;
2425 wid.type = WID_STR;
2426 wid.size = 2;
2427 wid.val = kmalloc(wid.size, GFP_KERNEL);
2428 if (!wid.val) {
2429 result = -ENOMEM;
2430 goto ERRORHANDLER;
2431 }
2432
2433 wid.val[0] = u8remain_on_chan_flag;
2434 wid.val[1] = (s8)pstrHostIfRemainOnChan->ch;
2435
2436 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2437 wilc_get_vif_idx(vif));
2438 if (result != 0)
2439 PRINT_ER("Failed to set remain on channel\n");
2440
2441 ERRORHANDLER:
2442 {
2443 P2P_LISTEN_STATE = 1;
2444 hif_drv->remain_on_ch_timer.data = (unsigned long)vif;
2445 mod_timer(&hif_drv->remain_on_ch_timer,
2446 jiffies +
2447 msecs_to_jiffies(pstrHostIfRemainOnChan->duration));
2448
2449 if (hif_drv->remain_on_ch.ready)
2450 hif_drv->remain_on_ch.ready(hif_drv->remain_on_ch.arg);
2451
2452 if (hif_drv->remain_on_ch_pending)
2453 hif_drv->remain_on_ch_pending = 0;
2454 }
2455
2456 return result;
2457 }
2458
2459 static int Handle_RegisterFrame(struct wilc_vif *vif,
2460 struct reg_frame *pstrHostIfRegisterFrame)
2461 {
2462 s32 result = 0;
2463 struct wid wid;
2464 u8 *pu8CurrByte;
2465
2466 wid.id = (u16)WID_REGISTER_FRAME;
2467 wid.type = WID_STR;
2468 wid.val = kmalloc(sizeof(u16) + 2, GFP_KERNEL);
2469 if (!wid.val)
2470 return -ENOMEM;
2471
2472 pu8CurrByte = wid.val;
2473
2474 *pu8CurrByte++ = pstrHostIfRegisterFrame->reg;
2475 *pu8CurrByte++ = pstrHostIfRegisterFrame->reg_id;
2476 memcpy(pu8CurrByte, &pstrHostIfRegisterFrame->frame_type, sizeof(u16));
2477
2478 wid.size = sizeof(u16) + 2;
2479
2480 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2481 wilc_get_vif_idx(vif));
2482 if (result) {
2483 PRINT_ER("Failed to frame register config packet\n");
2484 result = -EINVAL;
2485 }
2486
2487 return result;
2488 }
2489
2490 static u32 Handle_ListenStateExpired(struct wilc_vif *vif,
2491 struct remain_ch *pstrHostIfRemainOnChan)
2492 {
2493 u8 u8remain_on_chan_flag;
2494 struct wid wid;
2495 s32 result = 0;
2496 struct host_if_drv *hif_drv = vif->hif_drv;
2497
2498 if (P2P_LISTEN_STATE) {
2499 u8remain_on_chan_flag = false;
2500 wid.id = (u16)WID_REMAIN_ON_CHAN;
2501 wid.type = WID_STR;
2502 wid.size = 2;
2503 wid.val = kmalloc(wid.size, GFP_KERNEL);
2504
2505 if (!wid.val) {
2506 PRINT_ER("Failed to allocate memory\n");
2507 return -ENOMEM;
2508 }
2509
2510 wid.val[0] = u8remain_on_chan_flag;
2511 wid.val[1] = FALSE_FRMWR_CHANNEL;
2512
2513 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2514 wilc_get_vif_idx(vif));
2515 if (result != 0) {
2516 PRINT_ER("Failed to set remain on channel\n");
2517 goto _done_;
2518 }
2519
2520 if (hif_drv->remain_on_ch.expired) {
2521 hif_drv->remain_on_ch.expired(hif_drv->remain_on_ch.arg,
2522 pstrHostIfRemainOnChan->id);
2523 }
2524 P2P_LISTEN_STATE = 0;
2525 } else {
2526 netdev_dbg(vif->ndev, "Not in listen state\n");
2527 result = -EFAULT;
2528 }
2529
2530 _done_:
2531 return result;
2532 }
2533
2534 static void ListenTimerCB(unsigned long arg)
2535 {
2536 s32 result = 0;
2537 struct host_if_msg msg;
2538 struct wilc_vif *vif = (struct wilc_vif *)arg;
2539
2540 del_timer(&vif->hif_drv->remain_on_ch_timer);
2541
2542 memset(&msg, 0, sizeof(struct host_if_msg));
2543 msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
2544 msg.vif = vif;
2545 msg.body.remain_on_ch.id = vif->hif_drv->remain_on_ch.id;
2546
2547 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
2548 if (result)
2549 PRINT_ER("wilc_mq_send fail\n");
2550 }
2551
2552 static void Handle_PowerManagement(struct wilc_vif *vif,
2553 struct power_mgmt_param *strPowerMgmtParam)
2554 {
2555 s32 result = 0;
2556 struct wid wid;
2557 s8 s8PowerMode;
2558
2559 wid.id = (u16)WID_POWER_MANAGEMENT;
2560
2561 if (strPowerMgmtParam->enabled)
2562 s8PowerMode = MIN_FAST_PS;
2563 else
2564 s8PowerMode = NO_POWERSAVE;
2565
2566 wid.val = &s8PowerMode;
2567 wid.size = sizeof(char);
2568
2569 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2570 wilc_get_vif_idx(vif));
2571 if (result)
2572 PRINT_ER("Failed to send power management config packet\n");
2573 }
2574
2575 static void Handle_SetMulticastFilter(struct wilc_vif *vif,
2576 struct set_multicast *strHostIfSetMulti)
2577 {
2578 s32 result = 0;
2579 struct wid wid;
2580 u8 *pu8CurrByte;
2581
2582 wid.id = (u16)WID_SETUP_MULTICAST_FILTER;
2583 wid.type = WID_BIN;
2584 wid.size = sizeof(struct set_multicast) + ((strHostIfSetMulti->cnt) * ETH_ALEN);
2585 wid.val = kmalloc(wid.size, GFP_KERNEL);
2586 if (!wid.val)
2587 goto ERRORHANDLER;
2588
2589 pu8CurrByte = wid.val;
2590 *pu8CurrByte++ = (strHostIfSetMulti->enabled & 0xFF);
2591 *pu8CurrByte++ = 0;
2592 *pu8CurrByte++ = 0;
2593 *pu8CurrByte++ = 0;
2594
2595 *pu8CurrByte++ = (strHostIfSetMulti->cnt & 0xFF);
2596 *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 8) & 0xFF);
2597 *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 16) & 0xFF);
2598 *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 24) & 0xFF);
2599
2600 if ((strHostIfSetMulti->cnt) > 0)
2601 memcpy(pu8CurrByte, wilc_multicast_mac_addr_list,
2602 ((strHostIfSetMulti->cnt) * ETH_ALEN));
2603
2604 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2605 wilc_get_vif_idx(vif));
2606 if (result)
2607 PRINT_ER("Failed to send setup multicast config packet\n");
2608
2609 ERRORHANDLER:
2610 kfree(wid.val);
2611 }
2612
2613 static s32 Handle_DelAllRxBASessions(struct wilc_vif *vif,
2614 struct ba_session_info *strHostIfBASessionInfo)
2615 {
2616 s32 result = 0;
2617 struct wid wid;
2618 char *ptr = NULL;
2619
2620 wid.id = (u16)WID_DEL_ALL_RX_BA;
2621 wid.type = WID_STR;
2622 wid.val = kmalloc(BLOCK_ACK_REQ_SIZE, GFP_KERNEL);
2623 wid.size = BLOCK_ACK_REQ_SIZE;
2624 ptr = wid.val;
2625 *ptr++ = 0x14;
2626 *ptr++ = 0x3;
2627 *ptr++ = 0x2;
2628 memcpy(ptr, strHostIfBASessionInfo->bssid, ETH_ALEN);
2629 ptr += ETH_ALEN;
2630 *ptr++ = strHostIfBASessionInfo->tid;
2631 *ptr++ = 0;
2632 *ptr++ = 32;
2633
2634 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2635 wilc_get_vif_idx(vif));
2636
2637 kfree(wid.val);
2638
2639 up(&hif_sema_wait_response);
2640
2641 return result;
2642 }
2643
2644 static void handle_set_tx_pwr(struct wilc_vif *vif, u8 tx_pwr)
2645 {
2646 int ret;
2647 struct wid wid;
2648
2649 wid.id = (u16)WID_TX_POWER;
2650 wid.type = WID_CHAR;
2651 wid.val = &tx_pwr;
2652 wid.size = sizeof(char);
2653
2654 ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2655 wilc_get_vif_idx(vif));
2656 if (ret)
2657 netdev_err(vif->ndev, "Failed to set TX PWR\n");
2658 }
2659
2660 static void handle_get_tx_pwr(struct wilc_vif *vif, u8 *tx_pwr)
2661 {
2662 s32 ret = 0;
2663 struct wid wid;
2664
2665 wid.id = (u16)WID_TX_POWER;
2666 wid.type = WID_CHAR;
2667 wid.val = (s8 *)tx_pwr;
2668 wid.size = sizeof(char);
2669
2670 ret = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
2671 wilc_get_vif_idx(vif));
2672 if (ret)
2673 netdev_err(vif->ndev, "Failed to get TX PWR\n");
2674
2675 up(&hif_sema_wait_response);
2676 }
2677
2678 static int hostIFthread(void *pvArg)
2679 {
2680 u32 u32Ret;
2681 struct host_if_msg msg;
2682 struct wilc *wilc = (struct wilc*)pvArg;
2683 struct wilc_vif *vif;
2684
2685 memset(&msg, 0, sizeof(struct host_if_msg));
2686
2687 while (1) {
2688 wilc_mq_recv(&hif_msg_q, &msg, sizeof(struct host_if_msg), &u32Ret);
2689 vif = msg.vif;
2690 if (msg.id == HOST_IF_MSG_EXIT)
2691 break;
2692
2693 if ((!wilc_initialized)) {
2694 usleep_range(200 * 1000, 200 * 1000);
2695 wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
2696 continue;
2697 }
2698
2699 if (msg.id == HOST_IF_MSG_CONNECT &&
2700 vif->hif_drv->usr_scan_req.scan_result) {
2701 wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
2702 usleep_range(2 * 1000, 2 * 1000);
2703 continue;
2704 }
2705
2706 switch (msg.id) {
2707 case HOST_IF_MSG_Q_IDLE:
2708 Handle_wait_msg_q_empty();
2709 break;
2710
2711 case HOST_IF_MSG_SCAN:
2712 Handle_Scan(msg.vif, &msg.body.scan_info);
2713 break;
2714
2715 case HOST_IF_MSG_CONNECT:
2716 Handle_Connect(msg.vif, &msg.body.con_info);
2717 break;
2718
2719 case HOST_IF_MSG_FLUSH_CONNECT:
2720 Handle_FlushConnect(msg.vif);
2721 break;
2722
2723 case HOST_IF_MSG_RCVD_NTWRK_INFO:
2724 Handle_RcvdNtwrkInfo(msg.vif, &msg.body.net_info);
2725 break;
2726
2727 case HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO:
2728 Handle_RcvdGnrlAsyncInfo(vif,
2729 &msg.body.async_info);
2730 break;
2731
2732 case HOST_IF_MSG_KEY:
2733 Handle_Key(msg.vif, &msg.body.key_info);
2734 break;
2735
2736 case HOST_IF_MSG_CFG_PARAMS:
2737 handle_cfg_param(msg.vif, &msg.body.cfg_info);
2738 break;
2739
2740 case HOST_IF_MSG_SET_CHANNEL:
2741 handle_set_channel(msg.vif, &msg.body.channel_info);
2742 break;
2743
2744 case HOST_IF_MSG_DISCONNECT:
2745 Handle_Disconnect(msg.vif);
2746 break;
2747
2748 case HOST_IF_MSG_RCVD_SCAN_COMPLETE:
2749 del_timer(&vif->hif_drv->scan_timer);
2750
2751 if (!wilc_wlan_get_num_conn_ifcs(wilc))
2752 wilc_chip_sleep_manually(wilc);
2753
2754 Handle_ScanDone(msg.vif, SCAN_EVENT_DONE);
2755
2756 if (vif->hif_drv->remain_on_ch_pending)
2757 Handle_RemainOnChan(msg.vif,
2758 &msg.body.remain_on_ch);
2759
2760 break;
2761
2762 case HOST_IF_MSG_GET_RSSI:
2763 Handle_GetRssi(msg.vif);
2764 break;
2765
2766 case HOST_IF_MSG_GET_LINKSPEED:
2767 Handle_GetLinkspeed(msg.vif);
2768 break;
2769
2770 case HOST_IF_MSG_GET_STATISTICS:
2771 Handle_GetStatistics(msg.vif,
2772 (struct rf_info *)msg.body.data);
2773 break;
2774
2775 case HOST_IF_MSG_GET_CHNL:
2776 Handle_GetChnl(msg.vif);
2777 break;
2778
2779 case HOST_IF_MSG_ADD_BEACON:
2780 Handle_AddBeacon(msg.vif, &msg.body.beacon_info);
2781 break;
2782
2783 case HOST_IF_MSG_DEL_BEACON:
2784 Handle_DelBeacon(msg.vif);
2785 break;
2786
2787 case HOST_IF_MSG_ADD_STATION:
2788 Handle_AddStation(msg.vif, &msg.body.add_sta_info);
2789 break;
2790
2791 case HOST_IF_MSG_DEL_STATION:
2792 Handle_DelStation(msg.vif, &msg.body.del_sta_info);
2793 break;
2794
2795 case HOST_IF_MSG_EDIT_STATION:
2796 Handle_EditStation(msg.vif, &msg.body.edit_sta_info);
2797 break;
2798
2799 case HOST_IF_MSG_GET_INACTIVETIME:
2800 Handle_Get_InActiveTime(msg.vif, &msg.body.mac_info);
2801 break;
2802
2803 case HOST_IF_MSG_SCAN_TIMER_FIRED:
2804
2805 Handle_ScanDone(msg.vif, SCAN_EVENT_ABORTED);
2806 break;
2807
2808 case HOST_IF_MSG_CONNECT_TIMER_FIRED:
2809 Handle_ConnectTimeout(msg.vif);
2810 break;
2811
2812 case HOST_IF_MSG_POWER_MGMT:
2813 Handle_PowerManagement(msg.vif,
2814 &msg.body.pwr_mgmt_info);
2815 break;
2816
2817 case HOST_IF_MSG_SET_WFIDRV_HANDLER:
2818 handle_set_wfi_drv_handler(msg.vif, &msg.body.drv);
2819 break;
2820
2821 case HOST_IF_MSG_SET_OPERATION_MODE:
2822 handle_set_operation_mode(msg.vif, &msg.body.mode);
2823 break;
2824
2825 case HOST_IF_MSG_SET_IPADDRESS:
2826 handle_set_ip_address(vif,
2827 msg.body.ip_info.ip_addr,
2828 msg.body.ip_info.idx);
2829 break;
2830
2831 case HOST_IF_MSG_GET_IPADDRESS:
2832 handle_get_ip_address(vif, msg.body.ip_info.idx);
2833 break;
2834
2835 case HOST_IF_MSG_SET_MAC_ADDRESS:
2836 handle_set_mac_address(msg.vif,
2837 &msg.body.set_mac_info);
2838 break;
2839
2840 case HOST_IF_MSG_GET_MAC_ADDRESS:
2841 handle_get_mac_address(msg.vif,
2842 &msg.body.get_mac_info);
2843 break;
2844
2845 case HOST_IF_MSG_REMAIN_ON_CHAN:
2846 Handle_RemainOnChan(msg.vif, &msg.body.remain_on_ch);
2847 break;
2848
2849 case HOST_IF_MSG_REGISTER_FRAME:
2850 Handle_RegisterFrame(msg.vif, &msg.body.reg_frame);
2851 break;
2852
2853 case HOST_IF_MSG_LISTEN_TIMER_FIRED:
2854 Handle_ListenStateExpired(msg.vif, &msg.body.remain_on_ch);
2855 break;
2856
2857 case HOST_IF_MSG_SET_MULTICAST_FILTER:
2858 Handle_SetMulticastFilter(msg.vif, &msg.body.multicast_info);
2859 break;
2860
2861 case HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS:
2862 Handle_DelAllRxBASessions(msg.vif, &msg.body.session_info);
2863 break;
2864
2865 case HOST_IF_MSG_DEL_ALL_STA:
2866 Handle_DelAllSta(msg.vif, &msg.body.del_all_sta_info);
2867 break;
2868
2869 case HOST_IF_MSG_SET_TX_POWER:
2870 handle_set_tx_pwr(msg.vif, msg.body.tx_power.tx_pwr);
2871 break;
2872
2873 case HOST_IF_MSG_GET_TX_POWER:
2874 handle_get_tx_pwr(msg.vif, &msg.body.tx_power.tx_pwr);
2875 break;
2876 default:
2877 PRINT_ER("[Host Interface] undefined Received Msg ID\n");
2878 break;
2879 }
2880 }
2881
2882 up(&hif_sema_thread);
2883 return 0;
2884 }
2885
2886 static void TimerCB_Scan(unsigned long arg)
2887 {
2888 struct wilc_vif *vif = (struct wilc_vif *)arg;
2889 struct host_if_msg msg;
2890
2891 memset(&msg, 0, sizeof(struct host_if_msg));
2892 msg.vif = vif;
2893 msg.id = HOST_IF_MSG_SCAN_TIMER_FIRED;
2894
2895 wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
2896 }
2897
2898 static void TimerCB_Connect(unsigned long arg)
2899 {
2900 struct wilc_vif *vif = (struct wilc_vif *)arg;
2901 struct host_if_msg msg;
2902
2903 memset(&msg, 0, sizeof(struct host_if_msg));
2904 msg.vif = vif;
2905 msg.id = HOST_IF_MSG_CONNECT_TIMER_FIRED;
2906
2907 wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
2908 }
2909
2910 s32 wilc_remove_key(struct host_if_drv *hif_drv, const u8 *pu8StaAddress)
2911 {
2912 struct wid wid;
2913
2914 wid.id = (u16)WID_REMOVE_KEY;
2915 wid.type = WID_STR;
2916 wid.val = (s8 *)pu8StaAddress;
2917 wid.size = 6;
2918
2919 return 0;
2920 }
2921
2922 int wilc_remove_wep_key(struct wilc_vif *vif, u8 index)
2923 {
2924 int result = 0;
2925 struct host_if_msg msg;
2926 struct host_if_drv *hif_drv = vif->hif_drv;
2927
2928 if (!hif_drv) {
2929 result = -EFAULT;
2930 PRINT_ER("Failed to send setup multicast config packet\n");
2931 return result;
2932 }
2933
2934 memset(&msg, 0, sizeof(struct host_if_msg));
2935
2936 msg.id = HOST_IF_MSG_KEY;
2937 msg.body.key_info.type = WEP;
2938 msg.body.key_info.action = REMOVEKEY;
2939 msg.vif = vif;
2940 msg.body.key_info.attr.wep.index = index;
2941
2942 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
2943 if (result)
2944 PRINT_ER("Error in sending message queue : Request to remove WEP key\n");
2945 down(&hif_drv->sem_test_key_block);
2946
2947 return result;
2948 }
2949
2950 int wilc_set_wep_default_keyid(struct wilc_vif *vif, u8 index)
2951 {
2952 int result = 0;
2953 struct host_if_msg msg;
2954 struct host_if_drv *hif_drv = vif->hif_drv;
2955
2956 if (!hif_drv) {
2957 result = -EFAULT;
2958 PRINT_ER("driver is null\n");
2959 return result;
2960 }
2961
2962 memset(&msg, 0, sizeof(struct host_if_msg));
2963
2964 msg.id = HOST_IF_MSG_KEY;
2965 msg.body.key_info.type = WEP;
2966 msg.body.key_info.action = DEFAULTKEY;
2967 msg.vif = vif;
2968 msg.body.key_info.attr.wep.index = index;
2969
2970 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
2971 if (result)
2972 PRINT_ER("Error in sending message queue : Default key index\n");
2973 down(&hif_drv->sem_test_key_block);
2974
2975 return result;
2976 }
2977
2978 int wilc_add_wep_key_bss_sta(struct wilc_vif *vif, const u8 *key, u8 len,
2979 u8 index)
2980 {
2981 int result = 0;
2982 struct host_if_msg msg;
2983 struct host_if_drv *hif_drv = vif->hif_drv;
2984
2985 if (!hif_drv) {
2986 PRINT_ER("driver is null\n");
2987 return -EFAULT;
2988 }
2989
2990 memset(&msg, 0, sizeof(struct host_if_msg));
2991
2992 msg.id = HOST_IF_MSG_KEY;
2993 msg.body.key_info.type = WEP;
2994 msg.body.key_info.action = ADDKEY;
2995 msg.vif = vif;
2996 msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL);
2997 if (!msg.body.key_info.attr.wep.key)
2998 return -ENOMEM;
2999
3000 msg.body.key_info.attr.wep.key_len = len;
3001 msg.body.key_info.attr.wep.index = index;
3002
3003 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3004 if (result)
3005 PRINT_ER("Error in sending message queue :WEP Key\n");
3006 down(&hif_drv->sem_test_key_block);
3007
3008 return result;
3009 }
3010
3011 int wilc_add_wep_key_bss_ap(struct wilc_vif *vif, const u8 *key, u8 len,
3012 u8 index, u8 mode, enum AUTHTYPE auth_type)
3013 {
3014 int result = 0;
3015 struct host_if_msg msg;
3016 struct host_if_drv *hif_drv = vif->hif_drv;
3017 int i;
3018
3019 if (!hif_drv) {
3020 PRINT_ER("driver is null\n");
3021 return -EFAULT;
3022 }
3023
3024 memset(&msg, 0, sizeof(struct host_if_msg));
3025
3026 if (INFO) {
3027 for (i = 0; i < len; i++)
3028 PRINT_INFO(HOSTAPD_DBG, "KEY is %x\n", key[i]);
3029 }
3030 msg.id = HOST_IF_MSG_KEY;
3031 msg.body.key_info.type = WEP;
3032 msg.body.key_info.action = ADDKEY_AP;
3033 msg.vif = vif;
3034 msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL);
3035 if (!msg.body.key_info.attr.wep.key)
3036 return -ENOMEM;
3037
3038 msg.body.key_info.attr.wep.key_len = len;
3039 msg.body.key_info.attr.wep.index = index;
3040 msg.body.key_info.attr.wep.mode = mode;
3041 msg.body.key_info.attr.wep.auth_type = auth_type;
3042
3043 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3044
3045 if (result)
3046 PRINT_ER("Error in sending message queue :WEP Key\n");
3047 down(&hif_drv->sem_test_key_block);
3048
3049 return result;
3050 }
3051
3052 int wilc_add_ptk(struct wilc_vif *vif, const u8 *ptk, u8 ptk_key_len,
3053 const u8 *mac_addr, const u8 *rx_mic, const u8 *tx_mic,
3054 u8 mode, u8 cipher_mode, u8 index)
3055 {
3056 int result = 0;
3057 struct host_if_msg msg;
3058 struct host_if_drv *hif_drv = vif->hif_drv;
3059 u8 key_len = ptk_key_len;
3060 int i;
3061
3062 if (!hif_drv) {
3063 PRINT_ER("driver is null\n");
3064 return -EFAULT;
3065 }
3066
3067 if (rx_mic)
3068 key_len += RX_MIC_KEY_LEN;
3069
3070 if (tx_mic)
3071 key_len += TX_MIC_KEY_LEN;
3072
3073 memset(&msg, 0, sizeof(struct host_if_msg));
3074
3075 msg.id = HOST_IF_MSG_KEY;
3076 msg.body.key_info.type = WPA_PTK;
3077 if (mode == AP_MODE) {
3078 msg.body.key_info.action = ADDKEY_AP;
3079 msg.body.key_info.attr.wpa.index = index;
3080 }
3081 if (mode == STATION_MODE)
3082 msg.body.key_info.action = ADDKEY;
3083
3084 msg.body.key_info.attr.wpa.key = kmemdup(ptk, ptk_key_len, GFP_KERNEL);
3085 if (!msg.body.key_info.attr.wpa.key)
3086 return -ENOMEM;
3087
3088 if (rx_mic) {
3089 memcpy(msg.body.key_info.attr.wpa.key + 16, rx_mic, RX_MIC_KEY_LEN);
3090 if (INFO) {
3091 for (i = 0; i < RX_MIC_KEY_LEN; i++)
3092 PRINT_INFO(CFG80211_DBG, "PairwiseRx[%d] = %x\n", i, rx_mic[i]);
3093 }
3094 }
3095 if (tx_mic) {
3096 memcpy(msg.body.key_info.attr.wpa.key + 24, tx_mic, TX_MIC_KEY_LEN);
3097 if (INFO) {
3098 for (i = 0; i < TX_MIC_KEY_LEN; i++)
3099 PRINT_INFO(CFG80211_DBG, "PairwiseTx[%d] = %x\n", i, tx_mic[i]);
3100 }
3101 }
3102
3103 msg.body.key_info.attr.wpa.key_len = key_len;
3104 msg.body.key_info.attr.wpa.mac_addr = mac_addr;
3105 msg.body.key_info.attr.wpa.mode = cipher_mode;
3106 msg.vif = vif;
3107
3108 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3109
3110 if (result)
3111 PRINT_ER("Error in sending message queue: PTK Key\n");
3112
3113 down(&hif_drv->sem_test_key_block);
3114
3115 return result;
3116 }
3117
3118 int wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *rx_gtk, u8 gtk_key_len,
3119 u8 index, u32 key_rsc_len, const u8 *key_rsc,
3120 const u8 *rx_mic, const u8 *tx_mic, u8 mode,
3121 u8 cipher_mode)
3122 {
3123 int result = 0;
3124 struct host_if_msg msg;
3125 struct host_if_drv *hif_drv = vif->hif_drv;
3126 u8 key_len = gtk_key_len;
3127
3128 if (!hif_drv) {
3129 PRINT_ER("driver is null\n");
3130 return -EFAULT;
3131 }
3132 memset(&msg, 0, sizeof(struct host_if_msg));
3133
3134 if (rx_mic)
3135 key_len += RX_MIC_KEY_LEN;
3136
3137 if (tx_mic)
3138 key_len += TX_MIC_KEY_LEN;
3139
3140 if (key_rsc) {
3141 msg.body.key_info.attr.wpa.seq = kmemdup(key_rsc,
3142 key_rsc_len,
3143 GFP_KERNEL);
3144 if (!msg.body.key_info.attr.wpa.seq)
3145 return -ENOMEM;
3146 }
3147
3148 msg.id = HOST_IF_MSG_KEY;
3149 msg.body.key_info.type = WPA_RX_GTK;
3150 msg.vif = vif;
3151
3152 if (mode == AP_MODE) {
3153 msg.body.key_info.action = ADDKEY_AP;
3154 msg.body.key_info.attr.wpa.mode = cipher_mode;
3155 }
3156 if (mode == STATION_MODE)
3157 msg.body.key_info.action = ADDKEY;
3158
3159 msg.body.key_info.attr.wpa.key = kmemdup(rx_gtk,
3160 key_len,
3161 GFP_KERNEL);
3162 if (!msg.body.key_info.attr.wpa.key)
3163 return -ENOMEM;
3164
3165 if (rx_mic)
3166 memcpy(msg.body.key_info.attr.wpa.key + 16, rx_mic,
3167 RX_MIC_KEY_LEN);
3168
3169 if (tx_mic)
3170 memcpy(msg.body.key_info.attr.wpa.key + 24, tx_mic,
3171 TX_MIC_KEY_LEN);
3172
3173 msg.body.key_info.attr.wpa.index = index;
3174 msg.body.key_info.attr.wpa.key_len = key_len;
3175 msg.body.key_info.attr.wpa.seq_len = key_rsc_len;
3176
3177 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3178 if (result)
3179 PRINT_ER("Error in sending message queue: RX GTK\n");
3180
3181 down(&hif_drv->sem_test_key_block);
3182
3183 return result;
3184 }
3185
3186 int wilc_set_pmkid_info(struct wilc_vif *vif,
3187 struct host_if_pmkid_attr *pmkid)
3188 {
3189 int result = 0;
3190 struct host_if_msg msg;
3191 struct host_if_drv *hif_drv = vif->hif_drv;
3192 int i;
3193
3194 if (!hif_drv) {
3195 PRINT_ER("driver is null\n");
3196 return -EFAULT;
3197 }
3198
3199 memset(&msg, 0, sizeof(struct host_if_msg));
3200
3201 msg.id = HOST_IF_MSG_KEY;
3202 msg.body.key_info.type = PMKSA;
3203 msg.body.key_info.action = ADDKEY;
3204 msg.vif = vif;
3205
3206 for (i = 0; i < pmkid->numpmkid; i++) {
3207 memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].bssid,
3208 &pmkid->pmkidlist[i].bssid, ETH_ALEN);
3209 memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].pmkid,
3210 &pmkid->pmkidlist[i].pmkid, PMKID_LEN);
3211 }
3212
3213 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3214 if (result)
3215 PRINT_ER(" Error in sending messagequeue: PMKID Info\n");
3216
3217 return result;
3218 }
3219
3220 int wilc_get_mac_address(struct wilc_vif *vif, u8 *mac_addr)
3221 {
3222 int result = 0;
3223 struct host_if_msg msg;
3224
3225 memset(&msg, 0, sizeof(struct host_if_msg));
3226
3227 msg.id = HOST_IF_MSG_GET_MAC_ADDRESS;
3228 msg.body.get_mac_info.mac_addr = mac_addr;
3229 msg.vif = vif;
3230
3231 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3232 if (result) {
3233 PRINT_ER("Failed to send get mac address\n");
3234 return -EFAULT;
3235 }
3236
3237 down(&hif_sema_wait_response);
3238 return result;
3239 }
3240
3241 int wilc_set_join_req(struct wilc_vif *vif, u8 *bssid, const u8 *ssid,
3242 size_t ssid_len, const u8 *ies, size_t ies_len,
3243 wilc_connect_result connect_result, void *user_arg,
3244 u8 security, enum AUTHTYPE auth_type,
3245 u8 channel, void *join_params)
3246 {
3247 int result = 0;
3248 struct host_if_msg msg;
3249 struct host_if_drv *hif_drv = vif->hif_drv;
3250
3251 if (!hif_drv || !connect_result) {
3252 PRINT_ER("Driver is null\n");
3253 return -EFAULT;
3254 }
3255
3256 if (!join_params) {
3257 PRINT_ER("Unable to Join - JoinParams is NULL\n");
3258 return -EFAULT;
3259 }
3260
3261 memset(&msg, 0, sizeof(struct host_if_msg));
3262
3263 msg.id = HOST_IF_MSG_CONNECT;
3264
3265 msg.body.con_info.security = security;
3266 msg.body.con_info.auth_type = auth_type;
3267 msg.body.con_info.ch = channel;
3268 msg.body.con_info.result = connect_result;
3269 msg.body.con_info.arg = user_arg;
3270 msg.body.con_info.params = join_params;
3271 msg.vif = vif;
3272
3273 if (bssid) {
3274 msg.body.con_info.bssid = kmemdup(bssid, 6, GFP_KERNEL);
3275 if (!msg.body.con_info.bssid)
3276 return -ENOMEM;
3277 }
3278
3279 if (ssid) {
3280 msg.body.con_info.ssid_len = ssid_len;
3281 msg.body.con_info.ssid = kmemdup(ssid, ssid_len, GFP_KERNEL);
3282 if (!msg.body.con_info.ssid)
3283 return -ENOMEM;
3284 }
3285
3286 if (ies) {
3287 msg.body.con_info.ies_len = ies_len;
3288 msg.body.con_info.ies = kmemdup(ies, ies_len, GFP_KERNEL);
3289 if (!msg.body.con_info.ies)
3290 return -ENOMEM;
3291 }
3292 if (hif_drv->hif_state < HOST_IF_CONNECTING)
3293 hif_drv->hif_state = HOST_IF_CONNECTING;
3294
3295 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3296 if (result) {
3297 PRINT_ER("Failed to send message queue: Set join request\n");
3298 return -EFAULT;
3299 }
3300
3301 hif_drv->connect_timer.data = (unsigned long)vif;
3302 mod_timer(&hif_drv->connect_timer,
3303 jiffies + msecs_to_jiffies(HOST_IF_CONNECT_TIMEOUT));
3304
3305 return result;
3306 }
3307
3308 int wilc_disconnect(struct wilc_vif *vif, u16 reason_code)
3309 {
3310 int result = 0;
3311 struct host_if_msg msg;
3312 struct host_if_drv *hif_drv = vif->hif_drv;
3313
3314 if (!hif_drv) {
3315 PRINT_ER("Driver is null\n");
3316 return -EFAULT;
3317 }
3318
3319 memset(&msg, 0, sizeof(struct host_if_msg));
3320
3321 msg.id = HOST_IF_MSG_DISCONNECT;
3322 msg.vif = vif;
3323
3324 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3325 if (result)
3326 PRINT_ER("Failed to send message queue: disconnect\n");
3327
3328 down(&hif_drv->sem_test_disconn_block);
3329
3330 return result;
3331 }
3332
3333 static s32 host_int_get_assoc_res_info(struct wilc_vif *vif,
3334 u8 *pu8AssocRespInfo,
3335 u32 u32MaxAssocRespInfoLen,
3336 u32 *pu32RcvdAssocRespInfoLen)
3337 {
3338 s32 result = 0;
3339 struct wid wid;
3340 struct host_if_drv *hif_drv = vif->hif_drv;
3341
3342 if (!hif_drv) {
3343 PRINT_ER("Driver is null\n");
3344 return -EFAULT;
3345 }
3346
3347 wid.id = (u16)WID_ASSOC_RES_INFO;
3348 wid.type = WID_STR;
3349 wid.val = pu8AssocRespInfo;
3350 wid.size = u32MaxAssocRespInfoLen;
3351
3352 result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
3353 wilc_get_vif_idx(vif));
3354 if (result) {
3355 *pu32RcvdAssocRespInfoLen = 0;
3356 PRINT_ER("Failed to send association response config packet\n");
3357 return -EINVAL;
3358 } else {
3359 *pu32RcvdAssocRespInfoLen = wid.size;
3360 }
3361
3362 return result;
3363 }
3364
3365 int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 channel)
3366 {
3367 int result;
3368 struct host_if_msg msg;
3369 struct host_if_drv *hif_drv = vif->hif_drv;
3370
3371 if (!hif_drv) {
3372 PRINT_ER("driver is null\n");
3373 return -EFAULT;
3374 }
3375
3376 memset(&msg, 0, sizeof(struct host_if_msg));
3377 msg.id = HOST_IF_MSG_SET_CHANNEL;
3378 msg.body.channel_info.set_ch = channel;
3379 msg.vif = vif;
3380
3381 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3382 if (result) {
3383 PRINT_ER("wilc mq send fail\n");
3384 return -EINVAL;
3385 }
3386
3387 return 0;
3388 }
3389
3390 int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mac_idx)
3391 {
3392 int result = 0;
3393 struct host_if_msg msg;
3394
3395 memset(&msg, 0, sizeof(struct host_if_msg));
3396 msg.id = HOST_IF_MSG_SET_WFIDRV_HANDLER;
3397 msg.body.drv.handler = index;
3398 msg.body.drv.mac_idx = mac_idx;
3399 msg.vif = vif;
3400
3401 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3402 if (result) {
3403 PRINT_ER("wilc mq send fail\n");
3404 result = -EINVAL;
3405 }
3406
3407 return result;
3408 }
3409
3410 int wilc_set_operation_mode(struct wilc_vif *vif, u32 mode)
3411 {
3412 int result = 0;
3413 struct host_if_msg msg;
3414
3415 memset(&msg, 0, sizeof(struct host_if_msg));
3416 msg.id = HOST_IF_MSG_SET_OPERATION_MODE;
3417 msg.body.mode.mode = mode;
3418 msg.vif = vif;
3419
3420 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3421 if (result) {
3422 PRINT_ER("wilc mq send fail\n");
3423 result = -EINVAL;
3424 }
3425
3426 return result;
3427 }
3428
3429 s32 wilc_get_inactive_time(struct wilc_vif *vif, const u8 *mac,
3430 u32 *pu32InactiveTime)
3431 {
3432 s32 result = 0;
3433 struct host_if_msg msg;
3434 struct host_if_drv *hif_drv = vif->hif_drv;
3435
3436 if (!hif_drv) {
3437 PRINT_ER("driver is null\n");
3438 return -EFAULT;
3439 }
3440
3441 memset(&msg, 0, sizeof(struct host_if_msg));
3442 memcpy(msg.body.mac_info.mac, mac, ETH_ALEN);
3443
3444 msg.id = HOST_IF_MSG_GET_INACTIVETIME;
3445 msg.vif = vif;
3446
3447 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3448 if (result)
3449 PRINT_ER("Failed to send get host channel param's message queue ");
3450
3451 down(&hif_drv->sem_inactive_time);
3452
3453 *pu32InactiveTime = inactive_time;
3454
3455 return result;
3456 }
3457
3458 int wilc_get_rssi(struct wilc_vif *vif, s8 *rssi_level)
3459 {
3460 int result = 0;
3461 struct host_if_msg msg;
3462 struct host_if_drv *hif_drv = vif->hif_drv;
3463
3464 memset(&msg, 0, sizeof(struct host_if_msg));
3465 msg.id = HOST_IF_MSG_GET_RSSI;
3466 msg.vif = vif;
3467
3468 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3469 if (result) {
3470 PRINT_ER("Failed to send get host channel param's message queue ");
3471 return -EFAULT;
3472 }
3473
3474 down(&hif_drv->sem_get_rssi);
3475
3476 if (!rssi_level) {
3477 PRINT_ER("RSS pointer value is null");
3478 return -EFAULT;
3479 }
3480
3481 *rssi_level = rssi;
3482
3483 return result;
3484 }
3485
3486 int wilc_get_statistics(struct wilc_vif *vif, struct rf_info *stats)
3487 {
3488 int result = 0;
3489 struct host_if_msg msg;
3490
3491 memset(&msg, 0, sizeof(struct host_if_msg));
3492 msg.id = HOST_IF_MSG_GET_STATISTICS;
3493 msg.body.data = (char *)stats;
3494 msg.vif = vif;
3495
3496 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3497 if (result) {
3498 PRINT_ER("Failed to send get host channel param's message queue ");
3499 return -EFAULT;
3500 }
3501
3502 if (stats != &vif->wilc->dummy_statistics)
3503 down(&hif_sema_wait_response);
3504 return result;
3505 }
3506
3507 int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 scan_type,
3508 u8 *ch_freq_list, u8 ch_list_len, const u8 *ies,
3509 size_t ies_len, wilc_scan_result scan_result, void *user_arg,
3510 struct hidden_network *hidden_network)
3511 {
3512 int result = 0;
3513 struct host_if_msg msg;
3514 struct scan_attr *scan_info = &msg.body.scan_info;
3515 struct host_if_drv *hif_drv = vif->hif_drv;
3516
3517 if (!hif_drv || !scan_result) {
3518 PRINT_ER("hif_drv or scan_result = NULL\n");
3519 return -EFAULT;
3520 }
3521
3522 memset(&msg, 0, sizeof(struct host_if_msg));
3523
3524 msg.id = HOST_IF_MSG_SCAN;
3525
3526 if (hidden_network) {
3527 scan_info->hidden_network.net_info = hidden_network->net_info;
3528 scan_info->hidden_network.n_ssids = hidden_network->n_ssids;
3529 }
3530
3531 msg.vif = vif;
3532 scan_info->src = scan_source;
3533 scan_info->type = scan_type;
3534 scan_info->result = scan_result;
3535 scan_info->arg = user_arg;
3536
3537 scan_info->ch_list_len = ch_list_len;
3538 scan_info->ch_freq_list = kmemdup(ch_freq_list,
3539 ch_list_len,
3540 GFP_KERNEL);
3541 if (!scan_info->ch_freq_list)
3542 return -ENOMEM;
3543
3544 scan_info->ies_len = ies_len;
3545 scan_info->ies = kmemdup(ies, ies_len, GFP_KERNEL);
3546 if (!scan_info->ies)
3547 return -ENOMEM;
3548
3549 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3550 if (result) {
3551 PRINT_ER("Error in sending message queue\n");
3552 return -EINVAL;
3553 }
3554
3555 hif_drv->scan_timer.data = (unsigned long)vif;
3556 mod_timer(&hif_drv->scan_timer,
3557 jiffies + msecs_to_jiffies(HOST_IF_SCAN_TIMEOUT));
3558
3559 return result;
3560 }
3561
3562 int wilc_hif_set_cfg(struct wilc_vif *vif,
3563 struct cfg_param_val *cfg_param)
3564 {
3565 int result = 0;
3566 struct host_if_msg msg;
3567 struct host_if_drv *hif_drv = vif->hif_drv;
3568
3569 if (!hif_drv) {
3570 PRINT_ER("hif_drv NULL\n");
3571 return -EFAULT;
3572 }
3573
3574 memset(&msg, 0, sizeof(struct host_if_msg));
3575 msg.id = HOST_IF_MSG_CFG_PARAMS;
3576 msg.body.cfg_info.cfg_attr_info = *cfg_param;
3577 msg.vif = vif;
3578
3579 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3580
3581 return result;
3582 }
3583
3584 static void GetPeriodicRSSI(unsigned long arg)
3585 {
3586 struct wilc_vif *vif = (struct wilc_vif *)arg;
3587
3588 if (!vif->hif_drv) {
3589 PRINT_ER("Driver handler is NULL\n");
3590 return;
3591 }
3592
3593 if (vif->hif_drv->hif_state == HOST_IF_CONNECTED)
3594 wilc_get_statistics(vif, &vif->wilc->dummy_statistics);
3595
3596 periodic_rssi.data = (unsigned long)vif;
3597 mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
3598 }
3599
3600 int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
3601 {
3602 int result = 0;
3603 struct host_if_drv *hif_drv;
3604 struct wilc_vif *vif;
3605 struct wilc *wilc;
3606 int i;
3607
3608 vif = netdev_priv(dev);
3609 wilc = vif->wilc;
3610
3611 scan_while_connected = false;
3612
3613 sema_init(&hif_sema_wait_response, 0);
3614
3615 hif_drv = kzalloc(sizeof(struct host_if_drv), GFP_KERNEL);
3616 if (!hif_drv) {
3617 result = -ENOMEM;
3618 goto _fail_;
3619 }
3620 *hif_drv_handler = hif_drv;
3621 for (i = 0; i < wilc->vif_num; i++)
3622 if (dev == wilc->vif[i]->ndev) {
3623 wilc->vif[i]->hif_drv = hif_drv;
3624 break;
3625 }
3626
3627 wilc_optaining_ip = false;
3628
3629 if (clients_count == 0) {
3630 sema_init(&hif_sema_thread, 0);
3631 sema_init(&hif_sema_driver, 0);
3632 sema_init(&hif_sema_deinit, 1);
3633 }
3634
3635 sema_init(&hif_drv->sem_test_key_block, 0);
3636 sema_init(&hif_drv->sem_test_disconn_block, 0);
3637 sema_init(&hif_drv->sem_get_rssi, 0);
3638 sema_init(&hif_drv->sem_get_link_speed, 0);
3639 sema_init(&hif_drv->sem_get_chnl, 0);
3640 sema_init(&hif_drv->sem_inactive_time, 0);
3641
3642 if (clients_count == 0) {
3643 result = wilc_mq_create(&hif_msg_q);
3644
3645 if (result < 0) {
3646 PRINT_ER("Failed to creat MQ\n");
3647 goto _fail_;
3648 }
3649
3650 hif_thread_handler = kthread_run(hostIFthread, wilc,
3651 "WILC_kthread");
3652
3653 if (IS_ERR(hif_thread_handler)) {
3654 PRINT_ER("Failed to creat Thread\n");
3655 result = -EFAULT;
3656 goto _fail_mq_;
3657 }
3658 setup_timer(&periodic_rssi, GetPeriodicRSSI,
3659 (unsigned long)vif);
3660 mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
3661 }
3662
3663 setup_timer(&hif_drv->scan_timer, TimerCB_Scan, 0);
3664 setup_timer(&hif_drv->connect_timer, TimerCB_Connect, 0);
3665 setup_timer(&hif_drv->remain_on_ch_timer, ListenTimerCB, 0);
3666
3667 sema_init(&hif_drv->sem_cfg_values, 1);
3668 down(&hif_drv->sem_cfg_values);
3669
3670 hif_drv->hif_state = HOST_IF_IDLE;
3671 hif_drv->cfg_values.site_survey_enabled = SITE_SURVEY_OFF;
3672 hif_drv->cfg_values.scan_source = DEFAULT_SCAN;
3673 hif_drv->cfg_values.active_scan_time = ACTIVE_SCAN_TIME;
3674 hif_drv->cfg_values.passive_scan_time = PASSIVE_SCAN_TIME;
3675 hif_drv->cfg_values.curr_tx_rate = AUTORATE;
3676
3677 hif_drv->p2p_timeout = 0;
3678
3679 up(&hif_drv->sem_cfg_values);
3680
3681 clients_count++;
3682
3683 return result;
3684
3685 _fail_mq_:
3686 wilc_mq_destroy(&hif_msg_q);
3687 _fail_:
3688 return result;
3689 }
3690
3691 int wilc_deinit(struct wilc_vif *vif)
3692 {
3693 int result = 0;
3694 struct host_if_msg msg;
3695 struct host_if_drv *hif_drv = vif->hif_drv;
3696
3697 if (!hif_drv) {
3698 PRINT_ER("hif_drv = NULL\n");
3699 return -EFAULT;
3700 }
3701
3702 down(&hif_sema_deinit);
3703
3704 terminated_handle = hif_drv;
3705
3706 del_timer_sync(&hif_drv->scan_timer);
3707 del_timer_sync(&hif_drv->connect_timer);
3708 del_timer_sync(&periodic_rssi);
3709 del_timer_sync(&hif_drv->remain_on_ch_timer);
3710
3711 wilc_set_wfi_drv_handler(vif, 0, 0);
3712 down(&hif_sema_driver);
3713
3714 if (hif_drv->usr_scan_req.scan_result) {
3715 hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED, NULL,
3716 hif_drv->usr_scan_req.arg, NULL);
3717 hif_drv->usr_scan_req.scan_result = NULL;
3718 }
3719
3720 hif_drv->hif_state = HOST_IF_IDLE;
3721
3722 scan_while_connected = false;
3723
3724 memset(&msg, 0, sizeof(struct host_if_msg));
3725
3726 if (clients_count == 1) {
3727 del_timer_sync(&periodic_rssi);
3728 msg.id = HOST_IF_MSG_EXIT;
3729 msg.vif = vif;
3730
3731 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3732 if (result != 0)
3733 PRINT_ER("Error in sending deinit's message queue message function: Error(%d)\n", result);
3734
3735 down(&hif_sema_thread);
3736
3737 wilc_mq_destroy(&hif_msg_q);
3738 }
3739
3740 kfree(hif_drv);
3741
3742 clients_count--;
3743 terminated_handle = NULL;
3744 up(&hif_sema_deinit);
3745 return result;
3746 }
3747
3748 void wilc_network_info_received(struct wilc *wilc, u8 *pu8Buffer,
3749 u32 u32Length)
3750 {
3751 s32 result = 0;
3752 struct host_if_msg msg;
3753 int id;
3754 struct host_if_drv *hif_drv = NULL;
3755 struct wilc_vif *vif;
3756
3757 id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
3758 vif = wilc_get_vif_from_idx(wilc, id);
3759 if (!vif)
3760 return;
3761 hif_drv = vif->hif_drv;
3762
3763 if (!hif_drv || hif_drv == terminated_handle) {
3764 PRINT_ER("NetworkInfo received but driver not init[%p]\n", hif_drv);
3765 return;
3766 }
3767
3768 memset(&msg, 0, sizeof(struct host_if_msg));
3769
3770 msg.id = HOST_IF_MSG_RCVD_NTWRK_INFO;
3771 msg.vif = vif;
3772
3773 msg.body.net_info.len = u32Length;
3774 msg.body.net_info.buffer = kmalloc(u32Length, GFP_KERNEL);
3775 memcpy(msg.body.net_info.buffer, pu8Buffer, u32Length);
3776
3777 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3778 if (result)
3779 PRINT_ER("Error in sending network info message queue message parameters: Error(%d)\n", result);
3780 }
3781
3782 void wilc_gnrl_async_info_received(struct wilc *wilc, u8 *pu8Buffer,
3783 u32 u32Length)
3784 {
3785 s32 result = 0;
3786 struct host_if_msg msg;
3787 int id;
3788 struct host_if_drv *hif_drv = NULL;
3789 struct wilc_vif *vif;
3790
3791 down(&hif_sema_deinit);
3792
3793 id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
3794 vif = wilc_get_vif_from_idx(wilc, id);
3795 if (!vif) {
3796 up(&hif_sema_deinit);
3797 return;
3798 }
3799
3800 hif_drv = vif->hif_drv;
3801
3802 if (!hif_drv || hif_drv == terminated_handle) {
3803 up(&hif_sema_deinit);
3804 return;
3805 }
3806
3807 if (!hif_drv->usr_conn_req.conn_result) {
3808 PRINT_ER("Received mac status is not needed when there is no current Connect Reques\n");
3809 up(&hif_sema_deinit);
3810 return;
3811 }
3812
3813 memset(&msg, 0, sizeof(struct host_if_msg));
3814
3815 msg.id = HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO;
3816 msg.vif = vif;
3817
3818 msg.body.async_info.len = u32Length;
3819 msg.body.async_info.buffer = kmalloc(u32Length, GFP_KERNEL);
3820 memcpy(msg.body.async_info.buffer, pu8Buffer, u32Length);
3821
3822 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3823 if (result)
3824 PRINT_ER("Error in sending message queue asynchronous message info: Error(%d)\n", result);
3825
3826 up(&hif_sema_deinit);
3827 }
3828
3829 void wilc_scan_complete_received(struct wilc *wilc, u8 *pu8Buffer,
3830 u32 u32Length)
3831 {
3832 s32 result = 0;
3833 struct host_if_msg msg;
3834 int id;
3835 struct host_if_drv *hif_drv = NULL;
3836 struct wilc_vif *vif;
3837
3838 id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
3839 vif = wilc_get_vif_from_idx(wilc, id);
3840 if (!vif)
3841 return;
3842 hif_drv = vif->hif_drv;
3843
3844 if (!hif_drv || hif_drv == terminated_handle)
3845 return;
3846
3847 if (hif_drv->usr_scan_req.scan_result) {
3848 memset(&msg, 0, sizeof(struct host_if_msg));
3849
3850 msg.id = HOST_IF_MSG_RCVD_SCAN_COMPLETE;
3851 msg.vif = vif;
3852
3853 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3854 if (result)
3855 PRINT_ER("Error in sending message queue scan complete parameters: Error(%d)\n", result);
3856 }
3857
3858 return;
3859 }
3860
3861 int wilc_remain_on_channel(struct wilc_vif *vif, u32 session_id,
3862 u32 duration, u16 chan,
3863 wilc_remain_on_chan_expired expired,
3864 wilc_remain_on_chan_ready ready,
3865 void *user_arg)
3866 {
3867 int result = 0;
3868 struct host_if_msg msg;
3869 struct host_if_drv *hif_drv = vif->hif_drv;
3870
3871 if (!hif_drv) {
3872 PRINT_ER("driver is null\n");
3873 return -EFAULT;
3874 }
3875
3876 memset(&msg, 0, sizeof(struct host_if_msg));
3877
3878 msg.id = HOST_IF_MSG_REMAIN_ON_CHAN;
3879 msg.body.remain_on_ch.ch = chan;
3880 msg.body.remain_on_ch.expired = expired;
3881 msg.body.remain_on_ch.ready = ready;
3882 msg.body.remain_on_ch.arg = user_arg;
3883 msg.body.remain_on_ch.duration = duration;
3884 msg.body.remain_on_ch.id = session_id;
3885 msg.vif = vif;
3886
3887 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3888 if (result)
3889 PRINT_ER("wilc mq send fail\n");
3890
3891 return result;
3892 }
3893
3894 int wilc_listen_state_expired(struct wilc_vif *vif, u32 session_id)
3895 {
3896 int result = 0;
3897 struct host_if_msg msg;
3898 struct host_if_drv *hif_drv = vif->hif_drv;
3899
3900 if (!hif_drv) {
3901 PRINT_ER("driver is null\n");
3902 return -EFAULT;
3903 }
3904
3905 del_timer(&hif_drv->remain_on_ch_timer);
3906
3907 memset(&msg, 0, sizeof(struct host_if_msg));
3908 msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
3909 msg.vif = vif;
3910 msg.body.remain_on_ch.id = session_id;
3911
3912 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3913 if (result)
3914 PRINT_ER("wilc mq send fail\n");
3915
3916 return result;
3917 }
3918
3919 int wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg)
3920 {
3921 int result = 0;
3922 struct host_if_msg msg;
3923 struct host_if_drv *hif_drv = vif->hif_drv;
3924
3925 if (!hif_drv) {
3926 PRINT_ER("driver is null\n");
3927 return -EFAULT;
3928 }
3929
3930 memset(&msg, 0, sizeof(struct host_if_msg));
3931
3932 msg.id = HOST_IF_MSG_REGISTER_FRAME;
3933 switch (frame_type) {
3934 case ACTION:
3935 msg.body.reg_frame.reg_id = ACTION_FRM_IDX;
3936 break;
3937
3938 case PROBE_REQ:
3939 msg.body.reg_frame.reg_id = PROBE_REQ_IDX;
3940 break;
3941
3942 default:
3943 break;
3944 }
3945 msg.body.reg_frame.frame_type = frame_type;
3946 msg.body.reg_frame.reg = reg;
3947 msg.vif = vif;
3948
3949 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3950 if (result)
3951 PRINT_ER("wilc mq send fail\n");
3952
3953 return result;
3954 }
3955
3956 int wilc_add_beacon(struct wilc_vif *vif, u32 interval, u32 dtim_period,
3957 u32 head_len, u8 *head, u32 tail_len, u8 *tail)
3958 {
3959 int result = 0;
3960 struct host_if_msg msg;
3961 struct beacon_attr *beacon_info = &msg.body.beacon_info;
3962 struct host_if_drv *hif_drv = vif->hif_drv;
3963
3964 if (!hif_drv) {
3965 PRINT_ER("driver is null\n");
3966 return -EFAULT;
3967 }
3968
3969 memset(&msg, 0, sizeof(struct host_if_msg));
3970
3971 msg.id = HOST_IF_MSG_ADD_BEACON;
3972 msg.vif = vif;
3973 beacon_info->interval = interval;
3974 beacon_info->dtim_period = dtim_period;
3975 beacon_info->head_len = head_len;
3976 beacon_info->head = kmemdup(head, head_len, GFP_KERNEL);
3977 if (!beacon_info->head) {
3978 result = -ENOMEM;
3979 goto ERRORHANDLER;
3980 }
3981 beacon_info->tail_len = tail_len;
3982
3983 if (tail_len > 0) {
3984 beacon_info->tail = kmemdup(tail, tail_len, GFP_KERNEL);
3985 if (!beacon_info->tail) {
3986 result = -ENOMEM;
3987 goto ERRORHANDLER;
3988 }
3989 } else {
3990 beacon_info->tail = NULL;
3991 }
3992
3993 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3994 if (result)
3995 PRINT_ER("wilc mq send fail\n");
3996
3997 ERRORHANDLER:
3998 if (result) {
3999 kfree(beacon_info->head);
4000
4001 kfree(beacon_info->tail);
4002 }
4003
4004 return result;
4005 }
4006
4007 int wilc_del_beacon(struct wilc_vif *vif)
4008 {
4009 int result = 0;
4010 struct host_if_msg msg;
4011 struct host_if_drv *hif_drv = vif->hif_drv;
4012
4013 if (!hif_drv) {
4014 PRINT_ER("driver is null\n");
4015 return -EFAULT;
4016 }
4017
4018 msg.id = HOST_IF_MSG_DEL_BEACON;
4019 msg.vif = vif;
4020
4021 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4022 if (result)
4023 PRINT_ER("wilc_mq_send fail\n");
4024
4025 return result;
4026 }
4027
4028 int wilc_add_station(struct wilc_vif *vif, struct add_sta_param *sta_param)
4029 {
4030 int result = 0;
4031 struct host_if_msg msg;
4032 struct add_sta_param *add_sta_info = &msg.body.add_sta_info;
4033 struct host_if_drv *hif_drv = vif->hif_drv;
4034
4035 if (!hif_drv) {
4036 PRINT_ER("driver is null\n");
4037 return -EFAULT;
4038 }
4039
4040 memset(&msg, 0, sizeof(struct host_if_msg));
4041
4042 msg.id = HOST_IF_MSG_ADD_STATION;
4043 msg.vif = vif;
4044
4045 memcpy(add_sta_info, sta_param, sizeof(struct add_sta_param));
4046 if (add_sta_info->rates_len > 0) {
4047 add_sta_info->rates = kmemdup(sta_param->rates,
4048 add_sta_info->rates_len,
4049 GFP_KERNEL);
4050 if (!add_sta_info->rates)
4051 return -ENOMEM;
4052 }
4053
4054 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4055 if (result)
4056 PRINT_ER("wilc_mq_send fail\n");
4057 return result;
4058 }
4059
4060 int wilc_del_station(struct wilc_vif *vif, const u8 *mac_addr)
4061 {
4062 int result = 0;
4063 struct host_if_msg msg;
4064 struct del_sta *del_sta_info = &msg.body.del_sta_info;
4065 struct host_if_drv *hif_drv = vif->hif_drv;
4066
4067 if (!hif_drv) {
4068 PRINT_ER("driver is null\n");
4069 return -EFAULT;
4070 }
4071
4072 memset(&msg, 0, sizeof(struct host_if_msg));
4073
4074 msg.id = HOST_IF_MSG_DEL_STATION;
4075 msg.vif = vif;
4076
4077 if (!mac_addr)
4078 eth_broadcast_addr(del_sta_info->mac_addr);
4079 else
4080 memcpy(del_sta_info->mac_addr, mac_addr, ETH_ALEN);
4081
4082 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4083 if (result)
4084 PRINT_ER("wilc_mq_send fail\n");
4085 return result;
4086 }
4087
4088 int wilc_del_allstation(struct wilc_vif *vif, u8 mac_addr[][ETH_ALEN])
4089 {
4090 int result = 0;
4091 struct host_if_msg msg;
4092 struct del_all_sta *del_all_sta_info = &msg.body.del_all_sta_info;
4093 struct host_if_drv *hif_drv = vif->hif_drv;
4094 u8 zero_addr[ETH_ALEN] = {0};
4095 int i;
4096 u8 assoc_sta = 0;
4097
4098 if (!hif_drv) {
4099 PRINT_ER("driver is null\n");
4100 return -EFAULT;
4101 }
4102
4103 memset(&msg, 0, sizeof(struct host_if_msg));
4104
4105 msg.id = HOST_IF_MSG_DEL_ALL_STA;
4106 msg.vif = vif;
4107
4108 for (i = 0; i < MAX_NUM_STA; i++) {
4109 if (memcmp(mac_addr[i], zero_addr, ETH_ALEN)) {
4110 memcpy(del_all_sta_info->del_all_sta[i], mac_addr[i], ETH_ALEN);
4111 PRINT_D(CFG80211_DBG, "BSSID = %x%x%x%x%x%x\n",
4112 del_all_sta_info->del_all_sta[i][0],
4113 del_all_sta_info->del_all_sta[i][1],
4114 del_all_sta_info->del_all_sta[i][2],
4115 del_all_sta_info->del_all_sta[i][3],
4116 del_all_sta_info->del_all_sta[i][4],
4117 del_all_sta_info->del_all_sta[i][5]);
4118 assoc_sta++;
4119 }
4120 }
4121 if (!assoc_sta) {
4122 PRINT_D(CFG80211_DBG, "NO ASSOCIATED STAS\n");
4123 return result;
4124 }
4125
4126 del_all_sta_info->assoc_sta = assoc_sta;
4127 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4128
4129 if (result)
4130 PRINT_ER("wilc_mq_send fail\n");
4131
4132 down(&hif_sema_wait_response);
4133
4134 return result;
4135 }
4136
4137 int wilc_edit_station(struct wilc_vif *vif,
4138 struct add_sta_param *sta_param)
4139 {
4140 int result = 0;
4141 struct host_if_msg msg;
4142 struct add_sta_param *add_sta_info = &msg.body.add_sta_info;
4143 struct host_if_drv *hif_drv = vif->hif_drv;
4144
4145 if (!hif_drv) {
4146 PRINT_ER("driver is null\n");
4147 return -EFAULT;
4148 }
4149
4150 memset(&msg, 0, sizeof(struct host_if_msg));
4151
4152 msg.id = HOST_IF_MSG_EDIT_STATION;
4153 msg.vif = vif;
4154
4155 memcpy(add_sta_info, sta_param, sizeof(struct add_sta_param));
4156 if (add_sta_info->rates_len > 0) {
4157 add_sta_info->rates = kmemdup(sta_param->rates,
4158 add_sta_info->rates_len,
4159 GFP_KERNEL);
4160 if (!add_sta_info->rates)
4161 return -ENOMEM;
4162 }
4163
4164 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4165 if (result)
4166 PRINT_ER("wilc_mq_send fail\n");
4167
4168 return result;
4169 }
4170
4171 int wilc_set_power_mgmt(struct wilc_vif *vif, bool enabled, u32 timeout)
4172 {
4173 int result = 0;
4174 struct host_if_msg msg;
4175 struct power_mgmt_param *pwr_mgmt_info = &msg.body.pwr_mgmt_info;
4176 struct host_if_drv *hif_drv = vif->hif_drv;
4177
4178 if (!hif_drv) {
4179 PRINT_ER("driver is null\n");
4180 return -EFAULT;
4181 }
4182
4183 if (wilc_wlan_get_num_conn_ifcs(vif->wilc) == 2 && enabled)
4184 return 0;
4185
4186 memset(&msg, 0, sizeof(struct host_if_msg));
4187
4188 msg.id = HOST_IF_MSG_POWER_MGMT;
4189 msg.vif = vif;
4190
4191 pwr_mgmt_info->enabled = enabled;
4192 pwr_mgmt_info->timeout = timeout;
4193
4194 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4195 if (result)
4196 PRINT_ER("wilc_mq_send fail\n");
4197 return result;
4198 }
4199
4200 int wilc_setup_multicast_filter(struct wilc_vif *vif, bool enabled,
4201 u32 count)
4202 {
4203 int result = 0;
4204 struct host_if_msg msg;
4205 struct set_multicast *multicast_filter_param = &msg.body.multicast_info;
4206 struct host_if_drv *hif_drv = vif->hif_drv;
4207
4208 if (!hif_drv) {
4209 PRINT_ER("driver is null\n");
4210 return -EFAULT;
4211 }
4212
4213 memset(&msg, 0, sizeof(struct host_if_msg));
4214
4215 msg.id = HOST_IF_MSG_SET_MULTICAST_FILTER;
4216 msg.vif = vif;
4217
4218 multicast_filter_param->enabled = enabled;
4219 multicast_filter_param->cnt = count;
4220
4221 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4222 if (result)
4223 PRINT_ER("wilc_mq_send fail\n");
4224 return result;
4225 }
4226
4227 static void *host_int_ParseJoinBssParam(struct network_info *ptstrNetworkInfo)
4228 {
4229 struct join_bss_param *pNewJoinBssParam = NULL;
4230 u8 *pu8IEs;
4231 u16 u16IEsLen;
4232 u16 index = 0;
4233 u8 suppRatesNo = 0;
4234 u8 extSuppRatesNo;
4235 u16 jumpOffset;
4236 u8 pcipherCount;
4237 u8 authCount;
4238 u8 pcipherTotalCount = 0;
4239 u8 authTotalCount = 0;
4240 u8 i, j;
4241
4242 pu8IEs = ptstrNetworkInfo->ies;
4243 u16IEsLen = ptstrNetworkInfo->ies_len;
4244
4245 pNewJoinBssParam = kzalloc(sizeof(struct join_bss_param), GFP_KERNEL);
4246 if (pNewJoinBssParam) {
4247 pNewJoinBssParam->dtim_period = ptstrNetworkInfo->dtim_period;
4248 pNewJoinBssParam->beacon_period = ptstrNetworkInfo->beacon_period;
4249 pNewJoinBssParam->cap_info = ptstrNetworkInfo->cap_info;
4250 memcpy(pNewJoinBssParam->bssid, ptstrNetworkInfo->bssid, 6);
4251 memcpy((u8 *)pNewJoinBssParam->ssid, ptstrNetworkInfo->ssid,
4252 ptstrNetworkInfo->ssid_len + 1);
4253 pNewJoinBssParam->ssid_len = ptstrNetworkInfo->ssid_len;
4254 memset(pNewJoinBssParam->rsn_pcip_policy, 0xFF, 3);
4255 memset(pNewJoinBssParam->rsn_auth_policy, 0xFF, 3);
4256
4257 while (index < u16IEsLen) {
4258 if (pu8IEs[index] == SUPP_RATES_IE) {
4259 suppRatesNo = pu8IEs[index + 1];
4260 pNewJoinBssParam->supp_rates[0] = suppRatesNo;
4261 index += 2;
4262
4263 for (i = 0; i < suppRatesNo; i++)
4264 pNewJoinBssParam->supp_rates[i + 1] = pu8IEs[index + i];
4265
4266 index += suppRatesNo;
4267 continue;
4268 } else if (pu8IEs[index] == EXT_SUPP_RATES_IE) {
4269 extSuppRatesNo = pu8IEs[index + 1];
4270 if (extSuppRatesNo > (MAX_RATES_SUPPORTED - suppRatesNo))
4271 pNewJoinBssParam->supp_rates[0] = MAX_RATES_SUPPORTED;
4272 else
4273 pNewJoinBssParam->supp_rates[0] += extSuppRatesNo;
4274 index += 2;
4275 for (i = 0; i < (pNewJoinBssParam->supp_rates[0] - suppRatesNo); i++)
4276 pNewJoinBssParam->supp_rates[suppRatesNo + i + 1] = pu8IEs[index + i];
4277
4278 index += extSuppRatesNo;
4279 continue;
4280 } else if (pu8IEs[index] == HT_CAPABILITY_IE) {
4281 pNewJoinBssParam->ht_capable = true;
4282 index += pu8IEs[index + 1] + 2;
4283 continue;
4284 } else if ((pu8IEs[index] == WMM_IE) &&
4285 (pu8IEs[index + 2] == 0x00) && (pu8IEs[index + 3] == 0x50) &&
4286 (pu8IEs[index + 4] == 0xF2) &&
4287 (pu8IEs[index + 5] == 0x02) &&
4288 ((pu8IEs[index + 6] == 0x00) || (pu8IEs[index + 6] == 0x01)) &&
4289 (pu8IEs[index + 7] == 0x01)) {
4290 pNewJoinBssParam->wmm_cap = true;
4291
4292 if (pu8IEs[index + 8] & BIT(7))
4293 pNewJoinBssParam->uapsd_cap = true;
4294 index += pu8IEs[index + 1] + 2;
4295 continue;
4296 } else if ((pu8IEs[index] == P2P_IE) &&
4297 (pu8IEs[index + 2] == 0x50) && (pu8IEs[index + 3] == 0x6f) &&
4298 (pu8IEs[index + 4] == 0x9a) &&
4299 (pu8IEs[index + 5] == 0x09) && (pu8IEs[index + 6] == 0x0c)) {
4300 u16 u16P2P_count;
4301
4302 pNewJoinBssParam->tsf = ptstrNetworkInfo->tsf_lo;
4303 pNewJoinBssParam->noa_enabled = 1;
4304 pNewJoinBssParam->idx = pu8IEs[index + 9];
4305
4306 if (pu8IEs[index + 10] & BIT(7)) {
4307 pNewJoinBssParam->opp_enabled = 1;
4308 pNewJoinBssParam->ct_window = pu8IEs[index + 10];
4309 } else {
4310 pNewJoinBssParam->opp_enabled = 0;
4311 }
4312
4313 pNewJoinBssParam->cnt = pu8IEs[index + 11];
4314 u16P2P_count = index + 12;
4315
4316 memcpy(pNewJoinBssParam->duration, pu8IEs + u16P2P_count, 4);
4317 u16P2P_count += 4;
4318
4319 memcpy(pNewJoinBssParam->interval, pu8IEs + u16P2P_count, 4);
4320 u16P2P_count += 4;
4321
4322 memcpy(pNewJoinBssParam->start_time, pu8IEs + u16P2P_count, 4);
4323
4324 index += pu8IEs[index + 1] + 2;
4325 continue;
4326
4327 } else if ((pu8IEs[index] == RSN_IE) ||
4328 ((pu8IEs[index] == WPA_IE) && (pu8IEs[index + 2] == 0x00) &&
4329 (pu8IEs[index + 3] == 0x50) && (pu8IEs[index + 4] == 0xF2) &&
4330 (pu8IEs[index + 5] == 0x01))) {
4331 u16 rsnIndex = index;
4332
4333 if (pu8IEs[rsnIndex] == RSN_IE) {
4334 pNewJoinBssParam->mode_802_11i = 2;
4335 } else {
4336 if (pNewJoinBssParam->mode_802_11i == 0)
4337 pNewJoinBssParam->mode_802_11i = 1;
4338 rsnIndex += 4;
4339 }
4340
4341 rsnIndex += 7;
4342 pNewJoinBssParam->rsn_grp_policy = pu8IEs[rsnIndex];
4343 rsnIndex++;
4344 jumpOffset = pu8IEs[rsnIndex] * 4;
4345 pcipherCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex];
4346 rsnIndex += 2;
4347
4348 for (i = pcipherTotalCount, j = 0; i < pcipherCount + pcipherTotalCount && i < 3; i++, j++)
4349 pNewJoinBssParam->rsn_pcip_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1];
4350
4351 pcipherTotalCount += pcipherCount;
4352 rsnIndex += jumpOffset;
4353
4354 jumpOffset = pu8IEs[rsnIndex] * 4;
4355
4356 authCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex];
4357 rsnIndex += 2;
4358
4359 for (i = authTotalCount, j = 0; i < authTotalCount + authCount; i++, j++)
4360 pNewJoinBssParam->rsn_auth_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1];
4361
4362 authTotalCount += authCount;
4363 rsnIndex += jumpOffset;
4364
4365 if (pu8IEs[index] == RSN_IE) {
4366 pNewJoinBssParam->rsn_cap[0] = pu8IEs[rsnIndex];
4367 pNewJoinBssParam->rsn_cap[1] = pu8IEs[rsnIndex + 1];
4368 rsnIndex += 2;
4369 }
4370 pNewJoinBssParam->rsn_found = true;
4371 index += pu8IEs[index + 1] + 2;
4372 continue;
4373 } else
4374 index += pu8IEs[index + 1] + 2;
4375 }
4376 }
4377
4378 return (void *)pNewJoinBssParam;
4379 }
4380
4381 int wilc_setup_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
4382 {
4383 int result = 0;
4384 struct host_if_msg msg;
4385 struct host_if_drv *hif_drv = vif->hif_drv;
4386
4387 if (!hif_drv) {
4388 PRINT_ER("driver is null\n");
4389 return -EFAULT;
4390 }
4391
4392 memset(&msg, 0, sizeof(struct host_if_msg));
4393
4394 msg.id = HOST_IF_MSG_SET_IPADDRESS;
4395
4396 msg.body.ip_info.ip_addr = ip_addr;
4397 msg.vif = vif;
4398 msg.body.ip_info.idx = idx;
4399
4400 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4401 if (result)
4402 PRINT_ER("wilc_mq_send fail\n");
4403
4404 return result;
4405 }
4406
4407 static int host_int_get_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
4408 {
4409 int result = 0;
4410 struct host_if_msg msg;
4411 struct host_if_drv *hif_drv = vif->hif_drv;
4412
4413 if (!hif_drv) {
4414 PRINT_ER("driver is null\n");
4415 return -EFAULT;
4416 }
4417
4418 memset(&msg, 0, sizeof(struct host_if_msg));
4419
4420 msg.id = HOST_IF_MSG_GET_IPADDRESS;
4421
4422 msg.body.ip_info.ip_addr = ip_addr;
4423 msg.vif = vif;
4424 msg.body.ip_info.idx = idx;
4425
4426 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4427 if (result)
4428 PRINT_ER("wilc_mq_send fail\n");
4429
4430 return result;
4431 }
4432
4433 int wilc_set_tx_power(struct wilc_vif *vif, u8 tx_power)
4434 {
4435 int ret = 0;
4436 struct host_if_msg msg;
4437
4438 memset(&msg, 0, sizeof(struct host_if_msg));
4439
4440 msg.id = HOST_IF_MSG_SET_TX_POWER;
4441 msg.body.tx_power.tx_pwr = tx_power;
4442 msg.vif = vif;
4443
4444 ret = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4445 if (ret)
4446 netdev_err(vif->ndev, "wilc_mq_send fail\n");
4447
4448 return ret;
4449 }
4450
4451 int wilc_get_tx_power(struct wilc_vif *vif, u8 *tx_power)
4452 {
4453 int ret = 0;
4454 struct host_if_msg msg;
4455
4456 memset(&msg, 0, sizeof(struct host_if_msg));
4457
4458 msg.id = HOST_IF_MSG_GET_TX_POWER;
4459 msg.vif = vif;
4460
4461 ret = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4462 if (ret)
4463 netdev_err(vif->ndev, "Failed to get TX PWR\n");
4464
4465 down(&hif_sema_wait_response);
4466 *tx_power = msg.body.tx_power.tx_pwr;
4467
4468 return ret;
4469 }
This page took 0.184899 seconds and 4 git commands to generate.