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