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