These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / 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 index,
3146                                 u8 mode,
3147                                 enum AUTHTYPE auth_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 = kmemdup(key, len, GFP_KERNEL);
3169         if (!msg.body.key_info.attr.wep.key)
3170                 return -ENOMEM;
3171
3172         msg.body.key_info.attr.wep.key_len = len;
3173         msg.body.key_info.attr.wep.index = index;
3174         msg.body.key_info.attr.wep.mode = mode;
3175         msg.body.key_info.attr.wep.auth_type = auth_type;
3176
3177         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3178
3179         if (result)
3180                 PRINT_ER("Error in sending message queue :WEP Key\n");
3181         down(&hif_drv->hSemTestKeyBlock);
3182
3183         return result;
3184 }
3185
3186 s32 host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *pu8Ptk,
3187                      u8 u8PtkKeylen, const u8 *mac_addr,
3188                      const u8 *pu8RxMic, const u8 *pu8TxMic,
3189                      u8 mode, u8 u8Ciphermode, u8 u8Idx)
3190 {
3191         s32 result = 0;
3192         struct host_if_msg msg;
3193         u8 u8KeyLen = u8PtkKeylen;
3194         u32 i;
3195
3196         if (!hif_drv) {
3197                 PRINT_ER("driver is null\n");
3198                 return -EFAULT;
3199         }
3200
3201         if (pu8RxMic)
3202                 u8KeyLen += RX_MIC_KEY_LEN;
3203
3204         if (pu8TxMic)
3205                 u8KeyLen += TX_MIC_KEY_LEN;
3206
3207         memset(&msg, 0, sizeof(struct host_if_msg));
3208
3209         msg.id = HOST_IF_MSG_KEY;
3210         msg.body.key_info.type = WPAPtk;
3211         if (mode == AP_MODE) {
3212                 msg.body.key_info.action = ADDKEY_AP;
3213                 msg.body.key_info.attr.wpa.index = u8Idx;
3214         }
3215         if (mode == STATION_MODE)
3216                 msg.body.key_info.action = ADDKEY;
3217
3218         msg.body.key_info.attr.wpa.key = kmalloc(u8PtkKeylen, GFP_KERNEL);
3219         memcpy(msg.body.key_info.attr.wpa.key, pu8Ptk, u8PtkKeylen);
3220
3221         if (pu8RxMic) {
3222                 memcpy(msg.body.key_info.attr.wpa.key + 16, pu8RxMic, RX_MIC_KEY_LEN);
3223                 if (INFO) {
3224                         for (i = 0; i < RX_MIC_KEY_LEN; i++)
3225                                 PRINT_INFO(CFG80211_DBG, "PairwiseRx[%d] = %x\n", i, pu8RxMic[i]);
3226                 }
3227         }
3228         if (pu8TxMic) {
3229                 memcpy(msg.body.key_info.attr.wpa.key + 24, pu8TxMic, TX_MIC_KEY_LEN);
3230                 if (INFO) {
3231                         for (i = 0; i < TX_MIC_KEY_LEN; i++)
3232                                 PRINT_INFO(CFG80211_DBG, "PairwiseTx[%d] = %x\n", i, pu8TxMic[i]);
3233                 }
3234         }
3235
3236         msg.body.key_info.attr.wpa.key_len = u8KeyLen;
3237         msg.body.key_info.attr.wpa.mac_addr = mac_addr;
3238         msg.body.key_info.attr.wpa.mode = u8Ciphermode;
3239         msg.drv = hif_drv;
3240
3241         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3242
3243         if (result)
3244                 PRINT_ER("Error in sending message queue:  PTK Key\n");
3245
3246         down(&hif_drv->hSemTestKeyBlock);
3247
3248         return result;
3249 }
3250
3251 s32 host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *pu8RxGtk,
3252                         u8 u8GtkKeylen, u8 u8KeyIdx,
3253                         u32 u32KeyRSClen, const u8 *KeyRSC,
3254                         const u8 *pu8RxMic, const u8 *pu8TxMic,
3255                         u8 mode, u8 u8Ciphermode)
3256 {
3257         s32 result = 0;
3258         struct host_if_msg msg;
3259         u8 u8KeyLen = u8GtkKeylen;
3260
3261         if (!hif_drv) {
3262                 PRINT_ER("driver is null\n");
3263                 return -EFAULT;
3264         }
3265         memset(&msg, 0, sizeof(struct host_if_msg));
3266
3267         if (pu8RxMic)
3268                 u8KeyLen += RX_MIC_KEY_LEN;
3269
3270         if (pu8TxMic)
3271                 u8KeyLen += TX_MIC_KEY_LEN;
3272
3273         if (KeyRSC) {
3274                 msg.body.key_info.attr.wpa.seq = kmalloc(u32KeyRSClen, GFP_KERNEL);
3275                 memcpy(msg.body.key_info.attr.wpa.seq, KeyRSC, u32KeyRSClen);
3276         }
3277
3278         msg.id = HOST_IF_MSG_KEY;
3279         msg.body.key_info.type = WPARxGtk;
3280         msg.drv = hif_drv;
3281
3282         if (mode == AP_MODE) {
3283                 msg.body.key_info.action = ADDKEY_AP;
3284                 msg.body.key_info.attr.wpa.mode = u8Ciphermode;
3285         }
3286         if (mode == STATION_MODE)
3287                 msg.body.key_info.action = ADDKEY;
3288
3289         msg.body.key_info.attr.wpa.key = kmalloc(u8KeyLen, GFP_KERNEL);
3290         memcpy(msg.body.key_info.attr.wpa.key, pu8RxGtk, u8GtkKeylen);
3291
3292         if (pu8RxMic)
3293                 memcpy(msg.body.key_info.attr.wpa.key + 16, pu8RxMic,
3294                        RX_MIC_KEY_LEN);
3295
3296         if (pu8TxMic)
3297                 memcpy(msg.body.key_info.attr.wpa.key + 24, pu8TxMic,
3298                        TX_MIC_KEY_LEN);
3299
3300         msg.body.key_info.attr.wpa.index = u8KeyIdx;
3301         msg.body.key_info.attr.wpa.key_len = u8KeyLen;
3302         msg.body.key_info.attr.wpa.seq_len = u32KeyRSClen;
3303
3304         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3305         if (result)
3306                 PRINT_ER("Error in sending message queue:  RX GTK\n");
3307
3308         down(&hif_drv->hSemTestKeyBlock);
3309
3310         return result;
3311 }
3312
3313 s32 host_int_set_pmkid_info(struct host_if_drv *hif_drv, struct host_if_pmkid_attr *pu8PmkidInfoArray)
3314 {
3315         s32 result = 0;
3316         struct host_if_msg msg;
3317         u32 i;
3318
3319         if (!hif_drv) {
3320                 PRINT_ER("driver is null\n");
3321                 return -EFAULT;
3322         }
3323
3324         memset(&msg, 0, sizeof(struct host_if_msg));
3325
3326         msg.id = HOST_IF_MSG_KEY;
3327         msg.body.key_info.type = PMKSA;
3328         msg.body.key_info.action = ADDKEY;
3329         msg.drv = hif_drv;
3330
3331         for (i = 0; i < pu8PmkidInfoArray->numpmkid; i++) {
3332                 memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].bssid,
3333                        &pu8PmkidInfoArray->pmkidlist[i].bssid, ETH_ALEN);
3334                 memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].pmkid,
3335                        &pu8PmkidInfoArray->pmkidlist[i].pmkid, PMKID_LEN);
3336         }
3337
3338         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3339         if (result)
3340                 PRINT_ER(" Error in sending messagequeue: PMKID Info\n");
3341
3342         return result;
3343 }
3344
3345 s32 host_int_get_pmkid_info(struct host_if_drv *hif_drv,
3346                             u8 *pu8PmkidInfoArray,
3347                             u32 u32PmkidInfoLen)
3348 {
3349         struct wid wid;
3350
3351         wid.id = (u16)WID_PMKID_INFO;
3352         wid.type = WID_STR;
3353         wid.size = u32PmkidInfoLen;
3354         wid.val = pu8PmkidInfoArray;
3355
3356         return 0;
3357 }
3358
3359 s32 host_int_set_RSNAConfigPSKPassPhrase(struct host_if_drv *hif_drv,
3360                                          u8 *pu8PassPhrase,
3361                                          u8 u8Psklength)
3362 {
3363         struct wid wid;
3364
3365         if ((u8Psklength > 7) && (u8Psklength < 65)) {
3366                 wid.id = (u16)WID_11I_PSK;
3367                 wid.type = WID_STR;
3368                 wid.val = pu8PassPhrase;
3369                 wid.size = u8Psklength;
3370         }
3371
3372         return 0;
3373 }
3374
3375 s32 host_int_get_MacAddress(struct host_if_drv *hif_drv, u8 *pu8MacAddress)
3376 {
3377         s32 result = 0;
3378         struct host_if_msg msg;
3379
3380         memset(&msg, 0, sizeof(struct host_if_msg));
3381
3382         msg.id = HOST_IF_MSG_GET_MAC_ADDRESS;
3383         msg.body.get_mac_info.mac_addr = pu8MacAddress;
3384         msg.drv = hif_drv;
3385
3386         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3387         if (result) {
3388                 PRINT_ER("Failed to send get mac address\n");
3389                 return -EFAULT;
3390         }
3391
3392         down(&hif_sema_wait_response);
3393         return result;
3394 }
3395
3396 s32 host_int_set_MacAddress(struct host_if_drv *hif_drv, u8 *pu8MacAddress)
3397 {
3398         s32 result = 0;
3399         struct host_if_msg msg;
3400
3401         PRINT_D(GENERIC_DBG, "mac addr = %x:%x:%x\n", pu8MacAddress[0], pu8MacAddress[1], pu8MacAddress[2]);
3402
3403         memset(&msg, 0, sizeof(struct host_if_msg));
3404         msg.id = HOST_IF_MSG_SET_MAC_ADDRESS;
3405         memcpy(msg.body.set_mac_info.mac_addr, pu8MacAddress, ETH_ALEN);
3406         msg.drv = hif_drv;
3407
3408         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3409         if (result)
3410                 PRINT_ER("Failed to send message queue: Set mac address\n");
3411
3412         return result;
3413 }
3414
3415 s32 host_int_get_RSNAConfigPSKPassPhrase(struct host_if_drv *hif_drv,
3416                                          u8 *pu8PassPhrase, u8 u8Psklength)
3417 {
3418         struct wid wid;
3419
3420         wid.id = (u16)WID_11I_PSK;
3421         wid.type = WID_STR;
3422         wid.size = u8Psklength;
3423         wid.val = pu8PassPhrase;
3424
3425         return 0;
3426 }
3427
3428 s32 host_int_set_start_scan_req(struct host_if_drv *hif_drv, u8 scanSource)
3429 {
3430         struct wid wid;
3431
3432         wid.id = (u16)WID_START_SCAN_REQ;
3433         wid.type = WID_CHAR;
3434         wid.val = (s8 *)&scanSource;
3435         wid.size = sizeof(char);
3436
3437         return 0;
3438 }
3439
3440 s32 host_int_get_start_scan_req(struct host_if_drv *hif_drv, u8 *pu8ScanSource)
3441 {
3442         struct wid wid;
3443
3444         wid.id = (u16)WID_START_SCAN_REQ;
3445         wid.type = WID_CHAR;
3446         wid.val = (s8 *)pu8ScanSource;
3447         wid.size = sizeof(char);
3448
3449         return 0;
3450 }
3451
3452 s32 host_int_set_join_req(struct host_if_drv *hif_drv, u8 *pu8bssid,
3453                           const u8 *pu8ssid, size_t ssidLen,
3454                           const u8 *pu8IEs, size_t IEsLen,
3455                           wilc_connect_result pfConnectResult, void *pvUserArg,
3456                           u8 u8security, enum AUTHTYPE tenuAuth_type,
3457                           u8 u8channel, void *pJoinParams)
3458 {
3459         s32 result = 0;
3460         struct host_if_msg msg;
3461
3462         if (!hif_drv || !pfConnectResult) {
3463                 PRINT_ER("Driver is null\n");
3464                 return -EFAULT;
3465         }
3466
3467         if (!pJoinParams) {
3468                 PRINT_ER("Unable to Join - JoinParams is NULL\n");
3469                 return -EFAULT;
3470         }
3471
3472         memset(&msg, 0, sizeof(struct host_if_msg));
3473
3474         msg.id = HOST_IF_MSG_CONNECT;
3475
3476         msg.body.con_info.security = u8security;
3477         msg.body.con_info.auth_type = tenuAuth_type;
3478         msg.body.con_info.ch = u8channel;
3479         msg.body.con_info.result = pfConnectResult;
3480         msg.body.con_info.arg = pvUserArg;
3481         msg.body.con_info.params = pJoinParams;
3482         msg.drv = hif_drv ;
3483
3484         if (pu8bssid) {
3485                 msg.body.con_info.bssid = kmalloc(6, GFP_KERNEL);
3486                 memcpy(msg.body.con_info.bssid, pu8bssid, 6);
3487         }
3488
3489         if (pu8ssid) {
3490                 msg.body.con_info.ssid_len = ssidLen;
3491                 msg.body.con_info.ssid = kmalloc(ssidLen, GFP_KERNEL);
3492                 memcpy(msg.body.con_info.ssid, pu8ssid, ssidLen);
3493         }
3494
3495         if (pu8IEs) {
3496                 msg.body.con_info.ies_len = IEsLen;
3497                 msg.body.con_info.ies = kmalloc(IEsLen, GFP_KERNEL);
3498                 memcpy(msg.body.con_info.ies, pu8IEs, IEsLen);
3499         }
3500         if (hif_drv->enuHostIFstate < HOST_IF_CONNECTING)
3501                 hif_drv->enuHostIFstate = HOST_IF_CONNECTING;
3502         else
3503                 PRINT_D(GENERIC_DBG, "Don't set state to 'connecting' as state is %d\n", hif_drv->enuHostIFstate);
3504
3505         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3506         if (result) {
3507                 PRINT_ER("Failed to send message queue: Set join request\n");
3508                 return -EFAULT;
3509         }
3510
3511         hif_drv->hConnectTimer.data = (unsigned long)hif_drv;
3512         mod_timer(&hif_drv->hConnectTimer,
3513                   jiffies + msecs_to_jiffies(HOST_IF_CONNECT_TIMEOUT));
3514
3515         return result;
3516 }
3517
3518 s32 host_int_flush_join_req(struct host_if_drv *hif_drv)
3519 {
3520         s32 result = 0;
3521         struct host_if_msg msg;
3522
3523         if (!join_req)
3524                 return -EFAULT;
3525
3526         if (!hif_drv) {
3527                 PRINT_ER("Driver is null\n");
3528                 return -EFAULT;
3529         }
3530
3531         msg.id = HOST_IF_MSG_FLUSH_CONNECT;
3532         msg.drv = hif_drv;
3533
3534         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3535         if (result) {
3536                 PRINT_ER("Failed to send message queue: Flush join request\n");
3537                 return -EFAULT;
3538         }
3539
3540         return result;
3541 }
3542
3543 s32 host_int_disconnect(struct host_if_drv *hif_drv, u16 u16ReasonCode)
3544 {
3545         s32 result = 0;
3546         struct host_if_msg msg;
3547
3548         if (!hif_drv) {
3549                 PRINT_ER("Driver is null\n");
3550                 return -EFAULT;
3551         }
3552
3553         memset(&msg, 0, sizeof(struct host_if_msg));
3554
3555         msg.id = HOST_IF_MSG_DISCONNECT;
3556         msg.drv = hif_drv;
3557
3558         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3559         if (result)
3560                 PRINT_ER("Failed to send message queue: disconnect\n");
3561
3562         down(&hif_drv->hSemTestDisconnectBlock);
3563
3564         return result;
3565 }
3566
3567 s32 host_int_disconnect_station(struct host_if_drv *hif_drv, u8 assoc_id)
3568 {
3569         struct wid wid;
3570
3571         wid.id = (u16)WID_DISCONNECT;
3572         wid.type = WID_CHAR;
3573         wid.val = (s8 *)&assoc_id;
3574         wid.size = sizeof(char);
3575
3576         return 0;
3577 }
3578
3579 s32 host_int_get_assoc_req_info(struct host_if_drv *hif_drv,
3580                                 u8 *pu8AssocReqInfo,
3581                                 u32 u32AssocReqInfoLen)
3582 {
3583         struct wid wid;
3584
3585         wid.id = (u16)WID_ASSOC_REQ_INFO;
3586         wid.type = WID_STR;
3587         wid.val = pu8AssocReqInfo;
3588         wid.size = u32AssocReqInfoLen;
3589
3590         return 0;
3591 }
3592
3593 s32 host_int_get_assoc_res_info(struct host_if_drv *hif_drv,
3594                                 u8 *pu8AssocRespInfo,
3595                                 u32 u32MaxAssocRespInfoLen,
3596                                 u32 *pu32RcvdAssocRespInfoLen)
3597 {
3598         s32 result = 0;
3599         struct wid wid;
3600
3601         if (!hif_drv) {
3602                 PRINT_ER("Driver is null\n");
3603                 return -EFAULT;
3604         }
3605
3606         wid.id = (u16)WID_ASSOC_RES_INFO;
3607         wid.type = WID_STR;
3608         wid.val = pu8AssocRespInfo;
3609         wid.size = u32MaxAssocRespInfoLen;
3610
3611         result = send_config_pkt(GET_CFG, &wid, 1,
3612                                  get_id_from_handler(hif_drv));
3613         if (result) {
3614                 *pu32RcvdAssocRespInfoLen = 0;
3615                 PRINT_ER("Failed to send association response config packet\n");
3616                 return -EINVAL;
3617         } else {
3618                 *pu32RcvdAssocRespInfoLen = wid.size;
3619         }
3620
3621         return result;
3622 }
3623
3624 s32 host_int_get_rx_power_level(struct host_if_drv *hif_drv,
3625                                 u8 *pu8RxPowerLevel,
3626                                 u32 u32RxPowerLevelLen)
3627 {
3628         struct wid wid;
3629
3630         wid.id = (u16)WID_RX_POWER_LEVEL;
3631         wid.type = WID_STR;
3632         wid.val = pu8RxPowerLevel;
3633         wid.size = u32RxPowerLevelLen;
3634
3635         return 0;
3636 }
3637
3638 int host_int_set_mac_chnl_num(struct host_if_drv *hif_drv, u8 channel)
3639 {
3640         int result;
3641         struct host_if_msg msg;
3642
3643         if (!hif_drv) {
3644                 PRINT_ER("driver is null\n");
3645                 return -EFAULT;
3646         }
3647
3648         memset(&msg, 0, sizeof(struct host_if_msg));
3649         msg.id = HOST_IF_MSG_SET_CHANNEL;
3650         msg.body.channel_info.set_ch = channel;
3651         msg.drv = hif_drv;
3652
3653         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3654         if (result) {
3655                 PRINT_ER("wilc mq send fail\n");
3656                 return -EINVAL;
3657         }
3658
3659         return 0;
3660 }
3661
3662 int host_int_wait_msg_queue_idle(void)
3663 {
3664         int result = 0;
3665         struct host_if_msg msg;
3666
3667         memset(&msg, 0, sizeof(struct host_if_msg));
3668         msg.id = HOST_IF_MSG_Q_IDLE;
3669         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3670         if (result) {
3671                 PRINT_ER("wilc mq send fail\n");
3672                 result = -EINVAL;
3673         }
3674
3675         down(&hif_sema_wait_response);
3676
3677         return result;
3678 }
3679
3680 int host_int_set_wfi_drv_handler(struct host_if_drv *hif_drv)
3681 {
3682         int result = 0;
3683         struct host_if_msg msg;
3684
3685         memset(&msg, 0, sizeof(struct host_if_msg));
3686         msg.id = HOST_IF_MSG_SET_WFIDRV_HANDLER;
3687         msg.body.drv.handler = get_id_from_handler(hif_drv);
3688         msg.drv = hif_drv;
3689
3690         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3691         if (result) {
3692                 PRINT_ER("wilc mq send fail\n");
3693                 result = -EINVAL;
3694         }
3695
3696         return result;
3697 }
3698
3699 int host_int_set_operation_mode(struct host_if_drv *hif_drv, u32 mode)
3700 {
3701         int result = 0;
3702         struct host_if_msg msg;
3703
3704         memset(&msg, 0, sizeof(struct host_if_msg));
3705         msg.id = HOST_IF_MSG_SET_OPERATION_MODE;
3706         msg.body.mode.mode = mode;
3707         msg.drv = hif_drv;
3708
3709         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3710         if (result) {
3711                 PRINT_ER("wilc mq send fail\n");
3712                 result = -EINVAL;
3713         }
3714
3715         return result;
3716 }
3717
3718 s32 host_int_get_host_chnl_num(struct host_if_drv *hif_drv, u8 *pu8ChNo)
3719 {
3720         s32 result = 0;
3721         struct host_if_msg msg;
3722
3723         if (!hif_drv) {
3724                 PRINT_ER("driver is null\n");
3725                 return -EFAULT;
3726         }
3727
3728         memset(&msg, 0, sizeof(struct host_if_msg));
3729
3730         msg.id = HOST_IF_MSG_GET_CHNL;
3731         msg.drv = hif_drv;
3732
3733         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3734         if (result)
3735                 PRINT_ER("wilc mq send fail\n");
3736         down(&hif_drv->hSemGetCHNL);
3737
3738         *pu8ChNo = ch_no;
3739
3740         return result;
3741 }
3742
3743 s32 host_int_get_inactive_time(struct host_if_drv *hif_drv,
3744                                const u8 *mac, u32 *pu32InactiveTime)
3745 {
3746         s32 result = 0;
3747         struct host_if_msg msg;
3748
3749         if (!hif_drv) {
3750                 PRINT_ER("driver is null\n");
3751                 return -EFAULT;
3752         }
3753
3754         memset(&msg, 0, sizeof(struct host_if_msg));
3755         memcpy(msg.body.mac_info.mac, mac, ETH_ALEN);
3756
3757         msg.id = HOST_IF_MSG_GET_INACTIVETIME;
3758         msg.drv = hif_drv;
3759
3760         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3761         if (result)
3762                 PRINT_ER("Failed to send get host channel param's message queue ");
3763
3764         down(&hif_drv->hSemInactiveTime);
3765
3766         *pu32InactiveTime = inactive_time;
3767
3768         return result;
3769 }
3770
3771 s32 host_int_test_get_int_wid(struct host_if_drv *hif_drv, u32 *pu32TestMemAddr)
3772 {
3773         s32 result = 0;
3774         struct wid wid;
3775
3776         if (!hif_drv) {
3777                 PRINT_ER("driver is null\n");
3778                 return -EFAULT;
3779         }
3780
3781         wid.id = (u16)WID_MEMORY_ADDRESS;
3782         wid.type = WID_INT;
3783         wid.val = (s8 *)pu32TestMemAddr;
3784         wid.size = sizeof(u32);
3785
3786         result = send_config_pkt(GET_CFG, &wid, 1,
3787                                  get_id_from_handler(hif_drv));
3788
3789         if (result) {
3790                 PRINT_ER("Failed to get wid value\n");
3791                 return -EINVAL;
3792         } else {
3793                 PRINT_D(HOSTINF_DBG, "Successfully got wid value\n");
3794         }
3795
3796         return result;
3797 }
3798
3799 s32 host_int_get_rssi(struct host_if_drv *hif_drv, s8 *ps8Rssi)
3800 {
3801         s32 result = 0;
3802         struct host_if_msg msg;
3803
3804         memset(&msg, 0, sizeof(struct host_if_msg));
3805         msg.id = HOST_IF_MSG_GET_RSSI;
3806         msg.drv = hif_drv;
3807
3808         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3809         if (result) {
3810                 PRINT_ER("Failed to send get host channel param's message queue ");
3811                 return -EFAULT;
3812         }
3813
3814         down(&hif_drv->hSemGetRSSI);
3815
3816         if (!ps8Rssi) {
3817                 PRINT_ER("RSS pointer value is null");
3818                 return -EFAULT;
3819         }
3820
3821         *ps8Rssi = rssi;
3822
3823         return result;
3824 }
3825
3826 s32 host_int_get_link_speed(struct host_if_drv *hif_drv, s8 *ps8lnkspd)
3827 {
3828         struct host_if_msg msg;
3829         s32 result = 0;
3830
3831         memset(&msg, 0, sizeof(struct host_if_msg));
3832         msg.id = HOST_IF_MSG_GET_LINKSPEED;
3833         msg.drv = hif_drv;
3834
3835         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3836         if (result) {
3837                 PRINT_ER("Failed to send GET_LINKSPEED to message queue ");
3838                 return -EFAULT;
3839         }
3840
3841         down(&hif_drv->hSemGetLINKSPEED);
3842
3843         if (!ps8lnkspd) {
3844                 PRINT_ER("LINKSPEED pointer value is null");
3845                 return -EFAULT;
3846         }
3847
3848         *ps8lnkspd = link_speed;
3849
3850         return result;
3851 }
3852
3853 s32 host_int_get_statistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatistics)
3854 {
3855         s32 result = 0;
3856         struct host_if_msg msg;
3857
3858         memset(&msg, 0, sizeof(struct host_if_msg));
3859         msg.id = HOST_IF_MSG_GET_STATISTICS;
3860         msg.body.data = (char *)pstrStatistics;
3861         msg.drv = hif_drv;
3862
3863         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3864         if (result) {
3865                 PRINT_ER("Failed to send get host channel param's message queue ");
3866                 return -EFAULT;
3867         }
3868
3869         down(&hif_sema_wait_response);
3870         return result;
3871 }
3872
3873 s32 host_int_scan(struct host_if_drv *hif_drv, u8 u8ScanSource,
3874                   u8 u8ScanType, u8 *pu8ChnlFreqList,
3875                   u8 u8ChnlListLen, const u8 *pu8IEs,
3876                   size_t IEsLen, wilc_scan_result ScanResult,
3877                   void *pvUserArg, struct hidden_network *pstrHiddenNetwork)
3878 {
3879         s32 result = 0;
3880         struct host_if_msg msg;
3881
3882         if (!hif_drv || !ScanResult) {
3883                 PRINT_ER("hif_drv or ScanResult = NULL\n");
3884                 return -EFAULT;
3885         }
3886
3887         memset(&msg, 0, sizeof(struct host_if_msg));
3888
3889         msg.id = HOST_IF_MSG_SCAN;
3890
3891         if (pstrHiddenNetwork) {
3892                 msg.body.scan_info.hidden_network.pstrHiddenNetworkInfo = pstrHiddenNetwork->pstrHiddenNetworkInfo;
3893                 msg.body.scan_info.hidden_network.u8ssidnum = pstrHiddenNetwork->u8ssidnum;
3894
3895         } else
3896                 PRINT_D(HOSTINF_DBG, "pstrHiddenNetwork IS EQUAL TO NULL\n");
3897
3898         msg.drv = hif_drv;
3899         msg.body.scan_info.src = u8ScanSource;
3900         msg.body.scan_info.type = u8ScanType;
3901         msg.body.scan_info.result = ScanResult;
3902         msg.body.scan_info.arg = pvUserArg;
3903
3904         msg.body.scan_info.ch_list_len = u8ChnlListLen;
3905         msg.body.scan_info.ch_freq_list = kmalloc(u8ChnlListLen, GFP_KERNEL);
3906         memcpy(msg.body.scan_info.ch_freq_list, pu8ChnlFreqList, u8ChnlListLen);
3907
3908         msg.body.scan_info.ies_len = IEsLen;
3909         msg.body.scan_info.ies = kmalloc(IEsLen, GFP_KERNEL);
3910         memcpy(msg.body.scan_info.ies, pu8IEs, IEsLen);
3911
3912         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3913         if (result) {
3914                 PRINT_ER("Error in sending message queue\n");
3915                 return -EINVAL;
3916         }
3917
3918         PRINT_D(HOSTINF_DBG, ">> Starting the SCAN timer\n");
3919         hif_drv->hScanTimer.data = (unsigned long)hif_drv;
3920         mod_timer(&hif_drv->hScanTimer,
3921                   jiffies + msecs_to_jiffies(HOST_IF_SCAN_TIMEOUT));
3922
3923         return result;
3924 }
3925
3926 s32 hif_set_cfg(struct host_if_drv *hif_drv,
3927                 struct cfg_param_val *pstrCfgParamVal)
3928 {
3929         s32 result = 0;
3930         struct host_if_msg msg;
3931
3932         if (!hif_drv) {
3933                 PRINT_ER("hif_drv NULL\n");
3934                 return -EFAULT;
3935         }
3936
3937         memset(&msg, 0, sizeof(struct host_if_msg));
3938         msg.id = HOST_IF_MSG_CFG_PARAMS;
3939         msg.body.cfg_info.cfg_attr_info = *pstrCfgParamVal;
3940         msg.drv = hif_drv;
3941
3942         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3943
3944         return result;
3945 }
3946
3947 s32 hif_get_cfg(struct host_if_drv *hif_drv, u16 u16WID, u16 *pu16WID_Value)
3948 {
3949         s32 result = 0;
3950
3951         down(&hif_drv->gtOsCfgValuesSem);
3952
3953         if (!hif_drv) {
3954                 PRINT_ER("hif_drv NULL\n");
3955                 return -EFAULT;
3956         }
3957         PRINT_D(HOSTINF_DBG, "Getting configuration parameters\n");
3958         switch (u16WID) {
3959         case WID_BSS_TYPE:
3960                 *pu16WID_Value = (u16)hif_drv->strCfgValues.bss_type;
3961                 break;
3962
3963         case WID_AUTH_TYPE:
3964                 *pu16WID_Value = (u16)hif_drv->strCfgValues.auth_type;
3965                 break;
3966
3967         case WID_AUTH_TIMEOUT:
3968                 *pu16WID_Value = hif_drv->strCfgValues.auth_timeout;
3969                 break;
3970
3971         case WID_POWER_MANAGEMENT:
3972                 *pu16WID_Value = (u16)hif_drv->strCfgValues.power_mgmt_mode;
3973                 break;
3974
3975         case WID_SHORT_RETRY_LIMIT:
3976                 *pu16WID_Value =       hif_drv->strCfgValues.short_retry_limit;
3977                 break;
3978
3979         case WID_LONG_RETRY_LIMIT:
3980                 *pu16WID_Value = hif_drv->strCfgValues.long_retry_limit;
3981                 break;
3982
3983         case WID_FRAG_THRESHOLD:
3984                 *pu16WID_Value = hif_drv->strCfgValues.frag_threshold;
3985                 break;
3986
3987         case WID_RTS_THRESHOLD:
3988                 *pu16WID_Value = hif_drv->strCfgValues.rts_threshold;
3989                 break;
3990
3991         case WID_PREAMBLE:
3992                 *pu16WID_Value = (u16)hif_drv->strCfgValues.preamble_type;
3993                 break;
3994
3995         case WID_SHORT_SLOT_ALLOWED:
3996                 *pu16WID_Value = (u16) hif_drv->strCfgValues.short_slot_allowed;
3997                 break;
3998
3999         case WID_11N_TXOP_PROT_DISABLE:
4000                 *pu16WID_Value = (u16)hif_drv->strCfgValues.txop_prot_disabled;
4001                 break;
4002
4003         case WID_BEACON_INTERVAL:
4004                 *pu16WID_Value = hif_drv->strCfgValues.beacon_interval;
4005                 break;
4006
4007         case WID_DTIM_PERIOD:
4008                 *pu16WID_Value = (u16)hif_drv->strCfgValues.dtim_period;
4009                 break;
4010
4011         case WID_SITE_SURVEY:
4012                 *pu16WID_Value = (u16)hif_drv->strCfgValues.site_survey_enabled;
4013                 break;
4014
4015         case WID_SITE_SURVEY_SCAN_TIME:
4016                 *pu16WID_Value = hif_drv->strCfgValues.site_survey_scan_time;
4017                 break;
4018
4019         case WID_ACTIVE_SCAN_TIME:
4020                 *pu16WID_Value = hif_drv->strCfgValues.active_scan_time;
4021                 break;
4022
4023         case WID_PASSIVE_SCAN_TIME:
4024                 *pu16WID_Value = hif_drv->strCfgValues.passive_scan_time;
4025                 break;
4026
4027         case WID_CURRENT_TX_RATE:
4028                 *pu16WID_Value = hif_drv->strCfgValues.curr_tx_rate;
4029                 break;
4030
4031         default:
4032                 break;
4033         }
4034
4035         up(&hif_drv->gtOsCfgValuesSem);
4036
4037         return result;
4038 }
4039
4040 static void GetPeriodicRSSI(unsigned long arg)
4041 {
4042         struct host_if_drv *hif_drv = (struct host_if_drv *)arg;
4043
4044         if (!hif_drv)   {
4045                 PRINT_ER("Driver handler is NULL\n");
4046                 return;
4047         }
4048
4049         if (hif_drv->enuHostIFstate == HOST_IF_CONNECTED) {
4050                 s32 result = 0;
4051                 struct host_if_msg msg;
4052
4053                 memset(&msg, 0, sizeof(struct host_if_msg));
4054
4055                 msg.id = HOST_IF_MSG_GET_RSSI;
4056                 msg.drv = hif_drv;
4057
4058                 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4059                 if (result) {
4060                         PRINT_ER("Failed to send get host channel param's message queue ");
4061                         return;
4062                 }
4063         }
4064         periodic_rssi.data = (unsigned long)hif_drv;
4065         mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
4066 }
4067
4068 s32 host_int_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
4069 {
4070         s32 result = 0;
4071         struct host_if_drv *hif_drv;
4072         int err;
4073         perInterface_wlan_t *nic;
4074         struct wilc *wilc;
4075
4076         nic = netdev_priv(dev);
4077         wilc = nic->wilc;
4078
4079         PRINT_D(HOSTINF_DBG, "Initializing host interface for client %d\n", clients_count + 1);
4080
4081         scan_while_connected = false;
4082
4083         sema_init(&hif_sema_wait_response, 0);
4084
4085         hif_drv  = kzalloc(sizeof(struct host_if_drv), GFP_KERNEL);
4086         if (!hif_drv) {
4087                 result = -ENOMEM;
4088                 goto _fail_;
4089         }
4090         *hif_drv_handler = hif_drv;
4091         err = add_handler_in_list(hif_drv);
4092         if (err) {
4093                 result = -EFAULT;
4094                 goto _fail_timer_2;
4095         }
4096
4097         g_obtainingIP = false;
4098
4099         PRINT_D(HOSTINF_DBG, "Global handle pointer value=%p\n", hif_drv);
4100         if (clients_count == 0) {
4101                 sema_init(&hif_sema_thread, 0);
4102                 sema_init(&hif_sema_driver, 0);
4103                 sema_init(&hif_sema_deinit, 1);
4104         }
4105
4106         sema_init(&hif_drv->hSemTestKeyBlock, 0);
4107         sema_init(&hif_drv->hSemTestDisconnectBlock, 0);
4108         sema_init(&hif_drv->hSemGetRSSI, 0);
4109         sema_init(&hif_drv->hSemGetLINKSPEED, 0);
4110         sema_init(&hif_drv->hSemGetCHNL, 0);
4111         sema_init(&hif_drv->hSemInactiveTime, 0);
4112
4113         PRINT_D(HOSTINF_DBG, "INIT: CLIENT COUNT %d\n", clients_count);
4114
4115         if (clients_count == 0) {
4116                 result = wilc_mq_create(&hif_msg_q);
4117
4118                 if (result < 0) {
4119                         PRINT_ER("Failed to creat MQ\n");
4120                         goto _fail_;
4121                 }
4122
4123                 hif_thread_handler = kthread_run(hostIFthread, wilc,
4124                                                  "WILC_kthread");
4125
4126                 if (IS_ERR(hif_thread_handler)) {
4127                         PRINT_ER("Failed to creat Thread\n");
4128                         result = -EFAULT;
4129                         goto _fail_mq_;
4130                 }
4131                 setup_timer(&periodic_rssi, GetPeriodicRSSI,
4132                             (unsigned long)hif_drv);
4133                 mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
4134         }
4135
4136         setup_timer(&hif_drv->hScanTimer, TimerCB_Scan, 0);
4137
4138         setup_timer(&hif_drv->hConnectTimer, TimerCB_Connect, 0);
4139
4140         setup_timer(&hif_drv->hRemainOnChannel, ListenTimerCB, 0);
4141
4142         sema_init(&hif_drv->gtOsCfgValuesSem, 1);
4143         down(&hif_drv->gtOsCfgValuesSem);
4144
4145         hif_drv->enuHostIFstate = HOST_IF_IDLE;
4146         hif_drv->strCfgValues.site_survey_enabled = SITE_SURVEY_OFF;
4147         hif_drv->strCfgValues.scan_source = DEFAULT_SCAN;
4148         hif_drv->strCfgValues.active_scan_time = ACTIVE_SCAN_TIME;
4149         hif_drv->strCfgValues.passive_scan_time = PASSIVE_SCAN_TIME;
4150         hif_drv->strCfgValues.curr_tx_rate = AUTORATE;
4151
4152         hif_drv->u64P2p_MgmtTimeout = 0;
4153
4154         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",
4155
4156                    hif_drv->strCfgValues.site_survey_enabled, hif_drv->strCfgValues.scan_source,
4157                    hif_drv->strCfgValues.active_scan_time, hif_drv->strCfgValues.passive_scan_time,
4158                    hif_drv->strCfgValues.curr_tx_rate);
4159
4160         up(&hif_drv->gtOsCfgValuesSem);
4161
4162         clients_count++;
4163
4164         return result;
4165
4166 _fail_timer_2:
4167         up(&hif_drv->gtOsCfgValuesSem);
4168         del_timer_sync(&hif_drv->hConnectTimer);
4169         del_timer_sync(&hif_drv->hScanTimer);
4170         kthread_stop(hif_thread_handler);
4171 _fail_mq_:
4172         wilc_mq_destroy(&hif_msg_q);
4173 _fail_:
4174         return result;
4175 }
4176
4177 s32 host_int_deinit(struct host_if_drv *hif_drv)
4178 {
4179         s32 result = 0;
4180         struct host_if_msg msg;
4181         int ret;
4182
4183         if (!hif_drv)   {
4184                 PRINT_ER("hif_drv = NULL\n");
4185                 return 0;
4186         }
4187
4188         down(&hif_sema_deinit);
4189
4190         terminated_handle = hif_drv;
4191         PRINT_D(HOSTINF_DBG, "De-initializing host interface for client %d\n", clients_count);
4192
4193         if (del_timer_sync(&hif_drv->hScanTimer))
4194                 PRINT_D(HOSTINF_DBG, ">> Scan timer is active\n");
4195
4196         if (del_timer_sync(&hif_drv->hConnectTimer))
4197                 PRINT_D(HOSTINF_DBG, ">> Connect timer is active\n");
4198
4199         if (del_timer_sync(&periodic_rssi))
4200                 PRINT_D(HOSTINF_DBG, ">> Connect timer is active\n");
4201
4202         del_timer_sync(&hif_drv->hRemainOnChannel);
4203
4204         host_int_set_wfi_drv_handler(NULL);
4205         down(&hif_sema_driver);
4206
4207         if (hif_drv->usr_scan_req.pfUserScanResult) {
4208                 hif_drv->usr_scan_req.pfUserScanResult(SCAN_EVENT_ABORTED, NULL,
4209                                                        hif_drv->usr_scan_req.u32UserScanPvoid, NULL);
4210
4211                 hif_drv->usr_scan_req.pfUserScanResult = NULL;
4212         }
4213
4214         hif_drv->enuHostIFstate = HOST_IF_IDLE;
4215
4216         scan_while_connected = false;
4217
4218         memset(&msg, 0, sizeof(struct host_if_msg));
4219
4220         if (clients_count == 1) {
4221                 if (del_timer_sync(&periodic_rssi))
4222                         PRINT_D(HOSTINF_DBG, ">> Connect timer is active\n");
4223
4224                 msg.id = HOST_IF_MSG_EXIT;
4225                 msg.drv = hif_drv;
4226
4227                 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4228                 if (result != 0)
4229                         PRINT_ER("Error in sending deinit's message queue message function: Error(%d)\n", result);
4230
4231                 down(&hif_sema_thread);
4232
4233                 wilc_mq_destroy(&hif_msg_q);
4234         }
4235
4236         down(&hif_drv->gtOsCfgValuesSem);
4237
4238         ret = remove_handler_in_list(hif_drv);
4239         if (ret)
4240                 result = -ENOENT;
4241
4242         kfree(hif_drv);
4243
4244         clients_count--;
4245         terminated_handle = NULL;
4246         up(&hif_sema_deinit);
4247         return result;
4248 }
4249
4250 void NetworkInfoReceived(u8 *pu8Buffer, u32 u32Length)
4251 {
4252         s32 result = 0;
4253         struct host_if_msg msg;
4254         int id;
4255         struct host_if_drv *hif_drv = NULL;
4256
4257         id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
4258         hif_drv = get_handler_from_id(id);
4259
4260         if (!hif_drv || hif_drv == terminated_handle)   {
4261                 PRINT_ER("NetworkInfo received but driver not init[%p]\n", hif_drv);
4262                 return;
4263         }
4264
4265         memset(&msg, 0, sizeof(struct host_if_msg));
4266
4267         msg.id = HOST_IF_MSG_RCVD_NTWRK_INFO;
4268         msg.drv = hif_drv;
4269
4270         msg.body.net_info.len = u32Length;
4271         msg.body.net_info.buffer = kmalloc(u32Length, GFP_KERNEL);
4272         memcpy(msg.body.net_info.buffer, pu8Buffer, u32Length);
4273
4274         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4275         if (result)
4276                 PRINT_ER("Error in sending network info message queue message parameters: Error(%d)\n", result);
4277 }
4278
4279 void GnrlAsyncInfoReceived(u8 *pu8Buffer, u32 u32Length)
4280 {
4281         s32 result = 0;
4282         struct host_if_msg msg;
4283         int id;
4284         struct host_if_drv *hif_drv = NULL;
4285
4286         down(&hif_sema_deinit);
4287
4288         id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
4289         hif_drv = get_handler_from_id(id);
4290         PRINT_D(HOSTINF_DBG, "General asynchronous info packet received\n");
4291
4292         if (!hif_drv || hif_drv == terminated_handle) {
4293                 PRINT_D(HOSTINF_DBG, "Wifi driver handler is equal to NULL\n");
4294                 up(&hif_sema_deinit);
4295                 return;
4296         }
4297
4298         if (!hif_drv->usr_conn_req.pfUserConnectResult) {
4299                 PRINT_ER("Received mac status is not needed when there is no current Connect Reques\n");
4300                 up(&hif_sema_deinit);
4301                 return;
4302         }
4303
4304         memset(&msg, 0, sizeof(struct host_if_msg));
4305
4306         msg.id = HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO;
4307         msg.drv = hif_drv;
4308
4309         msg.body.async_info.len = u32Length;
4310         msg.body.async_info.buffer = kmalloc(u32Length, GFP_KERNEL);
4311         memcpy(msg.body.async_info.buffer, pu8Buffer, u32Length);
4312
4313         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4314         if (result)
4315                 PRINT_ER("Error in sending message queue asynchronous message info: Error(%d)\n", result);
4316
4317         up(&hif_sema_deinit);
4318 }
4319
4320 void host_int_ScanCompleteReceived(u8 *pu8Buffer, u32 u32Length)
4321 {
4322         s32 result = 0;
4323         struct host_if_msg msg;
4324         int id;
4325         struct host_if_drv *hif_drv = NULL;
4326
4327         id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
4328         hif_drv = get_handler_from_id(id);
4329
4330         PRINT_D(GENERIC_DBG, "Scan notification received %p\n", hif_drv);
4331
4332         if (!hif_drv || hif_drv == terminated_handle)
4333                 return;
4334
4335         if (hif_drv->usr_scan_req.pfUserScanResult) {
4336                 memset(&msg, 0, sizeof(struct host_if_msg));
4337
4338                 msg.id = HOST_IF_MSG_RCVD_SCAN_COMPLETE;
4339                 msg.drv = hif_drv;
4340
4341                 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4342                 if (result)
4343                         PRINT_ER("Error in sending message queue scan complete parameters: Error(%d)\n", result);
4344         }
4345
4346         return;
4347 }
4348
4349 s32 host_int_remain_on_channel(struct host_if_drv *hif_drv, u32 u32SessionID,
4350                                u32 u32duration, u16 chan,
4351                                wilc_remain_on_chan_expired RemainOnChanExpired,
4352                                wilc_remain_on_chan_ready RemainOnChanReady,
4353                                void *pvUserArg)
4354 {
4355         s32 result = 0;
4356         struct host_if_msg msg;
4357
4358         if (!hif_drv) {
4359                 PRINT_ER("driver is null\n");
4360                 return -EFAULT;
4361         }
4362
4363         memset(&msg, 0, sizeof(struct host_if_msg));
4364
4365         msg.id = HOST_IF_MSG_REMAIN_ON_CHAN;
4366         msg.body.remain_on_ch.u16Channel = chan;
4367         msg.body.remain_on_ch.pRemainOnChanExpired = RemainOnChanExpired;
4368         msg.body.remain_on_ch.pRemainOnChanReady = RemainOnChanReady;
4369         msg.body.remain_on_ch.pVoid = pvUserArg;
4370         msg.body.remain_on_ch.u32duration = u32duration;
4371         msg.body.remain_on_ch.u32ListenSessionID = u32SessionID;
4372         msg.drv = hif_drv;
4373
4374         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4375         if (result)
4376                 PRINT_ER("wilc mq send fail\n");
4377
4378         return result;
4379 }
4380
4381 s32 host_int_ListenStateExpired(struct host_if_drv *hif_drv, u32 u32SessionID)
4382 {
4383         s32 result = 0;
4384         struct host_if_msg msg;
4385
4386         if (!hif_drv) {
4387                 PRINT_ER("driver is null\n");
4388                 return -EFAULT;
4389         }
4390
4391         del_timer(&hif_drv->hRemainOnChannel);
4392
4393         memset(&msg, 0, sizeof(struct host_if_msg));
4394         msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
4395         msg.drv = hif_drv;
4396         msg.body.remain_on_ch.u32ListenSessionID = u32SessionID;
4397
4398         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4399         if (result)
4400                 PRINT_ER("wilc mq send fail\n");
4401
4402         return result;
4403 }
4404
4405 s32 host_int_frame_register(struct host_if_drv *hif_drv, u16 u16FrameType, bool bReg)
4406 {
4407         s32 result = 0;
4408         struct host_if_msg msg;
4409
4410         if (!hif_drv) {
4411                 PRINT_ER("driver is null\n");
4412                 return -EFAULT;
4413         }
4414
4415         memset(&msg, 0, sizeof(struct host_if_msg));
4416
4417         msg.id = HOST_IF_MSG_REGISTER_FRAME;
4418         switch (u16FrameType) {
4419         case ACTION:
4420                 PRINT_D(HOSTINF_DBG, "ACTION\n");
4421                 msg.body.reg_frame.u8Regid = ACTION_FRM_IDX;
4422                 break;
4423
4424         case PROBE_REQ:
4425                 PRINT_D(HOSTINF_DBG, "PROBE REQ\n");
4426                 msg.body.reg_frame.u8Regid = PROBE_REQ_IDX;
4427                 break;
4428
4429         default:
4430                 PRINT_D(HOSTINF_DBG, "Not valid frame type\n");
4431                 break;
4432         }
4433         msg.body.reg_frame.u16FrameType = u16FrameType;
4434         msg.body.reg_frame.bReg = bReg;
4435         msg.drv = hif_drv;
4436
4437         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4438         if (result)
4439                 PRINT_ER("wilc mq send fail\n");
4440
4441         return result;
4442 }
4443
4444 s32 host_int_add_beacon(struct host_if_drv *hif_drv, u32 u32Interval,
4445                         u32 u32DTIMPeriod, u32 u32HeadLen, u8 *pu8Head,
4446                         u32 u32TailLen, u8 *pu8Tail)
4447 {
4448         s32 result = 0;
4449         struct host_if_msg msg;
4450         struct beacon_attr *pstrSetBeaconParam = &msg.body.beacon_info;
4451
4452         if (!hif_drv) {
4453                 PRINT_ER("driver is null\n");
4454                 return -EFAULT;
4455         }
4456
4457         memset(&msg, 0, sizeof(struct host_if_msg));
4458
4459         PRINT_D(HOSTINF_DBG, "Setting adding beacon message queue params\n");
4460
4461         msg.id = HOST_IF_MSG_ADD_BEACON;
4462         msg.drv = hif_drv;
4463         pstrSetBeaconParam->interval = u32Interval;
4464         pstrSetBeaconParam->dtim_period = u32DTIMPeriod;
4465         pstrSetBeaconParam->head_len = u32HeadLen;
4466         pstrSetBeaconParam->head = kmemdup(pu8Head, u32HeadLen, GFP_KERNEL);
4467         if (!pstrSetBeaconParam->head) {
4468                 result = -ENOMEM;
4469                 goto ERRORHANDLER;
4470         }
4471         pstrSetBeaconParam->tail_len = u32TailLen;
4472
4473         if (u32TailLen > 0) {
4474                 pstrSetBeaconParam->tail = kmemdup(pu8Tail, u32TailLen,
4475                                                    GFP_KERNEL);
4476                 if (!pstrSetBeaconParam->tail) {
4477                         result = -ENOMEM;
4478                         goto ERRORHANDLER;
4479                 }
4480         } else {
4481                 pstrSetBeaconParam->tail = NULL;
4482         }
4483
4484         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4485         if (result)
4486                 PRINT_ER("wilc mq send fail\n");
4487
4488 ERRORHANDLER:
4489         if (result) {
4490                 kfree(pstrSetBeaconParam->head);
4491
4492                 kfree(pstrSetBeaconParam->tail);
4493         }
4494
4495         return result;
4496 }
4497
4498 s32 host_int_del_beacon(struct host_if_drv *hif_drv)
4499 {
4500         s32 result = 0;
4501         struct host_if_msg msg;
4502
4503         if (!hif_drv) {
4504                 PRINT_ER("driver is null\n");
4505                 return -EFAULT;
4506         }
4507
4508         msg.id = HOST_IF_MSG_DEL_BEACON;
4509         msg.drv = hif_drv;
4510         PRINT_D(HOSTINF_DBG, "Setting deleting beacon message queue params\n");
4511
4512         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4513         if (result)
4514                 PRINT_ER("wilc_mq_send fail\n");
4515
4516         return result;
4517 }
4518
4519 s32 host_int_add_station(struct host_if_drv *hif_drv,
4520                          struct add_sta_param *pstrStaParams)
4521 {
4522         s32 result = 0;
4523         struct host_if_msg msg;
4524         struct add_sta_param *pstrAddStationMsg = &msg.body.add_sta_info;
4525
4526         if (!hif_drv) {
4527                 PRINT_ER("driver is null\n");
4528                 return -EFAULT;
4529         }
4530
4531         memset(&msg, 0, sizeof(struct host_if_msg));
4532
4533         PRINT_D(HOSTINF_DBG, "Setting adding station message queue params\n");
4534
4535         msg.id = HOST_IF_MSG_ADD_STATION;
4536         msg.drv = hif_drv;
4537
4538         memcpy(pstrAddStationMsg, pstrStaParams, sizeof(struct add_sta_param));
4539         if (pstrAddStationMsg->u8NumRates > 0) {
4540                 u8 *rates = kmalloc(pstrAddStationMsg->u8NumRates, GFP_KERNEL);
4541
4542                 if (!rates)
4543                         return -ENOMEM;
4544
4545                 memcpy(rates, pstrStaParams->pu8Rates, pstrAddStationMsg->u8NumRates);
4546                 pstrAddStationMsg->pu8Rates = rates;
4547         }
4548
4549         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4550         if (result)
4551                 PRINT_ER("wilc_mq_send fail\n");
4552         return result;
4553 }
4554
4555 s32 host_int_del_station(struct host_if_drv *hif_drv, const u8 *pu8MacAddr)
4556 {
4557         s32 result = 0;
4558         struct host_if_msg msg;
4559         struct del_sta *pstrDelStationMsg = &msg.body.del_sta_info;
4560
4561         if (!hif_drv) {
4562                 PRINT_ER("driver is null\n");
4563                 return -EFAULT;
4564         }
4565
4566         memset(&msg, 0, sizeof(struct host_if_msg));
4567
4568         PRINT_D(HOSTINF_DBG, "Setting deleting station message queue params\n");
4569
4570         msg.id = HOST_IF_MSG_DEL_STATION;
4571         msg.drv = hif_drv;
4572
4573         if (!pu8MacAddr)
4574                 eth_broadcast_addr(pstrDelStationMsg->mac_addr);
4575         else
4576                 memcpy(pstrDelStationMsg->mac_addr, pu8MacAddr, ETH_ALEN);
4577
4578         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4579         if (result)
4580                 PRINT_ER("wilc_mq_send fail\n");
4581         return result;
4582 }
4583
4584 s32 host_int_del_allstation(struct host_if_drv *hif_drv,
4585                             u8 pu8MacAddr[][ETH_ALEN])
4586 {
4587         s32 result = 0;
4588         struct host_if_msg msg;
4589         struct del_all_sta *pstrDelAllStationMsg = &msg.body.del_all_sta_info;
4590         u8 au8Zero_Buff[ETH_ALEN] = {0};
4591         u32 i;
4592         u8 u8AssocNumb = 0;
4593
4594         if (!hif_drv) {
4595                 PRINT_ER("driver is null\n");
4596                 return -EFAULT;
4597         }
4598
4599         memset(&msg, 0, sizeof(struct host_if_msg));
4600
4601         PRINT_D(HOSTINF_DBG, "Setting deauthenticating station message queue params\n");
4602
4603         msg.id = HOST_IF_MSG_DEL_ALL_STA;
4604         msg.drv = hif_drv;
4605
4606         for (i = 0; i < MAX_NUM_STA; i++) {
4607                 if (memcmp(pu8MacAddr[i], au8Zero_Buff, ETH_ALEN)) {
4608                         memcpy(pstrDelAllStationMsg->del_all_sta[i], pu8MacAddr[i], ETH_ALEN);
4609                         PRINT_D(CFG80211_DBG, "BSSID = %x%x%x%x%x%x\n",
4610                                 pstrDelAllStationMsg->del_all_sta[i][0],
4611                                 pstrDelAllStationMsg->del_all_sta[i][1],
4612                                 pstrDelAllStationMsg->del_all_sta[i][2],
4613                                 pstrDelAllStationMsg->del_all_sta[i][3],
4614                                 pstrDelAllStationMsg->del_all_sta[i][4],
4615                                 pstrDelAllStationMsg->del_all_sta[i][5]);
4616                         u8AssocNumb++;
4617                 }
4618         }
4619         if (!u8AssocNumb) {
4620                 PRINT_D(CFG80211_DBG, "NO ASSOCIATED STAS\n");
4621                 return result;
4622         }
4623
4624         pstrDelAllStationMsg->assoc_sta = u8AssocNumb;
4625         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4626
4627         if (result)
4628                 PRINT_ER("wilc_mq_send fail\n");
4629
4630         down(&hif_sema_wait_response);
4631
4632         return result;
4633 }
4634
4635 s32 host_int_edit_station(struct host_if_drv *hif_drv,
4636                           struct add_sta_param *pstrStaParams)
4637 {
4638         s32 result = 0;
4639         struct host_if_msg msg;
4640         struct add_sta_param *pstrAddStationMsg = &msg.body.add_sta_info;
4641
4642         if (!hif_drv) {
4643                 PRINT_ER("driver is null\n");
4644                 return -EFAULT;
4645         }
4646
4647         PRINT_D(HOSTINF_DBG, "Setting editing station message queue params\n");
4648
4649         memset(&msg, 0, sizeof(struct host_if_msg));
4650
4651         msg.id = HOST_IF_MSG_EDIT_STATION;
4652         msg.drv = hif_drv;
4653
4654         memcpy(pstrAddStationMsg, pstrStaParams, sizeof(struct add_sta_param));
4655         if (pstrAddStationMsg->u8NumRates > 0) {
4656                 u8 *rates = kmalloc(pstrAddStationMsg->u8NumRates, GFP_KERNEL);
4657
4658                 if (!rates)
4659                         return -ENOMEM;
4660
4661                 memcpy(rates, pstrStaParams->pu8Rates, pstrAddStationMsg->u8NumRates);
4662                 pstrAddStationMsg->pu8Rates = rates;
4663         }
4664
4665         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4666         if (result)
4667                 PRINT_ER("wilc_mq_send fail\n");
4668
4669         return result;
4670 }
4671
4672 s32 host_int_set_power_mgmt(struct host_if_drv *hif_drv,
4673                             bool bIsEnabled,
4674                             u32 u32Timeout)
4675 {
4676         s32 result = 0;
4677         struct host_if_msg msg;
4678         struct power_mgmt_param *pstrPowerMgmtParam = &msg.body.pwr_mgmt_info;
4679
4680         PRINT_INFO(HOSTINF_DBG, "\n\n>> Setting PS to %d <<\n\n", bIsEnabled);
4681
4682         if (!hif_drv) {
4683                 PRINT_ER("driver is null\n");
4684                 return -EFAULT;
4685         }
4686
4687         PRINT_D(HOSTINF_DBG, "Setting Power management message queue params\n");
4688
4689         memset(&msg, 0, sizeof(struct host_if_msg));
4690
4691         msg.id = HOST_IF_MSG_POWER_MGMT;
4692         msg.drv = hif_drv;
4693
4694         pstrPowerMgmtParam->enabled = bIsEnabled;
4695         pstrPowerMgmtParam->timeout = u32Timeout;
4696
4697         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4698         if (result)
4699                 PRINT_ER("wilc_mq_send fail\n");
4700         return result;
4701 }
4702
4703 s32 host_int_setup_multicast_filter(struct host_if_drv *hif_drv,
4704                                     bool bIsEnabled,
4705                                     u32 u32count)
4706 {
4707         s32 result = 0;
4708         struct host_if_msg msg;
4709         struct set_multicast *pstrMulticastFilterParam = &msg.body.multicast_info;
4710
4711         if (!hif_drv) {
4712                 PRINT_ER("driver is null\n");
4713                 return -EFAULT;
4714         }
4715
4716         PRINT_D(HOSTINF_DBG, "Setting Multicast Filter params\n");
4717
4718         memset(&msg, 0, sizeof(struct host_if_msg));
4719
4720         msg.id = HOST_IF_MSG_SET_MULTICAST_FILTER;
4721         msg.drv = hif_drv;
4722
4723         pstrMulticastFilterParam->enabled = bIsEnabled;
4724         pstrMulticastFilterParam->cnt = u32count;
4725
4726         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4727         if (result)
4728                 PRINT_ER("wilc_mq_send fail\n");
4729         return result;
4730 }
4731
4732 static void *host_int_ParseJoinBssParam(tstrNetworkInfo *ptstrNetworkInfo)
4733 {
4734         struct join_bss_param *pNewJoinBssParam = NULL;
4735         u8 *pu8IEs;
4736         u16 u16IEsLen;
4737         u16 index = 0;
4738         u8 suppRatesNo = 0;
4739         u8 extSuppRatesNo;
4740         u16 jumpOffset;
4741         u8 pcipherCount;
4742         u8 authCount;
4743         u8 pcipherTotalCount = 0;
4744         u8 authTotalCount = 0;
4745         u8 i, j;
4746
4747         pu8IEs = ptstrNetworkInfo->pu8IEs;
4748         u16IEsLen = ptstrNetworkInfo->u16IEsLen;
4749
4750         pNewJoinBssParam = kzalloc(sizeof(struct join_bss_param), GFP_KERNEL);
4751         if (pNewJoinBssParam) {
4752                 pNewJoinBssParam->dtim_period = ptstrNetworkInfo->u8DtimPeriod;
4753                 pNewJoinBssParam->beacon_period = ptstrNetworkInfo->u16BeaconPeriod;
4754                 pNewJoinBssParam->cap_info = ptstrNetworkInfo->u16CapInfo;
4755                 memcpy(pNewJoinBssParam->au8bssid, ptstrNetworkInfo->au8bssid, 6);
4756                 memcpy((u8 *)pNewJoinBssParam->ssid, ptstrNetworkInfo->au8ssid, ptstrNetworkInfo->u8SsidLen + 1);
4757                 pNewJoinBssParam->ssid_len = ptstrNetworkInfo->u8SsidLen;
4758                 memset(pNewJoinBssParam->rsn_pcip_policy, 0xFF, 3);
4759                 memset(pNewJoinBssParam->rsn_auth_policy, 0xFF, 3);
4760
4761                 while (index < u16IEsLen) {
4762                         if (pu8IEs[index] == SUPP_RATES_IE) {
4763                                 suppRatesNo = pu8IEs[index + 1];
4764                                 pNewJoinBssParam->supp_rates[0] = suppRatesNo;
4765                                 index += 2;
4766
4767                                 for (i = 0; i < suppRatesNo; i++)
4768                                         pNewJoinBssParam->supp_rates[i + 1] = pu8IEs[index + i];
4769
4770                                 index += suppRatesNo;
4771                                 continue;
4772                         } else if (pu8IEs[index] == EXT_SUPP_RATES_IE) {
4773                                 extSuppRatesNo = pu8IEs[index + 1];
4774                                 if (extSuppRatesNo > (MAX_RATES_SUPPORTED - suppRatesNo))
4775                                         pNewJoinBssParam->supp_rates[0] = MAX_RATES_SUPPORTED;
4776                                 else
4777                                         pNewJoinBssParam->supp_rates[0] += extSuppRatesNo;
4778                                 index += 2;
4779                                 for (i = 0; i < (pNewJoinBssParam->supp_rates[0] - suppRatesNo); i++)
4780                                         pNewJoinBssParam->supp_rates[suppRatesNo + i + 1] = pu8IEs[index + i];
4781
4782                                 index += extSuppRatesNo;
4783                                 continue;
4784                         } else if (pu8IEs[index] == HT_CAPABILITY_IE) {
4785                                 pNewJoinBssParam->ht_capable = true;
4786                                 index += pu8IEs[index + 1] + 2;
4787                                 continue;
4788                         } else if ((pu8IEs[index] == WMM_IE) &&
4789                                    (pu8IEs[index + 2] == 0x00) && (pu8IEs[index + 3] == 0x50) &&
4790                                    (pu8IEs[index + 4] == 0xF2) &&
4791                                    (pu8IEs[index + 5] == 0x02) &&
4792                                    ((pu8IEs[index + 6] == 0x00) || (pu8IEs[index + 6] == 0x01)) &&
4793                                    (pu8IEs[index + 7] == 0x01)) {
4794                                 pNewJoinBssParam->wmm_cap = true;
4795
4796                                 if (pu8IEs[index + 8] & BIT(7))
4797                                         pNewJoinBssParam->uapsd_cap = true;
4798                                 index += pu8IEs[index + 1] + 2;
4799                                 continue;
4800                         } else if ((pu8IEs[index] == P2P_IE) &&
4801                                  (pu8IEs[index + 2] == 0x50) && (pu8IEs[index + 3] == 0x6f) &&
4802                                  (pu8IEs[index + 4] == 0x9a) &&
4803                                  (pu8IEs[index + 5] == 0x09) && (pu8IEs[index + 6] == 0x0c)) {
4804                                 u16 u16P2P_count;
4805
4806                                 pNewJoinBssParam->tsf = ptstrNetworkInfo->u32Tsf;
4807                                 pNewJoinBssParam->noa_enabled = 1;
4808                                 pNewJoinBssParam->idx = pu8IEs[index + 9];
4809
4810                                 if (pu8IEs[index + 10] & BIT(7)) {
4811                                         pNewJoinBssParam->opp_enabled = 1;
4812                                         pNewJoinBssParam->ct_window = pu8IEs[index + 10];
4813                                 } else {
4814                                         pNewJoinBssParam->opp_enabled = 0;
4815                                 }
4816
4817                                 PRINT_D(GENERIC_DBG, "P2P Dump\n");
4818                                 for (i = 0; i < pu8IEs[index + 7]; i++)
4819                                         PRINT_D(GENERIC_DBG, " %x\n", pu8IEs[index + 9 + i]);
4820
4821                                 pNewJoinBssParam->cnt = pu8IEs[index + 11];
4822                                 u16P2P_count = index + 12;
4823
4824                                 memcpy(pNewJoinBssParam->duration, pu8IEs + u16P2P_count, 4);
4825                                 u16P2P_count += 4;
4826
4827                                 memcpy(pNewJoinBssParam->interval, pu8IEs + u16P2P_count, 4);
4828                                 u16P2P_count += 4;
4829
4830                                 memcpy(pNewJoinBssParam->start_time, pu8IEs + u16P2P_count, 4);
4831
4832                                 index += pu8IEs[index + 1] + 2;
4833                                 continue;
4834
4835                         } else if ((pu8IEs[index] == RSN_IE) ||
4836                                  ((pu8IEs[index] == WPA_IE) && (pu8IEs[index + 2] == 0x00) &&
4837                                   (pu8IEs[index + 3] == 0x50) && (pu8IEs[index + 4] == 0xF2) &&
4838                                   (pu8IEs[index + 5] == 0x01))) {
4839                                 u16 rsnIndex = index;
4840
4841                                 if (pu8IEs[rsnIndex] == RSN_IE) {
4842                                         pNewJoinBssParam->mode_802_11i = 2;
4843                                 } else {
4844                                         if (pNewJoinBssParam->mode_802_11i == 0)
4845                                                 pNewJoinBssParam->mode_802_11i = 1;
4846                                         rsnIndex += 4;
4847                                 }
4848
4849                                 rsnIndex += 7;
4850                                 pNewJoinBssParam->rsn_grp_policy = pu8IEs[rsnIndex];
4851                                 rsnIndex++;
4852                                 jumpOffset = pu8IEs[rsnIndex] * 4;
4853                                 pcipherCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex];
4854                                 rsnIndex += 2;
4855
4856                                 for (i = pcipherTotalCount, j = 0; i < pcipherCount + pcipherTotalCount && i < 3; i++, j++)
4857                                         pNewJoinBssParam->rsn_pcip_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1];
4858
4859                                 pcipherTotalCount += pcipherCount;
4860                                 rsnIndex += jumpOffset;
4861
4862                                 jumpOffset = pu8IEs[rsnIndex] * 4;
4863
4864                                 authCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex];
4865                                 rsnIndex += 2;
4866
4867                                 for (i = authTotalCount, j = 0; i < authTotalCount + authCount; i++, j++)
4868                                         pNewJoinBssParam->rsn_auth_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1];
4869
4870                                 authTotalCount += authCount;
4871                                 rsnIndex += jumpOffset;
4872
4873                                 if (pu8IEs[index] == RSN_IE) {
4874                                         pNewJoinBssParam->rsn_cap[0] = pu8IEs[rsnIndex];
4875                                         pNewJoinBssParam->rsn_cap[1] = pu8IEs[rsnIndex + 1];
4876                                         rsnIndex += 2;
4877                                 }
4878                                 pNewJoinBssParam->rsn_found = true;
4879                                 index += pu8IEs[index + 1] + 2;
4880                                 continue;
4881                         } else
4882                                 index += pu8IEs[index + 1] + 2;
4883                 }
4884         }
4885
4886         return (void *)pNewJoinBssParam;
4887 }
4888
4889 void host_int_freeJoinParams(void *pJoinParams)
4890 {
4891         if ((struct bss_param *)pJoinParams)
4892                 kfree((struct bss_param *)pJoinParams);
4893         else
4894                 PRINT_ER("Unable to FREE null pointer\n");
4895 }
4896
4897 s32 host_int_delBASession(struct host_if_drv *hif_drv, char *pBSSID, char TID)
4898 {
4899         s32 result = 0;
4900         struct host_if_msg msg;
4901         struct ba_session_info *pBASessionInfo = &msg.body.session_info;
4902
4903         if (!hif_drv) {
4904                 PRINT_ER("driver is null\n");
4905                 return -EFAULT;
4906         }
4907
4908         memset(&msg, 0, sizeof(struct host_if_msg));
4909
4910         msg.id = HOST_IF_MSG_DEL_BA_SESSION;
4911
4912         memcpy(pBASessionInfo->au8Bssid, pBSSID, ETH_ALEN);
4913         pBASessionInfo->u8Ted = TID;
4914         msg.drv = hif_drv;
4915
4916         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4917         if (result)
4918                 PRINT_ER("wilc_mq_send fail\n");
4919
4920         down(&hif_sema_wait_response);
4921
4922         return result;
4923 }
4924
4925 s32 host_int_del_All_Rx_BASession(struct host_if_drv *hif_drv,
4926                                   char *pBSSID,
4927                                   char TID)
4928 {
4929         s32 result = 0;
4930         struct host_if_msg msg;
4931         struct ba_session_info *pBASessionInfo = &msg.body.session_info;
4932
4933         if (!hif_drv) {
4934                 PRINT_ER("driver is null\n");
4935                 return -EFAULT;
4936         }
4937
4938         memset(&msg, 0, sizeof(struct host_if_msg));
4939
4940         msg.id = HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS;
4941
4942         memcpy(pBASessionInfo->au8Bssid, pBSSID, ETH_ALEN);
4943         pBASessionInfo->u8Ted = TID;
4944         msg.drv = hif_drv;
4945
4946         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4947         if (result)
4948                 PRINT_ER("wilc_mq_send fail\n");
4949
4950         down(&hif_sema_wait_response);
4951
4952         return result;
4953 }
4954
4955 s32 host_int_setup_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx)
4956 {
4957         s32 result = 0;
4958         struct host_if_msg msg;
4959
4960         return 0;
4961
4962         if (!hif_drv) {
4963                 PRINT_ER("driver is null\n");
4964                 return -EFAULT;
4965         }
4966
4967         memset(&msg, 0, sizeof(struct host_if_msg));
4968
4969         msg.id = HOST_IF_MSG_SET_IPADDRESS;
4970
4971         msg.body.ip_info.ip_addr = u16ipadd;
4972         msg.drv = hif_drv;
4973         msg.body.ip_info.idx = idx;
4974
4975         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4976         if (result)
4977                 PRINT_ER("wilc_mq_send fail\n");
4978
4979         return result;
4980 }
4981
4982 s32 host_int_get_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx)
4983 {
4984         s32 result = 0;
4985         struct host_if_msg msg;
4986
4987         if (!hif_drv) {
4988                 PRINT_ER("driver is null\n");
4989                 return -EFAULT;
4990         }
4991
4992         memset(&msg, 0, sizeof(struct host_if_msg));
4993
4994         msg.id = HOST_IF_MSG_GET_IPADDRESS;
4995
4996         msg.body.ip_info.ip_addr = u16ipadd;
4997         msg.drv = hif_drv;
4998         msg.body.ip_info.idx = idx;
4999
5000         result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
5001         if (result)
5002                 PRINT_ER("wilc_mq_send fail\n");
5003
5004         return result;
5005 }