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