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