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