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