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