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