staging: wilc1000: rename u8WepKeylen in host_int_add_wep_key_bss_ap
[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->usr_conn_req.pu8bssid = kmalloc(6, GFP_KERNEL);
1008                 memcpy(hif_drv->usr_conn_req.pu8bssid, pstrHostIFconnectAttr->bssid, 6);
1009         }
1010
1011         hif_drv->usr_conn_req.ssidLen = pstrHostIFconnectAttr->ssid_len;
1012         if (pstrHostIFconnectAttr->ssid) {
1013                 hif_drv->usr_conn_req.pu8ssid = kmalloc(pstrHostIFconnectAttr->ssid_len + 1, GFP_KERNEL);
1014                 memcpy(hif_drv->usr_conn_req.pu8ssid,
1015                        pstrHostIFconnectAttr->ssid,
1016                        pstrHostIFconnectAttr->ssid_len);
1017                 hif_drv->usr_conn_req.pu8ssid[pstrHostIFconnectAttr->ssid_len] = '\0';
1018         }
1019
1020         hif_drv->usr_conn_req.ConnReqIEsLen = pstrHostIFconnectAttr->ies_len;
1021         if (pstrHostIFconnectAttr->ies) {
1022                 hif_drv->usr_conn_req.pu8ConnReqIEs = kmalloc(pstrHostIFconnectAttr->ies_len, GFP_KERNEL);
1023                 memcpy(hif_drv->usr_conn_req.pu8ConnReqIEs,
1024                        pstrHostIFconnectAttr->ies,
1025                        pstrHostIFconnectAttr->ies_len);
1026         }
1027
1028         hif_drv->usr_conn_req.u8security = pstrHostIFconnectAttr->security;
1029         hif_drv->usr_conn_req.tenuAuth_type = pstrHostIFconnectAttr->auth_type;
1030         hif_drv->usr_conn_req.pfUserConnectResult = pstrHostIFconnectAttr->result;
1031         hif_drv->usr_conn_req.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->usr_conn_req.pu8ConnReqIEs;
1055                 strWIDList[u32WidsCount].size = hif_drv->usr_conn_req.ConnReqIEsLen;
1056                 u32WidsCount++;
1057
1058                 if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
1059                         info_element_size = hif_drv->usr_conn_req.ConnReqIEsLen;
1060                         info_element = kmalloc(info_element_size, GFP_KERNEL);
1061                         memcpy(info_element, hif_drv->usr_conn_req.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->usr_conn_req.u8security;
1069         u32WidsCount++;
1070
1071         if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7))
1072                 mode_11i = hif_drv->usr_conn_req.u8security;
1073
1074         PRINT_INFO(HOSTINF_DBG, "Encrypt Mode = %x\n", hif_drv->usr_conn_req.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->usr_conn_req.tenuAuth_type);
1080         u32WidsCount++;
1081
1082         if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7))
1083                 auth_type = (u8)hif_drv->usr_conn_req.tenuAuth_type;
1084
1085         PRINT_INFO(HOSTINF_DBG, "Authentication Type = %x\n", hif_drv->usr_conn_req.tenuAuth_type);
1086         PRINT_D(HOSTINF_DBG, "Connecting to network of SSID %s on channel %d\n",
1087                 hif_drv->usr_conn_req.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->usr_conn_req.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->usr_conn_req.pfUserConnectResult) {
1335                 if (hif_drv->usr_conn_req.pu8bssid) {
1336                         memcpy(strConnectInfo.au8bssid,
1337                                hif_drv->usr_conn_req.pu8bssid, 6);
1338                 }
1339
1340                 if (hif_drv->usr_conn_req.pu8ConnReqIEs) {
1341                         strConnectInfo.ReqIEsLen = hif_drv->usr_conn_req.ConnReqIEsLen;
1342                         strConnectInfo.pu8ReqIEs = kmalloc(hif_drv->usr_conn_req.ConnReqIEsLen, GFP_KERNEL);
1343                         memcpy(strConnectInfo.pu8ReqIEs,
1344                                hif_drv->usr_conn_req.pu8ConnReqIEs,
1345                                hif_drv->usr_conn_req.ConnReqIEsLen);
1346                 }
1347
1348                 hif_drv->usr_conn_req.pfUserConnectResult(CONN_DISCONN_EVENT_CONN_RESP,
1349                                                           &strConnectInfo,
1350                                                           MAC_DISCONNECTED,
1351                                                           NULL,
1352                                                           hif_drv->usr_conn_req.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->usr_conn_req.ssidLen = 0;
1373         kfree(hif_drv->usr_conn_req.pu8ssid);
1374         kfree(hif_drv->usr_conn_req.pu8bssid);
1375         hif_drv->usr_conn_req.ConnReqIEsLen = 0;
1376         kfree(hif_drv->usr_conn_req.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->usr_conn_req.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->usr_conn_req.pu8bssid) {
1577                                 PRINT_D(HOSTINF_DBG, "Retrieving actual BSSID from AP\n");
1578                                 memcpy(strConnectInfo.au8bssid, hif_drv->usr_conn_req.pu8bssid, 6);
1579
1580                                 if ((u8MacStatus == MAC_CONNECTED) &&
1581                                     (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
1582                                         memcpy(hif_drv->au8AssociatedBSSID,
1583                                                hif_drv->usr_conn_req.pu8bssid, ETH_ALEN);
1584                                 }
1585                         }
1586
1587                         if (hif_drv->usr_conn_req.pu8ConnReqIEs) {
1588                                 strConnectInfo.ReqIEsLen = hif_drv->usr_conn_req.ConnReqIEsLen;
1589                                 strConnectInfo.pu8ReqIEs = kmalloc(hif_drv->usr_conn_req.ConnReqIEsLen, GFP_KERNEL);
1590                                 memcpy(strConnectInfo.pu8ReqIEs,
1591                                        hif_drv->usr_conn_req.pu8ConnReqIEs,
1592                                        hif_drv->usr_conn_req.ConnReqIEsLen);
1593                         }
1594
1595                         del_timer(&hif_drv->hConnectTimer);
1596                         hif_drv->usr_conn_req.pfUserConnectResult(CONN_DISCONN_EVENT_CONN_RESP,
1597                                                                   &strConnectInfo,
1598                                                                   u8MacStatus,
1599                                                                   NULL,
1600                                                                   hif_drv->usr_conn_req.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->usr_conn_req.ssidLen = 0;
1625                         kfree(hif_drv->usr_conn_req.pu8ssid);
1626                         kfree(hif_drv->usr_conn_req.pu8bssid);
1627                         hif_drv->usr_conn_req.ConnReqIEsLen = 0;
1628                         kfree(hif_drv->usr_conn_req.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->usr_conn_req.pfUserConnectResult) {
1646                                 g_obtainingIP = false;
1647                                 host_int_set_power_mgmt(hif_drv, 0, 0);
1648
1649                                 hif_drv->usr_conn_req.pfUserConnectResult(CONN_DISCONN_EVENT_DISCONN_NOTIF,
1650                                                                           NULL,
1651                                                                           0,
1652                                                                           &strDisconnectNotifInfo,
1653                                                                           hif_drv->usr_conn_req.u32UserConnectPvoid);
1654                         } else {
1655                                 PRINT_ER("Connect result callback function is NULL\n");
1656                         }
1657
1658                         eth_zero_addr(hif_drv->au8AssociatedBSSID);
1659
1660                         hif_drv->usr_conn_req.ssidLen = 0;
1661                         kfree(hif_drv->usr_conn_req.pu8ssid);
1662                         kfree(hif_drv->usr_conn_req.pu8bssid);
1663                         hif_drv->usr_conn_req.ConnReqIEsLen = 0;
1664                         kfree(hif_drv->usr_conn_req.pu8ConnReqIEs);
1665
1666                         if (join_req && join_req_drv == hif_drv) {
1667                                 kfree(join_req);
1668                                 join_req = NULL;
1669                         }
1670
1671                         if (info_element && join_req_drv == hif_drv) {
1672                                 kfree(info_element);
1673                                 info_element = NULL;
1674                         }
1675
1676                         hif_drv->enuHostIFstate = HOST_IF_IDLE;
1677                         scan_while_connected = false;
1678
1679                 } else if ((u8MacStatus == MAC_DISCONNECTED) &&
1680                            (hif_drv->usr_scan_req.pfUserScanResult)) {
1681                         PRINT_D(HOSTINF_DBG, "Received MAC_DISCONNECTED from the FW while scanning\n");
1682                         PRINT_D(HOSTINF_DBG, "\n\n<< Abort the running Scan >>\n\n");
1683
1684                         del_timer(&hif_drv->hScanTimer);
1685                         if (hif_drv->usr_scan_req.pfUserScanResult)
1686                                 Handle_ScanDone(hif_drv, SCAN_EVENT_ABORTED);
1687                 }
1688         }
1689
1690         kfree(pstrRcvdGnrlAsyncInfo->buffer);
1691         pstrRcvdGnrlAsyncInfo->buffer = NULL;
1692
1693         return result;
1694 }
1695
1696 static int Handle_Key(struct host_if_drv *hif_drv,
1697                       struct key_attr *pstrHostIFkeyAttr)
1698 {
1699         s32 result = 0;
1700         struct wid wid;
1701         struct wid strWIDList[5];
1702         u8 i;
1703         u8 *pu8keybuf;
1704         s8 s8idxarray[1];
1705         s8 ret = 0;
1706
1707         switch (pstrHostIFkeyAttr->type) {
1708         case WEP:
1709
1710                 if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
1711                         PRINT_D(HOSTINF_DBG, "Handling WEP key\n");
1712                         PRINT_D(GENERIC_DBG, "ID Hostint is %d\n", pstrHostIFkeyAttr->attr.wep.index);
1713                         strWIDList[0].id = (u16)WID_11I_MODE;
1714                         strWIDList[0].type = WID_CHAR;
1715                         strWIDList[0].size = sizeof(char);
1716                         strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wep.mode;
1717
1718                         strWIDList[1].id = WID_AUTH_TYPE;
1719                         strWIDList[1].type = WID_CHAR;
1720                         strWIDList[1].size = sizeof(char);
1721                         strWIDList[1].val = (s8 *)&pstrHostIFkeyAttr->attr.wep.auth_type;
1722
1723                         strWIDList[2].id = (u16)WID_KEY_ID;
1724                         strWIDList[2].type = WID_CHAR;
1725
1726                         strWIDList[2].val = (s8 *)&pstrHostIFkeyAttr->attr.wep.index;
1727                         strWIDList[2].size = sizeof(char);
1728
1729                         pu8keybuf = kmemdup(pstrHostIFkeyAttr->attr.wep.key,
1730                                             pstrHostIFkeyAttr->attr.wep.key_len,
1731                                             GFP_KERNEL);
1732
1733                         if (pu8keybuf == NULL) {
1734                                 PRINT_ER("No buffer to send Key\n");
1735                                 return -ENOMEM;
1736                         }
1737
1738                         kfree(pstrHostIFkeyAttr->attr.wep.key);
1739
1740                         strWIDList[3].id = (u16)WID_WEP_KEY_VALUE;
1741                         strWIDList[3].type = WID_STR;
1742                         strWIDList[3].size = pstrHostIFkeyAttr->attr.wep.key_len;
1743                         strWIDList[3].val = (s8 *)pu8keybuf;
1744
1745                         result = send_config_pkt(SET_CFG, strWIDList, 4,
1746                                                  get_id_from_handler(hif_drv));
1747                         kfree(pu8keybuf);
1748                 }
1749
1750                 if (pstrHostIFkeyAttr->action & ADDKEY) {
1751                         PRINT_D(HOSTINF_DBG, "Handling WEP key\n");
1752                         pu8keybuf = kmalloc(pstrHostIFkeyAttr->attr.wep.key_len + 2, GFP_KERNEL);
1753                         if (!pu8keybuf) {
1754                                 PRINT_ER("No buffer to send Key\n");
1755                                 return -ENOMEM;
1756                         }
1757                         pu8keybuf[0] = pstrHostIFkeyAttr->attr.wep.index;
1758                         memcpy(pu8keybuf + 1, &pstrHostIFkeyAttr->attr.wep.key_len, 1);
1759                         memcpy(pu8keybuf + 2, pstrHostIFkeyAttr->attr.wep.key,
1760                                pstrHostIFkeyAttr->attr.wep.key_len);
1761                         kfree(pstrHostIFkeyAttr->attr.wep.key);
1762
1763                         wid.id = (u16)WID_ADD_WEP_KEY;
1764                         wid.type = WID_STR;
1765                         wid.val = (s8 *)pu8keybuf;
1766                         wid.size = pstrHostIFkeyAttr->attr.wep.key_len + 2;
1767
1768                         result = send_config_pkt(SET_CFG, &wid, 1,
1769                                                  get_id_from_handler(hif_drv));
1770                         kfree(pu8keybuf);
1771                 } else if (pstrHostIFkeyAttr->action & REMOVEKEY) {
1772                         PRINT_D(HOSTINF_DBG, "Removing key\n");
1773                         wid.id = (u16)WID_REMOVE_WEP_KEY;
1774                         wid.type = WID_STR;
1775
1776                         s8idxarray[0] = (s8)pstrHostIFkeyAttr->attr.wep.index;
1777                         wid.val = s8idxarray;
1778                         wid.size = 1;
1779
1780                         result = send_config_pkt(SET_CFG, &wid, 1,
1781                                                  get_id_from_handler(hif_drv));
1782                 } else {
1783                         wid.id = (u16)WID_KEY_ID;
1784                         wid.type = WID_CHAR;
1785                         wid.val = (s8 *)&pstrHostIFkeyAttr->attr.wep.index;
1786                         wid.size = sizeof(char);
1787
1788                         PRINT_D(HOSTINF_DBG, "Setting default key index\n");
1789
1790                         result = send_config_pkt(SET_CFG, &wid, 1,
1791                                                  get_id_from_handler(hif_drv));
1792                 }
1793                 up(&hif_drv->hSemTestKeyBlock);
1794                 break;
1795
1796         case WPARxGtk:
1797                 if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
1798                         pu8keybuf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
1799                         if (!pu8keybuf) {
1800                                 PRINT_ER("No buffer to send RxGTK Key\n");
1801                                 ret = -ENOMEM;
1802                                 goto _WPARxGtk_end_case_;
1803                         }
1804
1805                         if (pstrHostIFkeyAttr->attr.wpa.seq)
1806                                 memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->attr.wpa.seq, 8);
1807
1808                         memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->attr.wpa.index, 1);
1809                         memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
1810                         memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->attr.wpa.key,
1811                                pstrHostIFkeyAttr->attr.wpa.key_len);
1812
1813                         strWIDList[0].id = (u16)WID_11I_MODE;
1814                         strWIDList[0].type = WID_CHAR;
1815                         strWIDList[0].size = sizeof(char);
1816                         strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wpa.mode;
1817
1818                         strWIDList[1].id = (u16)WID_ADD_RX_GTK;
1819                         strWIDList[1].type = WID_STR;
1820                         strWIDList[1].val = (s8 *)pu8keybuf;
1821                         strWIDList[1].size = RX_MIC_KEY_MSG_LEN;
1822
1823                         result = send_config_pkt(SET_CFG, strWIDList, 2,
1824                                                  get_id_from_handler(hif_drv));
1825
1826                         kfree(pu8keybuf);
1827                         up(&hif_drv->hSemTestKeyBlock);
1828                 }
1829
1830                 if (pstrHostIFkeyAttr->action & ADDKEY) {
1831                         PRINT_D(HOSTINF_DBG, "Handling group key(Rx) function\n");
1832
1833                         pu8keybuf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
1834                         if (pu8keybuf == NULL) {
1835                                 PRINT_ER("No buffer to send RxGTK Key\n");
1836                                 ret = -ENOMEM;
1837                                 goto _WPARxGtk_end_case_;
1838                         }
1839
1840                         if (hif_drv->enuHostIFstate == HOST_IF_CONNECTED)
1841                                 memcpy(pu8keybuf, hif_drv->au8AssociatedBSSID, ETH_ALEN);
1842                         else
1843                                 PRINT_ER("Couldn't handle WPARxGtk while enuHostIFstate is not HOST_IF_CONNECTED\n");
1844
1845                         memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->attr.wpa.seq, 8);
1846                         memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->attr.wpa.index, 1);
1847                         memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
1848                         memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->attr.wpa.key,
1849                                pstrHostIFkeyAttr->attr.wpa.key_len);
1850
1851                         wid.id = (u16)WID_ADD_RX_GTK;
1852                         wid.type = WID_STR;
1853                         wid.val = (s8 *)pu8keybuf;
1854                         wid.size = RX_MIC_KEY_MSG_LEN;
1855
1856                         result = send_config_pkt(SET_CFG, &wid, 1,
1857                                                  get_id_from_handler(hif_drv));
1858
1859                         kfree(pu8keybuf);
1860                         up(&hif_drv->hSemTestKeyBlock);
1861                 }
1862 _WPARxGtk_end_case_:
1863                 kfree(pstrHostIFkeyAttr->attr.wpa.key);
1864                 kfree(pstrHostIFkeyAttr->attr.wpa.seq);
1865                 if (ret)
1866                         return ret;
1867
1868                 break;
1869
1870         case WPAPtk:
1871                 if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
1872                         pu8keybuf = kmalloc(PTK_KEY_MSG_LEN + 1, GFP_KERNEL);
1873                         if (!pu8keybuf) {
1874                                 PRINT_ER("No buffer to send PTK Key\n");
1875                                 ret = -ENOMEM;
1876                                 goto _WPAPtk_end_case_;
1877                         }
1878
1879                         memcpy(pu8keybuf, pstrHostIFkeyAttr->attr.wpa.mac_addr, 6);
1880                         memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->attr.wpa.index, 1);
1881                         memcpy(pu8keybuf + 7, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
1882                         memcpy(pu8keybuf + 8, pstrHostIFkeyAttr->attr.wpa.key,
1883                                pstrHostIFkeyAttr->attr.wpa.key_len);
1884
1885                         strWIDList[0].id = (u16)WID_11I_MODE;
1886                         strWIDList[0].type = WID_CHAR;
1887                         strWIDList[0].size = sizeof(char);
1888                         strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wpa.mode;
1889
1890                         strWIDList[1].id = (u16)WID_ADD_PTK;
1891                         strWIDList[1].type = WID_STR;
1892                         strWIDList[1].val = (s8 *)pu8keybuf;
1893                         strWIDList[1].size = PTK_KEY_MSG_LEN + 1;
1894
1895                         result = send_config_pkt(SET_CFG, strWIDList, 2,
1896                                                  get_id_from_handler(hif_drv));
1897                         kfree(pu8keybuf);
1898                         up(&hif_drv->hSemTestKeyBlock);
1899                 }
1900                 if (pstrHostIFkeyAttr->action & ADDKEY) {
1901                         pu8keybuf = kmalloc(PTK_KEY_MSG_LEN, GFP_KERNEL);
1902                         if (!pu8keybuf) {
1903                                 PRINT_ER("No buffer to send PTK Key\n");
1904                                 ret = -ENOMEM;
1905                                 goto _WPAPtk_end_case_;
1906                         }
1907
1908                         memcpy(pu8keybuf, pstrHostIFkeyAttr->attr.wpa.mac_addr, 6);
1909                         memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
1910                         memcpy(pu8keybuf + 7, pstrHostIFkeyAttr->attr.wpa.key,
1911                                pstrHostIFkeyAttr->attr.wpa.key_len);
1912
1913                         wid.id = (u16)WID_ADD_PTK;
1914                         wid.type = WID_STR;
1915                         wid.val = (s8 *)pu8keybuf;
1916                         wid.size = PTK_KEY_MSG_LEN;
1917
1918                         result = send_config_pkt(SET_CFG, &wid, 1,
1919                                                  get_id_from_handler(hif_drv));
1920                         kfree(pu8keybuf);
1921                         up(&hif_drv->hSemTestKeyBlock);
1922                 }
1923
1924 _WPAPtk_end_case_:
1925                 kfree(pstrHostIFkeyAttr->attr.wpa.key);
1926                 if (ret)
1927                         return ret;
1928
1929                 break;
1930
1931         case PMKSA:
1932
1933                 PRINT_D(HOSTINF_DBG, "Handling PMKSA key\n");
1934
1935                 pu8keybuf = kmalloc((pstrHostIFkeyAttr->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1, GFP_KERNEL);
1936                 if (!pu8keybuf) {
1937                         PRINT_ER("No buffer to send PMKSA Key\n");
1938                         return -ENOMEM;
1939                 }
1940
1941                 pu8keybuf[0] = pstrHostIFkeyAttr->attr.pmkid.numpmkid;
1942
1943                 for (i = 0; i < pstrHostIFkeyAttr->attr.pmkid.numpmkid; i++) {
1944                         memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + 1), pstrHostIFkeyAttr->attr.pmkid.pmkidlist[i].bssid, ETH_ALEN);
1945                         memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + ETH_ALEN + 1), pstrHostIFkeyAttr->attr.pmkid.pmkidlist[i].pmkid, PMKID_LEN);
1946                 }
1947
1948                 wid.id = (u16)WID_PMKID_INFO;
1949                 wid.type = WID_STR;
1950                 wid.val = (s8 *)pu8keybuf;
1951                 wid.size = (pstrHostIFkeyAttr->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1;
1952
1953                 result = send_config_pkt(SET_CFG, &wid, 1,
1954                                          get_id_from_handler(hif_drv));
1955
1956                 kfree(pu8keybuf);
1957                 break;
1958         }
1959
1960         if (result)
1961                 PRINT_ER("Failed to send key config packet\n");
1962
1963         return result;
1964 }
1965
1966 static void Handle_Disconnect(struct host_if_drv *hif_drv)
1967 {
1968         struct wid wid;
1969
1970         s32 result = 0;
1971         u16 u16DummyReasonCode = 0;
1972
1973         wid.id = (u16)WID_DISCONNECT;
1974         wid.type = WID_CHAR;
1975         wid.val = (s8 *)&u16DummyReasonCode;
1976         wid.size = sizeof(char);
1977
1978         PRINT_D(HOSTINF_DBG, "Sending disconnect request\n");
1979
1980         g_obtainingIP = false;
1981         host_int_set_power_mgmt(hif_drv, 0, 0);
1982
1983         eth_zero_addr(u8ConnectedSSID);
1984
1985         result = send_config_pkt(SET_CFG, &wid, 1,
1986                                  get_id_from_handler(hif_drv));
1987
1988         if (result) {
1989                 PRINT_ER("Failed to send dissconect config packet\n");
1990         } else {
1991                 tstrDisconnectNotifInfo strDisconnectNotifInfo;
1992
1993                 memset(&strDisconnectNotifInfo, 0, sizeof(tstrDisconnectNotifInfo));
1994
1995                 strDisconnectNotifInfo.u16reason = 0;
1996                 strDisconnectNotifInfo.ie = NULL;
1997                 strDisconnectNotifInfo.ie_len = 0;
1998
1999                 if (hif_drv->usr_scan_req.pfUserScanResult) {
2000                         del_timer(&hif_drv->hScanTimer);
2001                         hif_drv->usr_scan_req.pfUserScanResult(SCAN_EVENT_ABORTED, NULL,
2002                                                                hif_drv->usr_scan_req.u32UserScanPvoid, NULL);
2003
2004                         hif_drv->usr_scan_req.pfUserScanResult = NULL;
2005                 }
2006
2007                 if (hif_drv->usr_conn_req.pfUserConnectResult) {
2008                         if (hif_drv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) {
2009                                 PRINT_D(HOSTINF_DBG, "Upper layer requested termination of connection\n");
2010                                 del_timer(&hif_drv->hConnectTimer);
2011                         }
2012
2013                         hif_drv->usr_conn_req.pfUserConnectResult(CONN_DISCONN_EVENT_DISCONN_NOTIF, NULL,
2014                                                                   0, &strDisconnectNotifInfo, hif_drv->usr_conn_req.u32UserConnectPvoid);
2015                 } else {
2016                         PRINT_ER("usr_conn_req.pfUserConnectResult = NULL\n");
2017                 }
2018
2019                 scan_while_connected = false;
2020
2021                 hif_drv->enuHostIFstate = HOST_IF_IDLE;
2022
2023                 eth_zero_addr(hif_drv->au8AssociatedBSSID);
2024
2025                 hif_drv->usr_conn_req.ssidLen = 0;
2026                 kfree(hif_drv->usr_conn_req.pu8ssid);
2027                 kfree(hif_drv->usr_conn_req.pu8bssid);
2028                 hif_drv->usr_conn_req.ConnReqIEsLen = 0;
2029                 kfree(hif_drv->usr_conn_req.pu8ConnReqIEs);
2030
2031                 if (join_req && join_req_drv == hif_drv) {
2032                         kfree(join_req);
2033                         join_req = NULL;
2034                 }
2035
2036                 if (info_element && join_req_drv == hif_drv) {
2037                         kfree(info_element);
2038                         info_element = NULL;
2039                 }
2040         }
2041
2042         up(&hif_drv->hSemTestDisconnectBlock);
2043 }
2044
2045 void resolve_disconnect_aberration(struct host_if_drv *hif_drv)
2046 {
2047         if (!hif_drv)
2048                 return;
2049         if ((hif_drv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) || (hif_drv->enuHostIFstate == HOST_IF_CONNECTING)) {
2050                 PRINT_D(HOSTINF_DBG, "\n\n<< correcting Supplicant state machine >>\n\n");
2051                 host_int_disconnect(hif_drv, 1);
2052         }
2053 }
2054
2055 static s32 Handle_GetChnl(struct host_if_drv *hif_drv)
2056 {
2057         s32 result = 0;
2058         struct wid wid;
2059
2060         wid.id = (u16)WID_CURRENT_CHANNEL;
2061         wid.type = WID_CHAR;
2062         wid.val = (s8 *)&ch_no;
2063         wid.size = sizeof(char);
2064
2065         PRINT_D(HOSTINF_DBG, "Getting channel value\n");
2066
2067         result = send_config_pkt(GET_CFG, &wid, 1,
2068                                  get_id_from_handler(hif_drv));
2069
2070         if (result) {
2071                 PRINT_ER("Failed to get channel number\n");
2072                 result = -EFAULT;
2073         }
2074
2075         up(&hif_drv->hSemGetCHNL);
2076
2077         return result;
2078 }
2079
2080 static void Handle_GetRssi(struct host_if_drv *hif_drv)
2081 {
2082         s32 result = 0;
2083         struct wid wid;
2084
2085         wid.id = (u16)WID_RSSI;
2086         wid.type = WID_CHAR;
2087         wid.val = &rssi;
2088         wid.size = sizeof(char);
2089
2090         PRINT_D(HOSTINF_DBG, "Getting RSSI value\n");
2091
2092         result = send_config_pkt(GET_CFG, &wid, 1,
2093                                  get_id_from_handler(hif_drv));
2094         if (result) {
2095                 PRINT_ER("Failed to get RSSI value\n");
2096                 result = -EFAULT;
2097         }
2098
2099         up(&hif_drv->hSemGetRSSI);
2100 }
2101
2102 static void Handle_GetLinkspeed(struct host_if_drv *hif_drv)
2103 {
2104         s32 result = 0;
2105         struct wid wid;
2106
2107         link_speed = 0;
2108
2109         wid.id = (u16)WID_LINKSPEED;
2110         wid.type = WID_CHAR;
2111         wid.val = &link_speed;
2112         wid.size = sizeof(char);
2113
2114         PRINT_D(HOSTINF_DBG, "Getting LINKSPEED value\n");
2115
2116         result = send_config_pkt(GET_CFG, &wid, 1,
2117                                  get_id_from_handler(hif_drv));
2118         if (result) {
2119                 PRINT_ER("Failed to get LINKSPEED value\n");
2120                 result = -EFAULT;
2121         }
2122
2123         up(&hif_drv->hSemGetLINKSPEED);
2124 }
2125
2126 s32 Handle_GetStatistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatistics)
2127 {
2128         struct wid strWIDList[5];
2129         u32 u32WidsCount = 0, result = 0;
2130
2131         strWIDList[u32WidsCount].id = WID_LINKSPEED;
2132         strWIDList[u32WidsCount].type = WID_CHAR;
2133         strWIDList[u32WidsCount].size = sizeof(char);
2134         strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->u8LinkSpeed;
2135         u32WidsCount++;
2136
2137         strWIDList[u32WidsCount].id = WID_RSSI;
2138         strWIDList[u32WidsCount].type = WID_CHAR;
2139         strWIDList[u32WidsCount].size = sizeof(char);
2140         strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->s8RSSI;
2141         u32WidsCount++;
2142
2143         strWIDList[u32WidsCount].id = WID_SUCCESS_FRAME_COUNT;
2144         strWIDList[u32WidsCount].type = WID_INT;
2145         strWIDList[u32WidsCount].size = sizeof(u32);
2146         strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->u32TxCount;
2147         u32WidsCount++;
2148
2149         strWIDList[u32WidsCount].id = WID_RECEIVED_FRAGMENT_COUNT;
2150         strWIDList[u32WidsCount].type = WID_INT;
2151         strWIDList[u32WidsCount].size = sizeof(u32);
2152         strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->u32RxCount;
2153         u32WidsCount++;
2154
2155         strWIDList[u32WidsCount].id = WID_FAILED_COUNT;
2156         strWIDList[u32WidsCount].type = WID_INT;
2157         strWIDList[u32WidsCount].size = sizeof(u32);
2158         strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->u32TxFailureCount;
2159         u32WidsCount++;
2160
2161         result = send_config_pkt(GET_CFG, strWIDList, u32WidsCount,
2162                                  get_id_from_handler(hif_drv));
2163
2164         if (result)
2165                 PRINT_ER("Failed to send scan paramters config packet\n");
2166
2167         up(&hif_sema_wait_response);
2168         return 0;
2169 }
2170
2171 static s32 Handle_Get_InActiveTime(struct host_if_drv *hif_drv,
2172                                    struct sta_inactive_t *strHostIfStaInactiveT)
2173 {
2174         s32 result = 0;
2175         u8 *stamac;
2176         struct wid wid;
2177
2178         wid.id = (u16)WID_SET_STA_MAC_INACTIVE_TIME;
2179         wid.type = WID_STR;
2180         wid.size = ETH_ALEN;
2181         wid.val = kmalloc(wid.size, GFP_KERNEL);
2182
2183         stamac = wid.val;
2184         memcpy(stamac, strHostIfStaInactiveT->mac, ETH_ALEN);
2185
2186         PRINT_D(CFG80211_DBG, "SETING STA inactive time\n");
2187
2188         result = send_config_pkt(SET_CFG, &wid, 1,
2189                                  get_id_from_handler(hif_drv));
2190
2191         if (result) {
2192                 PRINT_ER("Failed to SET incative time\n");
2193                 return -EFAULT;
2194         }
2195
2196         wid.id = (u16)WID_GET_INACTIVE_TIME;
2197         wid.type = WID_INT;
2198         wid.val = (s8 *)&inactive_time;
2199         wid.size = sizeof(u32);
2200
2201         result = send_config_pkt(GET_CFG, &wid, 1,
2202                                  get_id_from_handler(hif_drv));
2203
2204         if (result) {
2205                 PRINT_ER("Failed to get incative time\n");
2206                 return -EFAULT;
2207         }
2208
2209         PRINT_D(CFG80211_DBG, "Getting inactive time : %d\n", inactive_time);
2210
2211         up(&hif_drv->hSemInactiveTime);
2212
2213         return result;
2214 }
2215
2216 static void Handle_AddBeacon(struct host_if_drv *hif_drv,
2217                              struct beacon_attr *pstrSetBeaconParam)
2218 {
2219         s32 result = 0;
2220         struct wid wid;
2221         u8 *pu8CurrByte;
2222
2223         PRINT_D(HOSTINF_DBG, "Adding BEACON\n");
2224
2225         wid.id = (u16)WID_ADD_BEACON;
2226         wid.type = WID_BIN;
2227         wid.size = pstrSetBeaconParam->head_len + pstrSetBeaconParam->tail_len + 16;
2228         wid.val = kmalloc(wid.size, GFP_KERNEL);
2229         if (!wid.val)
2230                 goto ERRORHANDLER;
2231
2232         pu8CurrByte = wid.val;
2233         *pu8CurrByte++ = (pstrSetBeaconParam->interval & 0xFF);
2234         *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 8) & 0xFF);
2235         *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 16) & 0xFF);
2236         *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 24) & 0xFF);
2237
2238         *pu8CurrByte++ = (pstrSetBeaconParam->dtim_period & 0xFF);
2239         *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 8) & 0xFF);
2240         *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 16) & 0xFF);
2241         *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 24) & 0xFF);
2242
2243         *pu8CurrByte++ = (pstrSetBeaconParam->head_len & 0xFF);
2244         *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 8) & 0xFF);
2245         *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 16) & 0xFF);
2246         *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 24) & 0xFF);
2247
2248         memcpy(pu8CurrByte, pstrSetBeaconParam->head, pstrSetBeaconParam->head_len);
2249         pu8CurrByte += pstrSetBeaconParam->head_len;
2250
2251         *pu8CurrByte++ = (pstrSetBeaconParam->tail_len & 0xFF);
2252         *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 8) & 0xFF);
2253         *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 16) & 0xFF);
2254         *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 24) & 0xFF);
2255
2256         if (pstrSetBeaconParam->tail > 0)
2257                 memcpy(pu8CurrByte, pstrSetBeaconParam->tail, pstrSetBeaconParam->tail_len);
2258         pu8CurrByte += pstrSetBeaconParam->tail_len;
2259
2260         result = send_config_pkt(SET_CFG, &wid, 1,
2261                                  get_id_from_handler(hif_drv));
2262         if (result)
2263                 PRINT_ER("Failed to send add beacon config packet\n");
2264
2265 ERRORHANDLER:
2266         kfree(wid.val);
2267         kfree(pstrSetBeaconParam->head);
2268         kfree(pstrSetBeaconParam->tail);
2269 }
2270
2271 static void Handle_DelBeacon(struct host_if_drv *hif_drv)
2272 {
2273         s32 result = 0;
2274         struct wid wid;
2275         u8 *pu8CurrByte;
2276
2277         wid.id = (u16)WID_DEL_BEACON;
2278         wid.type = WID_CHAR;
2279         wid.size = sizeof(char);
2280         wid.val = &del_beacon;
2281
2282         if (!wid.val)
2283                 return;
2284
2285         pu8CurrByte = wid.val;
2286
2287         PRINT_D(HOSTINF_DBG, "Deleting BEACON\n");
2288
2289         result = send_config_pkt(SET_CFG, &wid, 1,
2290                                  get_id_from_handler(hif_drv));
2291         if (result)
2292                 PRINT_ER("Failed to send delete beacon config packet\n");
2293 }
2294
2295 static u32 WILC_HostIf_PackStaParam(u8 *pu8Buffer,
2296                                     struct add_sta_param *pstrStationParam)
2297 {
2298         u8 *pu8CurrByte;
2299
2300         pu8CurrByte = pu8Buffer;
2301
2302         PRINT_D(HOSTINF_DBG, "Packing STA params\n");
2303         memcpy(pu8CurrByte, pstrStationParam->au8BSSID, ETH_ALEN);
2304         pu8CurrByte +=  ETH_ALEN;
2305
2306         *pu8CurrByte++ = pstrStationParam->u16AssocID & 0xFF;
2307         *pu8CurrByte++ = (pstrStationParam->u16AssocID >> 8) & 0xFF;
2308
2309         *pu8CurrByte++ = pstrStationParam->u8NumRates;
2310         if (pstrStationParam->u8NumRates > 0)
2311                 memcpy(pu8CurrByte, pstrStationParam->pu8Rates, pstrStationParam->u8NumRates);
2312         pu8CurrByte += pstrStationParam->u8NumRates;
2313
2314         *pu8CurrByte++ = pstrStationParam->bIsHTSupported;
2315         *pu8CurrByte++ = pstrStationParam->u16HTCapInfo & 0xFF;
2316         *pu8CurrByte++ = (pstrStationParam->u16HTCapInfo >> 8) & 0xFF;
2317
2318         *pu8CurrByte++ = pstrStationParam->u8AmpduParams;
2319         memcpy(pu8CurrByte, pstrStationParam->au8SuppMCsSet, WILC_SUPP_MCS_SET_SIZE);
2320         pu8CurrByte += WILC_SUPP_MCS_SET_SIZE;
2321
2322         *pu8CurrByte++ = pstrStationParam->u16HTExtParams & 0xFF;
2323         *pu8CurrByte++ = (pstrStationParam->u16HTExtParams >> 8) & 0xFF;
2324
2325         *pu8CurrByte++ = pstrStationParam->u32TxBeamformingCap & 0xFF;
2326         *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 8) & 0xFF;
2327         *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 16) & 0xFF;
2328         *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 24) & 0xFF;
2329
2330         *pu8CurrByte++ = pstrStationParam->u8ASELCap;
2331
2332         *pu8CurrByte++ = pstrStationParam->u16FlagsMask & 0xFF;
2333         *pu8CurrByte++ = (pstrStationParam->u16FlagsMask >> 8) & 0xFF;
2334
2335         *pu8CurrByte++ = pstrStationParam->u16FlagsSet & 0xFF;
2336         *pu8CurrByte++ = (pstrStationParam->u16FlagsSet >> 8) & 0xFF;
2337
2338         return pu8CurrByte - pu8Buffer;
2339 }
2340
2341 static void Handle_AddStation(struct host_if_drv *hif_drv,
2342                               struct add_sta_param *pstrStationParam)
2343 {
2344         s32 result = 0;
2345         struct wid wid;
2346         u8 *pu8CurrByte;
2347
2348         PRINT_D(HOSTINF_DBG, "Handling add station\n");
2349         wid.id = (u16)WID_ADD_STA;
2350         wid.type = WID_BIN;
2351         wid.size = WILC_ADD_STA_LENGTH + pstrStationParam->u8NumRates;
2352
2353         wid.val = kmalloc(wid.size, GFP_KERNEL);
2354         if (!wid.val)
2355                 goto ERRORHANDLER;
2356
2357         pu8CurrByte = wid.val;
2358         pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam);
2359
2360         result = send_config_pkt(SET_CFG, &wid, 1,
2361                                  get_id_from_handler(hif_drv));
2362         if (result != 0)
2363                 PRINT_ER("Failed to send add station config packet\n");
2364
2365 ERRORHANDLER:
2366         kfree(pstrStationParam->pu8Rates);
2367         kfree(wid.val);
2368 }
2369
2370 static void Handle_DelAllSta(struct host_if_drv *hif_drv,
2371                              struct del_all_sta *pstrDelAllStaParam)
2372 {
2373         s32 result = 0;
2374         struct wid wid;
2375         u8 *pu8CurrByte;
2376         u8 i;
2377         u8 au8Zero_Buff[6] = {0};
2378
2379         wid.id = (u16)WID_DEL_ALL_STA;
2380         wid.type = WID_STR;
2381         wid.size = (pstrDelAllStaParam->assoc_sta * ETH_ALEN) + 1;
2382
2383         PRINT_D(HOSTINF_DBG, "Handling delete station\n");
2384
2385         wid.val = kmalloc((pstrDelAllStaParam->assoc_sta * ETH_ALEN) + 1, GFP_KERNEL);
2386         if (!wid.val)
2387                 goto ERRORHANDLER;
2388
2389         pu8CurrByte = wid.val;
2390
2391         *(pu8CurrByte++) = pstrDelAllStaParam->assoc_sta;
2392
2393         for (i = 0; i < MAX_NUM_STA; i++) {
2394                 if (memcmp(pstrDelAllStaParam->del_all_sta[i], au8Zero_Buff, ETH_ALEN))
2395                         memcpy(pu8CurrByte, pstrDelAllStaParam->del_all_sta[i], ETH_ALEN);
2396                 else
2397                         continue;
2398
2399                 pu8CurrByte += ETH_ALEN;
2400         }
2401
2402         result = send_config_pkt(SET_CFG, &wid, 1,
2403                                  get_id_from_handler(hif_drv));
2404         if (result)
2405                 PRINT_ER("Failed to send add station config packet\n");
2406
2407 ERRORHANDLER:
2408         kfree(wid.val);
2409
2410         up(&hif_sema_wait_response);
2411 }
2412
2413 static void Handle_DelStation(struct host_if_drv *hif_drv,
2414                               struct del_sta *pstrDelStaParam)
2415 {
2416         s32 result = 0;
2417         struct wid wid;
2418         u8 *pu8CurrByte;
2419
2420         wid.id = (u16)WID_REMOVE_STA;
2421         wid.type = WID_BIN;
2422         wid.size = ETH_ALEN;
2423
2424         PRINT_D(HOSTINF_DBG, "Handling delete station\n");
2425
2426         wid.val = kmalloc(wid.size, GFP_KERNEL);
2427         if (!wid.val)
2428                 goto ERRORHANDLER;
2429
2430         pu8CurrByte = wid.val;
2431
2432         memcpy(pu8CurrByte, pstrDelStaParam->mac_addr, ETH_ALEN);
2433
2434         result = send_config_pkt(SET_CFG, &wid, 1,
2435                                  get_id_from_handler(hif_drv));
2436         if (result)
2437                 PRINT_ER("Failed to send add station config packet\n");
2438
2439 ERRORHANDLER:
2440         kfree(wid.val);
2441 }
2442
2443 static void Handle_EditStation(struct host_if_drv *hif_drv,
2444                                struct add_sta_param *pstrStationParam)
2445 {
2446         s32 result = 0;
2447         struct wid wid;
2448         u8 *pu8CurrByte;
2449
2450         wid.id = (u16)WID_EDIT_STA;
2451         wid.type = WID_BIN;
2452         wid.size = WILC_ADD_STA_LENGTH + pstrStationParam->u8NumRates;
2453
2454         PRINT_D(HOSTINF_DBG, "Handling edit station\n");
2455         wid.val = kmalloc(wid.size, GFP_KERNEL);
2456         if (!wid.val)
2457                 goto ERRORHANDLER;
2458
2459         pu8CurrByte = wid.val;
2460         pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam);
2461
2462         result = send_config_pkt(SET_CFG, &wid, 1,
2463                                  get_id_from_handler(hif_drv));
2464         if (result)
2465                 PRINT_ER("Failed to send edit station config packet\n");
2466
2467 ERRORHANDLER:
2468         kfree(pstrStationParam->pu8Rates);
2469         kfree(wid.val);
2470 }
2471
2472 static int Handle_RemainOnChan(struct host_if_drv *hif_drv,
2473                                struct remain_ch *pstrHostIfRemainOnChan)
2474 {
2475         s32 result = 0;
2476         u8 u8remain_on_chan_flag;
2477         struct wid wid;
2478
2479         if (!hif_drv->remain_on_ch_pending) {
2480                 hif_drv->remain_on_ch.pVoid = pstrHostIfRemainOnChan->pVoid;
2481                 hif_drv->remain_on_ch.pRemainOnChanExpired = pstrHostIfRemainOnChan->pRemainOnChanExpired;
2482                 hif_drv->remain_on_ch.pRemainOnChanReady = pstrHostIfRemainOnChan->pRemainOnChanReady;
2483                 hif_drv->remain_on_ch.u16Channel = pstrHostIfRemainOnChan->u16Channel;
2484                 hif_drv->remain_on_ch.u32ListenSessionID = pstrHostIfRemainOnChan->u32ListenSessionID;
2485         } else {
2486                 pstrHostIfRemainOnChan->u16Channel = hif_drv->remain_on_ch.u16Channel;
2487         }
2488
2489         if (hif_drv->usr_scan_req.pfUserScanResult) {
2490                 PRINT_INFO(GENERIC_DBG, "Required to remain on chan while scanning return\n");
2491                 hif_drv->remain_on_ch_pending = 1;
2492                 result = -EBUSY;
2493                 goto ERRORHANDLER;
2494         }
2495         if (hif_drv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) {
2496                 PRINT_INFO(GENERIC_DBG, "Required to remain on chan while connecting return\n");
2497                 result = -EBUSY;
2498                 goto ERRORHANDLER;
2499         }
2500
2501         if (g_obtainingIP || connecting) {
2502                 PRINT_D(GENERIC_DBG, "[handle_scan]: Don't do obss scan until IP adresss is obtained\n");
2503                 result = -EBUSY;
2504                 goto ERRORHANDLER;
2505         }
2506
2507         PRINT_D(HOSTINF_DBG, "Setting channel :%d\n", pstrHostIfRemainOnChan->u16Channel);
2508
2509         u8remain_on_chan_flag = true;
2510         wid.id = (u16)WID_REMAIN_ON_CHAN;
2511         wid.type = WID_STR;
2512         wid.size = 2;
2513         wid.val = kmalloc(wid.size, GFP_KERNEL);
2514         if (!wid.val) {
2515                 result = -ENOMEM;
2516                 goto ERRORHANDLER;
2517         }
2518
2519         wid.val[0] = u8remain_on_chan_flag;
2520         wid.val[1] = (s8)pstrHostIfRemainOnChan->u16Channel;
2521
2522         result = send_config_pkt(SET_CFG, &wid, 1,
2523                                  get_id_from_handler(hif_drv));
2524         if (result != 0)
2525                 PRINT_ER("Failed to set remain on channel\n");
2526
2527 ERRORHANDLER:
2528         {
2529                 P2P_LISTEN_STATE = 1;
2530                 hif_drv->hRemainOnChannel.data = (unsigned long)hif_drv;
2531                 mod_timer(&hif_drv->hRemainOnChannel,
2532                           jiffies +
2533                           msecs_to_jiffies(pstrHostIfRemainOnChan->u32duration));
2534
2535                 if (hif_drv->remain_on_ch.pRemainOnChanReady)
2536                         hif_drv->remain_on_ch.pRemainOnChanReady(hif_drv->remain_on_ch.pVoid);
2537
2538                 if (hif_drv->remain_on_ch_pending)
2539                         hif_drv->remain_on_ch_pending = 0;
2540         }
2541
2542         return result;
2543 }
2544
2545 static int Handle_RegisterFrame(struct host_if_drv *hif_drv,
2546                                 struct reg_frame *pstrHostIfRegisterFrame)
2547 {
2548         s32 result = 0;
2549         struct wid wid;
2550         u8 *pu8CurrByte;
2551
2552         PRINT_D(HOSTINF_DBG, "Handling frame register Flag : %d FrameType: %d\n", pstrHostIfRegisterFrame->bReg, pstrHostIfRegisterFrame->u16FrameType);
2553
2554         wid.id = (u16)WID_REGISTER_FRAME;
2555         wid.type = WID_STR;
2556         wid.val = kmalloc(sizeof(u16) + 2, GFP_KERNEL);
2557         if (!wid.val)
2558                 return -ENOMEM;
2559
2560         pu8CurrByte = wid.val;
2561
2562         *pu8CurrByte++ = pstrHostIfRegisterFrame->bReg;
2563         *pu8CurrByte++ = pstrHostIfRegisterFrame->u8Regid;
2564         memcpy(pu8CurrByte, &pstrHostIfRegisterFrame->u16FrameType,
2565                sizeof(u16));
2566
2567         wid.size = sizeof(u16) + 2;
2568
2569         result = send_config_pkt(SET_CFG, &wid, 1,
2570                                  get_id_from_handler(hif_drv));
2571         if (result) {
2572                 PRINT_ER("Failed to frame register config packet\n");
2573                 result = -EINVAL;
2574         }
2575
2576         return result;
2577 }
2578
2579 static u32 Handle_ListenStateExpired(struct host_if_drv *hif_drv,
2580                                      struct remain_ch *pstrHostIfRemainOnChan)
2581 {
2582         u8 u8remain_on_chan_flag;
2583         struct wid wid;
2584         s32 result = 0;
2585
2586         PRINT_D(HOSTINF_DBG, "CANCEL REMAIN ON CHAN\n");
2587
2588         if (P2P_LISTEN_STATE) {
2589                 u8remain_on_chan_flag = false;
2590                 wid.id = (u16)WID_REMAIN_ON_CHAN;
2591                 wid.type = WID_STR;
2592                 wid.size = 2;
2593                 wid.val = kmalloc(wid.size, GFP_KERNEL);
2594
2595                 if (!wid.val)
2596                         PRINT_ER("Failed to allocate memory\n");
2597
2598                 wid.val[0] = u8remain_on_chan_flag;
2599                 wid.val[1] = FALSE_FRMWR_CHANNEL;
2600
2601                 result = send_config_pkt(SET_CFG, &wid, 1,
2602                                          get_id_from_handler(hif_drv));
2603                 if (result != 0) {
2604                         PRINT_ER("Failed to set remain on channel\n");
2605                         goto _done_;
2606                 }
2607
2608                 if (hif_drv->remain_on_ch.pRemainOnChanExpired) {
2609                         hif_drv->remain_on_ch.pRemainOnChanExpired(hif_drv->remain_on_ch.pVoid,
2610                                                                    pstrHostIfRemainOnChan->u32ListenSessionID);
2611                 }
2612                 P2P_LISTEN_STATE = 0;
2613         } else {
2614                 PRINT_D(GENERIC_DBG, "Not in listen state\n");
2615                 result = -EFAULT;
2616         }
2617
2618 _done_:
2619         return result;
2620 }
2621
2622 static void ListenTimerCB(unsigned long arg)
2623 {
2624         s32 result = 0;
2625         struct host_if_msg msg;
2626         struct host_if_drv *hif_drv = (struct host_if_drv *)arg;
2627
2628         del_timer(&hif_drv->hRemainOnChannel);
2629
2630         memset(&msg, 0, sizeof(struct host_if_msg));
2631         msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
2632         msg.drv = hif_drv;
2633         msg.body.remain_on_ch.u32ListenSessionID = hif_drv->remain_on_ch.u32ListenSessionID;
2634
2635         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
2636         if (result)
2637                 PRINT_ER("wilc_mq_send fail\n");
2638 }
2639
2640 static void Handle_PowerManagement(struct host_if_drv *hif_drv,
2641                                    struct power_mgmt_param *strPowerMgmtParam)
2642 {
2643         s32 result = 0;
2644         struct wid wid;
2645         s8 s8PowerMode;
2646
2647         wid.id = (u16)WID_POWER_MANAGEMENT;
2648
2649         if (strPowerMgmtParam->enabled)
2650                 s8PowerMode = MIN_FAST_PS;
2651         else
2652                 s8PowerMode = NO_POWERSAVE;
2653         PRINT_D(HOSTINF_DBG, "Handling power mgmt to %d\n", s8PowerMode);
2654         wid.val = &s8PowerMode;
2655         wid.size = sizeof(char);
2656
2657         PRINT_D(HOSTINF_DBG, "Handling Power Management\n");
2658
2659         result = send_config_pkt(SET_CFG, &wid, 1,
2660                                  get_id_from_handler(hif_drv));
2661         if (result)
2662                 PRINT_ER("Failed to send power management config packet\n");
2663 }
2664
2665 static void Handle_SetMulticastFilter(struct host_if_drv *hif_drv,
2666                                       struct set_multicast *strHostIfSetMulti)
2667 {
2668         s32 result = 0;
2669         struct wid wid;
2670         u8 *pu8CurrByte;
2671
2672         PRINT_D(HOSTINF_DBG, "Setup Multicast Filter\n");
2673
2674         wid.id = (u16)WID_SETUP_MULTICAST_FILTER;
2675         wid.type = WID_BIN;
2676         wid.size = sizeof(struct set_multicast) + ((strHostIfSetMulti->cnt) * ETH_ALEN);
2677         wid.val = kmalloc(wid.size, GFP_KERNEL);
2678         if (!wid.val)
2679                 goto ERRORHANDLER;
2680
2681         pu8CurrByte = wid.val;
2682         *pu8CurrByte++ = (strHostIfSetMulti->enabled & 0xFF);
2683         *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 8) & 0xFF);
2684         *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 16) & 0xFF);
2685         *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 24) & 0xFF);
2686
2687         *pu8CurrByte++ = (strHostIfSetMulti->cnt & 0xFF);
2688         *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 8) & 0xFF);
2689         *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 16) & 0xFF);
2690         *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 24) & 0xFF);
2691
2692         if ((strHostIfSetMulti->cnt) > 0)
2693                 memcpy(pu8CurrByte, gau8MulticastMacAddrList, ((strHostIfSetMulti->cnt) * ETH_ALEN));
2694
2695         result = send_config_pkt(SET_CFG, &wid, 1,
2696                                  get_id_from_handler(hif_drv));
2697         if (result)
2698                 PRINT_ER("Failed to send setup multicast config packet\n");
2699
2700 ERRORHANDLER:
2701         kfree(wid.val);
2702 }
2703
2704 static s32 Handle_AddBASession(struct host_if_drv *hif_drv,
2705                                struct ba_session_info *strHostIfBASessionInfo)
2706 {
2707         s32 result = 0;
2708         struct wid wid;
2709         int AddbaTimeout = 100;
2710         char *ptr = NULL;
2711
2712         PRINT_D(HOSTINF_DBG, "Opening Block Ack session with\nBSSID = %.2x:%.2x:%.2x\nTID=%d\nBufferSize == %d\nSessionTimeOut = %d\n",
2713                 strHostIfBASessionInfo->au8Bssid[0],
2714                 strHostIfBASessionInfo->au8Bssid[1],
2715                 strHostIfBASessionInfo->au8Bssid[2],
2716                 strHostIfBASessionInfo->u16BufferSize,
2717                 strHostIfBASessionInfo->u16SessionTimeout,
2718                 strHostIfBASessionInfo->u8Ted);
2719
2720         wid.id = (u16)WID_11E_P_ACTION_REQ;
2721         wid.type = WID_STR;
2722         wid.val = kmalloc(BLOCK_ACK_REQ_SIZE, GFP_KERNEL);
2723         wid.size = BLOCK_ACK_REQ_SIZE;
2724         ptr = wid.val;
2725         *ptr++ = 0x14;
2726         *ptr++ = 0x3;
2727         *ptr++ = 0x0;
2728         memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN);
2729         ptr += ETH_ALEN;
2730         *ptr++ = strHostIfBASessionInfo->u8Ted;
2731         *ptr++ = 1;
2732         *ptr++ = (strHostIfBASessionInfo->u16BufferSize & 0xFF);
2733         *ptr++ = ((strHostIfBASessionInfo->u16BufferSize >> 16) & 0xFF);
2734         *ptr++ = (strHostIfBASessionInfo->u16SessionTimeout & 0xFF);
2735         *ptr++ = ((strHostIfBASessionInfo->u16SessionTimeout >> 16) & 0xFF);
2736         *ptr++ = (AddbaTimeout & 0xFF);
2737         *ptr++ = ((AddbaTimeout >> 16) & 0xFF);
2738         *ptr++ = 8;
2739         *ptr++ = 0;
2740
2741         result = send_config_pkt(SET_CFG, &wid, 1,
2742                                  get_id_from_handler(hif_drv));
2743         if (result)
2744                 PRINT_D(HOSTINF_DBG, "Couldn't open BA Session\n");
2745
2746         wid.id = (u16)WID_11E_P_ACTION_REQ;
2747         wid.type = WID_STR;
2748         wid.size = 15;
2749         ptr = wid.val;
2750         *ptr++ = 15;
2751         *ptr++ = 7;
2752         *ptr++ = 0x2;
2753         memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN);
2754         ptr += ETH_ALEN;
2755         *ptr++ = strHostIfBASessionInfo->u8Ted;
2756         *ptr++ = 8;
2757         *ptr++ = (strHostIfBASessionInfo->u16BufferSize & 0xFF);
2758         *ptr++ = ((strHostIfBASessionInfo->u16SessionTimeout >> 16) & 0xFF);
2759         *ptr++ = 3;
2760         result = send_config_pkt(SET_CFG, &wid, 1,
2761                                  get_id_from_handler(hif_drv));
2762
2763         kfree(wid.val);
2764
2765         return result;
2766 }
2767
2768 static s32 Handle_DelAllRxBASessions(struct host_if_drv *hif_drv,
2769                                      struct ba_session_info *strHostIfBASessionInfo)
2770 {
2771         s32 result = 0;
2772         struct wid wid;
2773         char *ptr = NULL;
2774
2775         PRINT_D(GENERIC_DBG, "Delete Block Ack session with\nBSSID = %.2x:%.2x:%.2x\nTID=%d\n",
2776                 strHostIfBASessionInfo->au8Bssid[0],
2777                 strHostIfBASessionInfo->au8Bssid[1],
2778                 strHostIfBASessionInfo->au8Bssid[2],
2779                 strHostIfBASessionInfo->u8Ted);
2780
2781         wid.id = (u16)WID_DEL_ALL_RX_BA;
2782         wid.type = WID_STR;
2783         wid.val = kmalloc(BLOCK_ACK_REQ_SIZE, GFP_KERNEL);
2784         wid.size = BLOCK_ACK_REQ_SIZE;
2785         ptr = wid.val;
2786         *ptr++ = 0x14;
2787         *ptr++ = 0x3;
2788         *ptr++ = 0x2;
2789         memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN);
2790         ptr += ETH_ALEN;
2791         *ptr++ = strHostIfBASessionInfo->u8Ted;
2792         *ptr++ = 0;
2793         *ptr++ = 32;
2794
2795         result = send_config_pkt(SET_CFG, &wid, 1,
2796                                  get_id_from_handler(hif_drv));
2797         if (result)
2798                 PRINT_D(HOSTINF_DBG, "Couldn't delete BA Session\n");
2799
2800         kfree(wid.val);
2801
2802         up(&hif_sema_wait_response);
2803
2804         return result;
2805 }
2806
2807 static int hostIFthread(void *pvArg)
2808 {
2809         u32 u32Ret;
2810         struct host_if_msg msg;
2811         struct host_if_drv *hif_drv;
2812
2813         memset(&msg, 0, sizeof(struct host_if_msg));
2814
2815         while (1) {
2816                 wilc_mq_recv(&hif_msg_q, &msg, sizeof(struct host_if_msg), &u32Ret);
2817                 hif_drv = (struct host_if_drv *)msg.drv;
2818                 if (msg.id == HOST_IF_MSG_EXIT) {
2819                         PRINT_D(GENERIC_DBG, "THREAD: Exiting HostIfThread\n");
2820                         break;
2821                 }
2822
2823                 if ((!g_wilc_initialized)) {
2824                         PRINT_D(GENERIC_DBG, "--WAIT--");
2825                         usleep_range(200 * 1000, 200 * 1000);
2826                         wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
2827                         continue;
2828                 }
2829
2830                 if (msg.id == HOST_IF_MSG_CONNECT &&
2831                     hif_drv->usr_scan_req.pfUserScanResult) {
2832                         PRINT_D(HOSTINF_DBG, "Requeue connect request till scan done received\n");
2833                         wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
2834                         usleep_range(2 * 1000, 2 * 1000);
2835                         continue;
2836                 }
2837
2838                 switch (msg.id) {
2839                 case HOST_IF_MSG_Q_IDLE:
2840                         Handle_wait_msg_q_empty();
2841                         break;
2842
2843                 case HOST_IF_MSG_SCAN:
2844                         Handle_Scan(msg.drv, &msg.body.scan_info);
2845                         break;
2846
2847                 case HOST_IF_MSG_CONNECT:
2848                         Handle_Connect(msg.drv, &msg.body.con_info);
2849                         break;
2850
2851                 case HOST_IF_MSG_FLUSH_CONNECT:
2852                         Handle_FlushConnect(msg.drv);
2853                         break;
2854
2855                 case HOST_IF_MSG_RCVD_NTWRK_INFO:
2856                         Handle_RcvdNtwrkInfo(msg.drv, &msg.body.net_info);
2857                         break;
2858
2859                 case HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO:
2860                         Handle_RcvdGnrlAsyncInfo(msg.drv, &msg.body.async_info);
2861                         break;
2862
2863                 case HOST_IF_MSG_KEY:
2864                         Handle_Key(msg.drv, &msg.body.key_info);
2865                         break;
2866
2867                 case HOST_IF_MSG_CFG_PARAMS:
2868
2869                         Handle_CfgParam(msg.drv, &msg.body.cfg_info);
2870                         break;
2871
2872                 case HOST_IF_MSG_SET_CHANNEL:
2873                         Handle_SetChannel(msg.drv, &msg.body.channel_info);
2874                         break;
2875
2876                 case HOST_IF_MSG_DISCONNECT:
2877                         Handle_Disconnect(msg.drv);
2878                         break;
2879
2880                 case HOST_IF_MSG_RCVD_SCAN_COMPLETE:
2881                         del_timer(&hif_drv->hScanTimer);
2882                         PRINT_D(HOSTINF_DBG, "scan completed successfully\n");
2883
2884                         if (!linux_wlan_get_num_conn_ifcs())
2885                                 chip_sleep_manually(INFINITE_SLEEP_TIME);
2886
2887                         Handle_ScanDone(msg.drv, SCAN_EVENT_DONE);
2888
2889                         if (hif_drv->remain_on_ch_pending)
2890                                 Handle_RemainOnChan(msg.drv, &msg.body.remain_on_ch);
2891
2892                         break;
2893
2894                 case HOST_IF_MSG_GET_RSSI:
2895                         Handle_GetRssi(msg.drv);
2896                         break;
2897
2898                 case HOST_IF_MSG_GET_LINKSPEED:
2899                         Handle_GetLinkspeed(msg.drv);
2900                         break;
2901
2902                 case HOST_IF_MSG_GET_STATISTICS:
2903                         Handle_GetStatistics(msg.drv, (struct rf_info *)msg.body.data);
2904                         break;
2905
2906                 case HOST_IF_MSG_GET_CHNL:
2907                         Handle_GetChnl(msg.drv);
2908                         break;
2909
2910                 case HOST_IF_MSG_ADD_BEACON:
2911                         Handle_AddBeacon(msg.drv, &msg.body.beacon_info);
2912                         break;
2913
2914                 case HOST_IF_MSG_DEL_BEACON:
2915                         Handle_DelBeacon(msg.drv);
2916                         break;
2917
2918                 case HOST_IF_MSG_ADD_STATION:
2919                         Handle_AddStation(msg.drv, &msg.body.add_sta_info);
2920                         break;
2921
2922                 case HOST_IF_MSG_DEL_STATION:
2923                         Handle_DelStation(msg.drv, &msg.body.del_sta_info);
2924                         break;
2925
2926                 case HOST_IF_MSG_EDIT_STATION:
2927                         Handle_EditStation(msg.drv, &msg.body.edit_sta_info);
2928                         break;
2929
2930                 case HOST_IF_MSG_GET_INACTIVETIME:
2931                         Handle_Get_InActiveTime(msg.drv, &msg.body.mac_info);
2932                         break;
2933
2934                 case HOST_IF_MSG_SCAN_TIMER_FIRED:
2935                         PRINT_D(HOSTINF_DBG, "Scan Timeout\n");
2936
2937                         Handle_ScanDone(msg.drv, SCAN_EVENT_ABORTED);
2938                         break;
2939
2940                 case HOST_IF_MSG_CONNECT_TIMER_FIRED:
2941                         PRINT_D(HOSTINF_DBG, "Connect Timeout\n");
2942                         Handle_ConnectTimeout(msg.drv);
2943                         break;
2944
2945                 case HOST_IF_MSG_POWER_MGMT:
2946                         Handle_PowerManagement(msg.drv, &msg.body.pwr_mgmt_info);
2947                         break;
2948
2949                 case HOST_IF_MSG_SET_WFIDRV_HANDLER:
2950                         Handle_SetWfiDrvHandler(msg.drv,
2951                                                 &msg.body.drv);
2952                         break;
2953
2954                 case HOST_IF_MSG_SET_OPERATION_MODE:
2955                         Handle_SetOperationMode(msg.drv, &msg.body.mode);
2956                         break;
2957
2958                 case HOST_IF_MSG_SET_IPADDRESS:
2959                         PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_IPADDRESS\n");
2960                         Handle_set_IPAddress(msg.drv, msg.body.ip_info.ip_addr, msg.body.ip_info.idx);
2961                         break;
2962
2963                 case HOST_IF_MSG_GET_IPADDRESS:
2964                         PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_IPADDRESS\n");
2965                         Handle_get_IPAddress(msg.drv, msg.body.ip_info.ip_addr, msg.body.ip_info.idx);
2966                         break;
2967
2968                 case HOST_IF_MSG_SET_MAC_ADDRESS:
2969                         Handle_SetMacAddress(msg.drv, &msg.body.set_mac_info);
2970                         break;
2971
2972                 case HOST_IF_MSG_GET_MAC_ADDRESS:
2973                         Handle_GetMacAddress(msg.drv, &msg.body.get_mac_info);
2974                         break;
2975
2976                 case HOST_IF_MSG_REMAIN_ON_CHAN:
2977                         PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_REMAIN_ON_CHAN\n");
2978                         Handle_RemainOnChan(msg.drv, &msg.body.remain_on_ch);
2979                         break;
2980
2981                 case HOST_IF_MSG_REGISTER_FRAME:
2982                         PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_REGISTER_FRAME\n");
2983                         Handle_RegisterFrame(msg.drv, &msg.body.reg_frame);
2984                         break;
2985
2986                 case HOST_IF_MSG_LISTEN_TIMER_FIRED:
2987                         Handle_ListenStateExpired(msg.drv, &msg.body.remain_on_ch);
2988                         break;
2989
2990                 case HOST_IF_MSG_SET_MULTICAST_FILTER:
2991                         PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_MULTICAST_FILTER\n");
2992                         Handle_SetMulticastFilter(msg.drv, &msg.body.multicast_info);
2993                         break;
2994
2995                 case HOST_IF_MSG_ADD_BA_SESSION:
2996                         Handle_AddBASession(msg.drv, &msg.body.session_info);
2997                         break;
2998
2999                 case HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS:
3000                         Handle_DelAllRxBASessions(msg.drv, &msg.body.session_info);
3001                         break;
3002
3003                 case HOST_IF_MSG_DEL_ALL_STA:
3004                         Handle_DelAllSta(msg.drv, &msg.body.del_all_sta_info);
3005                         break;
3006
3007                 default:
3008                         PRINT_ER("[Host Interface] undefined Received Msg ID\n");
3009                         break;
3010                 }
3011         }
3012
3013         PRINT_D(HOSTINF_DBG, "Releasing thread exit semaphore\n");
3014         up(&hif_sema_thread);
3015         return 0;
3016 }
3017
3018 static void TimerCB_Scan(unsigned long arg)
3019 {
3020         void *pvArg = (void *)arg;
3021         struct host_if_msg msg;
3022
3023         memset(&msg, 0, sizeof(struct host_if_msg));
3024         msg.drv = pvArg;
3025         msg.id = HOST_IF_MSG_SCAN_TIMER_FIRED;
3026
3027         wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3028 }
3029
3030 static void TimerCB_Connect(unsigned long arg)
3031 {
3032         void *pvArg = (void *)arg;
3033         struct host_if_msg msg;
3034
3035         memset(&msg, 0, sizeof(struct host_if_msg));
3036         msg.drv = pvArg;
3037         msg.id = HOST_IF_MSG_CONNECT_TIMER_FIRED;
3038
3039         wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3040 }
3041
3042 s32 host_int_remove_key(struct host_if_drv *hif_drv, const u8 *pu8StaAddress)
3043 {
3044         struct wid wid;
3045
3046         wid.id = (u16)WID_REMOVE_KEY;
3047         wid.type = WID_STR;
3048         wid.val = (s8 *)pu8StaAddress;
3049         wid.size = 6;
3050
3051         return 0;
3052 }
3053
3054 int host_int_remove_wep_key(struct host_if_drv *hif_drv, u8 index)
3055 {
3056         int result = 0;
3057         struct host_if_msg msg;
3058
3059         if (!hif_drv) {
3060                 result = -EFAULT;
3061                 PRINT_ER("Failed to send setup multicast config packet\n");
3062                 return result;
3063         }
3064
3065         memset(&msg, 0, sizeof(struct host_if_msg));
3066
3067         msg.id = HOST_IF_MSG_KEY;
3068         msg.body.key_info.type = WEP;
3069         msg.body.key_info.action = REMOVEKEY;
3070         msg.drv = hif_drv;
3071         msg.body.key_info.attr.wep.index = index;
3072
3073         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3074         if (result)
3075                 PRINT_ER("Error in sending message queue : Request to remove WEP key\n");
3076         down(&hif_drv->hSemTestKeyBlock);
3077
3078         return result;
3079 }
3080
3081 int host_int_set_wep_default_key(struct host_if_drv *hif_drv, u8 index)
3082 {
3083         int result = 0;
3084         struct host_if_msg msg;
3085
3086         if (!hif_drv) {
3087                 result = -EFAULT;
3088                 PRINT_ER("driver is null\n");
3089                 return result;
3090         }
3091
3092         memset(&msg, 0, sizeof(struct host_if_msg));
3093
3094         msg.id = HOST_IF_MSG_KEY;
3095         msg.body.key_info.type = WEP;
3096         msg.body.key_info.action = DEFAULTKEY;
3097         msg.drv = hif_drv;
3098         msg.body.key_info.attr.wep.index = index;
3099
3100         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3101         if (result)
3102                 PRINT_ER("Error in sending message queue : Default key index\n");
3103         down(&hif_drv->hSemTestKeyBlock);
3104
3105         return result;
3106 }
3107
3108 int host_int_add_wep_key_bss_sta(struct host_if_drv *hif_drv,
3109                                  const u8 *key,
3110                                  u8 len,
3111                                  u8 index)
3112 {
3113         int result = 0;
3114         struct host_if_msg msg;
3115
3116         if (!hif_drv) {
3117                 PRINT_ER("driver is null\n");
3118                 return -EFAULT;
3119         }
3120
3121         memset(&msg, 0, sizeof(struct host_if_msg));
3122
3123         msg.id = HOST_IF_MSG_KEY;
3124         msg.body.key_info.type = WEP;
3125         msg.body.key_info.action = ADDKEY;
3126         msg.drv = hif_drv;
3127         msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL);
3128         if (!msg.body.key_info.attr.wep.key)
3129                 return -ENOMEM;
3130
3131         msg.body.key_info.attr.wep.key_len = len;
3132         msg.body.key_info.attr.wep.index = index;
3133
3134         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3135         if (result)
3136                 PRINT_ER("Error in sending message queue :WEP Key\n");
3137         down(&hif_drv->hSemTestKeyBlock);
3138
3139         return result;
3140 }
3141
3142 int host_int_add_wep_key_bss_ap(struct host_if_drv *hif_drv,
3143                                 const u8 *key,
3144                                 u8 len,
3145                                 u8 u8Keyidx,
3146                                 u8 u8mode,
3147                                 enum AUTHTYPE tenuAuth_type)
3148 {
3149         int result = 0;
3150         struct host_if_msg msg;
3151         int i;
3152
3153         if (!hif_drv) {
3154                 PRINT_ER("driver is null\n");
3155                 return -EFAULT;
3156         }
3157
3158         memset(&msg, 0, sizeof(struct host_if_msg));
3159
3160         if (INFO) {
3161                 for (i = 0; i < len; i++)
3162                         PRINT_INFO(HOSTAPD_DBG, "KEY is %x\n", key[i]);
3163         }
3164         msg.id = HOST_IF_MSG_KEY;
3165         msg.body.key_info.type = WEP;
3166         msg.body.key_info.action = ADDKEY_AP;
3167         msg.drv = hif_drv;
3168         msg.body.key_info.attr.wep.key = kmalloc(len, GFP_KERNEL);
3169         memcpy(msg.body.key_info.attr.wep.key, key, len);
3170         msg.body.key_info.attr.wep.key_len = len;
3171         msg.body.key_info.attr.wep.index = u8Keyidx;
3172         msg.body.key_info.attr.wep.mode = u8mode;
3173         msg.body.key_info.attr.wep.auth_type = tenuAuth_type;
3174
3175         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3176
3177         if (result)
3178                 PRINT_ER("Error in sending message queue :WEP Key\n");
3179         down(&hif_drv->hSemTestKeyBlock);
3180
3181         return result;
3182 }
3183
3184 s32 host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *pu8Ptk,
3185                      u8 u8PtkKeylen, const u8 *mac_addr,
3186                      const u8 *pu8RxMic, const u8 *pu8TxMic,
3187                      u8 mode, u8 u8Ciphermode, u8 u8Idx)
3188 {
3189         s32 result = 0;
3190         struct host_if_msg msg;
3191         u8 u8KeyLen = u8PtkKeylen;
3192         u32 i;
3193
3194         if (!hif_drv) {
3195                 PRINT_ER("driver is null\n");
3196                 return -EFAULT;
3197         }
3198
3199         if (pu8RxMic)
3200                 u8KeyLen += RX_MIC_KEY_LEN;
3201
3202         if (pu8TxMic)
3203                 u8KeyLen += TX_MIC_KEY_LEN;
3204
3205         memset(&msg, 0, sizeof(struct host_if_msg));
3206
3207         msg.id = HOST_IF_MSG_KEY;
3208         msg.body.key_info.type = WPAPtk;
3209         if (mode == AP_MODE) {
3210                 msg.body.key_info.action = ADDKEY_AP;
3211                 msg.body.key_info.attr.wpa.index = u8Idx;
3212         }
3213         if (mode == STATION_MODE)
3214                 msg.body.key_info.action = ADDKEY;
3215
3216         msg.body.key_info.attr.wpa.key = kmalloc(u8PtkKeylen, GFP_KERNEL);
3217         memcpy(msg.body.key_info.attr.wpa.key, pu8Ptk, u8PtkKeylen);
3218
3219         if (pu8RxMic) {
3220                 memcpy(msg.body.key_info.attr.wpa.key + 16, pu8RxMic, RX_MIC_KEY_LEN);
3221                 if (INFO) {
3222                         for (i = 0; i < RX_MIC_KEY_LEN; i++)
3223                                 PRINT_INFO(CFG80211_DBG, "PairwiseRx[%d] = %x\n", i, pu8RxMic[i]);
3224                 }
3225         }
3226         if (pu8TxMic) {
3227                 memcpy(msg.body.key_info.attr.wpa.key + 24, pu8TxMic, TX_MIC_KEY_LEN);
3228                 if (INFO) {
3229                         for (i = 0; i < TX_MIC_KEY_LEN; i++)
3230                                 PRINT_INFO(CFG80211_DBG, "PairwiseTx[%d] = %x\n", i, pu8TxMic[i]);
3231                 }
3232         }
3233
3234         msg.body.key_info.attr.wpa.key_len = u8KeyLen;
3235         msg.body.key_info.attr.wpa.mac_addr = mac_addr;
3236         msg.body.key_info.attr.wpa.mode = u8Ciphermode;
3237         msg.drv = hif_drv;
3238
3239         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3240
3241         if (result)
3242                 PRINT_ER("Error in sending message queue:  PTK Key\n");
3243
3244         down(&hif_drv->hSemTestKeyBlock);
3245
3246         return result;
3247 }
3248
3249 s32 host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *pu8RxGtk,
3250                         u8 u8GtkKeylen, u8 u8KeyIdx,
3251                         u32 u32KeyRSClen, const u8 *KeyRSC,
3252                         const u8 *pu8RxMic, const u8 *pu8TxMic,
3253                         u8 mode, u8 u8Ciphermode)
3254 {
3255         s32 result = 0;
3256         struct host_if_msg msg;
3257         u8 u8KeyLen = u8GtkKeylen;
3258
3259         if (!hif_drv) {
3260                 PRINT_ER("driver is null\n");
3261                 return -EFAULT;
3262         }
3263         memset(&msg, 0, sizeof(struct host_if_msg));
3264
3265         if (pu8RxMic)
3266                 u8KeyLen += RX_MIC_KEY_LEN;
3267
3268         if (pu8TxMic)
3269                 u8KeyLen += TX_MIC_KEY_LEN;
3270
3271         if (KeyRSC) {
3272                 msg.body.key_info.attr.wpa.seq = kmalloc(u32KeyRSClen, GFP_KERNEL);
3273                 memcpy(msg.body.key_info.attr.wpa.seq, KeyRSC, u32KeyRSClen);
3274         }
3275
3276         msg.id = HOST_IF_MSG_KEY;
3277         msg.body.key_info.type = WPARxGtk;
3278         msg.drv = hif_drv;
3279
3280         if (mode == AP_MODE) {
3281                 msg.body.key_info.action = ADDKEY_AP;
3282                 msg.body.key_info.attr.wpa.mode = u8Ciphermode;
3283         }
3284         if (mode == STATION_MODE)
3285                 msg.body.key_info.action = ADDKEY;
3286
3287         msg.body.key_info.attr.wpa.key = kmalloc(u8KeyLen, GFP_KERNEL);
3288         memcpy(msg.body.key_info.attr.wpa.key, pu8RxGtk, u8GtkKeylen);
3289
3290         if (pu8RxMic)
3291                 memcpy(msg.body.key_info.attr.wpa.key + 16, pu8RxMic,
3292                        RX_MIC_KEY_LEN);
3293
3294         if (pu8TxMic)
3295                 memcpy(msg.body.key_info.attr.wpa.key + 24, pu8TxMic,
3296                        TX_MIC_KEY_LEN);
3297
3298         msg.body.key_info.attr.wpa.index = u8KeyIdx;
3299         msg.body.key_info.attr.wpa.key_len = u8KeyLen;
3300         msg.body.key_info.attr.wpa.seq_len = u32KeyRSClen;
3301
3302         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3303         if (result)
3304                 PRINT_ER("Error in sending message queue:  RX GTK\n");
3305
3306         down(&hif_drv->hSemTestKeyBlock);
3307
3308         return result;
3309 }
3310
3311 s32 host_int_set_pmkid_info(struct host_if_drv *hif_drv, struct host_if_pmkid_attr *pu8PmkidInfoArray)
3312 {
3313         s32 result = 0;
3314         struct host_if_msg msg;
3315         u32 i;
3316
3317         if (!hif_drv) {
3318                 PRINT_ER("driver is null\n");
3319                 return -EFAULT;
3320         }
3321
3322         memset(&msg, 0, sizeof(struct host_if_msg));
3323
3324         msg.id = HOST_IF_MSG_KEY;
3325         msg.body.key_info.type = PMKSA;
3326         msg.body.key_info.action = ADDKEY;
3327         msg.drv = hif_drv;
3328
3329         for (i = 0; i < pu8PmkidInfoArray->numpmkid; i++) {
3330                 memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].bssid,
3331                        &pu8PmkidInfoArray->pmkidlist[i].bssid, ETH_ALEN);
3332                 memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].pmkid,
3333                        &pu8PmkidInfoArray->pmkidlist[i].pmkid, PMKID_LEN);
3334         }
3335
3336         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3337         if (result)
3338                 PRINT_ER(" Error in sending messagequeue: PMKID Info\n");
3339
3340         return result;
3341 }
3342
3343 s32 host_int_get_pmkid_info(struct host_if_drv *hif_drv,
3344                             u8 *pu8PmkidInfoArray,
3345                             u32 u32PmkidInfoLen)
3346 {
3347         struct wid wid;
3348
3349         wid.id = (u16)WID_PMKID_INFO;
3350         wid.type = WID_STR;
3351         wid.size = u32PmkidInfoLen;
3352         wid.val = pu8PmkidInfoArray;
3353
3354         return 0;
3355 }
3356
3357 s32 host_int_set_RSNAConfigPSKPassPhrase(struct host_if_drv *hif_drv,
3358                                          u8 *pu8PassPhrase,
3359                                          u8 u8Psklength)
3360 {
3361         struct wid wid;
3362
3363         if ((u8Psklength > 7) && (u8Psklength < 65)) {
3364                 wid.id = (u16)WID_11I_PSK;
3365                 wid.type = WID_STR;
3366                 wid.val = pu8PassPhrase;
3367                 wid.size = u8Psklength;
3368         }
3369
3370         return 0;
3371 }
3372
3373 s32 host_int_get_MacAddress(struct host_if_drv *hif_drv, u8 *pu8MacAddress)
3374 {
3375         s32 result = 0;
3376         struct host_if_msg msg;
3377
3378         memset(&msg, 0, sizeof(struct host_if_msg));
3379
3380         msg.id = HOST_IF_MSG_GET_MAC_ADDRESS;
3381         msg.body.get_mac_info.mac_addr = pu8MacAddress;
3382         msg.drv = hif_drv;
3383
3384         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3385         if (result) {
3386                 PRINT_ER("Failed to send get mac address\n");
3387                 return -EFAULT;
3388         }
3389
3390         down(&hif_sema_wait_response);
3391         return result;
3392 }
3393
3394 s32 host_int_set_MacAddress(struct host_if_drv *hif_drv, u8 *pu8MacAddress)
3395 {
3396         s32 result = 0;
3397         struct host_if_msg msg;
3398
3399         PRINT_D(GENERIC_DBG, "mac addr = %x:%x:%x\n", pu8MacAddress[0], pu8MacAddress[1], pu8MacAddress[2]);
3400
3401         memset(&msg, 0, sizeof(struct host_if_msg));
3402         msg.id = HOST_IF_MSG_SET_MAC_ADDRESS;
3403         memcpy(msg.body.set_mac_info.mac_addr, pu8MacAddress, ETH_ALEN);
3404         msg.drv = hif_drv;
3405
3406         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3407         if (result)
3408                 PRINT_ER("Failed to send message queue: Set mac address\n");
3409
3410         return result;
3411 }
3412
3413 s32 host_int_get_RSNAConfigPSKPassPhrase(struct host_if_drv *hif_drv,
3414                                          u8 *pu8PassPhrase, u8 u8Psklength)
3415 {
3416         struct wid wid;
3417
3418         wid.id = (u16)WID_11I_PSK;
3419         wid.type = WID_STR;
3420         wid.size = u8Psklength;
3421         wid.val = pu8PassPhrase;
3422
3423         return 0;
3424 }
3425
3426 s32 host_int_set_start_scan_req(struct host_if_drv *hif_drv, u8 scanSource)
3427 {
3428         struct wid wid;
3429
3430         wid.id = (u16)WID_START_SCAN_REQ;
3431         wid.type = WID_CHAR;
3432         wid.val = (s8 *)&scanSource;
3433         wid.size = sizeof(char);
3434
3435         return 0;
3436 }
3437
3438 s32 host_int_get_start_scan_req(struct host_if_drv *hif_drv, u8 *pu8ScanSource)
3439 {
3440         struct wid wid;
3441
3442         wid.id = (u16)WID_START_SCAN_REQ;
3443         wid.type = WID_CHAR;
3444         wid.val = (s8 *)pu8ScanSource;
3445         wid.size = sizeof(char);
3446
3447         return 0;
3448 }
3449
3450 s32 host_int_set_join_req(struct host_if_drv *hif_drv, u8 *pu8bssid,
3451                           const u8 *pu8ssid, size_t ssidLen,
3452                           const u8 *pu8IEs, size_t IEsLen,
3453                           wilc_connect_result pfConnectResult, void *pvUserArg,
3454                           u8 u8security, enum AUTHTYPE tenuAuth_type,
3455                           u8 u8channel, void *pJoinParams)
3456 {
3457         s32 result = 0;
3458         struct host_if_msg msg;
3459
3460         if (!hif_drv || !pfConnectResult) {
3461                 PRINT_ER("Driver is null\n");
3462                 return -EFAULT;
3463         }
3464
3465         if (!pJoinParams) {
3466                 PRINT_ER("Unable to Join - JoinParams is NULL\n");
3467                 return -EFAULT;
3468         }
3469
3470         memset(&msg, 0, sizeof(struct host_if_msg));
3471
3472         msg.id = HOST_IF_MSG_CONNECT;
3473
3474         msg.body.con_info.security = u8security;
3475         msg.body.con_info.auth_type = tenuAuth_type;
3476         msg.body.con_info.ch = u8channel;
3477         msg.body.con_info.result = pfConnectResult;
3478         msg.body.con_info.arg = pvUserArg;
3479         msg.body.con_info.params = pJoinParams;
3480         msg.drv = hif_drv ;
3481
3482         if (pu8bssid) {
3483                 msg.body.con_info.bssid = kmalloc(6, GFP_KERNEL);
3484                 memcpy(msg.body.con_info.bssid, pu8bssid, 6);
3485         }
3486
3487         if (pu8ssid) {
3488                 msg.body.con_info.ssid_len = ssidLen;
3489                 msg.body.con_info.ssid = kmalloc(ssidLen, GFP_KERNEL);
3490                 memcpy(msg.body.con_info.ssid, pu8ssid, ssidLen);
3491         }
3492
3493         if (pu8IEs) {
3494                 msg.body.con_info.ies_len = IEsLen;
3495                 msg.body.con_info.ies = kmalloc(IEsLen, GFP_KERNEL);
3496                 memcpy(msg.body.con_info.ies, pu8IEs, IEsLen);
3497         }
3498         if (hif_drv->enuHostIFstate < HOST_IF_CONNECTING)
3499                 hif_drv->enuHostIFstate = HOST_IF_CONNECTING;
3500         else
3501                 PRINT_D(GENERIC_DBG, "Don't set state to 'connecting' as state is %d\n", hif_drv->enuHostIFstate);
3502
3503         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3504         if (result) {
3505                 PRINT_ER("Failed to send message queue: Set join request\n");
3506                 return -EFAULT;
3507         }
3508
3509         hif_drv->hConnectTimer.data = (unsigned long)hif_drv;
3510         mod_timer(&hif_drv->hConnectTimer,
3511                   jiffies + msecs_to_jiffies(HOST_IF_CONNECT_TIMEOUT));
3512
3513         return result;
3514 }
3515
3516 s32 host_int_flush_join_req(struct host_if_drv *hif_drv)
3517 {
3518         s32 result = 0;
3519         struct host_if_msg msg;
3520
3521         if (!join_req)
3522                 return -EFAULT;
3523
3524         if (!hif_drv) {
3525                 PRINT_ER("Driver is null\n");
3526                 return -EFAULT;
3527         }
3528
3529         msg.id = HOST_IF_MSG_FLUSH_CONNECT;
3530         msg.drv = hif_drv;
3531
3532         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3533         if (result) {
3534                 PRINT_ER("Failed to send message queue: Flush join request\n");
3535                 return -EFAULT;
3536         }
3537
3538         return result;
3539 }
3540
3541 s32 host_int_disconnect(struct host_if_drv *hif_drv, u16 u16ReasonCode)
3542 {
3543         s32 result = 0;
3544         struct host_if_msg msg;
3545
3546         if (!hif_drv) {
3547                 PRINT_ER("Driver is null\n");
3548                 return -EFAULT;
3549         }
3550
3551         memset(&msg, 0, sizeof(struct host_if_msg));
3552
3553         msg.id = HOST_IF_MSG_DISCONNECT;
3554         msg.drv = hif_drv;
3555
3556         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3557         if (result)
3558                 PRINT_ER("Failed to send message queue: disconnect\n");
3559
3560         down(&hif_drv->hSemTestDisconnectBlock);
3561
3562         return result;
3563 }
3564
3565 s32 host_int_disconnect_station(struct host_if_drv *hif_drv, u8 assoc_id)
3566 {
3567         struct wid wid;
3568
3569         wid.id = (u16)WID_DISCONNECT;
3570         wid.type = WID_CHAR;
3571         wid.val = (s8 *)&assoc_id;
3572         wid.size = sizeof(char);
3573
3574         return 0;
3575 }
3576
3577 s32 host_int_get_assoc_req_info(struct host_if_drv *hif_drv,
3578                                 u8 *pu8AssocReqInfo,
3579                                 u32 u32AssocReqInfoLen)
3580 {
3581         struct wid wid;
3582
3583         wid.id = (u16)WID_ASSOC_REQ_INFO;
3584         wid.type = WID_STR;
3585         wid.val = pu8AssocReqInfo;
3586         wid.size = u32AssocReqInfoLen;
3587
3588         return 0;
3589 }
3590
3591 s32 host_int_get_assoc_res_info(struct host_if_drv *hif_drv,
3592                                 u8 *pu8AssocRespInfo,
3593                                 u32 u32MaxAssocRespInfoLen,
3594                                 u32 *pu32RcvdAssocRespInfoLen)
3595 {
3596         s32 result = 0;
3597         struct wid wid;
3598
3599         if (!hif_drv) {
3600                 PRINT_ER("Driver is null\n");
3601                 return -EFAULT;
3602         }
3603
3604         wid.id = (u16)WID_ASSOC_RES_INFO;
3605         wid.type = WID_STR;
3606         wid.val = pu8AssocRespInfo;
3607         wid.size = u32MaxAssocRespInfoLen;
3608
3609         result = send_config_pkt(GET_CFG, &wid, 1,
3610                                  get_id_from_handler(hif_drv));
3611         if (result) {
3612                 *pu32RcvdAssocRespInfoLen = 0;
3613                 PRINT_ER("Failed to send association response config packet\n");
3614                 return -EINVAL;
3615         } else {
3616                 *pu32RcvdAssocRespInfoLen = wid.size;
3617         }
3618
3619         return result;
3620 }
3621
3622 s32 host_int_get_rx_power_level(struct host_if_drv *hif_drv,
3623                                 u8 *pu8RxPowerLevel,
3624                                 u32 u32RxPowerLevelLen)
3625 {
3626         struct wid wid;
3627
3628         wid.id = (u16)WID_RX_POWER_LEVEL;
3629         wid.type = WID_STR;
3630         wid.val = pu8RxPowerLevel;
3631         wid.size = u32RxPowerLevelLen;
3632
3633         return 0;
3634 }
3635
3636 int host_int_set_mac_chnl_num(struct host_if_drv *hif_drv, u8 channel)
3637 {
3638         int result;
3639         struct host_if_msg msg;
3640
3641         if (!hif_drv) {
3642                 PRINT_ER("driver is null\n");
3643                 return -EFAULT;
3644         }
3645
3646         memset(&msg, 0, sizeof(struct host_if_msg));
3647         msg.id = HOST_IF_MSG_SET_CHANNEL;
3648         msg.body.channel_info.set_ch = channel;
3649         msg.drv = hif_drv;
3650
3651         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3652         if (result) {
3653                 PRINT_ER("wilc mq send fail\n");
3654                 return -EINVAL;
3655         }
3656
3657         return 0;
3658 }
3659
3660 int host_int_wait_msg_queue_idle(void)
3661 {
3662         int result = 0;
3663         struct host_if_msg msg;
3664
3665         memset(&msg, 0, sizeof(struct host_if_msg));
3666         msg.id = HOST_IF_MSG_Q_IDLE;
3667         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3668         if (result) {
3669                 PRINT_ER("wilc mq send fail\n");
3670                 result = -EINVAL;
3671         }
3672
3673         down(&hif_sema_wait_response);
3674
3675         return result;
3676 }
3677
3678 int host_int_set_wfi_drv_handler(struct host_if_drv *hif_drv)
3679 {
3680         int result = 0;
3681         struct host_if_msg msg;
3682
3683         memset(&msg, 0, sizeof(struct host_if_msg));
3684         msg.id = HOST_IF_MSG_SET_WFIDRV_HANDLER;
3685         msg.body.drv.handler = get_id_from_handler(hif_drv);
3686         msg.drv = hif_drv;
3687
3688         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3689         if (result) {
3690                 PRINT_ER("wilc mq send fail\n");
3691                 result = -EINVAL;
3692         }
3693
3694         return result;
3695 }
3696
3697 int host_int_set_operation_mode(struct host_if_drv *hif_drv, u32 mode)
3698 {
3699         int result = 0;
3700         struct host_if_msg msg;
3701
3702         memset(&msg, 0, sizeof(struct host_if_msg));
3703         msg.id = HOST_IF_MSG_SET_OPERATION_MODE;
3704         msg.body.mode.mode = mode;
3705         msg.drv = hif_drv;
3706
3707         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3708         if (result) {
3709                 PRINT_ER("wilc mq send fail\n");
3710                 result = -EINVAL;
3711         }
3712
3713         return result;
3714 }
3715
3716 s32 host_int_get_host_chnl_num(struct host_if_drv *hif_drv, u8 *pu8ChNo)
3717 {
3718         s32 result = 0;
3719         struct host_if_msg msg;
3720
3721         if (!hif_drv) {
3722                 PRINT_ER("driver is null\n");
3723                 return -EFAULT;
3724         }
3725
3726         memset(&msg, 0, sizeof(struct host_if_msg));
3727
3728         msg.id = HOST_IF_MSG_GET_CHNL;
3729         msg.drv = hif_drv;
3730
3731         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3732         if (result)
3733                 PRINT_ER("wilc mq send fail\n");
3734         down(&hif_drv->hSemGetCHNL);
3735
3736         *pu8ChNo = ch_no;
3737
3738         return result;
3739 }
3740
3741 s32 host_int_get_inactive_time(struct host_if_drv *hif_drv,
3742                                const u8 *mac, u32 *pu32InactiveTime)
3743 {
3744         s32 result = 0;
3745         struct host_if_msg msg;
3746
3747         if (!hif_drv) {
3748                 PRINT_ER("driver is null\n");
3749                 return -EFAULT;
3750         }
3751
3752         memset(&msg, 0, sizeof(struct host_if_msg));
3753         memcpy(msg.body.mac_info.mac, mac, ETH_ALEN);
3754
3755         msg.id = HOST_IF_MSG_GET_INACTIVETIME;
3756         msg.drv = hif_drv;
3757
3758         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3759         if (result)
3760                 PRINT_ER("Failed to send get host channel param's message queue ");
3761
3762         down(&hif_drv->hSemInactiveTime);
3763
3764         *pu32InactiveTime = inactive_time;
3765
3766         return result;
3767 }
3768
3769 s32 host_int_test_get_int_wid(struct host_if_drv *hif_drv, u32 *pu32TestMemAddr)
3770 {
3771         s32 result = 0;
3772         struct wid wid;
3773
3774         if (!hif_drv) {
3775                 PRINT_ER("driver is null\n");
3776                 return -EFAULT;
3777         }
3778
3779         wid.id = (u16)WID_MEMORY_ADDRESS;
3780         wid.type = WID_INT;
3781         wid.val = (s8 *)pu32TestMemAddr;
3782         wid.size = sizeof(u32);
3783
3784         result = send_config_pkt(GET_CFG, &wid, 1,
3785                                  get_id_from_handler(hif_drv));
3786
3787         if (result) {
3788                 PRINT_ER("Failed to get wid value\n");
3789                 return -EINVAL;
3790         } else {
3791                 PRINT_D(HOSTINF_DBG, "Successfully got wid value\n");
3792         }
3793
3794         return result;
3795 }
3796
3797 s32 host_int_get_rssi(struct host_if_drv *hif_drv, s8 *ps8Rssi)
3798 {
3799         s32 result = 0;
3800         struct host_if_msg msg;
3801
3802         memset(&msg, 0, sizeof(struct host_if_msg));
3803         msg.id = HOST_IF_MSG_GET_RSSI;
3804         msg.drv = hif_drv;
3805
3806         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3807         if (result) {
3808                 PRINT_ER("Failed to send get host channel param's message queue ");
3809                 return -EFAULT;
3810         }
3811
3812         down(&hif_drv->hSemGetRSSI);
3813
3814         if (!ps8Rssi) {
3815                 PRINT_ER("RSS pointer value is null");
3816                 return -EFAULT;
3817         }
3818
3819         *ps8Rssi = rssi;
3820
3821         return result;
3822 }
3823
3824 s32 host_int_get_link_speed(struct host_if_drv *hif_drv, s8 *ps8lnkspd)
3825 {
3826         struct host_if_msg msg;
3827         s32 result = 0;
3828
3829         memset(&msg, 0, sizeof(struct host_if_msg));
3830         msg.id = HOST_IF_MSG_GET_LINKSPEED;
3831         msg.drv = hif_drv;
3832
3833         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3834         if (result) {
3835                 PRINT_ER("Failed to send GET_LINKSPEED to message queue ");
3836                 return -EFAULT;
3837         }
3838
3839         down(&hif_drv->hSemGetLINKSPEED);
3840
3841         if (!ps8lnkspd) {
3842                 PRINT_ER("LINKSPEED pointer value is null");
3843                 return -EFAULT;
3844         }
3845
3846         *ps8lnkspd = link_speed;
3847
3848         return result;
3849 }
3850
3851 s32 host_int_get_statistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatistics)
3852 {
3853         s32 result = 0;
3854         struct host_if_msg msg;
3855
3856         memset(&msg, 0, sizeof(struct host_if_msg));
3857         msg.id = HOST_IF_MSG_GET_STATISTICS;
3858         msg.body.data = (char *)pstrStatistics;
3859         msg.drv = hif_drv;
3860
3861         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3862         if (result) {
3863                 PRINT_ER("Failed to send get host channel param's message queue ");
3864                 return -EFAULT;
3865         }
3866
3867         down(&hif_sema_wait_response);
3868         return result;
3869 }
3870
3871 s32 host_int_scan(struct host_if_drv *hif_drv, u8 u8ScanSource,
3872                   u8 u8ScanType, u8 *pu8ChnlFreqList,
3873                   u8 u8ChnlListLen, const u8 *pu8IEs,
3874                   size_t IEsLen, wilc_scan_result ScanResult,
3875                   void *pvUserArg, struct hidden_network *pstrHiddenNetwork)
3876 {
3877         s32 result = 0;
3878         struct host_if_msg msg;
3879
3880         if (!hif_drv || !ScanResult) {
3881                 PRINT_ER("hif_drv or ScanResult = NULL\n");
3882                 return -EFAULT;
3883         }
3884
3885         memset(&msg, 0, sizeof(struct host_if_msg));
3886
3887         msg.id = HOST_IF_MSG_SCAN;
3888
3889         if (pstrHiddenNetwork) {
3890                 msg.body.scan_info.hidden_network.pstrHiddenNetworkInfo = pstrHiddenNetwork->pstrHiddenNetworkInfo;
3891                 msg.body.scan_info.hidden_network.u8ssidnum = pstrHiddenNetwork->u8ssidnum;
3892
3893         } else
3894                 PRINT_D(HOSTINF_DBG, "pstrHiddenNetwork IS EQUAL TO NULL\n");
3895
3896         msg.drv = hif_drv;
3897         msg.body.scan_info.src = u8ScanSource;
3898         msg.body.scan_info.type = u8ScanType;
3899         msg.body.scan_info.result = ScanResult;
3900         msg.body.scan_info.arg = pvUserArg;
3901
3902         msg.body.scan_info.ch_list_len = u8ChnlListLen;
3903         msg.body.scan_info.ch_freq_list = kmalloc(u8ChnlListLen, GFP_KERNEL);
3904         memcpy(msg.body.scan_info.ch_freq_list, pu8ChnlFreqList, u8ChnlListLen);
3905
3906         msg.body.scan_info.ies_len = IEsLen;
3907         msg.body.scan_info.ies = kmalloc(IEsLen, GFP_KERNEL);
3908         memcpy(msg.body.scan_info.ies, pu8IEs, IEsLen);
3909
3910         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3911         if (result) {
3912                 PRINT_ER("Error in sending message queue\n");
3913                 return -EINVAL;
3914         }
3915
3916         PRINT_D(HOSTINF_DBG, ">> Starting the SCAN timer\n");
3917         hif_drv->hScanTimer.data = (unsigned long)hif_drv;
3918         mod_timer(&hif_drv->hScanTimer,
3919                   jiffies + msecs_to_jiffies(HOST_IF_SCAN_TIMEOUT));
3920
3921         return result;
3922 }
3923
3924 s32 hif_set_cfg(struct host_if_drv *hif_drv,
3925                 struct cfg_param_val *pstrCfgParamVal)
3926 {
3927         s32 result = 0;
3928         struct host_if_msg msg;
3929
3930         if (!hif_drv) {
3931                 PRINT_ER("hif_drv NULL\n");
3932                 return -EFAULT;
3933         }
3934
3935         memset(&msg, 0, sizeof(struct host_if_msg));
3936         msg.id = HOST_IF_MSG_CFG_PARAMS;
3937         msg.body.cfg_info.cfg_attr_info = *pstrCfgParamVal;
3938         msg.drv = hif_drv;
3939
3940         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3941
3942         return result;
3943 }
3944
3945 s32 hif_get_cfg(struct host_if_drv *hif_drv, u16 u16WID, u16 *pu16WID_Value)
3946 {
3947         s32 result = 0;
3948
3949         down(&hif_drv->gtOsCfgValuesSem);
3950
3951         if (!hif_drv) {
3952                 PRINT_ER("hif_drv NULL\n");
3953                 return -EFAULT;
3954         }
3955         PRINT_D(HOSTINF_DBG, "Getting configuration parameters\n");
3956         switch (u16WID) {
3957         case WID_BSS_TYPE:
3958                 *pu16WID_Value = (u16)hif_drv->strCfgValues.bss_type;
3959                 break;
3960
3961         case WID_AUTH_TYPE:
3962                 *pu16WID_Value = (u16)hif_drv->strCfgValues.auth_type;
3963                 break;
3964
3965         case WID_AUTH_TIMEOUT:
3966                 *pu16WID_Value = hif_drv->strCfgValues.auth_timeout;
3967                 break;
3968
3969         case WID_POWER_MANAGEMENT:
3970                 *pu16WID_Value = (u16)hif_drv->strCfgValues.power_mgmt_mode;
3971                 break;
3972
3973         case WID_SHORT_RETRY_LIMIT:
3974                 *pu16WID_Value =       hif_drv->strCfgValues.short_retry_limit;
3975                 break;
3976
3977         case WID_LONG_RETRY_LIMIT:
3978                 *pu16WID_Value = hif_drv->strCfgValues.long_retry_limit;
3979                 break;
3980
3981         case WID_FRAG_THRESHOLD:
3982                 *pu16WID_Value = hif_drv->strCfgValues.frag_threshold;
3983                 break;
3984
3985         case WID_RTS_THRESHOLD:
3986                 *pu16WID_Value = hif_drv->strCfgValues.rts_threshold;
3987                 break;
3988
3989         case WID_PREAMBLE:
3990                 *pu16WID_Value = (u16)hif_drv->strCfgValues.preamble_type;
3991                 break;
3992
3993         case WID_SHORT_SLOT_ALLOWED:
3994                 *pu16WID_Value = (u16) hif_drv->strCfgValues.short_slot_allowed;
3995                 break;
3996
3997         case WID_11N_TXOP_PROT_DISABLE:
3998                 *pu16WID_Value = (u16)hif_drv->strCfgValues.txop_prot_disabled;
3999                 break;
4000
4001         case WID_BEACON_INTERVAL:
4002                 *pu16WID_Value = hif_drv->strCfgValues.beacon_interval;
4003                 break;
4004
4005         case WID_DTIM_PERIOD:
4006                 *pu16WID_Value = (u16)hif_drv->strCfgValues.dtim_period;
4007                 break;
4008
4009         case WID_SITE_SURVEY:
4010                 *pu16WID_Value = (u16)hif_drv->strCfgValues.site_survey_enabled;
4011                 break;
4012
4013         case WID_SITE_SURVEY_SCAN_TIME:
4014                 *pu16WID_Value = hif_drv->strCfgValues.site_survey_scan_time;
4015                 break;
4016
4017         case WID_ACTIVE_SCAN_TIME:
4018                 *pu16WID_Value = hif_drv->strCfgValues.active_scan_time;
4019                 break;
4020
4021         case WID_PASSIVE_SCAN_TIME:
4022                 *pu16WID_Value = hif_drv->strCfgValues.passive_scan_time;
4023                 break;
4024
4025         case WID_CURRENT_TX_RATE:
4026                 *pu16WID_Value = hif_drv->strCfgValues.curr_tx_rate;
4027                 break;
4028
4029         default:
4030                 break;
4031         }
4032
4033         up(&hif_drv->gtOsCfgValuesSem);
4034
4035         return result;
4036 }
4037
4038 static void GetPeriodicRSSI(unsigned long arg)
4039 {
4040         struct host_if_drv *hif_drv = (struct host_if_drv *)arg;
4041
4042         if (!hif_drv)   {
4043                 PRINT_ER("Driver handler is NULL\n");
4044                 return;
4045         }
4046
4047         if (hif_drv->enuHostIFstate == HOST_IF_CONNECTED) {
4048                 s32 result = 0;
4049                 struct host_if_msg msg;
4050
4051                 memset(&msg, 0, sizeof(struct host_if_msg));
4052
4053                 msg.id = HOST_IF_MSG_GET_RSSI;
4054                 msg.drv = hif_drv;
4055
4056                 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4057                 if (result) {
4058                         PRINT_ER("Failed to send get host channel param's message queue ");
4059                         return;
4060                 }
4061         }
4062         periodic_rssi.data = (unsigned long)hif_drv;
4063         mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
4064 }
4065
4066 s32 host_int_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
4067 {
4068         s32 result = 0;
4069         struct host_if_drv *hif_drv;
4070         int err;
4071         perInterface_wlan_t *nic;
4072         struct wilc *wilc;
4073
4074         nic = netdev_priv(dev);
4075         wilc = nic->wilc;
4076
4077         PRINT_D(HOSTINF_DBG, "Initializing host interface for client %d\n", clients_count + 1);
4078
4079         scan_while_connected = false;
4080
4081         sema_init(&hif_sema_wait_response, 0);
4082
4083         hif_drv  = kzalloc(sizeof(struct host_if_drv), GFP_KERNEL);
4084         if (!hif_drv) {
4085                 result = -ENOMEM;
4086                 goto _fail_;
4087         }
4088         *hif_drv_handler = hif_drv;
4089         err = add_handler_in_list(hif_drv);
4090         if (err) {
4091                 result = -EFAULT;
4092                 goto _fail_timer_2;
4093         }
4094
4095         g_obtainingIP = false;
4096
4097         PRINT_D(HOSTINF_DBG, "Global handle pointer value=%p\n", hif_drv);
4098         if (clients_count == 0) {
4099                 sema_init(&hif_sema_thread, 0);
4100                 sema_init(&hif_sema_driver, 0);
4101                 sema_init(&hif_sema_deinit, 1);
4102         }
4103
4104         sema_init(&hif_drv->hSemTestKeyBlock, 0);
4105         sema_init(&hif_drv->hSemTestDisconnectBlock, 0);
4106         sema_init(&hif_drv->hSemGetRSSI, 0);
4107         sema_init(&hif_drv->hSemGetLINKSPEED, 0);
4108         sema_init(&hif_drv->hSemGetCHNL, 0);
4109         sema_init(&hif_drv->hSemInactiveTime, 0);
4110
4111         PRINT_D(HOSTINF_DBG, "INIT: CLIENT COUNT %d\n", clients_count);
4112
4113         if (clients_count == 0) {
4114                 result = wilc_mq_create(&hif_msg_q);
4115
4116                 if (result < 0) {
4117                         PRINT_ER("Failed to creat MQ\n");
4118                         goto _fail_;
4119                 }
4120
4121                 hif_thread_handler = kthread_run(hostIFthread, wilc,
4122                                                  "WILC_kthread");
4123
4124                 if (IS_ERR(hif_thread_handler)) {
4125                         PRINT_ER("Failed to creat Thread\n");
4126                         result = -EFAULT;
4127                         goto _fail_mq_;
4128                 }
4129                 setup_timer(&periodic_rssi, GetPeriodicRSSI,
4130                             (unsigned long)hif_drv);
4131                 mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
4132         }
4133
4134         setup_timer(&hif_drv->hScanTimer, TimerCB_Scan, 0);
4135
4136         setup_timer(&hif_drv->hConnectTimer, TimerCB_Connect, 0);
4137
4138         setup_timer(&hif_drv->hRemainOnChannel, ListenTimerCB, 0);
4139
4140         sema_init(&hif_drv->gtOsCfgValuesSem, 1);
4141         down(&hif_drv->gtOsCfgValuesSem);
4142
4143         hif_drv->enuHostIFstate = HOST_IF_IDLE;
4144         hif_drv->strCfgValues.site_survey_enabled = SITE_SURVEY_OFF;
4145         hif_drv->strCfgValues.scan_source = DEFAULT_SCAN;
4146         hif_drv->strCfgValues.active_scan_time = ACTIVE_SCAN_TIME;
4147         hif_drv->strCfgValues.passive_scan_time = PASSIVE_SCAN_TIME;
4148         hif_drv->strCfgValues.curr_tx_rate = AUTORATE;
4149
4150         hif_drv->u64P2p_MgmtTimeout = 0;
4151
4152         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",
4153
4154                    hif_drv->strCfgValues.site_survey_enabled, hif_drv->strCfgValues.scan_source,
4155                    hif_drv->strCfgValues.active_scan_time, hif_drv->strCfgValues.passive_scan_time,
4156                    hif_drv->strCfgValues.curr_tx_rate);
4157
4158         up(&hif_drv->gtOsCfgValuesSem);
4159
4160         clients_count++;
4161
4162         return result;
4163
4164 _fail_timer_2:
4165         up(&hif_drv->gtOsCfgValuesSem);
4166         del_timer_sync(&hif_drv->hConnectTimer);
4167         del_timer_sync(&hif_drv->hScanTimer);
4168         kthread_stop(hif_thread_handler);
4169 _fail_mq_:
4170         wilc_mq_destroy(&hif_msg_q);
4171 _fail_:
4172         return result;
4173 }
4174
4175 s32 host_int_deinit(struct host_if_drv *hif_drv)
4176 {
4177         s32 result = 0;
4178         struct host_if_msg msg;
4179         int ret;
4180
4181         if (!hif_drv)   {
4182                 PRINT_ER("hif_drv = NULL\n");
4183                 return 0;
4184         }
4185
4186         down(&hif_sema_deinit);
4187
4188         terminated_handle = hif_drv;
4189         PRINT_D(HOSTINF_DBG, "De-initializing host interface for client %d\n", clients_count);
4190
4191         if (del_timer_sync(&hif_drv->hScanTimer))
4192                 PRINT_D(HOSTINF_DBG, ">> Scan timer is active\n");
4193
4194         if (del_timer_sync(&hif_drv->hConnectTimer))
4195                 PRINT_D(HOSTINF_DBG, ">> Connect timer is active\n");
4196
4197         if (del_timer_sync(&periodic_rssi))
4198                 PRINT_D(HOSTINF_DBG, ">> Connect timer is active\n");
4199
4200         del_timer_sync(&hif_drv->hRemainOnChannel);
4201
4202         host_int_set_wfi_drv_handler(NULL);
4203         down(&hif_sema_driver);
4204
4205         if (hif_drv->usr_scan_req.pfUserScanResult) {
4206                 hif_drv->usr_scan_req.pfUserScanResult(SCAN_EVENT_ABORTED, NULL,
4207                                                        hif_drv->usr_scan_req.u32UserScanPvoid, NULL);
4208
4209                 hif_drv->usr_scan_req.pfUserScanResult = NULL;
4210         }
4211
4212         hif_drv->enuHostIFstate = HOST_IF_IDLE;
4213
4214         scan_while_connected = false;
4215
4216         memset(&msg, 0, sizeof(struct host_if_msg));
4217
4218         if (clients_count == 1) {
4219                 if (del_timer_sync(&periodic_rssi))
4220                         PRINT_D(HOSTINF_DBG, ">> Connect timer is active\n");
4221
4222                 msg.id = HOST_IF_MSG_EXIT;
4223                 msg.drv = hif_drv;
4224
4225                 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4226                 if (result != 0)
4227                         PRINT_ER("Error in sending deinit's message queue message function: Error(%d)\n", result);
4228
4229                 down(&hif_sema_thread);
4230
4231                 wilc_mq_destroy(&hif_msg_q);
4232         }
4233
4234         down(&hif_drv->gtOsCfgValuesSem);
4235
4236         ret = remove_handler_in_list(hif_drv);
4237         if (ret)
4238                 result = -ENOENT;
4239
4240         kfree(hif_drv);
4241
4242         clients_count--;
4243         terminated_handle = NULL;
4244         up(&hif_sema_deinit);
4245         return result;
4246 }
4247
4248 void NetworkInfoReceived(u8 *pu8Buffer, u32 u32Length)
4249 {
4250         s32 result = 0;
4251         struct host_if_msg msg;
4252         int id;
4253         struct host_if_drv *hif_drv = NULL;
4254
4255         id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
4256         hif_drv = get_handler_from_id(id);
4257
4258         if (!hif_drv || hif_drv == terminated_handle)   {
4259                 PRINT_ER("NetworkInfo received but driver not init[%p]\n", hif_drv);
4260                 return;
4261         }
4262
4263         memset(&msg, 0, sizeof(struct host_if_msg));
4264
4265         msg.id = HOST_IF_MSG_RCVD_NTWRK_INFO;
4266         msg.drv = hif_drv;
4267
4268         msg.body.net_info.len = u32Length;
4269         msg.body.net_info.buffer = kmalloc(u32Length, GFP_KERNEL);
4270         memcpy(msg.body.net_info.buffer, pu8Buffer, u32Length);
4271
4272         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4273         if (result)
4274                 PRINT_ER("Error in sending network info message queue message parameters: Error(%d)\n", result);
4275 }
4276
4277 void GnrlAsyncInfoReceived(u8 *pu8Buffer, u32 u32Length)
4278 {
4279         s32 result = 0;
4280         struct host_if_msg msg;
4281         int id;
4282         struct host_if_drv *hif_drv = NULL;
4283
4284         down(&hif_sema_deinit);
4285
4286         id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
4287         hif_drv = get_handler_from_id(id);
4288         PRINT_D(HOSTINF_DBG, "General asynchronous info packet received\n");
4289
4290         if (!hif_drv || hif_drv == terminated_handle) {
4291                 PRINT_D(HOSTINF_DBG, "Wifi driver handler is equal to NULL\n");
4292                 up(&hif_sema_deinit);
4293                 return;
4294         }
4295
4296         if (!hif_drv->usr_conn_req.pfUserConnectResult) {
4297                 PRINT_ER("Received mac status is not needed when there is no current Connect Reques\n");
4298                 up(&hif_sema_deinit);
4299                 return;
4300         }
4301
4302         memset(&msg, 0, sizeof(struct host_if_msg));
4303
4304         msg.id = HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO;
4305         msg.drv = hif_drv;
4306
4307         msg.body.async_info.len = u32Length;
4308         msg.body.async_info.buffer = kmalloc(u32Length, GFP_KERNEL);
4309         memcpy(msg.body.async_info.buffer, pu8Buffer, u32Length);
4310
4311         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4312         if (result)
4313                 PRINT_ER("Error in sending message queue asynchronous message info: Error(%d)\n", result);
4314
4315         up(&hif_sema_deinit);
4316 }
4317
4318 void host_int_ScanCompleteReceived(u8 *pu8Buffer, u32 u32Length)
4319 {
4320         s32 result = 0;
4321         struct host_if_msg msg;
4322         int id;
4323         struct host_if_drv *hif_drv = NULL;
4324
4325         id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
4326         hif_drv = get_handler_from_id(id);
4327
4328         PRINT_D(GENERIC_DBG, "Scan notification received %p\n", hif_drv);
4329
4330         if (!hif_drv || hif_drv == terminated_handle)
4331                 return;
4332
4333         if (hif_drv->usr_scan_req.pfUserScanResult) {
4334                 memset(&msg, 0, sizeof(struct host_if_msg));
4335
4336                 msg.id = HOST_IF_MSG_RCVD_SCAN_COMPLETE;
4337                 msg.drv = hif_drv;
4338
4339                 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4340                 if (result)
4341                         PRINT_ER("Error in sending message queue scan complete parameters: Error(%d)\n", result);
4342         }
4343
4344         return;
4345 }
4346
4347 s32 host_int_remain_on_channel(struct host_if_drv *hif_drv, u32 u32SessionID,
4348                                u32 u32duration, u16 chan,
4349                                wilc_remain_on_chan_expired RemainOnChanExpired,
4350                                wilc_remain_on_chan_ready RemainOnChanReady,
4351                                void *pvUserArg)
4352 {
4353         s32 result = 0;
4354         struct host_if_msg msg;
4355
4356         if (!hif_drv) {
4357                 PRINT_ER("driver is null\n");
4358                 return -EFAULT;
4359         }
4360
4361         memset(&msg, 0, sizeof(struct host_if_msg));
4362
4363         msg.id = HOST_IF_MSG_REMAIN_ON_CHAN;
4364         msg.body.remain_on_ch.u16Channel = chan;
4365         msg.body.remain_on_ch.pRemainOnChanExpired = RemainOnChanExpired;
4366         msg.body.remain_on_ch.pRemainOnChanReady = RemainOnChanReady;
4367         msg.body.remain_on_ch.pVoid = pvUserArg;
4368         msg.body.remain_on_ch.u32duration = u32duration;
4369         msg.body.remain_on_ch.u32ListenSessionID = u32SessionID;
4370         msg.drv = hif_drv;
4371
4372         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4373         if (result)
4374                 PRINT_ER("wilc mq send fail\n");
4375
4376         return result;
4377 }
4378
4379 s32 host_int_ListenStateExpired(struct host_if_drv *hif_drv, u32 u32SessionID)
4380 {
4381         s32 result = 0;
4382         struct host_if_msg msg;
4383
4384         if (!hif_drv) {
4385                 PRINT_ER("driver is null\n");
4386                 return -EFAULT;
4387         }
4388
4389         del_timer(&hif_drv->hRemainOnChannel);
4390
4391         memset(&msg, 0, sizeof(struct host_if_msg));
4392         msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
4393         msg.drv = hif_drv;
4394         msg.body.remain_on_ch.u32ListenSessionID = u32SessionID;
4395
4396         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4397         if (result)
4398                 PRINT_ER("wilc mq send fail\n");
4399
4400         return result;
4401 }
4402
4403 s32 host_int_frame_register(struct host_if_drv *hif_drv, u16 u16FrameType, bool bReg)
4404 {
4405         s32 result = 0;
4406         struct host_if_msg msg;
4407
4408         if (!hif_drv) {
4409                 PRINT_ER("driver is null\n");
4410                 return -EFAULT;
4411         }
4412
4413         memset(&msg, 0, sizeof(struct host_if_msg));
4414
4415         msg.id = HOST_IF_MSG_REGISTER_FRAME;
4416         switch (u16FrameType) {
4417         case ACTION:
4418                 PRINT_D(HOSTINF_DBG, "ACTION\n");
4419                 msg.body.reg_frame.u8Regid = ACTION_FRM_IDX;
4420                 break;
4421
4422         case PROBE_REQ:
4423                 PRINT_D(HOSTINF_DBG, "PROBE REQ\n");
4424                 msg.body.reg_frame.u8Regid = PROBE_REQ_IDX;
4425                 break;
4426
4427         default:
4428                 PRINT_D(HOSTINF_DBG, "Not valid frame type\n");
4429                 break;
4430         }
4431         msg.body.reg_frame.u16FrameType = u16FrameType;
4432         msg.body.reg_frame.bReg = bReg;
4433         msg.drv = hif_drv;
4434
4435         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4436         if (result)
4437                 PRINT_ER("wilc mq send fail\n");
4438
4439         return result;
4440 }
4441
4442 s32 host_int_add_beacon(struct host_if_drv *hif_drv, u32 u32Interval,
4443                         u32 u32DTIMPeriod, u32 u32HeadLen, u8 *pu8Head,
4444                         u32 u32TailLen, u8 *pu8Tail)
4445 {
4446         s32 result = 0;
4447         struct host_if_msg msg;
4448         struct beacon_attr *pstrSetBeaconParam = &msg.body.beacon_info;
4449
4450         if (!hif_drv) {
4451                 PRINT_ER("driver is null\n");
4452                 return -EFAULT;
4453         }
4454
4455         memset(&msg, 0, sizeof(struct host_if_msg));
4456
4457         PRINT_D(HOSTINF_DBG, "Setting adding beacon message queue params\n");
4458
4459         msg.id = HOST_IF_MSG_ADD_BEACON;
4460         msg.drv = hif_drv;
4461         pstrSetBeaconParam->interval = u32Interval;
4462         pstrSetBeaconParam->dtim_period = u32DTIMPeriod;
4463         pstrSetBeaconParam->head_len = u32HeadLen;
4464         pstrSetBeaconParam->head = kmemdup(pu8Head, u32HeadLen, GFP_KERNEL);
4465         if (!pstrSetBeaconParam->head) {
4466                 result = -ENOMEM;
4467                 goto ERRORHANDLER;
4468         }
4469         pstrSetBeaconParam->tail_len = u32TailLen;
4470
4471         if (u32TailLen > 0) {
4472                 pstrSetBeaconParam->tail = kmemdup(pu8Tail, u32TailLen,
4473                                                    GFP_KERNEL);
4474                 if (!pstrSetBeaconParam->tail) {
4475                         result = -ENOMEM;
4476                         goto ERRORHANDLER;
4477                 }
4478         } else {
4479                 pstrSetBeaconParam->tail = NULL;
4480         }
4481
4482         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4483         if (result)
4484                 PRINT_ER("wilc mq send fail\n");
4485
4486 ERRORHANDLER:
4487         if (result) {
4488                 kfree(pstrSetBeaconParam->head);
4489
4490                 kfree(pstrSetBeaconParam->tail);
4491         }
4492
4493         return result;
4494 }
4495
4496 s32 host_int_del_beacon(struct host_if_drv *hif_drv)
4497 {
4498         s32 result = 0;
4499         struct host_if_msg msg;
4500
4501         if (!hif_drv) {
4502                 PRINT_ER("driver is null\n");
4503                 return -EFAULT;
4504         }
4505
4506         msg.id = HOST_IF_MSG_DEL_BEACON;
4507         msg.drv = hif_drv;
4508         PRINT_D(HOSTINF_DBG, "Setting deleting beacon message queue params\n");
4509
4510         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4511         if (result)
4512                 PRINT_ER("wilc_mq_send fail\n");
4513
4514         return result;
4515 }
4516
4517 s32 host_int_add_station(struct host_if_drv *hif_drv,
4518                          struct add_sta_param *pstrStaParams)
4519 {
4520         s32 result = 0;
4521         struct host_if_msg msg;
4522         struct add_sta_param *pstrAddStationMsg = &msg.body.add_sta_info;
4523
4524         if (!hif_drv) {
4525                 PRINT_ER("driver is null\n");
4526                 return -EFAULT;
4527         }
4528
4529         memset(&msg, 0, sizeof(struct host_if_msg));
4530
4531         PRINT_D(HOSTINF_DBG, "Setting adding station message queue params\n");
4532
4533         msg.id = HOST_IF_MSG_ADD_STATION;
4534         msg.drv = hif_drv;
4535
4536         memcpy(pstrAddStationMsg, pstrStaParams, sizeof(struct add_sta_param));
4537         if (pstrAddStationMsg->u8NumRates > 0) {
4538                 u8 *rates = kmalloc(pstrAddStationMsg->u8NumRates, GFP_KERNEL);
4539
4540                 if (!rates)
4541                         return -ENOMEM;
4542
4543                 memcpy(rates, pstrStaParams->pu8Rates, pstrAddStationMsg->u8NumRates);
4544                 pstrAddStationMsg->pu8Rates = rates;
4545         }
4546
4547         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4548         if (result)
4549                 PRINT_ER("wilc_mq_send fail\n");
4550         return result;
4551 }
4552
4553 s32 host_int_del_station(struct host_if_drv *hif_drv, const u8 *pu8MacAddr)
4554 {
4555         s32 result = 0;
4556         struct host_if_msg msg;
4557         struct del_sta *pstrDelStationMsg = &msg.body.del_sta_info;
4558
4559         if (!hif_drv) {
4560                 PRINT_ER("driver is null\n");
4561                 return -EFAULT;
4562         }
4563
4564         memset(&msg, 0, sizeof(struct host_if_msg));
4565
4566         PRINT_D(HOSTINF_DBG, "Setting deleting station message queue params\n");
4567
4568         msg.id = HOST_IF_MSG_DEL_STATION;
4569         msg.drv = hif_drv;
4570
4571         if (!pu8MacAddr)
4572                 memset(pstrDelStationMsg->mac_addr, 255, ETH_ALEN);
4573         else
4574                 memcpy(pstrDelStationMsg->mac_addr, pu8MacAddr, ETH_ALEN);
4575
4576         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4577         if (result)
4578                 PRINT_ER("wilc_mq_send fail\n");
4579         return result;
4580 }
4581
4582 s32 host_int_del_allstation(struct host_if_drv *hif_drv,
4583                             u8 pu8MacAddr[][ETH_ALEN])
4584 {
4585         s32 result = 0;
4586         struct host_if_msg msg;
4587         struct del_all_sta *pstrDelAllStationMsg = &msg.body.del_all_sta_info;
4588         u8 au8Zero_Buff[ETH_ALEN] = {0};
4589         u32 i;
4590         u8 u8AssocNumb = 0;
4591
4592         if (!hif_drv) {
4593                 PRINT_ER("driver is null\n");
4594                 return -EFAULT;
4595         }
4596
4597         memset(&msg, 0, sizeof(struct host_if_msg));
4598
4599         PRINT_D(HOSTINF_DBG, "Setting deauthenticating station message queue params\n");
4600
4601         msg.id = HOST_IF_MSG_DEL_ALL_STA;
4602         msg.drv = hif_drv;
4603
4604         for (i = 0; i < MAX_NUM_STA; i++) {
4605                 if (memcmp(pu8MacAddr[i], au8Zero_Buff, ETH_ALEN)) {
4606                         memcpy(pstrDelAllStationMsg->del_all_sta[i], pu8MacAddr[i], ETH_ALEN);
4607                         PRINT_D(CFG80211_DBG, "BSSID = %x%x%x%x%x%x\n",
4608                                 pstrDelAllStationMsg->del_all_sta[i][0],
4609                                 pstrDelAllStationMsg->del_all_sta[i][1],
4610                                 pstrDelAllStationMsg->del_all_sta[i][2],
4611                                 pstrDelAllStationMsg->del_all_sta[i][3],
4612                                 pstrDelAllStationMsg->del_all_sta[i][4],
4613                                 pstrDelAllStationMsg->del_all_sta[i][5]);
4614                         u8AssocNumb++;
4615                 }
4616         }
4617         if (!u8AssocNumb) {
4618                 PRINT_D(CFG80211_DBG, "NO ASSOCIATED STAS\n");
4619                 return result;
4620         }
4621
4622         pstrDelAllStationMsg->assoc_sta = u8AssocNumb;
4623         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4624
4625         if (result)
4626                 PRINT_ER("wilc_mq_send fail\n");
4627
4628         down(&hif_sema_wait_response);
4629
4630         return result;
4631 }
4632
4633 s32 host_int_edit_station(struct host_if_drv *hif_drv,
4634                           struct add_sta_param *pstrStaParams)
4635 {
4636         s32 result = 0;
4637         struct host_if_msg msg;
4638         struct add_sta_param *pstrAddStationMsg = &msg.body.add_sta_info;
4639
4640         if (!hif_drv) {
4641                 PRINT_ER("driver is null\n");
4642                 return -EFAULT;
4643         }
4644
4645         PRINT_D(HOSTINF_DBG, "Setting editing station message queue params\n");
4646
4647         memset(&msg, 0, sizeof(struct host_if_msg));
4648
4649         msg.id = HOST_IF_MSG_EDIT_STATION;
4650         msg.drv = hif_drv;
4651
4652         memcpy(pstrAddStationMsg, pstrStaParams, sizeof(struct add_sta_param));
4653         if (pstrAddStationMsg->u8NumRates > 0) {
4654                 u8 *rates = kmalloc(pstrAddStationMsg->u8NumRates, GFP_KERNEL);
4655
4656                 if (!rates)
4657                         return -ENOMEM;
4658
4659                 memcpy(rates, pstrStaParams->pu8Rates, pstrAddStationMsg->u8NumRates);
4660                 pstrAddStationMsg->pu8Rates = rates;
4661         }
4662
4663         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4664         if (result)
4665                 PRINT_ER("wilc_mq_send fail\n");
4666
4667         return result;
4668 }
4669
4670 s32 host_int_set_power_mgmt(struct host_if_drv *hif_drv,
4671                             bool bIsEnabled,
4672                             u32 u32Timeout)
4673 {
4674         s32 result = 0;
4675         struct host_if_msg msg;
4676         struct power_mgmt_param *pstrPowerMgmtParam = &msg.body.pwr_mgmt_info;
4677
4678         PRINT_INFO(HOSTINF_DBG, "\n\n>> Setting PS to %d <<\n\n", bIsEnabled);
4679
4680         if (!hif_drv) {
4681                 PRINT_ER("driver is null\n");
4682                 return -EFAULT;
4683         }
4684
4685         PRINT_D(HOSTINF_DBG, "Setting Power management message queue params\n");
4686
4687         memset(&msg, 0, sizeof(struct host_if_msg));
4688
4689         msg.id = HOST_IF_MSG_POWER_MGMT;
4690         msg.drv = hif_drv;
4691
4692         pstrPowerMgmtParam->enabled = bIsEnabled;
4693         pstrPowerMgmtParam->timeout = u32Timeout;
4694
4695         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4696         if (result)
4697                 PRINT_ER("wilc_mq_send fail\n");
4698         return result;
4699 }
4700
4701 s32 host_int_setup_multicast_filter(struct host_if_drv *hif_drv,
4702                                     bool bIsEnabled,
4703                                     u32 u32count)
4704 {
4705         s32 result = 0;
4706         struct host_if_msg msg;
4707         struct set_multicast *pstrMulticastFilterParam = &msg.body.multicast_info;
4708
4709         if (!hif_drv) {
4710                 PRINT_ER("driver is null\n");
4711                 return -EFAULT;
4712         }
4713
4714         PRINT_D(HOSTINF_DBG, "Setting Multicast Filter params\n");
4715
4716         memset(&msg, 0, sizeof(struct host_if_msg));
4717
4718         msg.id = HOST_IF_MSG_SET_MULTICAST_FILTER;
4719         msg.drv = hif_drv;
4720
4721         pstrMulticastFilterParam->enabled = bIsEnabled;
4722         pstrMulticastFilterParam->cnt = u32count;
4723
4724         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4725         if (result)
4726                 PRINT_ER("wilc_mq_send fail\n");
4727         return result;
4728 }
4729
4730 static void *host_int_ParseJoinBssParam(tstrNetworkInfo *ptstrNetworkInfo)
4731 {
4732         struct join_bss_param *pNewJoinBssParam = NULL;
4733         u8 *pu8IEs;
4734         u16 u16IEsLen;
4735         u16 index = 0;
4736         u8 suppRatesNo = 0;
4737         u8 extSuppRatesNo;
4738         u16 jumpOffset;
4739         u8 pcipherCount;
4740         u8 authCount;
4741         u8 pcipherTotalCount = 0;
4742         u8 authTotalCount = 0;
4743         u8 i, j;
4744
4745         pu8IEs = ptstrNetworkInfo->pu8IEs;
4746         u16IEsLen = ptstrNetworkInfo->u16IEsLen;
4747
4748         pNewJoinBssParam = kzalloc(sizeof(struct join_bss_param), GFP_KERNEL);
4749         if (pNewJoinBssParam) {
4750                 pNewJoinBssParam->dtim_period = ptstrNetworkInfo->u8DtimPeriod;
4751                 pNewJoinBssParam->beacon_period = ptstrNetworkInfo->u16BeaconPeriod;
4752                 pNewJoinBssParam->cap_info = ptstrNetworkInfo->u16CapInfo;
4753                 memcpy(pNewJoinBssParam->au8bssid, ptstrNetworkInfo->au8bssid, 6);
4754                 memcpy((u8 *)pNewJoinBssParam->ssid, ptstrNetworkInfo->au8ssid, ptstrNetworkInfo->u8SsidLen + 1);
4755                 pNewJoinBssParam->ssid_len = ptstrNetworkInfo->u8SsidLen;
4756                 memset(pNewJoinBssParam->rsn_pcip_policy, 0xFF, 3);
4757                 memset(pNewJoinBssParam->rsn_auth_policy, 0xFF, 3);
4758
4759                 while (index < u16IEsLen) {
4760                         if (pu8IEs[index] == SUPP_RATES_IE) {
4761                                 suppRatesNo = pu8IEs[index + 1];
4762                                 pNewJoinBssParam->supp_rates[0] = suppRatesNo;
4763                                 index += 2;
4764
4765                                 for (i = 0; i < suppRatesNo; i++)
4766                                         pNewJoinBssParam->supp_rates[i + 1] = pu8IEs[index + i];
4767
4768                                 index += suppRatesNo;
4769                                 continue;
4770                         } else if (pu8IEs[index] == EXT_SUPP_RATES_IE) {
4771                                 extSuppRatesNo = pu8IEs[index + 1];
4772                                 if (extSuppRatesNo > (MAX_RATES_SUPPORTED - suppRatesNo))
4773                                         pNewJoinBssParam->supp_rates[0] = MAX_RATES_SUPPORTED;
4774                                 else
4775                                         pNewJoinBssParam->supp_rates[0] += extSuppRatesNo;
4776                                 index += 2;
4777                                 for (i = 0; i < (pNewJoinBssParam->supp_rates[0] - suppRatesNo); i++)
4778                                         pNewJoinBssParam->supp_rates[suppRatesNo + i + 1] = pu8IEs[index + i];
4779
4780                                 index += extSuppRatesNo;
4781                                 continue;
4782                         } else if (pu8IEs[index] == HT_CAPABILITY_IE) {
4783                                 pNewJoinBssParam->ht_capable = true;
4784                                 index += pu8IEs[index + 1] + 2;
4785                                 continue;
4786                         } else if ((pu8IEs[index] == WMM_IE) &&
4787                                    (pu8IEs[index + 2] == 0x00) && (pu8IEs[index + 3] == 0x50) &&
4788                                    (pu8IEs[index + 4] == 0xF2) &&
4789                                    (pu8IEs[index + 5] == 0x02) &&
4790                                    ((pu8IEs[index + 6] == 0x00) || (pu8IEs[index + 6] == 0x01)) &&
4791                                    (pu8IEs[index + 7] == 0x01)) {
4792                                 pNewJoinBssParam->wmm_cap = true;
4793
4794                                 if (pu8IEs[index + 8] & BIT(7))
4795                                         pNewJoinBssParam->uapsd_cap = true;
4796                                 index += pu8IEs[index + 1] + 2;
4797                                 continue;
4798                         } else if ((pu8IEs[index] == P2P_IE) &&
4799                                  (pu8IEs[index + 2] == 0x50) && (pu8IEs[index + 3] == 0x6f) &&
4800                                  (pu8IEs[index + 4] == 0x9a) &&
4801                                  (pu8IEs[index + 5] == 0x09) && (pu8IEs[index + 6] == 0x0c)) {
4802                                 u16 u16P2P_count;
4803
4804                                 pNewJoinBssParam->tsf = ptstrNetworkInfo->u32Tsf;
4805                                 pNewJoinBssParam->noa_enabled = 1;
4806                                 pNewJoinBssParam->idx = pu8IEs[index + 9];
4807
4808                                 if (pu8IEs[index + 10] & BIT(7)) {
4809                                         pNewJoinBssParam->opp_enabled = 1;
4810                                         pNewJoinBssParam->ct_window = pu8IEs[index + 10];
4811                                 } else {
4812                                         pNewJoinBssParam->opp_enabled = 0;
4813                                 }
4814
4815                                 PRINT_D(GENERIC_DBG, "P2P Dump\n");
4816                                 for (i = 0; i < pu8IEs[index + 7]; i++)
4817                                         PRINT_D(GENERIC_DBG, " %x\n", pu8IEs[index + 9 + i]);
4818
4819                                 pNewJoinBssParam->cnt = pu8IEs[index + 11];
4820                                 u16P2P_count = index + 12;
4821
4822                                 memcpy(pNewJoinBssParam->duration, pu8IEs + u16P2P_count, 4);
4823                                 u16P2P_count += 4;
4824
4825                                 memcpy(pNewJoinBssParam->interval, pu8IEs + u16P2P_count, 4);
4826                                 u16P2P_count += 4;
4827
4828                                 memcpy(pNewJoinBssParam->start_time, pu8IEs + u16P2P_count, 4);
4829
4830                                 index += pu8IEs[index + 1] + 2;
4831                                 continue;
4832
4833                         } else if ((pu8IEs[index] == RSN_IE) ||
4834                                  ((pu8IEs[index] == WPA_IE) && (pu8IEs[index + 2] == 0x00) &&
4835                                   (pu8IEs[index + 3] == 0x50) && (pu8IEs[index + 4] == 0xF2) &&
4836                                   (pu8IEs[index + 5] == 0x01))) {
4837                                 u16 rsnIndex = index;
4838
4839                                 if (pu8IEs[rsnIndex] == RSN_IE) {
4840                                         pNewJoinBssParam->mode_802_11i = 2;
4841                                 } else {
4842                                         if (pNewJoinBssParam->mode_802_11i == 0)
4843                                                 pNewJoinBssParam->mode_802_11i = 1;
4844                                         rsnIndex += 4;
4845                                 }
4846
4847                                 rsnIndex += 7;
4848                                 pNewJoinBssParam->rsn_grp_policy = pu8IEs[rsnIndex];
4849                                 rsnIndex++;
4850                                 jumpOffset = pu8IEs[rsnIndex] * 4;
4851                                 pcipherCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex];
4852                                 rsnIndex += 2;
4853
4854                                 for (i = pcipherTotalCount, j = 0; i < pcipherCount + pcipherTotalCount && i < 3; i++, j++)
4855                                         pNewJoinBssParam->rsn_pcip_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1];
4856
4857                                 pcipherTotalCount += pcipherCount;
4858                                 rsnIndex += jumpOffset;
4859
4860                                 jumpOffset = pu8IEs[rsnIndex] * 4;
4861
4862                                 authCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex];
4863                                 rsnIndex += 2;
4864
4865                                 for (i = authTotalCount, j = 0; i < authTotalCount + authCount; i++, j++)
4866                                         pNewJoinBssParam->rsn_auth_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1];
4867
4868                                 authTotalCount += authCount;
4869                                 rsnIndex += jumpOffset;
4870
4871                                 if (pu8IEs[index] == RSN_IE) {
4872                                         pNewJoinBssParam->rsn_cap[0] = pu8IEs[rsnIndex];
4873                                         pNewJoinBssParam->rsn_cap[1] = pu8IEs[rsnIndex + 1];
4874                                         rsnIndex += 2;
4875                                 }
4876                                 pNewJoinBssParam->rsn_found = true;
4877                                 index += pu8IEs[index + 1] + 2;
4878                                 continue;
4879                         } else
4880                                 index += pu8IEs[index + 1] + 2;
4881                 }
4882         }
4883
4884         return (void *)pNewJoinBssParam;
4885 }
4886
4887 void host_int_freeJoinParams(void *pJoinParams)
4888 {
4889         if ((struct bss_param *)pJoinParams)
4890                 kfree((struct bss_param *)pJoinParams);
4891         else
4892                 PRINT_ER("Unable to FREE null pointer\n");
4893 }
4894
4895 s32 host_int_delBASession(struct host_if_drv *hif_drv, char *pBSSID, char TID)
4896 {
4897         s32 result = 0;
4898         struct host_if_msg msg;
4899         struct ba_session_info *pBASessionInfo = &msg.body.session_info;
4900
4901         if (!hif_drv) {
4902                 PRINT_ER("driver is null\n");
4903                 return -EFAULT;
4904         }
4905
4906         memset(&msg, 0, sizeof(struct host_if_msg));
4907
4908         msg.id = HOST_IF_MSG_DEL_BA_SESSION;
4909
4910         memcpy(pBASessionInfo->au8Bssid, pBSSID, ETH_ALEN);
4911         pBASessionInfo->u8Ted = TID;
4912         msg.drv = hif_drv;
4913
4914         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4915         if (result)
4916                 PRINT_ER("wilc_mq_send fail\n");
4917
4918         down(&hif_sema_wait_response);
4919
4920         return result;
4921 }
4922
4923 s32 host_int_del_All_Rx_BASession(struct host_if_drv *hif_drv,
4924                                   char *pBSSID,
4925                                   char TID)
4926 {
4927         s32 result = 0;
4928         struct host_if_msg msg;
4929         struct ba_session_info *pBASessionInfo = &msg.body.session_info;
4930
4931         if (!hif_drv) {
4932                 PRINT_ER("driver is null\n");
4933                 return -EFAULT;
4934         }
4935
4936         memset(&msg, 0, sizeof(struct host_if_msg));
4937
4938         msg.id = HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS;
4939
4940         memcpy(pBASessionInfo->au8Bssid, pBSSID, ETH_ALEN);
4941         pBASessionInfo->u8Ted = TID;
4942         msg.drv = hif_drv;
4943
4944         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4945         if (result)
4946                 PRINT_ER("wilc_mq_send fail\n");
4947
4948         down(&hif_sema_wait_response);
4949
4950         return result;
4951 }
4952
4953 s32 host_int_setup_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx)
4954 {
4955         s32 result = 0;
4956         struct host_if_msg msg;
4957
4958         return 0;
4959
4960         if (!hif_drv) {
4961                 PRINT_ER("driver is null\n");
4962                 return -EFAULT;
4963         }
4964
4965         memset(&msg, 0, sizeof(struct host_if_msg));
4966
4967         msg.id = HOST_IF_MSG_SET_IPADDRESS;
4968
4969         msg.body.ip_info.ip_addr = u16ipadd;
4970         msg.drv = hif_drv;
4971         msg.body.ip_info.idx = idx;
4972
4973         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4974         if (result)
4975                 PRINT_ER("wilc_mq_send fail\n");
4976
4977         return result;
4978 }
4979
4980 s32 host_int_get_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx)
4981 {
4982         s32 result = 0;
4983         struct host_if_msg msg;
4984
4985         if (!hif_drv) {
4986                 PRINT_ER("driver is null\n");
4987                 return -EFAULT;
4988         }
4989
4990         memset(&msg, 0, sizeof(struct host_if_msg));
4991
4992         msg.id = HOST_IF_MSG_GET_IPADDRESS;
4993
4994         msg.body.ip_info.ip_addr = u16ipadd;
4995         msg.drv = hif_drv;
4996         msg.body.ip_info.idx = idx;
4997
4998         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4999         if (result)
5000                 PRINT_ER("wilc_mq_send fail\n");
5001
5002         return result;
5003 }