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