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