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