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