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