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