1 // SPDX-License-Identifier: GPL-2.0
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"
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
53 #define HOST_IF_SCAN_TIMEOUT 4000
54 #define HOST_IF_CONNECT_TIMEOUT 9500
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
61 #define TCP_ACK_FILTER_LINK_SPEED_THRESH 54
62 #define DEFAULT_LINK_SPEED 72
64 struct host_if_wpa_attr {
74 struct host_if_wep_attr {
79 enum AUTHTYPE auth_type;
82 union 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;
91 union host_if_key_attr attr;
101 wilc_scan_result result;
103 struct hidden_network hidden_network;
106 struct connect_attr {
113 wilc_connect_result result;
115 enum AUTHTYPE auth_type;
120 struct rcvd_async_info {
125 struct channel_attr {
138 struct set_multicast {
144 u8 del_all_sta[MAX_NUM_STA][ETH_ALEN];
149 u8 mac_addr[ETH_ALEN];
152 struct power_mgmt_param {
162 struct sta_inactive_t {
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;
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;
193 struct del_all_sta del_all_sta_info;
194 struct tx_power tx_power;
199 union message_body body;
200 struct wilc_vif *vif;
201 struct work_struct work;
204 struct join_bss_param {
205 enum bss_types bss_type;
210 char ssid[MAX_SSID_LEN];
212 u8 supp_rates[MAX_RATES_SUPPORTED + 1];
219 u8 rsn_pcip_policy[3];
220 u8 rsn_auth_policy[3];
233 static struct host_if_drv *terminated_handle;
234 bool wilc_optaining_ip;
235 static u8 P2P_LISTEN_STATE;
236 static struct workqueue_struct *hif_workqueue;
237 static struct completion hif_thread_comp;
238 static struct completion hif_driver_comp;
239 static struct completion hif_wait_response;
240 static struct mutex hif_deinit_lock;
241 static struct timer_list periodic_rssi;
242 static struct wilc_vif *periodic_rssi_vif;
244 u8 wilc_multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN];
246 static u8 rcv_assoc_resp[MAX_ASSOC_RESP_FRAME_SIZE];
248 static bool scan_while_connected;
251 static u8 set_ip[2][4];
252 static u8 get_ip[2][4];
253 static u32 inactive_time;
254 static u8 del_beacon;
255 static u32 clients_count;
257 #define REAL_JOIN_REQ 0
258 #define FLUSHED_JOIN_REQ 1
259 #define FLUSHED_BYTE_POS 79
261 static void *host_int_parse_join_bss_param(struct network_info *info);
262 static int host_int_get_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx);
263 static s32 handle_scan_done(struct wilc_vif *vif, enum scan_event evt);
264 static void host_if_work(struct work_struct *work);
269 * @note copied from FLO glue implementatuion
272 static int wilc_enqueue_cmd(struct host_if_msg *msg)
274 struct host_if_msg *new_msg;
276 new_msg = kmemdup(msg, sizeof(*new_msg), GFP_ATOMIC);
280 INIT_WORK(&new_msg->work, host_if_work);
281 queue_work(hif_workqueue, &new_msg->work);
285 /* The u8IfIdx starts from 0 to NUM_CONCURRENT_IFC -1, but 0 index used as
286 * special purpose in wilc device, so we add 1 to the index to starts from 1.
287 * As a result, the returned index will be 1 to NUM_CONCURRENT_IFC.
289 int wilc_get_vif_idx(struct wilc_vif *vif)
294 /* We need to minus 1 from idx which is from wilc device to get real index
295 * of wilc->vif[], because we add 1 when pass to wilc device in the function
297 * As a result, the index should be between 0 and NUM_CONCURRENT_IFC -1.
299 static struct wilc_vif *wilc_get_vif_from_idx(struct wilc *wilc, int idx)
303 if (index < 0 || index >= NUM_CONCURRENT_IFC)
306 return wilc->vif[index];
309 static void handle_set_channel(struct wilc_vif *vif,
310 struct channel_attr *hif_set_ch)
315 wid.id = (u16)WID_CURRENT_CHANNEL;
317 wid.val = (char *)&hif_set_ch->set_ch;
318 wid.size = sizeof(char);
320 ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
321 wilc_get_vif_idx(vif));
324 netdev_err(vif->ndev, "Failed to set channel\n");
327 static int handle_set_wfi_drv_handler(struct wilc_vif *vif,
328 struct drv_handler *hif_drv_handler)
332 u8 *currbyte, *buffer;
333 struct host_if_drv *hif_drv = NULL;
338 if (!hif_drv_handler)
341 hif_drv = vif->hif_drv;
343 buffer = kzalloc(DRV_HANDLER_SIZE, GFP_KERNEL);
348 *currbyte = hif_drv->driver_handler_id & DRV_HANDLER_MASK;
350 *currbyte = (u32)0 & DRV_HANDLER_MASK;
352 *currbyte = (u32)0 & DRV_HANDLER_MASK;
354 *currbyte = (u32)0 & DRV_HANDLER_MASK;
356 *currbyte = (hif_drv_handler->name | (hif_drv_handler->mode << 1));
358 wid.id = (u16)WID_SET_DRV_HANDLER;
360 wid.val = (s8 *)buffer;
361 wid.size = DRV_HANDLER_SIZE;
363 ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
364 hif_drv->driver_handler_id);
366 netdev_err(vif->ndev, "Failed to set driver handler\n");
367 complete(&hif_driver_comp);
371 complete(&hif_driver_comp);
376 static void handle_set_operation_mode(struct wilc_vif *vif,
377 struct op_mode *hif_op_mode)
382 wid.id = (u16)WID_SET_OPERATION_MODE;
384 wid.val = (s8 *)&hif_op_mode->mode;
385 wid.size = sizeof(u32);
387 ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
388 wilc_get_vif_idx(vif));
390 if (hif_op_mode->mode == IDLE_MODE)
391 complete(&hif_driver_comp);
394 netdev_err(vif->ndev, "Failed to set driver handler\n");
397 static void handle_set_ip_address(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
401 char firmware_ip_addr[4] = {0};
403 if (ip_addr[0] < 192)
406 memcpy(set_ip[idx], ip_addr, IP_ALEN);
408 wid.id = (u16)WID_IP_ADDRESS;
413 ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
414 wilc_get_vif_idx(vif));
416 host_int_get_ipaddress(vif, firmware_ip_addr, idx);
419 netdev_err(vif->ndev, "Failed to set IP address\n");
422 static void handle_get_ip_address(struct wilc_vif *vif, u8 idx)
427 wid.id = (u16)WID_IP_ADDRESS;
429 wid.val = kmalloc(IP_ALEN, GFP_KERNEL);
432 ret = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
433 wilc_get_vif_idx(vif));
435 memcpy(get_ip[idx], wid.val, IP_ALEN);
439 if (memcmp(get_ip[idx], set_ip[idx], IP_ALEN) != 0)
440 wilc_setup_ipaddress(vif, set_ip[idx], idx);
443 netdev_err(vif->ndev, "Failed to get IP address\n");
446 static void handle_get_mac_address(struct wilc_vif *vif,
447 struct get_mac_addr *get_mac_addr)
452 wid.id = (u16)WID_MAC_ADDR;
454 wid.val = get_mac_addr->mac_addr;
457 ret = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
458 wilc_get_vif_idx(vif));
461 netdev_err(vif->ndev, "Failed to get mac address\n");
462 complete(&hif_wait_response);
465 static void handle_cfg_param(struct wilc_vif *vif, struct cfg_param_attr *param)
468 struct wid wid_list[32];
469 struct host_if_drv *hif_drv = vif->hif_drv;
472 mutex_lock(&hif_drv->cfg_values_lock);
474 if (param->flag & BSS_TYPE) {
475 u8 bss_type = param->bss_type;
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;
484 netdev_err(vif->ndev, "check value 6 over\n");
489 if (param->flag & AUTH_TYPE) {
490 u8 auth_type = param->auth_type;
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;
499 netdev_err(vif->ndev, "Impossible value\n");
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;
512 netdev_err(vif->ndev, "Range(1 ~ 65535) over\n");
517 if (param->flag & POWER_MANAGEMENT) {
518 u8 pm_mode = param->power_mgmt_mode;
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;
527 netdev_err(vif->ndev, "Invalid power mode\n");
532 if (param->flag & RETRY_SHORT) {
533 u16 retry_limit = param->short_retry_limit;
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;
542 netdev_err(vif->ndev, "Range(1~256) over\n");
547 if (param->flag & RETRY_LONG) {
548 u16 limit = param->long_retry_limit;
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;
557 netdev_err(vif->ndev, "Range(1~256) over\n");
562 if (param->flag & FRAG_THRESHOLD) {
563 u16 frag_th = param->frag_threshold;
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;
572 netdev_err(vif->ndev, "Threshold Range fail\n");
577 if (param->flag & RTS_THRESHOLD) {
578 u16 rts_th = param->rts_threshold;
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;
587 netdev_err(vif->ndev, "Threshold Range fail\n");
592 if (param->flag & PREAMBLE) {
593 u16 preamble_type = param->preamble_type;
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;
602 netdev_err(vif->ndev, "Preamle Range(0~2) over\n");
607 if (param->flag & SHORT_SLOT_ALLOWED) {
608 u8 slot_allowed = param->short_slot_allowed;
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;
617 netdev_err(vif->ndev, "Short slot(2) over\n");
622 if (param->flag & TXOP_PROT_DISABLE) {
623 u8 prot_disabled = param->txop_prot_disabled;
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;
632 netdev_err(vif->ndev, "TXOP prot disable\n");
637 if (param->flag & BEACON_INTERVAL) {
638 u16 beacon_interval = param->beacon_interval;
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;
647 netdev_err(vif->ndev, "Beacon interval(1~65535)fail\n");
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;
660 netdev_err(vif->ndev, "DTIM range(1~255) fail\n");
665 if (param->flag & SITE_SURVEY) {
666 enum SITESURVEY enabled = param->site_survey_enabled;
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;
675 netdev_err(vif->ndev, "Site survey disable\n");
680 if (param->flag & SITE_SURVEY_SCAN_TIME) {
681 u16 scan_time = param->site_survey_scan_time;
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;
690 netdev_err(vif->ndev, "Site scan time(1~65535) over\n");
695 if (param->flag & ACTIVE_SCANTIME) {
696 u16 active_scan_time = param->active_scan_time;
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;
705 netdev_err(vif->ndev, "Active time(1~65535) over\n");
710 if (param->flag & PASSIVE_SCANTIME) {
711 u16 time = param->passive_scan_time;
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;
720 netdev_err(vif->ndev, "Passive time(1~65535) over\n");
725 if (param->flag & CURRENT_TX_RATE) {
726 enum CURRENT_TXRATE curr_tx_rate = param->curr_tx_rate;
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;
741 netdev_err(vif->ndev, "out of TX rate\n");
747 ret = wilc_send_config_pkt(vif, SET_CFG, wid_list,
748 i, wilc_get_vif_idx(vif));
751 netdev_err(vif->ndev, "Error in setting CFG params\n");
754 mutex_unlock(&hif_drv->cfg_values_lock);
757 static s32 handle_scan(struct wilc_vif *vif, struct scan_attr *scan_info)
760 struct wid wid_list[5];
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;
769 hif_drv->usr_scan_req.scan_result = scan_info->result;
770 hif_drv->usr_scan_req.arg = scan_info->arg;
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");
779 if (wilc_optaining_ip || wilc_connecting) {
780 netdev_err(vif->ndev, "Don't do obss scan\n");
785 hif_drv->usr_scan_req.rcvd_ch_cnt = 0;
787 wid_list[index].id = (u16)WID_SSID_PROBE_REQ;
788 wid_list[index].type = WID_STR;
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;
797 *buffer++ = hidden_net->n_ssids;
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;
806 wid_list[index].size = (s32)(valuesize + 1);
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;
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;
822 wid_list[index].id = WID_SCAN_CHANNEL_LIST;
823 wid_list[index].type = WID_BIN_DATA;
825 if (scan_info->ch_freq_list &&
826 scan_info->ch_list_len > 0) {
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;
835 wid_list[index].val = scan_info->ch_freq_list;
836 wid_list[index].size = scan_info->ch_list_len;
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;
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;
850 result = wilc_send_config_pkt(vif, SET_CFG, wid_list,
852 wilc_get_vif_idx(vif));
855 netdev_err(vif->ndev, "Failed to send scan parameters\n");
859 del_timer(&hif_drv->scan_timer);
860 handle_scan_done(vif, SCAN_EVENT_ABORTED);
863 kfree(scan_info->ch_freq_list);
864 scan_info->ch_freq_list = NULL;
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;
871 kfree(hdn_ntwk_wid_val);
876 static s32 handle_scan_done(struct wilc_vif *vif, enum scan_event evt)
879 u8 abort_running_scan;
881 struct host_if_drv *hif_drv = vif->hif_drv;
882 struct user_scan_req *scan_req;
884 if (evt == SCAN_EVENT_ABORTED) {
885 abort_running_scan = 1;
886 wid.id = (u16)WID_ABORT_RUNNING_SCAN;
888 wid.val = (s8 *)&abort_running_scan;
889 wid.size = sizeof(char);
891 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
892 wilc_get_vif_idx(vif));
895 netdev_err(vif->ndev, "Failed to set abort running\n");
901 netdev_err(vif->ndev, "Driver handler is NULL\n");
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;
914 u8 wilc_connected_ssid[6] = {0};
915 static s32 handle_connect(struct wilc_vif *vif,
916 struct connect_attr *conn_attr)
919 struct wid wid_list[8];
920 u32 wid_cnt = 0, dummyval = 0;
922 struct join_bss_param *bss_param;
923 struct host_if_drv *hif_drv = vif->hif_drv;
925 if (memcmp(conn_attr->bssid, wilc_connected_ssid, ETH_ALEN) == 0) {
927 netdev_err(vif->ndev, "Discard connect request\n");
931 bss_param = conn_attr->params;
933 netdev_err(vif->ndev, "Required BSSID not found\n");
938 if (conn_attr->bssid) {
939 hif_drv->usr_conn_req.bssid = kmemdup(conn_attr->bssid, 6,
941 if (!hif_drv->usr_conn_req.bssid) {
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,
951 if (!hif_drv->usr_conn_req.ssid) {
955 memcpy(hif_drv->usr_conn_req.ssid,
957 conn_attr->ssid_len);
958 hif_drv->usr_conn_req.ssid[conn_attr->ssid_len] = '\0';
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,
966 if (!hif_drv->usr_conn_req.ies) {
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;
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));
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));
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));
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;
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;
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;
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);
1018 if (!wid_list[wid_cnt].val) {
1023 cur_byte = wid_list[wid_cnt].val;
1025 if (conn_attr->ssid) {
1026 memcpy(cur_byte, conn_attr->ssid, conn_attr->ssid_len);
1027 cur_byte[conn_attr->ssid_len] = '\0';
1029 cur_byte += MAX_SSID_LEN;
1030 *(cur_byte++) = INFRASTRUCTURE;
1032 if (conn_attr->ch >= 1 && conn_attr->ch <= 14) {
1033 *(cur_byte++) = conn_attr->ch;
1035 netdev_err(vif->ndev, "Channel out of range\n");
1036 *(cur_byte++) = 0xFF;
1038 *(cur_byte++) = (bss_param->cap_info) & 0xFF;
1039 *(cur_byte++) = ((bss_param->cap_info) >> 8) & 0xFF;
1041 if (conn_attr->bssid)
1042 memcpy(cur_byte, conn_attr->bssid, 6);
1045 if (conn_attr->bssid)
1046 memcpy(cur_byte, conn_attr->bssid, 6);
1049 *(cur_byte++) = (bss_param->beacon_period) & 0xFF;
1050 *(cur_byte++) = ((bss_param->beacon_period) >> 8) & 0xFF;
1051 *(cur_byte++) = bss_param->dtim_period;
1053 memcpy(cur_byte, bss_param->supp_rates, MAX_RATES_SUPPORTED + 1);
1054 cur_byte += (MAX_RATES_SUPPORTED + 1);
1056 *(cur_byte++) = bss_param->wmm_cap;
1057 *(cur_byte++) = bss_param->uapsd_cap;
1059 *(cur_byte++) = bss_param->ht_capable;
1060 hif_drv->usr_conn_req.ht_capable = bss_param->ht_capable;
1062 *(cur_byte++) = bss_param->rsn_found;
1063 *(cur_byte++) = bss_param->rsn_grp_policy;
1064 *(cur_byte++) = bss_param->mode_802_11i;
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);
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);
1074 memcpy(cur_byte, bss_param->rsn_cap, sizeof(bss_param->rsn_cap));
1075 cur_byte += sizeof(bss_param->rsn_cap);
1077 *(cur_byte++) = REAL_JOIN_REQ;
1078 *(cur_byte++) = bss_param->noa_enabled;
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;
1086 *(cur_byte++) = bss_param->opp_enabled;
1087 *(cur_byte++) = bss_param->idx;
1089 if (bss_param->opp_enabled)
1090 *(cur_byte++) = bss_param->ct_window;
1092 *(cur_byte++) = bss_param->cnt;
1094 memcpy(cur_byte, bss_param->duration,
1095 sizeof(bss_param->duration));
1096 cur_byte += sizeof(bss_param->duration);
1098 memcpy(cur_byte, bss_param->interval,
1099 sizeof(bss_param->interval));
1100 cur_byte += sizeof(bss_param->interval);
1102 memcpy(cur_byte, bss_param->start_time,
1103 sizeof(bss_param->start_time));
1104 cur_byte += sizeof(bss_param->start_time);
1107 cur_byte = wid_list[wid_cnt].val;
1110 if (conn_attr->bssid)
1111 memcpy(wilc_connected_ssid,
1112 conn_attr->bssid, ETH_ALEN);
1114 result = wilc_send_config_pkt(vif, SET_CFG, wid_list,
1116 wilc_get_vif_idx(vif));
1118 netdev_err(vif->ndev, "failed to send config packet\n");
1122 hif_drv->hif_state = HOST_IF_WAITING_CONN_RESP;
1127 struct connect_info conn_info;
1129 del_timer(&hif_drv->connect_timer);
1131 memset(&conn_info, 0, sizeof(struct connect_info));
1133 if (conn_attr->result) {
1134 if (conn_attr->bssid)
1135 memcpy(conn_info.bssid, conn_attr->bssid, 6);
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,
1141 memcpy(conn_info.req_ies,
1143 conn_attr->ies_len);
1146 conn_attr->result(CONN_DISCONN_EVENT_CONN_RESP,
1151 hif_drv->hif_state = HOST_IF_IDLE;
1152 kfree(conn_info.req_ies);
1153 conn_info.req_ies = NULL;
1156 netdev_err(vif->ndev, "Connect callback is NULL\n");
1160 kfree(conn_attr->bssid);
1161 conn_attr->bssid = NULL;
1163 kfree(conn_attr->ssid);
1164 conn_attr->ssid = NULL;
1166 kfree(conn_attr->ies);
1167 conn_attr->ies = NULL;
1173 static s32 handle_connect_timeout(struct wilc_vif *vif)
1176 struct connect_info info;
1178 u16 dummy_reason_code = 0;
1179 struct host_if_drv *hif_drv = vif->hif_drv;
1182 netdev_err(vif->ndev, "Driver handler is NULL\n");
1186 hif_drv->hif_state = HOST_IF_IDLE;
1188 scan_while_connected = false;
1190 memset(&info, 0, sizeof(struct connect_info));
1192 if (hif_drv->usr_conn_req.conn_result) {
1193 if (hif_drv->usr_conn_req.bssid) {
1195 hif_drv->usr_conn_req.bssid, 6);
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);
1206 hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_CONN_RESP,
1210 hif_drv->usr_conn_req.arg);
1212 kfree(info.req_ies);
1213 info.req_ies = NULL;
1215 netdev_err(vif->ndev, "Connect callback is NULL\n");
1218 wid.id = (u16)WID_DISCONNECT;
1219 wid.type = WID_CHAR;
1220 wid.val = (s8 *)&dummy_reason_code;
1221 wid.size = sizeof(char);
1223 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
1224 wilc_get_vif_idx(vif));
1226 netdev_err(vif->ndev, "Failed to send disconnect\n");
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;
1237 eth_zero_addr(wilc_connected_ssid);
1242 static s32 handle_rcvd_ntwrk_info(struct wilc_vif *vif,
1243 struct rcvd_net_info *rcvd_info)
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;
1255 if (!scan_req->scan_result)
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");
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) {
1270 scan_req->net_info[i].rssi = info->rssi;
1278 if (scan_req->rcvd_ch_cnt < MAX_NUM_SCANNED_NETWORKS) {
1279 scan_req->net_info[scan_req->rcvd_ch_cnt].rssi = info->rssi;
1281 memcpy(scan_req->net_info[scan_req->rcvd_ch_cnt].bssid,
1284 scan_req->rcvd_ch_cnt++;
1286 info->new_network = true;
1287 params = host_int_parse_join_bss_param(info);
1289 scan_req->scan_result(SCAN_EVENT_NETWORK_FOUND, info,
1290 scan_req->arg, params);
1293 info->new_network = false;
1294 scan_req->scan_result(SCAN_EVENT_NETWORK_FOUND, info,
1295 scan_req->arg, NULL);
1299 kfree(rcvd_info->buffer);
1300 rcvd_info->buffer = NULL;
1310 static 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);
1315 static inline void host_int_free_user_conn_req(struct host_if_drv *hif_drv)
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;
1327 static inline void host_int_parse_assoc_resp_info(struct wilc_vif *vif,
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;
1334 memset(&conn_info, 0, sizeof(struct connect_info));
1336 if (mac_status == MAC_CONNECTED) {
1337 u32 rcvd_assoc_resp_info_len;
1339 memset(rcv_assoc_resp, 0, MAX_ASSOC_RESP_FRAME_SIZE);
1341 host_int_get_assoc_res_info(vif, rcv_assoc_resp,
1342 MAX_ASSOC_RESP_FRAME_SIZE,
1343 &rcvd_assoc_resp_info_len);
1345 if (rcvd_assoc_resp_info_len != 0) {
1348 err = wilc_parse_assoc_resp_info(rcv_assoc_resp, rcvd_assoc_resp_info_len,
1349 &connect_resp_info);
1351 netdev_err(vif->ndev,
1352 "wilc_parse_assoc_resp_info() returned error %d\n",
1355 conn_info.status = connect_resp_info->status;
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,
1362 if (conn_info.resp_ies)
1363 conn_info.resp_ies_len = connect_resp_info->ies_len;
1366 kfree(connect_resp_info->ies);
1367 kfree(connect_resp_info);
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);
1382 if (hif_drv->usr_conn_req.bssid) {
1383 memcpy(conn_info.bssid, hif_drv->usr_conn_req.bssid, 6);
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);
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,
1396 if (conn_info.req_ies)
1397 conn_info.req_ies_len = hif_drv->usr_conn_req.ies_len;
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);
1405 if (mac_status == MAC_CONNECTED &&
1406 conn_info.status == SUCCESSFUL_STATUSCODE) {
1407 wilc_set_power_mgmt(vif, 0, 0);
1409 hif_drv->hif_state = HOST_IF_CONNECTED;
1411 wilc_optaining_ip = true;
1412 mod_timer(&wilc_during_ip_timer,
1413 jiffies + msecs_to_jiffies(10000));
1415 hif_drv->hif_state = HOST_IF_IDLE;
1416 scan_while_connected = false;
1419 kfree(conn_info.resp_ies);
1420 conn_info.resp_ies = NULL;
1422 kfree(conn_info.req_ies);
1423 conn_info.req_ies = NULL;
1424 host_int_free_user_conn_req(hif_drv);
1427 static inline void host_int_handle_disconnect(struct wilc_vif *vif)
1429 struct disconnect_info disconn_info;
1430 struct host_if_drv *hif_drv = vif->hif_drv;
1432 memset(&disconn_info, 0, sizeof(struct disconnect_info));
1434 if (hif_drv->usr_scan_req.scan_result) {
1435 del_timer(&hif_drv->scan_timer);
1436 handle_scan_done(vif, SCAN_EVENT_ABORTED);
1439 disconn_info.reason = 0;
1440 disconn_info.ie = NULL;
1441 disconn_info.ie_len = 0;
1443 if (hif_drv->usr_conn_req.conn_result) {
1444 wilc_optaining_ip = false;
1445 wilc_set_power_mgmt(vif, 0, 0);
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);
1451 netdev_err(vif->ndev, "Connect result NULL\n");
1454 eth_zero_addr(hif_drv->assoc_bssid);
1456 host_int_free_user_conn_req(hif_drv);
1457 hif_drv->hif_state = HOST_IF_IDLE;
1458 scan_while_connected = false;
1461 static s32 handle_rcvd_gnrl_async_info(struct wilc_vif *vif,
1462 struct rcvd_async_info *rcvd_info)
1468 u16 wid_id = (u16)WID_NIL;
1471 u8 mac_status_reason_code;
1472 u8 mac_status_additional_info;
1473 struct host_if_drv *hif_drv = vif->hif_drv;
1475 if (!rcvd_info->buffer) {
1476 netdev_err(vif->ndev, "Received buffer is NULL\n");
1481 netdev_err(vif->ndev, "Driver handler is NULL\n");
1482 kfree(rcvd_info->buffer);
1483 rcvd_info->buffer = NULL;
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;
1497 msg_type = rcvd_info->buffer[0];
1499 if ('I' != msg_type) {
1500 netdev_err(vif->ndev, "Received Message incorrect.\n");
1501 kfree(rcvd_info->buffer);
1502 rcvd_info->buffer = NULL;
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);
1526 kfree(rcvd_info->buffer);
1527 rcvd_info->buffer = NULL;
1532 static int handle_key(struct wilc_vif *vif, struct key_attr *hif_key)
1536 struct wid wid_list[5];
1541 struct host_if_drv *hif_drv = vif->hif_drv;
1543 switch (hif_key->type) {
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;
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;
1557 key_buf = kmalloc(hif_key->attr.wep.key_len + 2,
1562 key_buf[0] = hif_key->attr.wep.index;
1563 key_buf[1] = hif_key->attr.wep.key_len;
1565 memcpy(&key_buf[2], hif_key->attr.wep.key,
1566 hif_key->attr.wep.key_len);
1568 kfree(hif_key->attr.wep.key);
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;
1575 result = wilc_send_config_pkt(vif, SET_CFG,
1577 wilc_get_vif_idx(vif));
1579 } else if (hif_key->action & ADDKEY) {
1580 key_buf = kmalloc(hif_key->attr.wep.key_len + 2, GFP_KERNEL);
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);
1589 wid.id = (u16)WID_ADD_WEP_KEY;
1591 wid.val = (s8 *)key_buf;
1592 wid.size = hif_key->attr.wep.key_len + 2;
1594 result = wilc_send_config_pkt(vif, SET_CFG,
1596 wilc_get_vif_idx(vif));
1598 } else if (hif_key->action & REMOVEKEY) {
1599 wid.id = (u16)WID_REMOVE_WEP_KEY;
1602 s8idxarray[0] = (s8)hif_key->attr.wep.index;
1603 wid.val = s8idxarray;
1606 result = wilc_send_config_pkt(vif, SET_CFG,
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);
1615 result = wilc_send_config_pkt(vif, SET_CFG,
1617 wilc_get_vif_idx(vif));
1619 complete(&hif_drv->comp_test_key_block);
1623 if (hif_key->action & ADDKEY_AP) {
1624 key_buf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
1627 goto out_wpa_rx_gtk;
1630 if (hif_key->attr.wpa.seq)
1631 memcpy(key_buf + 6, hif_key->attr.wpa.seq, 8);
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);
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;
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;
1648 result = wilc_send_config_pkt(vif, SET_CFG,
1650 wilc_get_vif_idx(vif));
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);
1658 goto out_wpa_rx_gtk;
1661 if (hif_drv->hif_state == HOST_IF_CONNECTED)
1662 memcpy(key_buf, hif_drv->assoc_bssid, ETH_ALEN);
1664 netdev_err(vif->ndev, "Couldn't handle\n");
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);
1672 wid.id = (u16)WID_ADD_RX_GTK;
1674 wid.val = (s8 *)key_buf;
1675 wid.size = RX_MIC_KEY_MSG_LEN;
1677 result = wilc_send_config_pkt(vif, SET_CFG,
1679 wilc_get_vif_idx(vif));
1682 complete(&hif_drv->comp_test_key_block);
1685 kfree(hif_key->attr.wpa.key);
1686 kfree(hif_key->attr.wpa.seq);
1693 if (hif_key->action & ADDKEY_AP) {
1694 key_buf = kmalloc(PTK_KEY_MSG_LEN + 1, GFP_KERNEL);
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);
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;
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;
1716 result = wilc_send_config_pkt(vif, SET_CFG,
1718 wilc_get_vif_idx(vif));
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);
1724 netdev_err(vif->ndev, "No buffer send PTK\n");
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);
1734 wid.id = (u16)WID_ADD_PTK;
1736 wid.val = (s8 *)key_buf;
1737 wid.size = PTK_KEY_MSG_LEN;
1739 result = wilc_send_config_pkt(vif, SET_CFG,
1741 wilc_get_vif_idx(vif));
1743 complete(&hif_drv->comp_test_key_block);
1747 kfree(hif_key->attr.wpa.key);
1754 key_buf = kmalloc((hif_key->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1, GFP_KERNEL);
1758 key_buf[0] = hif_key->attr.pmkid.numpmkid;
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);
1765 wid.id = (u16)WID_PMKID_INFO;
1767 wid.val = (s8 *)key_buf;
1768 wid.size = (hif_key->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1;
1770 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
1771 wilc_get_vif_idx(vif));
1778 netdev_err(vif->ndev, "Failed to send key config packet\n");
1783 static void handle_disconnect(struct wilc_vif *vif)
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;
1791 u16 dummy_reason_code = 0;
1793 wid.id = (u16)WID_DISCONNECT;
1794 wid.type = WID_CHAR;
1795 wid.val = (s8 *)&dummy_reason_code;
1796 wid.size = sizeof(char);
1798 wilc_optaining_ip = false;
1799 wilc_set_power_mgmt(vif, 0, 0);
1801 eth_zero_addr(wilc_connected_ssid);
1803 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
1804 wilc_get_vif_idx(vif));
1807 netdev_err(vif->ndev, "Failed to send dissconect\n");
1811 memset(&disconn_info, 0, sizeof(struct disconnect_info));
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;
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,
1823 scan_req->scan_result = NULL;
1826 if (conn_req->conn_result) {
1827 if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP)
1828 del_timer(&hif_drv->connect_timer);
1830 conn_req->conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF, NULL,
1831 0, &disconn_info, conn_req->arg);
1833 netdev_err(vif->ndev, "conn_result = NULL\n");
1836 scan_while_connected = false;
1838 hif_drv->hif_state = HOST_IF_IDLE;
1840 eth_zero_addr(hif_drv->assoc_bssid);
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;
1853 complete(&hif_drv->comp_test_disconn_block);
1856 void wilc_resolve_disconnect_aberration(struct wilc_vif *vif)
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);
1865 static void handle_get_rssi(struct wilc_vif *vif)
1870 wid.id = (u16)WID_RSSI;
1871 wid.type = WID_CHAR;
1873 wid.size = sizeof(char);
1875 result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
1876 wilc_get_vif_idx(vif));
1878 netdev_err(vif->ndev, "Failed to get RSSI value\n");
1882 complete(&vif->hif_drv->comp_get_rssi);
1885 static s32 handle_get_statistics(struct wilc_vif *vif,
1886 struct rf_info *stats)
1888 struct wid wid_list[5];
1889 u32 wid_cnt = 0, result = 0;
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;
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;
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;
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;
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;
1921 result = wilc_send_config_pkt(vif, GET_CFG, wid_list,
1923 wilc_get_vif_idx(vif));
1926 netdev_err(vif->ndev, "Failed to send scan parameters\n");
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);
1934 if (stats != &vif->wilc->dummy_statistics)
1935 complete(&hif_wait_response);
1939 static s32 handle_get_inactive_time(struct wilc_vif *vif,
1940 struct sta_inactive_t *hif_sta_inactive)
1944 struct host_if_drv *hif_drv = vif->hif_drv;
1946 wid.id = (u16)WID_SET_STA_MAC_INACTIVE_TIME;
1948 wid.size = ETH_ALEN;
1949 wid.val = kmalloc(wid.size, GFP_KERNEL);
1953 ether_addr_copy(wid.val, hif_sta_inactive->mac);
1955 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
1956 wilc_get_vif_idx(vif));
1960 netdev_err(vif->ndev, "Failed to SET inactive time\n");
1964 wid.id = (u16)WID_GET_INACTIVE_TIME;
1966 wid.val = (s8 *)&inactive_time;
1967 wid.size = sizeof(u32);
1969 result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
1970 wilc_get_vif_idx(vif));
1973 netdev_err(vif->ndev, "Failed to get inactive time\n");
1977 complete(&hif_drv->comp_inactive_time);
1982 static void handle_add_beacon(struct wilc_vif *vif, struct beacon_attr *param)
1988 wid.id = (u16)WID_ADD_BEACON;
1990 wid.size = param->head_len + param->tail_len + 16;
1991 wid.val = kmalloc(wid.size, GFP_KERNEL);
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);
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);
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);
2011 memcpy(cur_byte, param->head, param->head_len);
2012 cur_byte += param->head_len;
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);
2020 memcpy(cur_byte, param->tail, param->tail_len);
2021 cur_byte += param->tail_len;
2023 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2024 wilc_get_vif_idx(vif));
2026 netdev_err(vif->ndev, "Failed to send add beacon\n");
2034 static void handle_del_beacon(struct wilc_vif *vif)
2040 wid.id = (u16)WID_DEL_BEACON;
2041 wid.type = WID_CHAR;
2042 wid.size = sizeof(char);
2043 wid.val = &del_beacon;
2050 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2051 wilc_get_vif_idx(vif));
2053 netdev_err(vif->ndev, "Failed to send delete beacon\n");
2056 static u32 wilc_hif_pack_sta_param(u8 *buff, struct add_sta_param *param)
2062 memcpy(cur_byte, param->bssid, ETH_ALEN);
2063 cur_byte += ETH_ALEN;
2065 *cur_byte++ = param->aid & 0xFF;
2066 *cur_byte++ = (param->aid >> 8) & 0xFF;
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;
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);
2077 *cur_byte++ = param->flags_mask & 0xFF;
2078 *cur_byte++ = (param->flags_mask >> 8) & 0xFF;
2080 *cur_byte++ = param->flags_set & 0xFF;
2081 *cur_byte++ = (param->flags_set >> 8) & 0xFF;
2083 return cur_byte - buff;
2086 static void handle_add_station(struct wilc_vif *vif,
2087 struct add_sta_param *param)
2093 wid.id = (u16)WID_ADD_STA;
2095 wid.size = WILC_ADD_STA_LENGTH + param->rates_len;
2097 wid.val = kmalloc(wid.size, GFP_KERNEL);
2102 cur_byte += wilc_hif_pack_sta_param(cur_byte, param);
2104 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2105 wilc_get_vif_idx(vif));
2107 netdev_err(vif->ndev, "Failed to send add station\n");
2110 kfree(param->rates);
2114 static void handle_del_all_sta(struct wilc_vif *vif,
2115 struct del_all_sta *param)
2121 u8 zero_buff[6] = {0};
2123 wid.id = (u16)WID_DEL_ALL_STA;
2125 wid.size = (param->assoc_sta * ETH_ALEN) + 1;
2127 wid.val = kmalloc((param->assoc_sta * ETH_ALEN) + 1, GFP_KERNEL);
2131 curr_byte = wid.val;
2133 *(curr_byte++) = param->assoc_sta;
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);
2141 curr_byte += ETH_ALEN;
2144 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2145 wilc_get_vif_idx(vif));
2147 netdev_err(vif->ndev, "Failed to send add station\n");
2152 complete(&hif_wait_response);
2155 static void handle_del_station(struct wilc_vif *vif, struct del_sta *param)
2161 wid.id = (u16)WID_REMOVE_STA;
2163 wid.size = ETH_ALEN;
2165 wid.val = kmalloc(wid.size, GFP_KERNEL);
2171 ether_addr_copy(cur_byte, param->mac_addr);
2173 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2174 wilc_get_vif_idx(vif));
2176 netdev_err(vif->ndev, "Failed to send add station\n");
2182 static void handle_edit_station(struct wilc_vif *vif,
2183 struct add_sta_param *param)
2189 wid.id = (u16)WID_EDIT_STA;
2191 wid.size = WILC_ADD_STA_LENGTH + param->rates_len;
2193 wid.val = kmalloc(wid.size, GFP_KERNEL);
2198 cur_byte += wilc_hif_pack_sta_param(cur_byte, param);
2200 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2201 wilc_get_vif_idx(vif));
2203 netdev_err(vif->ndev, "Failed to send edit station\n");
2206 kfree(param->rates);
2210 static int handle_remain_on_chan(struct wilc_vif *vif,
2211 struct remain_ch *hif_remain_ch)
2214 u8 remain_on_chan_flag;
2216 struct host_if_drv *hif_drv = vif->hif_drv;
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;
2225 hif_remain_ch->ch = hif_drv->remain_on_ch.ch;
2228 if (hif_drv->usr_scan_req.scan_result) {
2229 hif_drv->remain_on_ch_pending = 1;
2233 if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) {
2238 if (wilc_optaining_ip || wilc_connecting) {
2243 remain_on_chan_flag = true;
2244 wid.id = (u16)WID_REMAIN_ON_CHAN;
2247 wid.val = kmalloc(wid.size, GFP_KERNEL);
2253 wid.val[0] = remain_on_chan_flag;
2254 wid.val[1] = (s8)hif_remain_ch->ch;
2256 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2257 wilc_get_vif_idx(vif));
2260 netdev_err(vif->ndev, "Failed to set remain on channel\n");
2264 P2P_LISTEN_STATE = 1;
2265 hif_drv->remain_on_ch_timer_vif = vif;
2266 mod_timer(&hif_drv->remain_on_ch_timer,
2268 msecs_to_jiffies(hif_remain_ch->duration));
2270 if (hif_drv->remain_on_ch.ready)
2271 hif_drv->remain_on_ch.ready(hif_drv->remain_on_ch.arg);
2273 if (hif_drv->remain_on_ch_pending)
2274 hif_drv->remain_on_ch_pending = 0;
2280 static int handle_register_frame(struct wilc_vif *vif,
2281 struct reg_frame *hif_reg_frame)
2287 wid.id = (u16)WID_REGISTER_FRAME;
2289 wid.val = kmalloc(sizeof(u16) + 2, GFP_KERNEL);
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));
2299 wid.size = sizeof(u16) + 2;
2301 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2302 wilc_get_vif_idx(vif));
2305 netdev_err(vif->ndev, "Failed to frame register\n");
2312 static u32 handle_listen_state_expired(struct wilc_vif *vif,
2313 struct remain_ch *hif_remain_ch)
2315 u8 remain_on_chan_flag;
2318 struct host_if_drv *hif_drv = vif->hif_drv;
2320 if (P2P_LISTEN_STATE) {
2321 remain_on_chan_flag = false;
2322 wid.id = (u16)WID_REMAIN_ON_CHAN;
2325 wid.val = kmalloc(wid.size, GFP_KERNEL);
2330 wid.val[0] = remain_on_chan_flag;
2331 wid.val[1] = FALSE_FRMWR_CHANNEL;
2333 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2334 wilc_get_vif_idx(vif));
2337 netdev_err(vif->ndev, "Failed to set remain channel\n");
2341 if (hif_drv->remain_on_ch.expired) {
2342 hif_drv->remain_on_ch.expired(hif_drv->remain_on_ch.arg,
2345 P2P_LISTEN_STATE = 0;
2347 netdev_dbg(vif->ndev, "Not in listen state\n");
2355 static void listen_timer_cb(struct timer_list *t)
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;
2361 struct host_if_msg msg;
2363 del_timer(&vif->hif_drv->remain_on_ch_timer);
2365 memset(&msg, 0, sizeof(struct host_if_msg));
2366 msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
2368 msg.body.remain_on_ch.id = vif->hif_drv->remain_on_ch.id;
2370 result = wilc_enqueue_cmd(&msg);
2372 netdev_err(vif->ndev, "wilc_mq_send fail\n");
2375 static void handle_power_management(struct wilc_vif *vif,
2376 struct power_mgmt_param *pm_param)
2382 wid.id = (u16)WID_POWER_MANAGEMENT;
2384 if (pm_param->enabled)
2385 power_mode = MIN_FAST_PS;
2387 power_mode = NO_POWERSAVE;
2389 wid.val = &power_mode;
2390 wid.size = sizeof(char);
2392 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2393 wilc_get_vif_idx(vif));
2395 netdev_err(vif->ndev, "Failed to send power management\n");
2398 static void handle_set_mcast_filter(struct wilc_vif *vif,
2399 struct set_multicast *hif_set_mc)
2405 wid.id = (u16)WID_SETUP_MULTICAST_FILTER;
2407 wid.size = sizeof(struct set_multicast) + (hif_set_mc->cnt * ETH_ALEN);
2408 wid.val = kmalloc(wid.size, GFP_KERNEL);
2413 *cur_byte++ = (hif_set_mc->enabled & 0xFF);
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);
2423 if (hif_set_mc->cnt > 0)
2424 memcpy(cur_byte, wilc_multicast_mac_addr_list,
2425 ((hif_set_mc->cnt) * ETH_ALEN));
2427 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2428 wilc_get_vif_idx(vif));
2430 netdev_err(vif->ndev, "Failed to send setup multicast\n");
2436 static void handle_set_tx_pwr(struct wilc_vif *vif, u8 tx_pwr)
2441 wid.id = (u16)WID_TX_POWER;
2442 wid.type = WID_CHAR;
2444 wid.size = sizeof(char);
2446 ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2447 wilc_get_vif_idx(vif));
2449 netdev_err(vif->ndev, "Failed to set TX PWR\n");
2452 static void handle_get_tx_pwr(struct wilc_vif *vif, u8 *tx_pwr)
2457 wid.id = (u16)WID_TX_POWER;
2458 wid.type = WID_CHAR;
2459 wid.val = (s8 *)tx_pwr;
2460 wid.size = sizeof(char);
2462 ret = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
2463 wilc_get_vif_idx(vif));
2465 netdev_err(vif->ndev, "Failed to get TX PWR\n");
2467 complete(&hif_wait_response);
2470 static void host_if_work(struct work_struct *work)
2472 struct host_if_msg *msg;
2476 msg = container_of(work, struct host_if_msg, work);
2477 wilc = msg->vif->wilc;
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);
2486 case HOST_IF_MSG_SCAN:
2487 handle_scan(msg->vif, &msg->body.scan_info);
2490 case HOST_IF_MSG_CONNECT:
2491 handle_connect(msg->vif, &msg->body.con_info);
2494 case HOST_IF_MSG_RCVD_NTWRK_INFO:
2495 handle_rcvd_ntwrk_info(msg->vif, &msg->body.net_info);
2498 case HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO:
2499 handle_rcvd_gnrl_async_info(msg->vif,
2500 &msg->body.async_info);
2503 case HOST_IF_MSG_KEY:
2504 handle_key(msg->vif, &msg->body.key_info);
2507 case HOST_IF_MSG_CFG_PARAMS:
2508 handle_cfg_param(msg->vif, &msg->body.cfg_info);
2511 case HOST_IF_MSG_SET_CHANNEL:
2512 handle_set_channel(msg->vif, &msg->body.channel_info);
2515 case HOST_IF_MSG_DISCONNECT:
2516 handle_disconnect(msg->vif);
2519 case HOST_IF_MSG_RCVD_SCAN_COMPLETE:
2520 del_timer(&msg->vif->hif_drv->scan_timer);
2522 if (!wilc_wlan_get_num_conn_ifcs(wilc))
2523 wilc_chip_sleep_manually(wilc);
2525 handle_scan_done(msg->vif, SCAN_EVENT_DONE);
2527 if (msg->vif->hif_drv->remain_on_ch_pending)
2528 handle_remain_on_chan(msg->vif,
2529 &msg->body.remain_on_ch);
2533 case HOST_IF_MSG_GET_RSSI:
2534 handle_get_rssi(msg->vif);
2537 case HOST_IF_MSG_GET_STATISTICS:
2538 handle_get_statistics(msg->vif,
2539 (struct rf_info *)msg->body.data);
2542 case HOST_IF_MSG_ADD_BEACON:
2543 handle_add_beacon(msg->vif, &msg->body.beacon_info);
2546 case HOST_IF_MSG_DEL_BEACON:
2547 handle_del_beacon(msg->vif);
2550 case HOST_IF_MSG_ADD_STATION:
2551 handle_add_station(msg->vif, &msg->body.add_sta_info);
2554 case HOST_IF_MSG_DEL_STATION:
2555 handle_del_station(msg->vif, &msg->body.del_sta_info);
2558 case HOST_IF_MSG_EDIT_STATION:
2559 handle_edit_station(msg->vif, &msg->body.edit_sta_info);
2562 case HOST_IF_MSG_GET_INACTIVETIME:
2563 handle_get_inactive_time(msg->vif, &msg->body.mac_info);
2566 case HOST_IF_MSG_SCAN_TIMER_FIRED:
2567 handle_scan_done(msg->vif, SCAN_EVENT_ABORTED);
2570 case HOST_IF_MSG_CONNECT_TIMER_FIRED:
2571 handle_connect_timeout(msg->vif);
2574 case HOST_IF_MSG_POWER_MGMT:
2575 handle_power_management(msg->vif,
2576 &msg->body.pwr_mgmt_info);
2579 case HOST_IF_MSG_SET_WFIDRV_HANDLER:
2580 ret = handle_set_wfi_drv_handler(msg->vif, &msg->body.drv);
2583 case HOST_IF_MSG_SET_OPERATION_MODE:
2584 handle_set_operation_mode(msg->vif, &msg->body.mode);
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);
2593 case HOST_IF_MSG_GET_IPADDRESS:
2594 handle_get_ip_address(msg->vif, msg->body.ip_info.idx);
2597 case HOST_IF_MSG_GET_MAC_ADDRESS:
2598 handle_get_mac_address(msg->vif,
2599 &msg->body.get_mac_info);
2602 case HOST_IF_MSG_REMAIN_ON_CHAN:
2603 handle_remain_on_chan(msg->vif, &msg->body.remain_on_ch);
2606 case HOST_IF_MSG_REGISTER_FRAME:
2607 handle_register_frame(msg->vif, &msg->body.reg_frame);
2610 case HOST_IF_MSG_LISTEN_TIMER_FIRED:
2611 handle_listen_state_expired(msg->vif, &msg->body.remain_on_ch);
2614 case HOST_IF_MSG_SET_MULTICAST_FILTER:
2615 handle_set_mcast_filter(msg->vif, &msg->body.multicast_info);
2618 case HOST_IF_MSG_DEL_ALL_STA:
2619 handle_del_all_sta(msg->vif, &msg->body.del_all_sta_info);
2622 case HOST_IF_MSG_SET_TX_POWER:
2623 handle_set_tx_pwr(msg->vif, msg->body.tx_power.tx_pwr);
2626 case HOST_IF_MSG_GET_TX_POWER:
2627 handle_get_tx_pwr(msg->vif, &msg->body.tx_power.tx_pwr);
2630 netdev_err(msg->vif->ndev, "[Host Interface] undefined\n");
2635 netdev_err(msg->vif->ndev, "Host cmd %d failed\n", msg->id);
2637 complete(&hif_thread_comp);
2640 static void timer_scan_cb(struct timer_list *t)
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;
2646 memset(&msg, 0, sizeof(struct host_if_msg));
2648 msg.id = HOST_IF_MSG_SCAN_TIMER_FIRED;
2650 wilc_enqueue_cmd(&msg);
2653 static void timer_connect_cb(struct timer_list *t)
2655 struct host_if_drv *hif_drv = from_timer(hif_drv, t,
2657 struct wilc_vif *vif = hif_drv->connect_timer_vif;
2658 struct host_if_msg msg;
2660 memset(&msg, 0, sizeof(struct host_if_msg));
2662 msg.id = HOST_IF_MSG_CONNECT_TIMER_FIRED;
2664 wilc_enqueue_cmd(&msg);
2667 s32 wilc_remove_key(struct host_if_drv *hif_drv, const u8 *sta_addr)
2671 wid.id = (u16)WID_REMOVE_KEY;
2673 wid.val = (s8 *)sta_addr;
2679 int wilc_remove_wep_key(struct wilc_vif *vif, u8 index)
2682 struct host_if_msg msg;
2683 struct host_if_drv *hif_drv = vif->hif_drv;
2687 netdev_err(vif->ndev, "Failed to send setup multicast\n");
2691 memset(&msg, 0, sizeof(struct host_if_msg));
2693 msg.id = HOST_IF_MSG_KEY;
2694 msg.body.key_info.type = WEP;
2695 msg.body.key_info.action = REMOVEKEY;
2697 msg.body.key_info.attr.wep.index = index;
2699 result = wilc_enqueue_cmd(&msg);
2701 netdev_err(vif->ndev, "Request to remove WEP key\n");
2703 wait_for_completion(&hif_drv->comp_test_key_block);
2708 int wilc_set_wep_default_keyid(struct wilc_vif *vif, u8 index)
2711 struct host_if_msg msg;
2712 struct host_if_drv *hif_drv = vif->hif_drv;
2716 netdev_err(vif->ndev, "driver is null\n");
2720 memset(&msg, 0, sizeof(struct host_if_msg));
2722 msg.id = HOST_IF_MSG_KEY;
2723 msg.body.key_info.type = WEP;
2724 msg.body.key_info.action = DEFAULTKEY;
2726 msg.body.key_info.attr.wep.index = index;
2728 result = wilc_enqueue_cmd(&msg);
2730 netdev_err(vif->ndev, "Default key index\n");
2732 wait_for_completion(&hif_drv->comp_test_key_block);
2737 int wilc_add_wep_key_bss_sta(struct wilc_vif *vif, const u8 *key, u8 len,
2741 struct host_if_msg msg;
2742 struct host_if_drv *hif_drv = vif->hif_drv;
2745 netdev_err(vif->ndev, "driver is null\n");
2749 memset(&msg, 0, sizeof(struct host_if_msg));
2751 msg.id = HOST_IF_MSG_KEY;
2752 msg.body.key_info.type = WEP;
2753 msg.body.key_info.action = ADDKEY;
2755 msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL);
2756 if (!msg.body.key_info.attr.wep.key)
2759 msg.body.key_info.attr.wep.key_len = len;
2760 msg.body.key_info.attr.wep.index = index;
2762 result = wilc_enqueue_cmd(&msg);
2764 netdev_err(vif->ndev, "STA - WEP Key\n");
2765 kfree(msg.body.key_info.attr.wep.key);
2769 wait_for_completion(&hif_drv->comp_test_key_block);
2773 int wilc_add_wep_key_bss_ap(struct wilc_vif *vif, const u8 *key, u8 len,
2774 u8 index, u8 mode, enum AUTHTYPE auth_type)
2777 struct host_if_msg msg;
2778 struct host_if_drv *hif_drv = vif->hif_drv;
2781 netdev_err(vif->ndev, "driver is null\n");
2785 memset(&msg, 0, sizeof(struct host_if_msg));
2787 msg.id = HOST_IF_MSG_KEY;
2788 msg.body.key_info.type = WEP;
2789 msg.body.key_info.action = ADDKEY_AP;
2791 msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL);
2792 if (!msg.body.key_info.attr.wep.key)
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;
2800 result = wilc_enqueue_cmd(&msg);
2802 netdev_err(vif->ndev, "AP - WEP Key\n");
2803 kfree(msg.body.key_info.attr.wep.key);
2807 wait_for_completion(&hif_drv->comp_test_key_block);
2811 int 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)
2816 struct host_if_msg msg;
2817 struct host_if_drv *hif_drv = vif->hif_drv;
2818 u8 key_len = ptk_key_len;
2821 netdev_err(vif->ndev, "driver is null\n");
2826 key_len += RX_MIC_KEY_LEN;
2829 key_len += TX_MIC_KEY_LEN;
2831 memset(&msg, 0, sizeof(struct host_if_msg));
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;
2839 if (mode == STATION_MODE)
2840 msg.body.key_info.action = ADDKEY;
2842 msg.body.key_info.attr.wpa.key = kmemdup(ptk, ptk_key_len, GFP_KERNEL);
2843 if (!msg.body.key_info.attr.wpa.key)
2847 memcpy(msg.body.key_info.attr.wpa.key + 16, rx_mic,
2851 memcpy(msg.body.key_info.attr.wpa.key + 24, tx_mic,
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;
2859 result = wilc_enqueue_cmd(&msg);
2861 netdev_err(vif->ndev, "PTK Key\n");
2862 kfree(msg.body.key_info.attr.wpa.key);
2866 wait_for_completion(&hif_drv->comp_test_key_block);
2870 int 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,
2876 struct host_if_msg msg;
2877 struct host_if_drv *hif_drv = vif->hif_drv;
2878 u8 key_len = gtk_key_len;
2881 netdev_err(vif->ndev, "driver is null\n");
2884 memset(&msg, 0, sizeof(struct host_if_msg));
2887 key_len += RX_MIC_KEY_LEN;
2890 key_len += TX_MIC_KEY_LEN;
2893 msg.body.key_info.attr.wpa.seq = kmemdup(key_rsc,
2896 if (!msg.body.key_info.attr.wpa.seq)
2900 msg.id = HOST_IF_MSG_KEY;
2901 msg.body.key_info.type = WPA_RX_GTK;
2904 if (mode == AP_MODE) {
2905 msg.body.key_info.action = ADDKEY_AP;
2906 msg.body.key_info.attr.wpa.mode = cipher_mode;
2908 if (mode == STATION_MODE)
2909 msg.body.key_info.action = ADDKEY;
2911 msg.body.key_info.attr.wpa.key = kmemdup(rx_gtk,
2914 if (!msg.body.key_info.attr.wpa.key) {
2915 kfree(msg.body.key_info.attr.wpa.seq);
2920 memcpy(msg.body.key_info.attr.wpa.key + 16, rx_mic,
2924 memcpy(msg.body.key_info.attr.wpa.key + 24, tx_mic,
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;
2931 result = wilc_enqueue_cmd(&msg);
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);
2939 wait_for_completion(&hif_drv->comp_test_key_block);
2943 int wilc_set_pmkid_info(struct wilc_vif *vif,
2944 struct host_if_pmkid_attr *pmkid)
2947 struct host_if_msg msg;
2950 memset(&msg, 0, sizeof(struct host_if_msg));
2952 msg.id = HOST_IF_MSG_KEY;
2953 msg.body.key_info.type = PMKSA;
2954 msg.body.key_info.action = ADDKEY;
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);
2964 result = wilc_enqueue_cmd(&msg);
2966 netdev_err(vif->ndev, "PMKID Info\n");
2971 int wilc_get_mac_address(struct wilc_vif *vif, u8 *mac_addr)
2974 struct host_if_msg msg;
2976 memset(&msg, 0, sizeof(struct host_if_msg));
2978 msg.id = HOST_IF_MSG_GET_MAC_ADDRESS;
2979 msg.body.get_mac_info.mac_addr = mac_addr;
2982 result = wilc_enqueue_cmd(&msg);
2984 netdev_err(vif->ndev, "Failed to send get mac address\n");
2988 wait_for_completion(&hif_wait_response);
2992 int 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)
2999 struct host_if_msg msg;
3000 struct host_if_drv *hif_drv = vif->hif_drv;
3002 if (!hif_drv || !connect_result) {
3003 netdev_err(vif->ndev, "Driver is null\n");
3008 netdev_err(vif->ndev, "Unable to Join - JoinParams is NULL\n");
3012 memset(&msg, 0, sizeof(struct host_if_msg));
3014 msg.id = HOST_IF_MSG_CONNECT;
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;
3025 msg.body.con_info.bssid = kmemdup(bssid, 6, GFP_KERNEL);
3026 if (!msg.body.con_info.bssid)
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)
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)
3043 if (hif_drv->hif_state < HOST_IF_CONNECTING)
3044 hif_drv->hif_state = HOST_IF_CONNECTING;
3046 result = wilc_enqueue_cmd(&msg);
3048 netdev_err(vif->ndev, "send message: Set join request\n");
3052 hif_drv->connect_timer_vif = vif;
3053 mod_timer(&hif_drv->connect_timer,
3054 jiffies + msecs_to_jiffies(HOST_IF_CONNECT_TIMEOUT));
3059 int wilc_disconnect(struct wilc_vif *vif, u16 reason_code)
3062 struct host_if_msg msg;
3063 struct host_if_drv *hif_drv = vif->hif_drv;
3066 netdev_err(vif->ndev, "Driver is null\n");
3070 memset(&msg, 0, sizeof(struct host_if_msg));
3072 msg.id = HOST_IF_MSG_DISCONNECT;
3075 result = wilc_enqueue_cmd(&msg);
3077 netdev_err(vif->ndev, "Failed to send message: disconnect\n");
3079 wait_for_completion(&hif_drv->comp_test_disconn_block);
3084 static 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)
3092 wid.id = (u16)WID_ASSOC_RES_INFO;
3094 wid.val = assoc_resp_info;
3095 wid.size = max_assoc_resp_info_len;
3097 result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
3098 wilc_get_vif_idx(vif));
3100 *rcvd_assoc_resp_info_len = 0;
3101 netdev_err(vif->ndev, "Failed to send association response\n");
3105 *rcvd_assoc_resp_info_len = wid.size;
3109 int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 channel)
3112 struct host_if_msg msg;
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;
3119 result = wilc_enqueue_cmd(&msg);
3121 netdev_err(vif->ndev, "wilc mq send fail\n");
3128 int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mode,
3132 struct host_if_msg msg;
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;
3141 result = wilc_enqueue_cmd(&msg);
3143 netdev_err(vif->ndev, "wilc mq send fail\n");
3150 int wilc_set_operation_mode(struct wilc_vif *vif, u32 mode)
3153 struct host_if_msg msg;
3155 memset(&msg, 0, sizeof(struct host_if_msg));
3156 msg.id = HOST_IF_MSG_SET_OPERATION_MODE;
3157 msg.body.mode.mode = mode;
3160 result = wilc_enqueue_cmd(&msg);
3162 netdev_err(vif->ndev, "wilc mq send fail\n");
3169 s32 wilc_get_inactive_time(struct wilc_vif *vif, const u8 *mac,
3173 struct host_if_msg msg;
3174 struct host_if_drv *hif_drv = vif->hif_drv;
3177 netdev_err(vif->ndev, "driver is null\n");
3181 memset(&msg, 0, sizeof(struct host_if_msg));
3182 memcpy(msg.body.mac_info.mac, mac, ETH_ALEN);
3184 msg.id = HOST_IF_MSG_GET_INACTIVETIME;
3187 result = wilc_enqueue_cmd(&msg);
3189 netdev_err(vif->ndev, "Failed to send get host ch param\n");
3191 wait_for_completion(&hif_drv->comp_inactive_time);
3193 *out_val = inactive_time;
3198 int wilc_get_rssi(struct wilc_vif *vif, s8 *rssi_level)
3201 struct host_if_msg msg;
3202 struct host_if_drv *hif_drv = vif->hif_drv;
3204 memset(&msg, 0, sizeof(struct host_if_msg));
3205 msg.id = HOST_IF_MSG_GET_RSSI;
3208 result = wilc_enqueue_cmd(&msg);
3210 netdev_err(vif->ndev, "Failed to send get host ch param\n");
3214 wait_for_completion(&hif_drv->comp_get_rssi);
3217 netdev_err(vif->ndev, "RSS pointer value is null\n");
3226 int wilc_get_statistics(struct wilc_vif *vif, struct rf_info *stats)
3229 struct host_if_msg msg;
3231 memset(&msg, 0, sizeof(struct host_if_msg));
3232 msg.id = HOST_IF_MSG_GET_STATISTICS;
3233 msg.body.data = (char *)stats;
3236 result = wilc_enqueue_cmd(&msg);
3238 netdev_err(vif->ndev, "Failed to send get host channel\n");
3242 if (stats != &vif->wilc->dummy_statistics)
3243 wait_for_completion(&hif_wait_response);
3247 int 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)
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;
3257 if (!hif_drv || !scan_result) {
3258 netdev_err(vif->ndev, "hif_drv or scan_result = NULL\n");
3262 memset(&msg, 0, sizeof(struct host_if_msg));
3264 msg.id = HOST_IF_MSG_SCAN;
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;
3272 scan_info->src = scan_source;
3273 scan_info->type = scan_type;
3274 scan_info->result = scan_result;
3275 scan_info->arg = user_arg;
3277 scan_info->ch_list_len = ch_list_len;
3278 scan_info->ch_freq_list = kmemdup(ch_freq_list,
3281 if (!scan_info->ch_freq_list)
3284 scan_info->ies_len = ies_len;
3285 scan_info->ies = kmemdup(ies, ies_len, GFP_KERNEL);
3286 if (!scan_info->ies)
3289 result = wilc_enqueue_cmd(&msg);
3291 netdev_err(vif->ndev, "Error in sending message queue\n");
3295 hif_drv->scan_timer_vif = vif;
3296 mod_timer(&hif_drv->scan_timer,
3297 jiffies + msecs_to_jiffies(HOST_IF_SCAN_TIMEOUT));
3302 int wilc_hif_set_cfg(struct wilc_vif *vif,
3303 struct cfg_param_attr *cfg_param)
3305 struct host_if_msg msg;
3306 struct host_if_drv *hif_drv = vif->hif_drv;
3309 netdev_err(vif->ndev, "hif_drv NULL\n");
3313 memset(&msg, 0, sizeof(struct host_if_msg));
3314 msg.id = HOST_IF_MSG_CFG_PARAMS;
3315 msg.body.cfg_info = *cfg_param;
3318 return wilc_enqueue_cmd(&msg);
3321 static void get_periodic_rssi(struct timer_list *unused)
3323 struct wilc_vif *vif = periodic_rssi_vif;
3325 if (!vif->hif_drv) {
3326 netdev_err(vif->ndev, "Driver handler is NULL\n");
3330 if (vif->hif_drv->hif_state == HOST_IF_CONNECTED)
3331 wilc_get_statistics(vif, &vif->wilc->dummy_statistics);
3333 mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
3336 int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
3339 struct host_if_drv *hif_drv;
3340 struct wilc_vif *vif;
3344 vif = netdev_priv(dev);
3347 scan_while_connected = false;
3349 init_completion(&hif_wait_response);
3351 hif_drv = kzalloc(sizeof(*hif_drv), GFP_KERNEL);
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;
3364 wilc_optaining_ip = false;
3366 if (clients_count == 0) {
3367 init_completion(&hif_thread_comp);
3368 init_completion(&hif_driver_comp);
3369 mutex_init(&hif_deinit_lock);
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);
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");
3385 periodic_rssi_vif = vif;
3386 timer_setup(&periodic_rssi, get_periodic_rssi, 0);
3387 mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
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);
3394 mutex_init(&hif_drv->cfg_values_lock);
3395 mutex_lock(&hif_drv->cfg_values_lock);
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;
3404 hif_drv->p2p_timeout = 0;
3406 mutex_unlock(&hif_drv->cfg_values_lock);
3414 int wilc_deinit(struct wilc_vif *vif)
3417 struct host_if_msg msg;
3418 struct host_if_drv *hif_drv = vif->hif_drv;
3421 netdev_err(vif->ndev, "hif_drv = NULL\n");
3425 mutex_lock(&hif_deinit_lock);
3427 terminated_handle = hif_drv;
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);
3434 wilc_set_wfi_drv_handler(vif, 0, 0, 0);
3435 wait_for_completion(&hif_driver_comp);
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,
3441 hif_drv->usr_scan_req.scan_result = NULL;
3444 hif_drv->hif_state = HOST_IF_IDLE;
3446 scan_while_connected = false;
3448 memset(&msg, 0, sizeof(struct host_if_msg));
3450 if (clients_count == 1) {
3451 msg.id = HOST_IF_MSG_EXIT;
3454 result = wilc_enqueue_cmd(&msg);
3456 netdev_err(vif->ndev, "deinit : Error(%d)\n", result);
3458 wait_for_completion(&hif_thread_comp);
3460 destroy_workqueue(hif_workqueue);
3466 terminated_handle = NULL;
3467 mutex_unlock(&hif_deinit_lock);
3471 void wilc_network_info_received(struct wilc *wilc, u8 *buffer, u32 length)
3474 struct host_if_msg msg;
3476 struct host_if_drv *hif_drv = NULL;
3477 struct wilc_vif *vif;
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);
3486 hif_drv = vif->hif_drv;
3488 if (!hif_drv || hif_drv == terminated_handle) {
3489 netdev_err(vif->ndev, "driver not init[%p]\n", hif_drv);
3493 memset(&msg, 0, sizeof(struct host_if_msg));
3495 msg.id = HOST_IF_MSG_RCVD_NTWRK_INFO;
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)
3503 result = wilc_enqueue_cmd(&msg);
3505 netdev_err(vif->ndev, "message parameters (%d)\n", result);
3506 kfree(msg.body.net_info.buffer);
3510 void wilc_gnrl_async_info_received(struct wilc *wilc, u8 *buffer, u32 length)
3513 struct host_if_msg msg;
3515 struct host_if_drv *hif_drv = NULL;
3516 struct wilc_vif *vif;
3518 mutex_lock(&hif_deinit_lock);
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);
3526 mutex_unlock(&hif_deinit_lock);
3530 hif_drv = vif->hif_drv;
3532 if (!hif_drv || hif_drv == terminated_handle) {
3533 mutex_unlock(&hif_deinit_lock);
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);
3543 memset(&msg, 0, sizeof(struct host_if_msg));
3545 msg.id = HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO;
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);
3555 result = wilc_enqueue_cmd(&msg);
3557 netdev_err(vif->ndev, "synchronous info (%d)\n", result);
3558 kfree(msg.body.async_info.buffer);
3561 mutex_unlock(&hif_deinit_lock);
3564 void wilc_scan_complete_received(struct wilc *wilc, u8 *buffer, u32 length)
3567 struct host_if_msg msg;
3569 struct host_if_drv *hif_drv = NULL;
3570 struct wilc_vif *vif;
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);
3579 hif_drv = vif->hif_drv;
3581 if (!hif_drv || hif_drv == terminated_handle)
3584 if (hif_drv->usr_scan_req.scan_result) {
3585 memset(&msg, 0, sizeof(struct host_if_msg));
3587 msg.id = HOST_IF_MSG_RCVD_SCAN_COMPLETE;
3590 result = wilc_enqueue_cmd(&msg);
3592 netdev_err(vif->ndev, "complete param (%d)\n", result);
3596 int 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,
3603 struct host_if_msg msg;
3605 memset(&msg, 0, sizeof(struct host_if_msg));
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;
3616 result = wilc_enqueue_cmd(&msg);
3618 netdev_err(vif->ndev, "wilc mq send fail\n");
3623 int wilc_listen_state_expired(struct wilc_vif *vif, u32 session_id)
3626 struct host_if_msg msg;
3627 struct host_if_drv *hif_drv = vif->hif_drv;
3630 netdev_err(vif->ndev, "driver is null\n");
3634 del_timer(&hif_drv->remain_on_ch_timer);
3636 memset(&msg, 0, sizeof(struct host_if_msg));
3637 msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
3639 msg.body.remain_on_ch.id = session_id;
3641 result = wilc_enqueue_cmd(&msg);
3643 netdev_err(vif->ndev, "wilc mq send fail\n");
3648 int wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg)
3651 struct host_if_msg msg;
3653 memset(&msg, 0, sizeof(struct host_if_msg));
3655 msg.id = HOST_IF_MSG_REGISTER_FRAME;
3656 switch (frame_type) {
3658 msg.body.reg_frame.reg_id = ACTION_FRM_IDX;
3662 msg.body.reg_frame.reg_id = PROBE_REQ_IDX;
3668 msg.body.reg_frame.frame_type = frame_type;
3669 msg.body.reg_frame.reg = reg;
3672 result = wilc_enqueue_cmd(&msg);
3674 netdev_err(vif->ndev, "wilc mq send fail\n");
3679 int wilc_add_beacon(struct wilc_vif *vif, u32 interval, u32 dtim_period,
3680 u32 head_len, u8 *head, u32 tail_len, u8 *tail)
3683 struct host_if_msg msg;
3684 struct beacon_attr *beacon_info = &msg.body.beacon_info;
3686 memset(&msg, 0, sizeof(struct host_if_msg));
3688 msg.id = HOST_IF_MSG_ADD_BEACON;
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) {
3698 beacon_info->tail_len = tail_len;
3701 beacon_info->tail = kmemdup(tail, tail_len, GFP_KERNEL);
3702 if (!beacon_info->tail) {
3707 beacon_info->tail = NULL;
3710 result = wilc_enqueue_cmd(&msg);
3712 netdev_err(vif->ndev, "wilc mq send fail\n");
3716 kfree(beacon_info->head);
3718 kfree(beacon_info->tail);
3724 int wilc_del_beacon(struct wilc_vif *vif)
3727 struct host_if_msg msg;
3729 msg.id = HOST_IF_MSG_DEL_BEACON;
3732 result = wilc_enqueue_cmd(&msg);
3734 netdev_err(vif->ndev, "wilc_mq_send fail\n");
3739 int wilc_add_station(struct wilc_vif *vif, struct add_sta_param *sta_param)
3742 struct host_if_msg msg;
3743 struct add_sta_param *add_sta_info = &msg.body.add_sta_info;
3745 memset(&msg, 0, sizeof(struct host_if_msg));
3747 msg.id = HOST_IF_MSG_ADD_STATION;
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,
3755 if (!add_sta_info->rates)
3759 result = wilc_enqueue_cmd(&msg);
3761 netdev_err(vif->ndev, "wilc_mq_send fail\n");
3762 kfree(add_sta_info->rates);
3767 int wilc_del_station(struct wilc_vif *vif, const u8 *mac_addr)
3770 struct host_if_msg msg;
3771 struct del_sta *del_sta_info = &msg.body.del_sta_info;
3773 memset(&msg, 0, sizeof(struct host_if_msg));
3775 msg.id = HOST_IF_MSG_DEL_STATION;
3779 eth_broadcast_addr(del_sta_info->mac_addr);
3781 memcpy(del_sta_info->mac_addr, mac_addr, ETH_ALEN);
3783 result = wilc_enqueue_cmd(&msg);
3785 netdev_err(vif->ndev, "wilc_mq_send fail\n");
3789 int wilc_del_allstation(struct wilc_vif *vif, u8 mac_addr[][ETH_ALEN])
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};
3798 memset(&msg, 0, sizeof(struct host_if_msg));
3800 msg.id = HOST_IF_MSG_DEL_ALL_STA;
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],
3813 del_all_sta_info->assoc_sta = assoc_sta;
3814 result = wilc_enqueue_cmd(&msg);
3817 netdev_err(vif->ndev, "wilc_mq_send fail\n");
3819 wait_for_completion(&hif_wait_response);
3824 int wilc_edit_station(struct wilc_vif *vif,
3825 struct add_sta_param *sta_param)
3828 struct host_if_msg msg;
3829 struct add_sta_param *add_sta_info = &msg.body.add_sta_info;
3831 memset(&msg, 0, sizeof(struct host_if_msg));
3833 msg.id = HOST_IF_MSG_EDIT_STATION;
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,
3841 if (!add_sta_info->rates)
3845 result = wilc_enqueue_cmd(&msg);
3847 netdev_err(vif->ndev, "wilc_mq_send fail\n");
3848 kfree(add_sta_info->rates);
3854 int wilc_set_power_mgmt(struct wilc_vif *vif, bool enabled, u32 timeout)
3857 struct host_if_msg msg;
3858 struct power_mgmt_param *pwr_mgmt_info = &msg.body.pwr_mgmt_info;
3860 if (wilc_wlan_get_num_conn_ifcs(vif->wilc) == 2 && enabled)
3863 memset(&msg, 0, sizeof(struct host_if_msg));
3865 msg.id = HOST_IF_MSG_POWER_MGMT;
3868 pwr_mgmt_info->enabled = enabled;
3869 pwr_mgmt_info->timeout = timeout;
3871 result = wilc_enqueue_cmd(&msg);
3873 netdev_err(vif->ndev, "wilc_mq_send fail\n");
3877 int wilc_setup_multicast_filter(struct wilc_vif *vif, bool enabled,
3881 struct host_if_msg msg;
3882 struct set_multicast *multicast_filter_param = &msg.body.multicast_info;
3884 memset(&msg, 0, sizeof(struct host_if_msg));
3886 msg.id = HOST_IF_MSG_SET_MULTICAST_FILTER;
3889 multicast_filter_param->enabled = enabled;
3890 multicast_filter_param->cnt = count;
3892 result = wilc_enqueue_cmd(&msg);
3894 netdev_err(vif->ndev, "wilc_mq_send fail\n");
3898 static void *host_int_parse_join_bss_param(struct network_info *info)
3900 struct join_bss_param *param = NULL;
3909 u8 pcipher_total_cnt = 0;
3910 u8 auth_total_cnt = 0;
3914 ies_len = info->ies_len;
3916 param = kzalloc(sizeof(*param), GFP_KERNEL);
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);
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;
3935 for (i = 0; i < rates_no; i++)
3936 param->supp_rates[i + 1] = ies[index + i];
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;
3944 param->supp_rates[0] += ext_rates_no;
3946 for (i = 0; i < (param->supp_rates[0] - rates_no); i++)
3947 param->supp_rates[rates_no + i + 1] = ies[index + i];
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;
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)) {
3970 param->tsf = info->tsf_lo;
3971 param->noa_enabled = 1;
3972 param->idx = ies[index + 9];
3974 if (ies[index + 10] & BIT(7)) {
3975 param->opp_enabled = 1;
3976 param->ct_window = ies[index + 10];
3978 param->opp_enabled = 0;
3981 param->cnt = ies[index + 11];
3982 p2p_cnt = index + 12;
3984 memcpy(param->duration, ies + p2p_cnt, 4);
3987 memcpy(param->interval, ies + p2p_cnt, 4);
3990 memcpy(param->start_time, ies + p2p_cnt, 4);
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;
3999 if (ies[rsn_idx] == RSN_IE) {
4000 param->mode_802_11i = 2;
4002 if (param->mode_802_11i == 0)
4003 param->mode_802_11i = 1;
4008 param->rsn_grp_policy = ies[rsn_idx];
4010 offset = ies[rsn_idx] * 4;
4011 pcipher_cnt = (ies[rsn_idx] > 3) ? 3 : ies[rsn_idx];
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];
4017 pcipher_total_cnt += pcipher_cnt;
4020 offset = ies[rsn_idx] * 4;
4022 auth_cnt = (ies[rsn_idx] > 3) ? 3 : ies[rsn_idx];
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];
4028 auth_total_cnt += auth_cnt;
4031 if (ies[index] == RSN_IE) {
4032 param->rsn_cap[0] = ies[rsn_idx];
4033 param->rsn_cap[1] = ies[rsn_idx + 1];
4036 param->rsn_found = true;
4037 index += ies[index + 1] + 2;
4039 index += ies[index + 1] + 2;
4043 return (void *)param;
4046 int wilc_setup_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
4049 struct host_if_msg msg;
4051 memset(&msg, 0, sizeof(struct host_if_msg));
4053 msg.id = HOST_IF_MSG_SET_IPADDRESS;
4055 msg.body.ip_info.ip_addr = ip_addr;
4057 msg.body.ip_info.idx = idx;
4059 result = wilc_enqueue_cmd(&msg);
4061 netdev_err(vif->ndev, "wilc_mq_send fail\n");
4066 static int host_int_get_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
4069 struct host_if_msg msg;
4071 memset(&msg, 0, sizeof(struct host_if_msg));
4073 msg.id = HOST_IF_MSG_GET_IPADDRESS;
4075 msg.body.ip_info.ip_addr = ip_addr;
4077 msg.body.ip_info.idx = idx;
4079 result = wilc_enqueue_cmd(&msg);
4081 netdev_err(vif->ndev, "wilc_mq_send fail\n");
4086 int wilc_set_tx_power(struct wilc_vif *vif, u8 tx_power)
4089 struct host_if_msg msg;
4091 memset(&msg, 0, sizeof(struct host_if_msg));
4093 msg.id = HOST_IF_MSG_SET_TX_POWER;
4094 msg.body.tx_power.tx_pwr = tx_power;
4097 ret = wilc_enqueue_cmd(&msg);
4099 netdev_err(vif->ndev, "wilc_mq_send fail\n");
4104 int wilc_get_tx_power(struct wilc_vif *vif, u8 *tx_power)
4107 struct host_if_msg msg;
4109 memset(&msg, 0, sizeof(struct host_if_msg));
4111 msg.id = HOST_IF_MSG_GET_TX_POWER;
4114 ret = wilc_enqueue_cmd(&msg);
4116 netdev_err(vif->ndev, "Failed to get TX PWR\n");
4118 wait_for_completion(&hif_wait_response);
4119 *tx_power = msg.body.tx_power.tx_pwr;