1 #include <linux/slab.h>
2 #include <linux/time.h>
3 #include <linux/kthread.h>
4 #include <linux/delay.h>
5 #include "host_interface.h"
6 #include "coreconfigurator.h"
8 #include "wilc_wlan_if.h"
9 #include "wilc_msgqueue.h"
10 #include <linux/etherdevice.h>
11 #include "wilc_wfi_netdevice.h"
13 #define HOST_IF_MSG_SCAN 0
14 #define HOST_IF_MSG_CONNECT 1
15 #define HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO 2
16 #define HOST_IF_MSG_KEY 3
17 #define HOST_IF_MSG_RCVD_NTWRK_INFO 4
18 #define HOST_IF_MSG_RCVD_SCAN_COMPLETE 5
19 #define HOST_IF_MSG_CFG_PARAMS 6
20 #define HOST_IF_MSG_SET_CHANNEL 7
21 #define HOST_IF_MSG_DISCONNECT 8
22 #define HOST_IF_MSG_GET_RSSI 9
23 #define HOST_IF_MSG_ADD_BEACON 11
24 #define HOST_IF_MSG_DEL_BEACON 12
25 #define HOST_IF_MSG_ADD_STATION 13
26 #define HOST_IF_MSG_DEL_STATION 14
27 #define HOST_IF_MSG_EDIT_STATION 15
28 #define HOST_IF_MSG_SCAN_TIMER_FIRED 16
29 #define HOST_IF_MSG_CONNECT_TIMER_FIRED 17
30 #define HOST_IF_MSG_POWER_MGMT 18
31 #define HOST_IF_MSG_GET_INACTIVETIME 19
32 #define HOST_IF_MSG_REMAIN_ON_CHAN 20
33 #define HOST_IF_MSG_REGISTER_FRAME 21
34 #define HOST_IF_MSG_LISTEN_TIMER_FIRED 22
35 #define HOST_IF_MSG_SET_WFIDRV_HANDLER 24
36 #define HOST_IF_MSG_SET_MAC_ADDRESS 25
37 #define HOST_IF_MSG_GET_MAC_ADDRESS 26
38 #define HOST_IF_MSG_SET_OPERATION_MODE 27
39 #define HOST_IF_MSG_SET_IPADDRESS 28
40 #define HOST_IF_MSG_GET_IPADDRESS 29
41 #define HOST_IF_MSG_GET_STATISTICS 31
42 #define HOST_IF_MSG_SET_MULTICAST_FILTER 32
43 #define HOST_IF_MSG_DEL_BA_SESSION 34
44 #define HOST_IF_MSG_DEL_ALL_STA 36
45 #define HOST_IF_MSG_SET_TX_POWER 38
46 #define HOST_IF_MSG_GET_TX_POWER 39
47 #define HOST_IF_MSG_EXIT 100
49 #define HOST_IF_SCAN_TIMEOUT 4000
50 #define HOST_IF_CONNECT_TIMEOUT 9500
52 #define BA_SESSION_DEFAULT_BUFFER_SIZE 16
53 #define BA_SESSION_DEFAULT_TIMEOUT 1000
54 #define BLOCK_ACK_REQ_SIZE 0x14
55 #define FALSE_FRMWR_CHANNEL 100
57 #define TCP_ACK_FILTER_LINK_SPEED_THRESH 54
58 #define DEFAULT_LINK_SPEED 72
60 struct host_if_wpa_attr {
70 struct host_if_wep_attr {
75 enum AUTHTYPE auth_type;
78 union host_if_key_attr {
79 struct host_if_wep_attr wep;
80 struct host_if_wpa_attr wpa;
81 struct host_if_pmkid_attr pmkid;
87 union host_if_key_attr attr;
97 wilc_scan_result result;
99 struct hidden_network hidden_network;
102 struct connect_attr {
109 wilc_connect_result result;
111 enum AUTHTYPE auth_type;
116 struct rcvd_async_info {
121 struct channel_attr {
134 struct set_multicast {
140 u8 del_all_sta[MAX_NUM_STA][ETH_ALEN];
145 u8 mac_addr[ETH_ALEN];
148 struct power_mgmt_param {
158 struct sta_inactive_t {
167 struct scan_attr scan_info;
168 struct connect_attr con_info;
169 struct rcvd_net_info net_info;
170 struct rcvd_async_info async_info;
171 struct key_attr key_info;
172 struct cfg_param_attr cfg_info;
173 struct channel_attr channel_info;
174 struct beacon_attr beacon_info;
175 struct add_sta_param add_sta_info;
176 struct del_sta del_sta_info;
177 struct add_sta_param edit_sta_info;
178 struct power_mgmt_param pwr_mgmt_info;
179 struct sta_inactive_t mac_info;
180 struct set_ip_addr ip_info;
181 struct drv_handler drv;
182 struct set_multicast multicast_info;
184 struct set_mac_addr set_mac_info;
185 struct get_mac_addr get_mac_info;
186 struct ba_session_info session_info;
187 struct remain_ch remain_on_ch;
188 struct reg_frame reg_frame;
190 struct del_all_sta del_all_sta_info;
191 struct tx_power tx_power;
196 union message_body body;
197 struct wilc_vif *vif;
200 struct join_bss_param {
206 char ssid[MAX_SSID_LEN];
208 u8 supp_rates[MAX_RATES_SUPPORTED + 1];
215 u8 rsn_pcip_policy[3];
216 u8 rsn_auth_policy[3];
229 static struct host_if_drv *terminated_handle;
230 bool wilc_optaining_ip;
231 static u8 P2P_LISTEN_STATE;
232 static struct task_struct *hif_thread_handler;
233 static struct message_queue hif_msg_q;
234 static struct semaphore hif_sema_thread;
235 static struct semaphore hif_sema_driver;
236 static struct semaphore hif_sema_wait_response;
237 static struct semaphore hif_sema_deinit;
238 static struct timer_list periodic_rssi;
240 u8 wilc_multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN];
242 static u8 rcv_assoc_resp[MAX_ASSOC_RESP_FRAME_SIZE];
244 static bool scan_while_connected;
247 static u8 set_ip[2][4];
248 static u8 get_ip[2][4];
249 static u32 inactive_time;
250 static u8 del_beacon;
251 static u32 clients_count;
254 static u8 *info_element;
257 static u32 join_req_size;
258 static u32 info_element_size;
259 static struct wilc_vif *join_req_vif;
260 #define REAL_JOIN_REQ 0
261 #define FLUSHED_JOIN_REQ 1
262 #define FLUSHED_BYTE_POS 79
264 static void *host_int_ParseJoinBssParam(struct network_info *ptstrNetworkInfo);
265 static int host_int_get_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx);
267 /* The u8IfIdx starts from 0 to NUM_CONCURRENT_IFC -1, but 0 index used as
268 * special purpose in wilc device, so we add 1 to the index to starts from 1.
269 * As a result, the returned index will be 1 to NUM_CONCURRENT_IFC.
271 int wilc_get_vif_idx(struct wilc_vif *vif)
276 /* We need to minus 1 from idx which is from wilc device to get real index
277 * of wilc->vif[], because we add 1 when pass to wilc device in the function
279 * As a result, the index should be between 0 and NUM_CONCURRENT_IFC -1.
281 static struct wilc_vif *wilc_get_vif_from_idx(struct wilc *wilc, int idx)
285 if (index < 0 || index >= NUM_CONCURRENT_IFC)
288 return wilc->vif[index];
291 static void handle_set_channel(struct wilc_vif *vif,
292 struct channel_attr *hif_set_ch)
297 wid.id = (u16)WID_CURRENT_CHANNEL;
299 wid.val = (char *)&hif_set_ch->set_ch;
300 wid.size = sizeof(char);
302 ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
303 wilc_get_vif_idx(vif));
306 netdev_err(vif->ndev, "Failed to set channel\n");
309 static s32 handle_set_wfi_drv_handler(struct wilc_vif *vif,
310 struct drv_handler *hif_drv_handler)
315 wid.id = (u16)WID_SET_DRV_HANDLER;
317 wid.val = (s8 *)hif_drv_handler;
318 wid.size = sizeof(*hif_drv_handler);
320 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
321 hif_drv_handler->handler);
323 if (!hif_drv_handler->handler)
324 up(&hif_sema_driver);
327 netdev_err(vif->ndev, "Failed to set driver handler\n");
334 static s32 handle_set_operation_mode(struct wilc_vif *vif,
335 struct op_mode *hif_op_mode)
340 wid.id = (u16)WID_SET_OPERATION_MODE;
342 wid.val = (s8 *)&hif_op_mode->mode;
343 wid.size = sizeof(u32);
345 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
346 wilc_get_vif_idx(vif));
348 if ((hif_op_mode->mode) == IDLE_MODE)
349 up(&hif_sema_driver);
352 netdev_err(vif->ndev, "Failed to set driver handler\n");
359 static s32 handle_set_ip_address(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
363 char firmware_ip_addr[4] = {0};
365 if (ip_addr[0] < 192)
368 memcpy(set_ip[idx], ip_addr, IP_ALEN);
370 wid.id = (u16)WID_IP_ADDRESS;
372 wid.val = (u8 *)ip_addr;
375 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
376 wilc_get_vif_idx(vif));
378 host_int_get_ipaddress(vif, firmware_ip_addr, idx);
381 netdev_err(vif->ndev, "Failed to set IP address\n");
388 static s32 handle_get_ip_address(struct wilc_vif *vif, u8 idx)
393 wid.id = (u16)WID_IP_ADDRESS;
395 wid.val = kmalloc(IP_ALEN, GFP_KERNEL);
398 result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
399 wilc_get_vif_idx(vif));
401 memcpy(get_ip[idx], wid.val, IP_ALEN);
405 if (memcmp(get_ip[idx], set_ip[idx], IP_ALEN) != 0)
406 wilc_setup_ipaddress(vif, set_ip[idx], idx);
409 netdev_err(vif->ndev, "Failed to get IP address\n");
416 static void handle_set_mac_address(struct wilc_vif *vif,
417 struct set_mac_addr *set_mac_addr)
423 mac_buf = kmemdup(set_mac_addr->mac_addr, ETH_ALEN, GFP_KERNEL);
427 wid.id = (u16)WID_MAC_ADDR;
432 ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
433 wilc_get_vif_idx(vif));
435 netdev_err(vif->ndev, "Failed to set mac address\n");
440 static s32 handle_get_mac_address(struct wilc_vif *vif,
441 struct get_mac_addr *get_mac_addr)
446 wid.id = (u16)WID_MAC_ADDR;
448 wid.val = get_mac_addr->mac_addr;
451 result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
452 wilc_get_vif_idx(vif));
455 netdev_err(vif->ndev, "Failed to get mac address\n");
458 up(&hif_sema_wait_response);
463 static s32 handle_cfg_param(struct wilc_vif *vif,
464 struct cfg_param_attr *cfg_param_attr)
467 struct wid wid_list[32];
468 struct host_if_drv *hif_drv = vif->hif_drv;
471 down(&hif_drv->sem_cfg_values);
473 if (cfg_param_attr->flag & BSS_TYPE) {
474 if (cfg_param_attr->bss_type < 6) {
475 wid_list[i].id = WID_BSS_TYPE;
476 wid_list[i].val = (s8 *)&cfg_param_attr->bss_type;
477 wid_list[i].type = WID_CHAR;
478 wid_list[i].size = sizeof(char);
479 hif_drv->cfg_values.bss_type = (u8)cfg_param_attr->bss_type;
481 netdev_err(vif->ndev, "check value 6 over\n");
487 if (cfg_param_attr->flag & AUTH_TYPE) {
488 if (cfg_param_attr->auth_type == 1 ||
489 cfg_param_attr->auth_type == 2 ||
490 cfg_param_attr->auth_type == 5) {
491 wid_list[i].id = WID_AUTH_TYPE;
492 wid_list[i].val = (s8 *)&cfg_param_attr->auth_type;
493 wid_list[i].type = WID_CHAR;
494 wid_list[i].size = sizeof(char);
495 hif_drv->cfg_values.auth_type = (u8)cfg_param_attr->auth_type;
497 netdev_err(vif->ndev, "Impossible value\n");
503 if (cfg_param_attr->flag & AUTHEN_TIMEOUT) {
504 if (cfg_param_attr->auth_timeout > 0 &&
505 cfg_param_attr->auth_timeout < 65536) {
506 wid_list[i].id = WID_AUTH_TIMEOUT;
507 wid_list[i].val = (s8 *)&cfg_param_attr->auth_timeout;
508 wid_list[i].type = WID_SHORT;
509 wid_list[i].size = sizeof(u16);
510 hif_drv->cfg_values.auth_timeout = cfg_param_attr->auth_timeout;
512 netdev_err(vif->ndev, "Range(1 ~ 65535) over\n");
518 if (cfg_param_attr->flag & POWER_MANAGEMENT) {
519 if (cfg_param_attr->power_mgmt_mode < 5) {
520 wid_list[i].id = WID_POWER_MANAGEMENT;
521 wid_list[i].val = (s8 *)&cfg_param_attr->power_mgmt_mode;
522 wid_list[i].type = WID_CHAR;
523 wid_list[i].size = sizeof(char);
524 hif_drv->cfg_values.power_mgmt_mode = (u8)cfg_param_attr->power_mgmt_mode;
526 netdev_err(vif->ndev, "Invalid power mode\n");
532 if (cfg_param_attr->flag & RETRY_SHORT) {
533 if (cfg_param_attr->short_retry_limit > 0 &&
534 cfg_param_attr->short_retry_limit < 256) {
535 wid_list[i].id = WID_SHORT_RETRY_LIMIT;
536 wid_list[i].val = (s8 *)&cfg_param_attr->short_retry_limit;
537 wid_list[i].type = WID_SHORT;
538 wid_list[i].size = sizeof(u16);
539 hif_drv->cfg_values.short_retry_limit = cfg_param_attr->short_retry_limit;
541 netdev_err(vif->ndev, "Range(1~256) over\n");
547 if (cfg_param_attr->flag & RETRY_LONG) {
548 if (cfg_param_attr->long_retry_limit > 0 &&
549 cfg_param_attr->long_retry_limit < 256) {
550 wid_list[i].id = WID_LONG_RETRY_LIMIT;
551 wid_list[i].val = (s8 *)&cfg_param_attr->long_retry_limit;
552 wid_list[i].type = WID_SHORT;
553 wid_list[i].size = sizeof(u16);
554 hif_drv->cfg_values.long_retry_limit = cfg_param_attr->long_retry_limit;
556 netdev_err(vif->ndev, "Range(1~256) over\n");
562 if (cfg_param_attr->flag & FRAG_THRESHOLD) {
563 if (cfg_param_attr->frag_threshold > 255 &&
564 cfg_param_attr->frag_threshold < 7937) {
565 wid_list[i].id = WID_FRAG_THRESHOLD;
566 wid_list[i].val = (s8 *)&cfg_param_attr->frag_threshold;
567 wid_list[i].type = WID_SHORT;
568 wid_list[i].size = sizeof(u16);
569 hif_drv->cfg_values.frag_threshold = cfg_param_attr->frag_threshold;
571 netdev_err(vif->ndev, "Threshold Range fail\n");
577 if (cfg_param_attr->flag & RTS_THRESHOLD) {
578 if (cfg_param_attr->rts_threshold > 255 &&
579 cfg_param_attr->rts_threshold < 65536) {
580 wid_list[i].id = WID_RTS_THRESHOLD;
581 wid_list[i].val = (s8 *)&cfg_param_attr->rts_threshold;
582 wid_list[i].type = WID_SHORT;
583 wid_list[i].size = sizeof(u16);
584 hif_drv->cfg_values.rts_threshold = cfg_param_attr->rts_threshold;
586 netdev_err(vif->ndev, "Threshold Range fail\n");
592 if (cfg_param_attr->flag & PREAMBLE) {
593 if (cfg_param_attr->preamble_type < 3) {
594 wid_list[i].id = WID_PREAMBLE;
595 wid_list[i].val = (s8 *)&cfg_param_attr->preamble_type;
596 wid_list[i].type = WID_CHAR;
597 wid_list[i].size = sizeof(char);
598 hif_drv->cfg_values.preamble_type = cfg_param_attr->preamble_type;
600 netdev_err(vif->ndev, "Preamle Range(0~2) over\n");
606 if (cfg_param_attr->flag & SHORT_SLOT_ALLOWED) {
607 if (cfg_param_attr->short_slot_allowed < 2) {
608 wid_list[i].id = WID_SHORT_SLOT_ALLOWED;
609 wid_list[i].val = (s8 *)&cfg_param_attr->short_slot_allowed;
610 wid_list[i].type = WID_CHAR;
611 wid_list[i].size = sizeof(char);
612 hif_drv->cfg_values.short_slot_allowed = (u8)cfg_param_attr->short_slot_allowed;
614 netdev_err(vif->ndev, "Short slot(2) over\n");
620 if (cfg_param_attr->flag & TXOP_PROT_DISABLE) {
621 if (cfg_param_attr->txop_prot_disabled < 2) {
622 wid_list[i].id = WID_11N_TXOP_PROT_DISABLE;
623 wid_list[i].val = (s8 *)&cfg_param_attr->txop_prot_disabled;
624 wid_list[i].type = WID_CHAR;
625 wid_list[i].size = sizeof(char);
626 hif_drv->cfg_values.txop_prot_disabled = (u8)cfg_param_attr->txop_prot_disabled;
628 netdev_err(vif->ndev, "TXOP prot disable\n");
634 if (cfg_param_attr->flag & BEACON_INTERVAL) {
635 if (cfg_param_attr->beacon_interval > 0 &&
636 cfg_param_attr->beacon_interval < 65536) {
637 wid_list[i].id = WID_BEACON_INTERVAL;
638 wid_list[i].val = (s8 *)&cfg_param_attr->beacon_interval;
639 wid_list[i].type = WID_SHORT;
640 wid_list[i].size = sizeof(u16);
641 hif_drv->cfg_values.beacon_interval = cfg_param_attr->beacon_interval;
643 netdev_err(vif->ndev, "Beacon interval(1~65535)fail\n");
649 if (cfg_param_attr->flag & DTIM_PERIOD) {
650 if (cfg_param_attr->dtim_period > 0 &&
651 cfg_param_attr->dtim_period < 256) {
652 wid_list[i].id = WID_DTIM_PERIOD;
653 wid_list[i].val = (s8 *)&cfg_param_attr->dtim_period;
654 wid_list[i].type = WID_CHAR;
655 wid_list[i].size = sizeof(char);
656 hif_drv->cfg_values.dtim_period = cfg_param_attr->dtim_period;
658 netdev_err(vif->ndev, "DTIM range(1~255) fail\n");
664 if (cfg_param_attr->flag & SITE_SURVEY) {
665 if (cfg_param_attr->site_survey_enabled < 3) {
666 wid_list[i].id = WID_SITE_SURVEY;
667 wid_list[i].val = (s8 *)&cfg_param_attr->site_survey_enabled;
668 wid_list[i].type = WID_CHAR;
669 wid_list[i].size = sizeof(char);
670 hif_drv->cfg_values.site_survey_enabled = (u8)cfg_param_attr->site_survey_enabled;
672 netdev_err(vif->ndev, "Site survey disable\n");
678 if (cfg_param_attr->flag & SITE_SURVEY_SCAN_TIME) {
679 if (cfg_param_attr->site_survey_scan_time > 0 &&
680 cfg_param_attr->site_survey_scan_time < 65536) {
681 wid_list[i].id = WID_SITE_SURVEY_SCAN_TIME;
682 wid_list[i].val = (s8 *)&cfg_param_attr->site_survey_scan_time;
683 wid_list[i].type = WID_SHORT;
684 wid_list[i].size = sizeof(u16);
685 hif_drv->cfg_values.site_survey_scan_time = cfg_param_attr->site_survey_scan_time;
687 netdev_err(vif->ndev, "Site scan time(1~65535) over\n");
693 if (cfg_param_attr->flag & ACTIVE_SCANTIME) {
694 if (cfg_param_attr->active_scan_time > 0 &&
695 cfg_param_attr->active_scan_time < 65536) {
696 wid_list[i].id = WID_ACTIVE_SCAN_TIME;
697 wid_list[i].val = (s8 *)&cfg_param_attr->active_scan_time;
698 wid_list[i].type = WID_SHORT;
699 wid_list[i].size = sizeof(u16);
700 hif_drv->cfg_values.active_scan_time = cfg_param_attr->active_scan_time;
702 netdev_err(vif->ndev, "Active time(1~65535) over\n");
708 if (cfg_param_attr->flag & PASSIVE_SCANTIME) {
709 if (cfg_param_attr->passive_scan_time > 0 &&
710 cfg_param_attr->passive_scan_time < 65536) {
711 wid_list[i].id = WID_PASSIVE_SCAN_TIME;
712 wid_list[i].val = (s8 *)&cfg_param_attr->passive_scan_time;
713 wid_list[i].type = WID_SHORT;
714 wid_list[i].size = sizeof(u16);
715 hif_drv->cfg_values.passive_scan_time = cfg_param_attr->passive_scan_time;
717 netdev_err(vif->ndev, "Passive time(1~65535) over\n");
723 if (cfg_param_attr->flag & CURRENT_TX_RATE) {
724 enum CURRENT_TXRATE curr_tx_rate = cfg_param_attr->curr_tx_rate;
726 if (curr_tx_rate == AUTORATE || curr_tx_rate == MBPS_1 ||
727 curr_tx_rate == MBPS_2 || curr_tx_rate == MBPS_5_5 ||
728 curr_tx_rate == MBPS_11 || curr_tx_rate == MBPS_6 ||
729 curr_tx_rate == MBPS_9 || curr_tx_rate == MBPS_12 ||
730 curr_tx_rate == MBPS_18 || curr_tx_rate == MBPS_24 ||
731 curr_tx_rate == MBPS_36 || curr_tx_rate == MBPS_48 ||
732 curr_tx_rate == MBPS_54) {
733 wid_list[i].id = WID_CURRENT_TX_RATE;
734 wid_list[i].val = (s8 *)&curr_tx_rate;
735 wid_list[i].type = WID_SHORT;
736 wid_list[i].size = sizeof(u16);
737 hif_drv->cfg_values.curr_tx_rate = (u8)curr_tx_rate;
739 netdev_err(vif->ndev, "out of TX rate\n");
746 result = wilc_send_config_pkt(vif, SET_CFG, wid_list,
747 i, wilc_get_vif_idx(vif));
750 netdev_err(vif->ndev, "Error in setting CFG params\n");
753 up(&hif_drv->sem_cfg_values);
757 static s32 Handle_ScanDone(struct wilc_vif *vif,
758 enum scan_event enuEvent);
760 static s32 Handle_Scan(struct wilc_vif *vif,
761 struct scan_attr *pstrHostIFscanAttr)
764 struct wid strWIDList[5];
765 u32 u32WidsCount = 0;
769 u8 *pu8HdnNtwrksWidVal = NULL;
770 struct host_if_drv *hif_drv = vif->hif_drv;
772 hif_drv->usr_scan_req.scan_result = pstrHostIFscanAttr->result;
773 hif_drv->usr_scan_req.arg = pstrHostIFscanAttr->arg;
775 if ((hif_drv->hif_state >= HOST_IF_SCANNING) &&
776 (hif_drv->hif_state < HOST_IF_CONNECTED)) {
777 netdev_err(vif->ndev, "Already scan\n");
782 if (wilc_optaining_ip || wilc_connecting) {
783 netdev_err(vif->ndev, "Don't do obss scan\n");
788 hif_drv->usr_scan_req.rcvd_ch_cnt = 0;
790 strWIDList[u32WidsCount].id = (u16)WID_SSID_PROBE_REQ;
791 strWIDList[u32WidsCount].type = WID_STR;
793 for (i = 0; i < pstrHostIFscanAttr->hidden_network.n_ssids; i++)
794 valuesize += ((pstrHostIFscanAttr->hidden_network.net_info[i].ssid_len) + 1);
795 pu8HdnNtwrksWidVal = kmalloc(valuesize + 1, GFP_KERNEL);
796 strWIDList[u32WidsCount].val = pu8HdnNtwrksWidVal;
797 if (strWIDList[u32WidsCount].val) {
798 pu8Buffer = strWIDList[u32WidsCount].val;
800 *pu8Buffer++ = pstrHostIFscanAttr->hidden_network.n_ssids;
802 for (i = 0; i < pstrHostIFscanAttr->hidden_network.n_ssids; i++) {
803 *pu8Buffer++ = pstrHostIFscanAttr->hidden_network.net_info[i].ssid_len;
804 memcpy(pu8Buffer, pstrHostIFscanAttr->hidden_network.net_info[i].ssid, pstrHostIFscanAttr->hidden_network.net_info[i].ssid_len);
805 pu8Buffer += pstrHostIFscanAttr->hidden_network.net_info[i].ssid_len;
808 strWIDList[u32WidsCount].size = (s32)(valuesize + 1);
813 strWIDList[u32WidsCount].id = WID_INFO_ELEMENT_PROBE;
814 strWIDList[u32WidsCount].type = WID_BIN_DATA;
815 strWIDList[u32WidsCount].val = pstrHostIFscanAttr->ies;
816 strWIDList[u32WidsCount].size = pstrHostIFscanAttr->ies_len;
820 strWIDList[u32WidsCount].id = WID_SCAN_TYPE;
821 strWIDList[u32WidsCount].type = WID_CHAR;
822 strWIDList[u32WidsCount].size = sizeof(char);
823 strWIDList[u32WidsCount].val = (s8 *)&pstrHostIFscanAttr->type;
826 strWIDList[u32WidsCount].id = WID_SCAN_CHANNEL_LIST;
827 strWIDList[u32WidsCount].type = WID_BIN_DATA;
829 if (pstrHostIFscanAttr->ch_freq_list &&
830 pstrHostIFscanAttr->ch_list_len > 0) {
833 for (i = 0; i < pstrHostIFscanAttr->ch_list_len; i++) {
834 if (pstrHostIFscanAttr->ch_freq_list[i] > 0)
835 pstrHostIFscanAttr->ch_freq_list[i] = pstrHostIFscanAttr->ch_freq_list[i] - 1;
839 strWIDList[u32WidsCount].val = pstrHostIFscanAttr->ch_freq_list;
840 strWIDList[u32WidsCount].size = pstrHostIFscanAttr->ch_list_len;
843 strWIDList[u32WidsCount].id = WID_START_SCAN_REQ;
844 strWIDList[u32WidsCount].type = WID_CHAR;
845 strWIDList[u32WidsCount].size = sizeof(char);
846 strWIDList[u32WidsCount].val = (s8 *)&pstrHostIFscanAttr->src;
849 if (hif_drv->hif_state == HOST_IF_CONNECTED)
850 scan_while_connected = true;
851 else if (hif_drv->hif_state == HOST_IF_IDLE)
852 scan_while_connected = false;
854 result = wilc_send_config_pkt(vif, SET_CFG, strWIDList,
856 wilc_get_vif_idx(vif));
859 netdev_err(vif->ndev, "Failed to send scan parameters\n");
863 del_timer(&hif_drv->scan_timer);
864 Handle_ScanDone(vif, SCAN_EVENT_ABORTED);
867 kfree(pstrHostIFscanAttr->ch_freq_list);
868 pstrHostIFscanAttr->ch_freq_list = NULL;
870 kfree(pstrHostIFscanAttr->ies);
871 pstrHostIFscanAttr->ies = NULL;
872 kfree(pstrHostIFscanAttr->hidden_network.net_info);
873 pstrHostIFscanAttr->hidden_network.net_info = NULL;
875 kfree(pu8HdnNtwrksWidVal);
880 static s32 Handle_ScanDone(struct wilc_vif *vif,
881 enum scan_event enuEvent)
884 u8 u8abort_running_scan;
886 struct host_if_drv *hif_drv = vif->hif_drv;
888 if (enuEvent == SCAN_EVENT_ABORTED) {
889 u8abort_running_scan = 1;
890 wid.id = (u16)WID_ABORT_RUNNING_SCAN;
892 wid.val = (s8 *)&u8abort_running_scan;
893 wid.size = sizeof(char);
895 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
896 wilc_get_vif_idx(vif));
899 netdev_err(vif->ndev, "Failed to set abort running\n");
905 netdev_err(vif->ndev, "Driver handler is NULL\n");
909 if (hif_drv->usr_scan_req.scan_result) {
910 hif_drv->usr_scan_req.scan_result(enuEvent, NULL,
911 hif_drv->usr_scan_req.arg, NULL);
912 hif_drv->usr_scan_req.scan_result = NULL;
918 u8 wilc_connected_ssid[6] = {0};
919 static s32 Handle_Connect(struct wilc_vif *vif,
920 struct connect_attr *pstrHostIFconnectAttr)
923 struct wid strWIDList[8];
924 u32 u32WidsCount = 0, dummyval = 0;
925 u8 *pu8CurrByte = NULL;
926 struct join_bss_param *ptstrJoinBssParam;
927 struct host_if_drv *hif_drv = vif->hif_drv;
929 if (memcmp(pstrHostIFconnectAttr->bssid, wilc_connected_ssid, ETH_ALEN) == 0) {
931 netdev_err(vif->ndev, "Discard connect request\n");
935 ptstrJoinBssParam = pstrHostIFconnectAttr->params;
936 if (!ptstrJoinBssParam) {
937 netdev_err(vif->ndev, "Required BSSID not found\n");
942 if (pstrHostIFconnectAttr->bssid) {
943 hif_drv->usr_conn_req.bssid = kmalloc(6, GFP_KERNEL);
944 memcpy(hif_drv->usr_conn_req.bssid, pstrHostIFconnectAttr->bssid, 6);
947 hif_drv->usr_conn_req.ssid_len = pstrHostIFconnectAttr->ssid_len;
948 if (pstrHostIFconnectAttr->ssid) {
949 hif_drv->usr_conn_req.ssid = kmalloc(pstrHostIFconnectAttr->ssid_len + 1, GFP_KERNEL);
950 memcpy(hif_drv->usr_conn_req.ssid,
951 pstrHostIFconnectAttr->ssid,
952 pstrHostIFconnectAttr->ssid_len);
953 hif_drv->usr_conn_req.ssid[pstrHostIFconnectAttr->ssid_len] = '\0';
956 hif_drv->usr_conn_req.ies_len = pstrHostIFconnectAttr->ies_len;
957 if (pstrHostIFconnectAttr->ies) {
958 hif_drv->usr_conn_req.ies = kmalloc(pstrHostIFconnectAttr->ies_len, GFP_KERNEL);
959 memcpy(hif_drv->usr_conn_req.ies,
960 pstrHostIFconnectAttr->ies,
961 pstrHostIFconnectAttr->ies_len);
964 hif_drv->usr_conn_req.security = pstrHostIFconnectAttr->security;
965 hif_drv->usr_conn_req.auth_type = pstrHostIFconnectAttr->auth_type;
966 hif_drv->usr_conn_req.conn_result = pstrHostIFconnectAttr->result;
967 hif_drv->usr_conn_req.arg = pstrHostIFconnectAttr->arg;
969 strWIDList[u32WidsCount].id = WID_SUCCESS_FRAME_COUNT;
970 strWIDList[u32WidsCount].type = WID_INT;
971 strWIDList[u32WidsCount].size = sizeof(u32);
972 strWIDList[u32WidsCount].val = (s8 *)(&(dummyval));
975 strWIDList[u32WidsCount].id = WID_RECEIVED_FRAGMENT_COUNT;
976 strWIDList[u32WidsCount].type = WID_INT;
977 strWIDList[u32WidsCount].size = sizeof(u32);
978 strWIDList[u32WidsCount].val = (s8 *)(&(dummyval));
981 strWIDList[u32WidsCount].id = WID_FAILED_COUNT;
982 strWIDList[u32WidsCount].type = WID_INT;
983 strWIDList[u32WidsCount].size = sizeof(u32);
984 strWIDList[u32WidsCount].val = (s8 *)(&(dummyval));
988 strWIDList[u32WidsCount].id = WID_INFO_ELEMENT_ASSOCIATE;
989 strWIDList[u32WidsCount].type = WID_BIN_DATA;
990 strWIDList[u32WidsCount].val = hif_drv->usr_conn_req.ies;
991 strWIDList[u32WidsCount].size = hif_drv->usr_conn_req.ies_len;
994 if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
995 info_element_size = hif_drv->usr_conn_req.ies_len;
996 info_element = kmalloc(info_element_size, GFP_KERNEL);
997 memcpy(info_element, hif_drv->usr_conn_req.ies,
1001 strWIDList[u32WidsCount].id = (u16)WID_11I_MODE;
1002 strWIDList[u32WidsCount].type = WID_CHAR;
1003 strWIDList[u32WidsCount].size = sizeof(char);
1004 strWIDList[u32WidsCount].val = (s8 *)&hif_drv->usr_conn_req.security;
1007 if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7))
1008 mode_11i = hif_drv->usr_conn_req.security;
1010 strWIDList[u32WidsCount].id = (u16)WID_AUTH_TYPE;
1011 strWIDList[u32WidsCount].type = WID_CHAR;
1012 strWIDList[u32WidsCount].size = sizeof(char);
1013 strWIDList[u32WidsCount].val = (s8 *)&hif_drv->usr_conn_req.auth_type;
1016 if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7))
1017 auth_type = (u8)hif_drv->usr_conn_req.auth_type;
1019 strWIDList[u32WidsCount].id = (u16)WID_JOIN_REQ_EXTENDED;
1020 strWIDList[u32WidsCount].type = WID_STR;
1021 strWIDList[u32WidsCount].size = 112;
1022 strWIDList[u32WidsCount].val = kmalloc(strWIDList[u32WidsCount].size, GFP_KERNEL);
1024 if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
1025 join_req_size = strWIDList[u32WidsCount].size;
1026 join_req = kmalloc(join_req_size, GFP_KERNEL);
1028 if (!strWIDList[u32WidsCount].val) {
1033 pu8CurrByte = strWIDList[u32WidsCount].val;
1035 if (pstrHostIFconnectAttr->ssid) {
1036 memcpy(pu8CurrByte, pstrHostIFconnectAttr->ssid, pstrHostIFconnectAttr->ssid_len);
1037 pu8CurrByte[pstrHostIFconnectAttr->ssid_len] = '\0';
1039 pu8CurrByte += MAX_SSID_LEN;
1040 *(pu8CurrByte++) = INFRASTRUCTURE;
1042 if ((pstrHostIFconnectAttr->ch >= 1) && (pstrHostIFconnectAttr->ch <= 14)) {
1043 *(pu8CurrByte++) = pstrHostIFconnectAttr->ch;
1045 netdev_err(vif->ndev, "Channel out of range\n");
1046 *(pu8CurrByte++) = 0xFF;
1048 *(pu8CurrByte++) = (ptstrJoinBssParam->cap_info) & 0xFF;
1049 *(pu8CurrByte++) = ((ptstrJoinBssParam->cap_info) >> 8) & 0xFF;
1051 if (pstrHostIFconnectAttr->bssid)
1052 memcpy(pu8CurrByte, pstrHostIFconnectAttr->bssid, 6);
1055 if (pstrHostIFconnectAttr->bssid)
1056 memcpy(pu8CurrByte, pstrHostIFconnectAttr->bssid, 6);
1059 *(pu8CurrByte++) = (ptstrJoinBssParam->beacon_period) & 0xFF;
1060 *(pu8CurrByte++) = ((ptstrJoinBssParam->beacon_period) >> 8) & 0xFF;
1061 *(pu8CurrByte++) = ptstrJoinBssParam->dtim_period;
1063 memcpy(pu8CurrByte, ptstrJoinBssParam->supp_rates, MAX_RATES_SUPPORTED + 1);
1064 pu8CurrByte += (MAX_RATES_SUPPORTED + 1);
1066 *(pu8CurrByte++) = ptstrJoinBssParam->wmm_cap;
1067 *(pu8CurrByte++) = ptstrJoinBssParam->uapsd_cap;
1069 *(pu8CurrByte++) = ptstrJoinBssParam->ht_capable;
1070 hif_drv->usr_conn_req.ht_capable = ptstrJoinBssParam->ht_capable;
1072 *(pu8CurrByte++) = ptstrJoinBssParam->rsn_found;
1073 *(pu8CurrByte++) = ptstrJoinBssParam->rsn_grp_policy;
1074 *(pu8CurrByte++) = ptstrJoinBssParam->mode_802_11i;
1076 memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_pcip_policy, sizeof(ptstrJoinBssParam->rsn_pcip_policy));
1077 pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_pcip_policy);
1079 memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_auth_policy, sizeof(ptstrJoinBssParam->rsn_auth_policy));
1080 pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_auth_policy);
1082 memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_cap, sizeof(ptstrJoinBssParam->rsn_cap));
1083 pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_cap);
1085 *(pu8CurrByte++) = REAL_JOIN_REQ;
1086 *(pu8CurrByte++) = ptstrJoinBssParam->noa_enabled;
1088 if (ptstrJoinBssParam->noa_enabled) {
1089 *(pu8CurrByte++) = (ptstrJoinBssParam->tsf) & 0xFF;
1090 *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 8) & 0xFF;
1091 *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 16) & 0xFF;
1092 *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 24) & 0xFF;
1094 *(pu8CurrByte++) = ptstrJoinBssParam->opp_enabled;
1095 *(pu8CurrByte++) = ptstrJoinBssParam->idx;
1097 if (ptstrJoinBssParam->opp_enabled)
1098 *(pu8CurrByte++) = ptstrJoinBssParam->ct_window;
1100 *(pu8CurrByte++) = ptstrJoinBssParam->cnt;
1102 memcpy(pu8CurrByte, ptstrJoinBssParam->duration, sizeof(ptstrJoinBssParam->duration));
1103 pu8CurrByte += sizeof(ptstrJoinBssParam->duration);
1105 memcpy(pu8CurrByte, ptstrJoinBssParam->interval, sizeof(ptstrJoinBssParam->interval));
1106 pu8CurrByte += sizeof(ptstrJoinBssParam->interval);
1108 memcpy(pu8CurrByte, ptstrJoinBssParam->start_time, sizeof(ptstrJoinBssParam->start_time));
1109 pu8CurrByte += sizeof(ptstrJoinBssParam->start_time);
1112 pu8CurrByte = strWIDList[u32WidsCount].val;
1115 if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
1116 memcpy(join_req, pu8CurrByte, join_req_size);
1120 if (pstrHostIFconnectAttr->bssid)
1121 memcpy(wilc_connected_ssid,
1122 pstrHostIFconnectAttr->bssid, ETH_ALEN);
1124 result = wilc_send_config_pkt(vif, SET_CFG, strWIDList,
1126 wilc_get_vif_idx(vif));
1128 netdev_err(vif->ndev, "failed to send config packet\n");
1132 hif_drv->hif_state = HOST_IF_WAITING_CONN_RESP;
1137 struct connect_info strConnectInfo;
1139 del_timer(&hif_drv->connect_timer);
1141 memset(&strConnectInfo, 0, sizeof(struct connect_info));
1143 if (pstrHostIFconnectAttr->result) {
1144 if (pstrHostIFconnectAttr->bssid)
1145 memcpy(strConnectInfo.bssid, pstrHostIFconnectAttr->bssid, 6);
1147 if (pstrHostIFconnectAttr->ies) {
1148 strConnectInfo.req_ies_len = pstrHostIFconnectAttr->ies_len;
1149 strConnectInfo.req_ies = kmalloc(pstrHostIFconnectAttr->ies_len, GFP_KERNEL);
1150 memcpy(strConnectInfo.req_ies,
1151 pstrHostIFconnectAttr->ies,
1152 pstrHostIFconnectAttr->ies_len);
1155 pstrHostIFconnectAttr->result(CONN_DISCONN_EVENT_CONN_RESP,
1159 pstrHostIFconnectAttr->arg);
1160 hif_drv->hif_state = HOST_IF_IDLE;
1161 kfree(strConnectInfo.req_ies);
1162 strConnectInfo.req_ies = NULL;
1165 netdev_err(vif->ndev, "Connect callback is NULL\n");
1169 kfree(pstrHostIFconnectAttr->bssid);
1170 pstrHostIFconnectAttr->bssid = NULL;
1172 kfree(pstrHostIFconnectAttr->ssid);
1173 pstrHostIFconnectAttr->ssid = NULL;
1175 kfree(pstrHostIFconnectAttr->ies);
1176 pstrHostIFconnectAttr->ies = NULL;
1182 static s32 Handle_ConnectTimeout(struct wilc_vif *vif)
1185 struct connect_info strConnectInfo;
1187 u16 u16DummyReasonCode = 0;
1188 struct host_if_drv *hif_drv = vif->hif_drv;
1191 netdev_err(vif->ndev, "Driver handler is NULL\n");
1195 hif_drv->hif_state = HOST_IF_IDLE;
1197 scan_while_connected = false;
1199 memset(&strConnectInfo, 0, sizeof(struct connect_info));
1201 if (hif_drv->usr_conn_req.conn_result) {
1202 if (hif_drv->usr_conn_req.bssid) {
1203 memcpy(strConnectInfo.bssid,
1204 hif_drv->usr_conn_req.bssid, 6);
1207 if (hif_drv->usr_conn_req.ies) {
1208 strConnectInfo.req_ies_len = hif_drv->usr_conn_req.ies_len;
1209 strConnectInfo.req_ies = kmalloc(hif_drv->usr_conn_req.ies_len, GFP_KERNEL);
1210 memcpy(strConnectInfo.req_ies,
1211 hif_drv->usr_conn_req.ies,
1212 hif_drv->usr_conn_req.ies_len);
1215 hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_CONN_RESP,
1219 hif_drv->usr_conn_req.arg);
1221 kfree(strConnectInfo.req_ies);
1222 strConnectInfo.req_ies = NULL;
1224 netdev_err(vif->ndev, "Connect callback is NULL\n");
1227 wid.id = (u16)WID_DISCONNECT;
1228 wid.type = WID_CHAR;
1229 wid.val = (s8 *)&u16DummyReasonCode;
1230 wid.size = sizeof(char);
1232 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
1233 wilc_get_vif_idx(vif));
1235 netdev_err(vif->ndev, "Failed to send dissconect\n");
1237 hif_drv->usr_conn_req.ssid_len = 0;
1238 kfree(hif_drv->usr_conn_req.ssid);
1239 hif_drv->usr_conn_req.ssid = NULL;
1240 kfree(hif_drv->usr_conn_req.bssid);
1241 hif_drv->usr_conn_req.bssid = NULL;
1242 hif_drv->usr_conn_req.ies_len = 0;
1243 kfree(hif_drv->usr_conn_req.ies);
1244 hif_drv->usr_conn_req.ies = NULL;
1246 eth_zero_addr(wilc_connected_ssid);
1248 if (join_req && join_req_vif == vif) {
1253 if (info_element && join_req_vif == vif) {
1254 kfree(info_element);
1255 info_element = NULL;
1261 static s32 Handle_RcvdNtwrkInfo(struct wilc_vif *vif,
1262 struct rcvd_net_info *pstrRcvdNetworkInfo)
1265 bool bNewNtwrkFound;
1267 struct network_info *pstrNetworkInfo = NULL;
1268 void *pJoinParams = NULL;
1269 struct host_if_drv *hif_drv = vif->hif_drv;
1271 bNewNtwrkFound = true;
1273 if (hif_drv->usr_scan_req.scan_result) {
1274 wilc_parse_network_info(pstrRcvdNetworkInfo->buffer, &pstrNetworkInfo);
1275 if ((!pstrNetworkInfo) ||
1276 (!hif_drv->usr_scan_req.scan_result)) {
1277 netdev_err(vif->ndev, "driver is null\n");
1282 for (i = 0; i < hif_drv->usr_scan_req.rcvd_ch_cnt; i++) {
1283 if ((hif_drv->usr_scan_req.net_info[i].bssid) &&
1284 (pstrNetworkInfo->bssid)) {
1285 if (memcmp(hif_drv->usr_scan_req.net_info[i].bssid,
1286 pstrNetworkInfo->bssid, 6) == 0) {
1287 if (pstrNetworkInfo->rssi <= hif_drv->usr_scan_req.net_info[i].rssi) {
1290 hif_drv->usr_scan_req.net_info[i].rssi = pstrNetworkInfo->rssi;
1291 bNewNtwrkFound = false;
1298 if (bNewNtwrkFound) {
1299 if (hif_drv->usr_scan_req.rcvd_ch_cnt < MAX_NUM_SCANNED_NETWORKS) {
1300 hif_drv->usr_scan_req.net_info[hif_drv->usr_scan_req.rcvd_ch_cnt].rssi = pstrNetworkInfo->rssi;
1302 if (hif_drv->usr_scan_req.net_info[hif_drv->usr_scan_req.rcvd_ch_cnt].bssid &&
1303 pstrNetworkInfo->bssid) {
1304 memcpy(hif_drv->usr_scan_req.net_info[hif_drv->usr_scan_req.rcvd_ch_cnt].bssid,
1305 pstrNetworkInfo->bssid, 6);
1307 hif_drv->usr_scan_req.rcvd_ch_cnt++;
1309 pstrNetworkInfo->new_network = true;
1310 pJoinParams = host_int_ParseJoinBssParam(pstrNetworkInfo);
1312 hif_drv->usr_scan_req.scan_result(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo,
1313 hif_drv->usr_scan_req.arg,
1318 pstrNetworkInfo->new_network = false;
1319 hif_drv->usr_scan_req.scan_result(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo,
1320 hif_drv->usr_scan_req.arg, NULL);
1325 kfree(pstrRcvdNetworkInfo->buffer);
1326 pstrRcvdNetworkInfo->buffer = NULL;
1328 if (pstrNetworkInfo) {
1329 kfree(pstrNetworkInfo->ies);
1330 kfree(pstrNetworkInfo);
1336 static s32 host_int_get_assoc_res_info(struct wilc_vif *vif,
1337 u8 *pu8AssocRespInfo,
1338 u32 u32MaxAssocRespInfoLen,
1339 u32 *pu32RcvdAssocRespInfoLen);
1341 static s32 Handle_RcvdGnrlAsyncInfo(struct wilc_vif *vif,
1342 struct rcvd_async_info *pstrRcvdGnrlAsyncInfo)
1348 u16 u16WidID = (u16)WID_NIL;
1351 u8 u8MacStatusReasonCode;
1352 u8 u8MacStatusAdditionalInfo;
1353 struct connect_info strConnectInfo;
1354 struct disconnect_info strDisconnectNotifInfo;
1356 struct host_if_drv *hif_drv = vif->hif_drv;
1359 netdev_err(vif->ndev, "Driver handler is NULL\n");
1363 if ((hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) ||
1364 (hif_drv->hif_state == HOST_IF_CONNECTED) ||
1365 hif_drv->usr_scan_req.scan_result) {
1366 if (!pstrRcvdGnrlAsyncInfo->buffer ||
1367 !hif_drv->usr_conn_req.conn_result) {
1368 netdev_err(vif->ndev, "driver is null\n");
1372 u8MsgType = pstrRcvdGnrlAsyncInfo->buffer[0];
1374 if ('I' != u8MsgType) {
1375 netdev_err(vif->ndev, "Received Message incorrect.\n");
1379 u8MsgID = pstrRcvdGnrlAsyncInfo->buffer[1];
1380 u16MsgLen = MAKE_WORD16(pstrRcvdGnrlAsyncInfo->buffer[2], pstrRcvdGnrlAsyncInfo->buffer[3]);
1381 u16WidID = MAKE_WORD16(pstrRcvdGnrlAsyncInfo->buffer[4], pstrRcvdGnrlAsyncInfo->buffer[5]);
1382 u8WidLen = pstrRcvdGnrlAsyncInfo->buffer[6];
1383 u8MacStatus = pstrRcvdGnrlAsyncInfo->buffer[7];
1384 u8MacStatusReasonCode = pstrRcvdGnrlAsyncInfo->buffer[8];
1385 u8MacStatusAdditionalInfo = pstrRcvdGnrlAsyncInfo->buffer[9];
1386 if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) {
1387 u32 u32RcvdAssocRespInfoLen = 0;
1388 struct connect_resp_info *pstrConnectRespInfo = NULL;
1390 memset(&strConnectInfo, 0, sizeof(struct connect_info));
1392 if (u8MacStatus == MAC_CONNECTED) {
1393 memset(rcv_assoc_resp, 0, MAX_ASSOC_RESP_FRAME_SIZE);
1395 host_int_get_assoc_res_info(vif,
1397 MAX_ASSOC_RESP_FRAME_SIZE,
1398 &u32RcvdAssocRespInfoLen);
1400 if (u32RcvdAssocRespInfoLen != 0) {
1401 s32Err = wilc_parse_assoc_resp_info(rcv_assoc_resp, u32RcvdAssocRespInfoLen,
1402 &pstrConnectRespInfo);
1404 netdev_err(vif->ndev, "wilc_parse_assoc_resp_info() returned error %d\n", s32Err);
1406 strConnectInfo.status = pstrConnectRespInfo->status;
1408 if (strConnectInfo.status == SUCCESSFUL_STATUSCODE) {
1409 if (pstrConnectRespInfo->ies) {
1410 strConnectInfo.resp_ies_len = pstrConnectRespInfo->ies_len;
1411 strConnectInfo.resp_ies = kmalloc(pstrConnectRespInfo->ies_len, GFP_KERNEL);
1412 memcpy(strConnectInfo.resp_ies, pstrConnectRespInfo->ies,
1413 pstrConnectRespInfo->ies_len);
1417 if (pstrConnectRespInfo) {
1418 kfree(pstrConnectRespInfo->ies);
1419 kfree(pstrConnectRespInfo);
1425 if ((u8MacStatus == MAC_CONNECTED) &&
1426 (strConnectInfo.status != SUCCESSFUL_STATUSCODE)) {
1427 netdev_err(vif->ndev, "Received MAC status is MAC_CONNECTED while the received status code in Asoc Resp is not SUCCESSFUL_STATUSCODE\n");
1428 eth_zero_addr(wilc_connected_ssid);
1429 } else if (u8MacStatus == MAC_DISCONNECTED) {
1430 netdev_err(vif->ndev, "Received MAC status is MAC_DISCONNECTED\n");
1431 eth_zero_addr(wilc_connected_ssid);
1434 if (hif_drv->usr_conn_req.bssid) {
1435 memcpy(strConnectInfo.bssid, hif_drv->usr_conn_req.bssid, 6);
1437 if ((u8MacStatus == MAC_CONNECTED) &&
1438 (strConnectInfo.status == SUCCESSFUL_STATUSCODE)) {
1439 memcpy(hif_drv->assoc_bssid,
1440 hif_drv->usr_conn_req.bssid, ETH_ALEN);
1444 if (hif_drv->usr_conn_req.ies) {
1445 strConnectInfo.req_ies_len = hif_drv->usr_conn_req.ies_len;
1446 strConnectInfo.req_ies = kmalloc(hif_drv->usr_conn_req.ies_len, GFP_KERNEL);
1447 memcpy(strConnectInfo.req_ies,
1448 hif_drv->usr_conn_req.ies,
1449 hif_drv->usr_conn_req.ies_len);
1452 del_timer(&hif_drv->connect_timer);
1453 hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_CONN_RESP,
1457 hif_drv->usr_conn_req.arg);
1459 if ((u8MacStatus == MAC_CONNECTED) &&
1460 (strConnectInfo.status == SUCCESSFUL_STATUSCODE)) {
1461 wilc_set_power_mgmt(vif, 0, 0);
1463 hif_drv->hif_state = HOST_IF_CONNECTED;
1465 wilc_optaining_ip = true;
1466 mod_timer(&wilc_during_ip_timer,
1467 jiffies + msecs_to_jiffies(10000));
1469 hif_drv->hif_state = HOST_IF_IDLE;
1470 scan_while_connected = false;
1473 kfree(strConnectInfo.resp_ies);
1474 strConnectInfo.resp_ies = NULL;
1476 kfree(strConnectInfo.req_ies);
1477 strConnectInfo.req_ies = NULL;
1478 hif_drv->usr_conn_req.ssid_len = 0;
1479 kfree(hif_drv->usr_conn_req.ssid);
1480 hif_drv->usr_conn_req.ssid = NULL;
1481 kfree(hif_drv->usr_conn_req.bssid);
1482 hif_drv->usr_conn_req.bssid = NULL;
1483 hif_drv->usr_conn_req.ies_len = 0;
1484 kfree(hif_drv->usr_conn_req.ies);
1485 hif_drv->usr_conn_req.ies = NULL;
1486 } else if ((u8MacStatus == MAC_DISCONNECTED) &&
1487 (hif_drv->hif_state == HOST_IF_CONNECTED)) {
1488 memset(&strDisconnectNotifInfo, 0, sizeof(struct disconnect_info));
1490 if (hif_drv->usr_scan_req.scan_result) {
1491 del_timer(&hif_drv->scan_timer);
1492 Handle_ScanDone(vif, SCAN_EVENT_ABORTED);
1495 strDisconnectNotifInfo.reason = 0;
1496 strDisconnectNotifInfo.ie = NULL;
1497 strDisconnectNotifInfo.ie_len = 0;
1499 if (hif_drv->usr_conn_req.conn_result) {
1500 wilc_optaining_ip = false;
1501 wilc_set_power_mgmt(vif, 0, 0);
1503 hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF,
1506 &strDisconnectNotifInfo,
1507 hif_drv->usr_conn_req.arg);
1509 netdev_err(vif->ndev, "Connect result NULL\n");
1512 eth_zero_addr(hif_drv->assoc_bssid);
1514 hif_drv->usr_conn_req.ssid_len = 0;
1515 kfree(hif_drv->usr_conn_req.ssid);
1516 hif_drv->usr_conn_req.ssid = NULL;
1517 kfree(hif_drv->usr_conn_req.bssid);
1518 hif_drv->usr_conn_req.bssid = NULL;
1519 hif_drv->usr_conn_req.ies_len = 0;
1520 kfree(hif_drv->usr_conn_req.ies);
1521 hif_drv->usr_conn_req.ies = NULL;
1523 if (join_req && join_req_vif == vif) {
1528 if (info_element && join_req_vif == vif) {
1529 kfree(info_element);
1530 info_element = NULL;
1533 hif_drv->hif_state = HOST_IF_IDLE;
1534 scan_while_connected = false;
1536 } else if ((u8MacStatus == MAC_DISCONNECTED) &&
1537 (hif_drv->usr_scan_req.scan_result)) {
1538 del_timer(&hif_drv->scan_timer);
1539 if (hif_drv->usr_scan_req.scan_result)
1540 Handle_ScanDone(vif, SCAN_EVENT_ABORTED);
1544 kfree(pstrRcvdGnrlAsyncInfo->buffer);
1545 pstrRcvdGnrlAsyncInfo->buffer = NULL;
1550 static int Handle_Key(struct wilc_vif *vif,
1551 struct key_attr *pstrHostIFkeyAttr)
1555 struct wid strWIDList[5];
1560 struct host_if_drv *hif_drv = vif->hif_drv;
1562 switch (pstrHostIFkeyAttr->type) {
1565 if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
1566 strWIDList[0].id = (u16)WID_11I_MODE;
1567 strWIDList[0].type = WID_CHAR;
1568 strWIDList[0].size = sizeof(char);
1569 strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wep.mode;
1571 strWIDList[1].id = WID_AUTH_TYPE;
1572 strWIDList[1].type = WID_CHAR;
1573 strWIDList[1].size = sizeof(char);
1574 strWIDList[1].val = (s8 *)&pstrHostIFkeyAttr->attr.wep.auth_type;
1576 pu8keybuf = kmalloc(pstrHostIFkeyAttr->attr.wep.key_len + 2,
1581 pu8keybuf[0] = pstrHostIFkeyAttr->attr.wep.index;
1582 pu8keybuf[1] = pstrHostIFkeyAttr->attr.wep.key_len;
1584 memcpy(&pu8keybuf[2], pstrHostIFkeyAttr->attr.wep.key,
1585 pstrHostIFkeyAttr->attr.wep.key_len);
1587 kfree(pstrHostIFkeyAttr->attr.wep.key);
1589 strWIDList[2].id = (u16)WID_WEP_KEY_VALUE;
1590 strWIDList[2].type = WID_STR;
1591 strWIDList[2].size = pstrHostIFkeyAttr->attr.wep.key_len + 2;
1592 strWIDList[2].val = (s8 *)pu8keybuf;
1594 result = wilc_send_config_pkt(vif, SET_CFG,
1596 wilc_get_vif_idx(vif));
1598 } else if (pstrHostIFkeyAttr->action & ADDKEY) {
1599 pu8keybuf = kmalloc(pstrHostIFkeyAttr->attr.wep.key_len + 2, GFP_KERNEL);
1602 pu8keybuf[0] = pstrHostIFkeyAttr->attr.wep.index;
1603 memcpy(pu8keybuf + 1, &pstrHostIFkeyAttr->attr.wep.key_len, 1);
1604 memcpy(pu8keybuf + 2, pstrHostIFkeyAttr->attr.wep.key,
1605 pstrHostIFkeyAttr->attr.wep.key_len);
1606 kfree(pstrHostIFkeyAttr->attr.wep.key);
1608 wid.id = (u16)WID_ADD_WEP_KEY;
1610 wid.val = (s8 *)pu8keybuf;
1611 wid.size = pstrHostIFkeyAttr->attr.wep.key_len + 2;
1613 result = wilc_send_config_pkt(vif, SET_CFG,
1615 wilc_get_vif_idx(vif));
1617 } else if (pstrHostIFkeyAttr->action & REMOVEKEY) {
1618 wid.id = (u16)WID_REMOVE_WEP_KEY;
1621 s8idxarray[0] = (s8)pstrHostIFkeyAttr->attr.wep.index;
1622 wid.val = s8idxarray;
1625 result = wilc_send_config_pkt(vif, SET_CFG,
1627 wilc_get_vif_idx(vif));
1628 } else if (pstrHostIFkeyAttr->action & DEFAULTKEY) {
1629 wid.id = (u16)WID_KEY_ID;
1630 wid.type = WID_CHAR;
1631 wid.val = (s8 *)&pstrHostIFkeyAttr->attr.wep.index;
1632 wid.size = sizeof(char);
1634 result = wilc_send_config_pkt(vif, SET_CFG,
1636 wilc_get_vif_idx(vif));
1638 up(&hif_drv->sem_test_key_block);
1642 if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
1643 pu8keybuf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
1646 goto _WPARxGtk_end_case_;
1649 if (pstrHostIFkeyAttr->attr.wpa.seq)
1650 memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->attr.wpa.seq, 8);
1652 memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->attr.wpa.index, 1);
1653 memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
1654 memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->attr.wpa.key,
1655 pstrHostIFkeyAttr->attr.wpa.key_len);
1657 strWIDList[0].id = (u16)WID_11I_MODE;
1658 strWIDList[0].type = WID_CHAR;
1659 strWIDList[0].size = sizeof(char);
1660 strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wpa.mode;
1662 strWIDList[1].id = (u16)WID_ADD_RX_GTK;
1663 strWIDList[1].type = WID_STR;
1664 strWIDList[1].val = (s8 *)pu8keybuf;
1665 strWIDList[1].size = RX_MIC_KEY_MSG_LEN;
1667 result = wilc_send_config_pkt(vif, SET_CFG,
1669 wilc_get_vif_idx(vif));
1672 up(&hif_drv->sem_test_key_block);
1673 } else if (pstrHostIFkeyAttr->action & ADDKEY) {
1674 pu8keybuf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
1675 if (pu8keybuf == NULL) {
1677 goto _WPARxGtk_end_case_;
1680 if (hif_drv->hif_state == HOST_IF_CONNECTED)
1681 memcpy(pu8keybuf, hif_drv->assoc_bssid, ETH_ALEN);
1683 netdev_err(vif->ndev, "Couldn't handle\n");
1685 memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->attr.wpa.seq, 8);
1686 memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->attr.wpa.index, 1);
1687 memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
1688 memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->attr.wpa.key,
1689 pstrHostIFkeyAttr->attr.wpa.key_len);
1691 wid.id = (u16)WID_ADD_RX_GTK;
1693 wid.val = (s8 *)pu8keybuf;
1694 wid.size = RX_MIC_KEY_MSG_LEN;
1696 result = wilc_send_config_pkt(vif, SET_CFG,
1698 wilc_get_vif_idx(vif));
1701 up(&hif_drv->sem_test_key_block);
1703 _WPARxGtk_end_case_:
1704 kfree(pstrHostIFkeyAttr->attr.wpa.key);
1705 kfree(pstrHostIFkeyAttr->attr.wpa.seq);
1712 if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
1713 pu8keybuf = kmalloc(PTK_KEY_MSG_LEN + 1, GFP_KERNEL);
1716 goto _WPAPtk_end_case_;
1719 memcpy(pu8keybuf, pstrHostIFkeyAttr->attr.wpa.mac_addr, 6);
1720 memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->attr.wpa.index, 1);
1721 memcpy(pu8keybuf + 7, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
1722 memcpy(pu8keybuf + 8, pstrHostIFkeyAttr->attr.wpa.key,
1723 pstrHostIFkeyAttr->attr.wpa.key_len);
1725 strWIDList[0].id = (u16)WID_11I_MODE;
1726 strWIDList[0].type = WID_CHAR;
1727 strWIDList[0].size = sizeof(char);
1728 strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wpa.mode;
1730 strWIDList[1].id = (u16)WID_ADD_PTK;
1731 strWIDList[1].type = WID_STR;
1732 strWIDList[1].val = (s8 *)pu8keybuf;
1733 strWIDList[1].size = PTK_KEY_MSG_LEN + 1;
1735 result = wilc_send_config_pkt(vif, SET_CFG,
1737 wilc_get_vif_idx(vif));
1739 up(&hif_drv->sem_test_key_block);
1740 } else if (pstrHostIFkeyAttr->action & ADDKEY) {
1741 pu8keybuf = kmalloc(PTK_KEY_MSG_LEN, GFP_KERNEL);
1743 netdev_err(vif->ndev, "No buffer send PTK\n");
1745 goto _WPAPtk_end_case_;
1748 memcpy(pu8keybuf, pstrHostIFkeyAttr->attr.wpa.mac_addr, 6);
1749 memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
1750 memcpy(pu8keybuf + 7, pstrHostIFkeyAttr->attr.wpa.key,
1751 pstrHostIFkeyAttr->attr.wpa.key_len);
1753 wid.id = (u16)WID_ADD_PTK;
1755 wid.val = (s8 *)pu8keybuf;
1756 wid.size = PTK_KEY_MSG_LEN;
1758 result = wilc_send_config_pkt(vif, SET_CFG,
1760 wilc_get_vif_idx(vif));
1762 up(&hif_drv->sem_test_key_block);
1766 kfree(pstrHostIFkeyAttr->attr.wpa.key);
1773 pu8keybuf = kmalloc((pstrHostIFkeyAttr->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1, GFP_KERNEL);
1775 netdev_err(vif->ndev, "No buffer to send PMKSA Key\n");
1779 pu8keybuf[0] = pstrHostIFkeyAttr->attr.pmkid.numpmkid;
1781 for (i = 0; i < pstrHostIFkeyAttr->attr.pmkid.numpmkid; i++) {
1782 memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + 1), pstrHostIFkeyAttr->attr.pmkid.pmkidlist[i].bssid, ETH_ALEN);
1783 memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + ETH_ALEN + 1), pstrHostIFkeyAttr->attr.pmkid.pmkidlist[i].pmkid, PMKID_LEN);
1786 wid.id = (u16)WID_PMKID_INFO;
1788 wid.val = (s8 *)pu8keybuf;
1789 wid.size = (pstrHostIFkeyAttr->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1;
1791 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
1792 wilc_get_vif_idx(vif));
1799 netdev_err(vif->ndev, "Failed to send key config packet\n");
1804 static void Handle_Disconnect(struct wilc_vif *vif)
1807 struct host_if_drv *hif_drv = vif->hif_drv;
1810 u16 u16DummyReasonCode = 0;
1812 wid.id = (u16)WID_DISCONNECT;
1813 wid.type = WID_CHAR;
1814 wid.val = (s8 *)&u16DummyReasonCode;
1815 wid.size = sizeof(char);
1817 wilc_optaining_ip = false;
1818 wilc_set_power_mgmt(vif, 0, 0);
1820 eth_zero_addr(wilc_connected_ssid);
1822 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
1823 wilc_get_vif_idx(vif));
1826 netdev_err(vif->ndev, "Failed to send dissconect\n");
1828 struct disconnect_info strDisconnectNotifInfo;
1830 memset(&strDisconnectNotifInfo, 0, sizeof(struct disconnect_info));
1832 strDisconnectNotifInfo.reason = 0;
1833 strDisconnectNotifInfo.ie = NULL;
1834 strDisconnectNotifInfo.ie_len = 0;
1836 if (hif_drv->usr_scan_req.scan_result) {
1837 del_timer(&hif_drv->scan_timer);
1838 hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED,
1840 hif_drv->usr_scan_req.arg,
1842 hif_drv->usr_scan_req.scan_result = NULL;
1845 if (hif_drv->usr_conn_req.conn_result) {
1846 if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP)
1847 del_timer(&hif_drv->connect_timer);
1849 hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF,
1852 &strDisconnectNotifInfo,
1853 hif_drv->usr_conn_req.arg);
1855 netdev_err(vif->ndev, "conn_result = NULL\n");
1858 scan_while_connected = false;
1860 hif_drv->hif_state = HOST_IF_IDLE;
1862 eth_zero_addr(hif_drv->assoc_bssid);
1864 hif_drv->usr_conn_req.ssid_len = 0;
1865 kfree(hif_drv->usr_conn_req.ssid);
1866 hif_drv->usr_conn_req.ssid = NULL;
1867 kfree(hif_drv->usr_conn_req.bssid);
1868 hif_drv->usr_conn_req.bssid = NULL;
1869 hif_drv->usr_conn_req.ies_len = 0;
1870 kfree(hif_drv->usr_conn_req.ies);
1871 hif_drv->usr_conn_req.ies = NULL;
1873 if (join_req && join_req_vif == vif) {
1878 if (info_element && join_req_vif == vif) {
1879 kfree(info_element);
1880 info_element = NULL;
1884 up(&hif_drv->sem_test_disconn_block);
1887 void wilc_resolve_disconnect_aberration(struct wilc_vif *vif)
1891 if ((vif->hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) ||
1892 (vif->hif_drv->hif_state == HOST_IF_CONNECTING))
1893 wilc_disconnect(vif, 1);
1896 static void Handle_GetRssi(struct wilc_vif *vif)
1901 wid.id = (u16)WID_RSSI;
1902 wid.type = WID_CHAR;
1904 wid.size = sizeof(char);
1906 result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
1907 wilc_get_vif_idx(vif));
1909 netdev_err(vif->ndev, "Failed to get RSSI value\n");
1913 up(&vif->hif_drv->sem_get_rssi);
1916 static s32 Handle_GetStatistics(struct wilc_vif *vif,
1917 struct rf_info *pstrStatistics)
1919 struct wid strWIDList[5];
1920 u32 u32WidsCount = 0, result = 0;
1922 strWIDList[u32WidsCount].id = WID_LINKSPEED;
1923 strWIDList[u32WidsCount].type = WID_CHAR;
1924 strWIDList[u32WidsCount].size = sizeof(char);
1925 strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->link_speed;
1928 strWIDList[u32WidsCount].id = WID_RSSI;
1929 strWIDList[u32WidsCount].type = WID_CHAR;
1930 strWIDList[u32WidsCount].size = sizeof(char);
1931 strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->rssi;
1934 strWIDList[u32WidsCount].id = WID_SUCCESS_FRAME_COUNT;
1935 strWIDList[u32WidsCount].type = WID_INT;
1936 strWIDList[u32WidsCount].size = sizeof(u32);
1937 strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->tx_cnt;
1940 strWIDList[u32WidsCount].id = WID_RECEIVED_FRAGMENT_COUNT;
1941 strWIDList[u32WidsCount].type = WID_INT;
1942 strWIDList[u32WidsCount].size = sizeof(u32);
1943 strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->rx_cnt;
1946 strWIDList[u32WidsCount].id = WID_FAILED_COUNT;
1947 strWIDList[u32WidsCount].type = WID_INT;
1948 strWIDList[u32WidsCount].size = sizeof(u32);
1949 strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->tx_fail_cnt;
1952 result = wilc_send_config_pkt(vif, GET_CFG, strWIDList,
1954 wilc_get_vif_idx(vif));
1957 netdev_err(vif->ndev, "Failed to send scan parameters\n");
1959 if (pstrStatistics->link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH &&
1960 pstrStatistics->link_speed != DEFAULT_LINK_SPEED)
1961 wilc_enable_tcp_ack_filter(true);
1962 else if (pstrStatistics->link_speed != DEFAULT_LINK_SPEED)
1963 wilc_enable_tcp_ack_filter(false);
1965 if (pstrStatistics != &vif->wilc->dummy_statistics)
1966 up(&hif_sema_wait_response);
1970 static s32 Handle_Get_InActiveTime(struct wilc_vif *vif,
1971 struct sta_inactive_t *strHostIfStaInactiveT)
1976 struct host_if_drv *hif_drv = vif->hif_drv;
1978 wid.id = (u16)WID_SET_STA_MAC_INACTIVE_TIME;
1980 wid.size = ETH_ALEN;
1981 wid.val = kmalloc(wid.size, GFP_KERNEL);
1984 memcpy(stamac, strHostIfStaInactiveT->mac, ETH_ALEN);
1986 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
1987 wilc_get_vif_idx(vif));
1990 netdev_err(vif->ndev, "Failed to SET incative time\n");
1994 wid.id = (u16)WID_GET_INACTIVE_TIME;
1996 wid.val = (s8 *)&inactive_time;
1997 wid.size = sizeof(u32);
1999 result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
2000 wilc_get_vif_idx(vif));
2003 netdev_err(vif->ndev, "Failed to get incative time\n");
2007 up(&hif_drv->sem_inactive_time);
2012 static void Handle_AddBeacon(struct wilc_vif *vif,
2013 struct beacon_attr *pstrSetBeaconParam)
2019 wid.id = (u16)WID_ADD_BEACON;
2021 wid.size = pstrSetBeaconParam->head_len + pstrSetBeaconParam->tail_len + 16;
2022 wid.val = kmalloc(wid.size, GFP_KERNEL);
2026 pu8CurrByte = wid.val;
2027 *pu8CurrByte++ = (pstrSetBeaconParam->interval & 0xFF);
2028 *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 8) & 0xFF);
2029 *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 16) & 0xFF);
2030 *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 24) & 0xFF);
2032 *pu8CurrByte++ = (pstrSetBeaconParam->dtim_period & 0xFF);
2033 *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 8) & 0xFF);
2034 *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 16) & 0xFF);
2035 *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 24) & 0xFF);
2037 *pu8CurrByte++ = (pstrSetBeaconParam->head_len & 0xFF);
2038 *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 8) & 0xFF);
2039 *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 16) & 0xFF);
2040 *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 24) & 0xFF);
2042 memcpy(pu8CurrByte, pstrSetBeaconParam->head, pstrSetBeaconParam->head_len);
2043 pu8CurrByte += pstrSetBeaconParam->head_len;
2045 *pu8CurrByte++ = (pstrSetBeaconParam->tail_len & 0xFF);
2046 *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 8) & 0xFF);
2047 *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 16) & 0xFF);
2048 *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 24) & 0xFF);
2050 if (pstrSetBeaconParam->tail)
2051 memcpy(pu8CurrByte, pstrSetBeaconParam->tail, pstrSetBeaconParam->tail_len);
2052 pu8CurrByte += pstrSetBeaconParam->tail_len;
2054 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2055 wilc_get_vif_idx(vif));
2057 netdev_err(vif->ndev, "Failed to send add beacon\n");
2061 kfree(pstrSetBeaconParam->head);
2062 kfree(pstrSetBeaconParam->tail);
2065 static void Handle_DelBeacon(struct wilc_vif *vif)
2071 wid.id = (u16)WID_DEL_BEACON;
2072 wid.type = WID_CHAR;
2073 wid.size = sizeof(char);
2074 wid.val = &del_beacon;
2079 pu8CurrByte = wid.val;
2081 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2082 wilc_get_vif_idx(vif));
2084 netdev_err(vif->ndev, "Failed to send delete beacon\n");
2087 static u32 WILC_HostIf_PackStaParam(u8 *pu8Buffer,
2088 struct add_sta_param *pstrStationParam)
2092 pu8CurrByte = pu8Buffer;
2094 memcpy(pu8CurrByte, pstrStationParam->bssid, ETH_ALEN);
2095 pu8CurrByte += ETH_ALEN;
2097 *pu8CurrByte++ = pstrStationParam->aid & 0xFF;
2098 *pu8CurrByte++ = (pstrStationParam->aid >> 8) & 0xFF;
2100 *pu8CurrByte++ = pstrStationParam->rates_len;
2101 if (pstrStationParam->rates_len > 0)
2102 memcpy(pu8CurrByte, pstrStationParam->rates,
2103 pstrStationParam->rates_len);
2104 pu8CurrByte += pstrStationParam->rates_len;
2106 *pu8CurrByte++ = pstrStationParam->ht_supported;
2107 *pu8CurrByte++ = pstrStationParam->ht_capa_info & 0xFF;
2108 *pu8CurrByte++ = (pstrStationParam->ht_capa_info >> 8) & 0xFF;
2110 *pu8CurrByte++ = pstrStationParam->ht_ampdu_params;
2111 memcpy(pu8CurrByte, pstrStationParam->ht_supp_mcs_set,
2112 WILC_SUPP_MCS_SET_SIZE);
2113 pu8CurrByte += WILC_SUPP_MCS_SET_SIZE;
2115 *pu8CurrByte++ = pstrStationParam->ht_ext_params & 0xFF;
2116 *pu8CurrByte++ = (pstrStationParam->ht_ext_params >> 8) & 0xFF;
2118 *pu8CurrByte++ = pstrStationParam->ht_tx_bf_cap & 0xFF;
2119 *pu8CurrByte++ = (pstrStationParam->ht_tx_bf_cap >> 8) & 0xFF;
2120 *pu8CurrByte++ = (pstrStationParam->ht_tx_bf_cap >> 16) & 0xFF;
2121 *pu8CurrByte++ = (pstrStationParam->ht_tx_bf_cap >> 24) & 0xFF;
2123 *pu8CurrByte++ = pstrStationParam->ht_ante_sel;
2125 *pu8CurrByte++ = pstrStationParam->flags_mask & 0xFF;
2126 *pu8CurrByte++ = (pstrStationParam->flags_mask >> 8) & 0xFF;
2128 *pu8CurrByte++ = pstrStationParam->flags_set & 0xFF;
2129 *pu8CurrByte++ = (pstrStationParam->flags_set >> 8) & 0xFF;
2131 return pu8CurrByte - pu8Buffer;
2134 static void Handle_AddStation(struct wilc_vif *vif,
2135 struct add_sta_param *pstrStationParam)
2141 wid.id = (u16)WID_ADD_STA;
2143 wid.size = WILC_ADD_STA_LENGTH + pstrStationParam->rates_len;
2145 wid.val = kmalloc(wid.size, GFP_KERNEL);
2149 pu8CurrByte = wid.val;
2150 pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam);
2152 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2153 wilc_get_vif_idx(vif));
2155 netdev_err(vif->ndev, "Failed to send add station\n");
2158 kfree(pstrStationParam->rates);
2162 static void Handle_DelAllSta(struct wilc_vif *vif,
2163 struct del_all_sta *pstrDelAllStaParam)
2169 u8 au8Zero_Buff[6] = {0};
2171 wid.id = (u16)WID_DEL_ALL_STA;
2173 wid.size = (pstrDelAllStaParam->assoc_sta * ETH_ALEN) + 1;
2175 wid.val = kmalloc((pstrDelAllStaParam->assoc_sta * ETH_ALEN) + 1, GFP_KERNEL);
2179 pu8CurrByte = wid.val;
2181 *(pu8CurrByte++) = pstrDelAllStaParam->assoc_sta;
2183 for (i = 0; i < MAX_NUM_STA; i++) {
2184 if (memcmp(pstrDelAllStaParam->del_all_sta[i], au8Zero_Buff, ETH_ALEN))
2185 memcpy(pu8CurrByte, pstrDelAllStaParam->del_all_sta[i], ETH_ALEN);
2189 pu8CurrByte += ETH_ALEN;
2192 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2193 wilc_get_vif_idx(vif));
2195 netdev_err(vif->ndev, "Failed to send add station\n");
2200 up(&hif_sema_wait_response);
2203 static void Handle_DelStation(struct wilc_vif *vif,
2204 struct del_sta *pstrDelStaParam)
2210 wid.id = (u16)WID_REMOVE_STA;
2212 wid.size = ETH_ALEN;
2214 wid.val = kmalloc(wid.size, GFP_KERNEL);
2218 pu8CurrByte = wid.val;
2220 memcpy(pu8CurrByte, pstrDelStaParam->mac_addr, ETH_ALEN);
2222 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2223 wilc_get_vif_idx(vif));
2225 netdev_err(vif->ndev, "Failed to send add station\n");
2231 static void Handle_EditStation(struct wilc_vif *vif,
2232 struct add_sta_param *pstrStationParam)
2238 wid.id = (u16)WID_EDIT_STA;
2240 wid.size = WILC_ADD_STA_LENGTH + pstrStationParam->rates_len;
2242 wid.val = kmalloc(wid.size, GFP_KERNEL);
2246 pu8CurrByte = wid.val;
2247 pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam);
2249 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2250 wilc_get_vif_idx(vif));
2252 netdev_err(vif->ndev, "Failed to send edit station\n");
2255 kfree(pstrStationParam->rates);
2259 static int Handle_RemainOnChan(struct wilc_vif *vif,
2260 struct remain_ch *pstrHostIfRemainOnChan)
2263 u8 u8remain_on_chan_flag;
2265 struct host_if_drv *hif_drv = vif->hif_drv;
2267 if (!hif_drv->remain_on_ch_pending) {
2268 hif_drv->remain_on_ch.arg = pstrHostIfRemainOnChan->arg;
2269 hif_drv->remain_on_ch.expired = pstrHostIfRemainOnChan->expired;
2270 hif_drv->remain_on_ch.ready = pstrHostIfRemainOnChan->ready;
2271 hif_drv->remain_on_ch.ch = pstrHostIfRemainOnChan->ch;
2272 hif_drv->remain_on_ch.id = pstrHostIfRemainOnChan->id;
2274 pstrHostIfRemainOnChan->ch = hif_drv->remain_on_ch.ch;
2277 if (hif_drv->usr_scan_req.scan_result) {
2278 hif_drv->remain_on_ch_pending = 1;
2282 if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) {
2287 if (wilc_optaining_ip || wilc_connecting) {
2292 u8remain_on_chan_flag = true;
2293 wid.id = (u16)WID_REMAIN_ON_CHAN;
2296 wid.val = kmalloc(wid.size, GFP_KERNEL);
2302 wid.val[0] = u8remain_on_chan_flag;
2303 wid.val[1] = (s8)pstrHostIfRemainOnChan->ch;
2305 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2306 wilc_get_vif_idx(vif));
2308 netdev_err(vif->ndev, "Failed to set remain on channel\n");
2312 P2P_LISTEN_STATE = 1;
2313 hif_drv->remain_on_ch_timer.data = (unsigned long)vif;
2314 mod_timer(&hif_drv->remain_on_ch_timer,
2316 msecs_to_jiffies(pstrHostIfRemainOnChan->duration));
2318 if (hif_drv->remain_on_ch.ready)
2319 hif_drv->remain_on_ch.ready(hif_drv->remain_on_ch.arg);
2321 if (hif_drv->remain_on_ch_pending)
2322 hif_drv->remain_on_ch_pending = 0;
2328 static int Handle_RegisterFrame(struct wilc_vif *vif,
2329 struct reg_frame *pstrHostIfRegisterFrame)
2335 wid.id = (u16)WID_REGISTER_FRAME;
2337 wid.val = kmalloc(sizeof(u16) + 2, GFP_KERNEL);
2341 pu8CurrByte = wid.val;
2343 *pu8CurrByte++ = pstrHostIfRegisterFrame->reg;
2344 *pu8CurrByte++ = pstrHostIfRegisterFrame->reg_id;
2345 memcpy(pu8CurrByte, &pstrHostIfRegisterFrame->frame_type, sizeof(u16));
2347 wid.size = sizeof(u16) + 2;
2349 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2350 wilc_get_vif_idx(vif));
2352 netdev_err(vif->ndev, "Failed to frame register\n");
2359 static u32 Handle_ListenStateExpired(struct wilc_vif *vif,
2360 struct remain_ch *pstrHostIfRemainOnChan)
2362 u8 u8remain_on_chan_flag;
2365 struct host_if_drv *hif_drv = vif->hif_drv;
2367 if (P2P_LISTEN_STATE) {
2368 u8remain_on_chan_flag = false;
2369 wid.id = (u16)WID_REMAIN_ON_CHAN;
2372 wid.val = kmalloc(wid.size, GFP_KERNEL);
2375 netdev_err(vif->ndev, "Failed to allocate memory\n");
2379 wid.val[0] = u8remain_on_chan_flag;
2380 wid.val[1] = FALSE_FRMWR_CHANNEL;
2382 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2383 wilc_get_vif_idx(vif));
2385 netdev_err(vif->ndev, "Failed to set remain channel\n");
2389 if (hif_drv->remain_on_ch.expired) {
2390 hif_drv->remain_on_ch.expired(hif_drv->remain_on_ch.arg,
2391 pstrHostIfRemainOnChan->id);
2393 P2P_LISTEN_STATE = 0;
2395 netdev_dbg(vif->ndev, "Not in listen state\n");
2403 static void ListenTimerCB(unsigned long arg)
2406 struct host_if_msg msg;
2407 struct wilc_vif *vif = (struct wilc_vif *)arg;
2409 del_timer(&vif->hif_drv->remain_on_ch_timer);
2411 memset(&msg, 0, sizeof(struct host_if_msg));
2412 msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
2414 msg.body.remain_on_ch.id = vif->hif_drv->remain_on_ch.id;
2416 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
2418 netdev_err(vif->ndev, "wilc_mq_send fail\n");
2421 static void Handle_PowerManagement(struct wilc_vif *vif,
2422 struct power_mgmt_param *strPowerMgmtParam)
2428 wid.id = (u16)WID_POWER_MANAGEMENT;
2430 if (strPowerMgmtParam->enabled)
2431 s8PowerMode = MIN_FAST_PS;
2433 s8PowerMode = NO_POWERSAVE;
2435 wid.val = &s8PowerMode;
2436 wid.size = sizeof(char);
2438 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2439 wilc_get_vif_idx(vif));
2441 netdev_err(vif->ndev, "Failed to send power management\n");
2444 static void Handle_SetMulticastFilter(struct wilc_vif *vif,
2445 struct set_multicast *strHostIfSetMulti)
2451 wid.id = (u16)WID_SETUP_MULTICAST_FILTER;
2453 wid.size = sizeof(struct set_multicast) + ((strHostIfSetMulti->cnt) * ETH_ALEN);
2454 wid.val = kmalloc(wid.size, GFP_KERNEL);
2458 pu8CurrByte = wid.val;
2459 *pu8CurrByte++ = (strHostIfSetMulti->enabled & 0xFF);
2464 *pu8CurrByte++ = (strHostIfSetMulti->cnt & 0xFF);
2465 *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 8) & 0xFF);
2466 *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 16) & 0xFF);
2467 *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 24) & 0xFF);
2469 if ((strHostIfSetMulti->cnt) > 0)
2470 memcpy(pu8CurrByte, wilc_multicast_mac_addr_list,
2471 ((strHostIfSetMulti->cnt) * ETH_ALEN));
2473 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2474 wilc_get_vif_idx(vif));
2476 netdev_err(vif->ndev, "Failed to send setup multicast\n");
2482 static void handle_set_tx_pwr(struct wilc_vif *vif, u8 tx_pwr)
2487 wid.id = (u16)WID_TX_POWER;
2488 wid.type = WID_CHAR;
2490 wid.size = sizeof(char);
2492 ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2493 wilc_get_vif_idx(vif));
2495 netdev_err(vif->ndev, "Failed to set TX PWR\n");
2498 static void handle_get_tx_pwr(struct wilc_vif *vif, u8 *tx_pwr)
2503 wid.id = (u16)WID_TX_POWER;
2504 wid.type = WID_CHAR;
2505 wid.val = (s8 *)tx_pwr;
2506 wid.size = sizeof(char);
2508 ret = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
2509 wilc_get_vif_idx(vif));
2511 netdev_err(vif->ndev, "Failed to get TX PWR\n");
2513 up(&hif_sema_wait_response);
2516 static int hostIFthread(void *pvArg)
2519 struct host_if_msg msg;
2520 struct wilc *wilc = pvArg;
2521 struct wilc_vif *vif;
2523 memset(&msg, 0, sizeof(struct host_if_msg));
2526 wilc_mq_recv(&hif_msg_q, &msg, sizeof(struct host_if_msg), &u32Ret);
2528 if (msg.id == HOST_IF_MSG_EXIT)
2531 if ((!wilc_initialized)) {
2532 usleep_range(200 * 1000, 200 * 1000);
2533 wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
2537 if (msg.id == HOST_IF_MSG_CONNECT &&
2538 vif->hif_drv->usr_scan_req.scan_result) {
2539 wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
2540 usleep_range(2 * 1000, 2 * 1000);
2545 case HOST_IF_MSG_SCAN:
2546 Handle_Scan(msg.vif, &msg.body.scan_info);
2549 case HOST_IF_MSG_CONNECT:
2550 Handle_Connect(msg.vif, &msg.body.con_info);
2553 case HOST_IF_MSG_RCVD_NTWRK_INFO:
2554 Handle_RcvdNtwrkInfo(msg.vif, &msg.body.net_info);
2557 case HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO:
2558 Handle_RcvdGnrlAsyncInfo(vif,
2559 &msg.body.async_info);
2562 case HOST_IF_MSG_KEY:
2563 Handle_Key(msg.vif, &msg.body.key_info);
2566 case HOST_IF_MSG_CFG_PARAMS:
2567 handle_cfg_param(msg.vif, &msg.body.cfg_info);
2570 case HOST_IF_MSG_SET_CHANNEL:
2571 handle_set_channel(msg.vif, &msg.body.channel_info);
2574 case HOST_IF_MSG_DISCONNECT:
2575 Handle_Disconnect(msg.vif);
2578 case HOST_IF_MSG_RCVD_SCAN_COMPLETE:
2579 del_timer(&vif->hif_drv->scan_timer);
2581 if (!wilc_wlan_get_num_conn_ifcs(wilc))
2582 wilc_chip_sleep_manually(wilc);
2584 Handle_ScanDone(msg.vif, SCAN_EVENT_DONE);
2586 if (vif->hif_drv->remain_on_ch_pending)
2587 Handle_RemainOnChan(msg.vif,
2588 &msg.body.remain_on_ch);
2592 case HOST_IF_MSG_GET_RSSI:
2593 Handle_GetRssi(msg.vif);
2596 case HOST_IF_MSG_GET_STATISTICS:
2597 Handle_GetStatistics(msg.vif,
2598 (struct rf_info *)msg.body.data);
2601 case HOST_IF_MSG_ADD_BEACON:
2602 Handle_AddBeacon(msg.vif, &msg.body.beacon_info);
2605 case HOST_IF_MSG_DEL_BEACON:
2606 Handle_DelBeacon(msg.vif);
2609 case HOST_IF_MSG_ADD_STATION:
2610 Handle_AddStation(msg.vif, &msg.body.add_sta_info);
2613 case HOST_IF_MSG_DEL_STATION:
2614 Handle_DelStation(msg.vif, &msg.body.del_sta_info);
2617 case HOST_IF_MSG_EDIT_STATION:
2618 Handle_EditStation(msg.vif, &msg.body.edit_sta_info);
2621 case HOST_IF_MSG_GET_INACTIVETIME:
2622 Handle_Get_InActiveTime(msg.vif, &msg.body.mac_info);
2625 case HOST_IF_MSG_SCAN_TIMER_FIRED:
2627 Handle_ScanDone(msg.vif, SCAN_EVENT_ABORTED);
2630 case HOST_IF_MSG_CONNECT_TIMER_FIRED:
2631 Handle_ConnectTimeout(msg.vif);
2634 case HOST_IF_MSG_POWER_MGMT:
2635 Handle_PowerManagement(msg.vif,
2636 &msg.body.pwr_mgmt_info);
2639 case HOST_IF_MSG_SET_WFIDRV_HANDLER:
2640 handle_set_wfi_drv_handler(msg.vif, &msg.body.drv);
2643 case HOST_IF_MSG_SET_OPERATION_MODE:
2644 handle_set_operation_mode(msg.vif, &msg.body.mode);
2647 case HOST_IF_MSG_SET_IPADDRESS:
2648 handle_set_ip_address(vif,
2649 msg.body.ip_info.ip_addr,
2650 msg.body.ip_info.idx);
2653 case HOST_IF_MSG_GET_IPADDRESS:
2654 handle_get_ip_address(vif, msg.body.ip_info.idx);
2657 case HOST_IF_MSG_SET_MAC_ADDRESS:
2658 handle_set_mac_address(msg.vif,
2659 &msg.body.set_mac_info);
2662 case HOST_IF_MSG_GET_MAC_ADDRESS:
2663 handle_get_mac_address(msg.vif,
2664 &msg.body.get_mac_info);
2667 case HOST_IF_MSG_REMAIN_ON_CHAN:
2668 Handle_RemainOnChan(msg.vif, &msg.body.remain_on_ch);
2671 case HOST_IF_MSG_REGISTER_FRAME:
2672 Handle_RegisterFrame(msg.vif, &msg.body.reg_frame);
2675 case HOST_IF_MSG_LISTEN_TIMER_FIRED:
2676 Handle_ListenStateExpired(msg.vif, &msg.body.remain_on_ch);
2679 case HOST_IF_MSG_SET_MULTICAST_FILTER:
2680 Handle_SetMulticastFilter(msg.vif, &msg.body.multicast_info);
2683 case HOST_IF_MSG_DEL_ALL_STA:
2684 Handle_DelAllSta(msg.vif, &msg.body.del_all_sta_info);
2687 case HOST_IF_MSG_SET_TX_POWER:
2688 handle_set_tx_pwr(msg.vif, msg.body.tx_power.tx_pwr);
2691 case HOST_IF_MSG_GET_TX_POWER:
2692 handle_get_tx_pwr(msg.vif, &msg.body.tx_power.tx_pwr);
2695 netdev_err(vif->ndev, "[Host Interface] undefined\n");
2700 up(&hif_sema_thread);
2704 static void TimerCB_Scan(unsigned long arg)
2706 struct wilc_vif *vif = (struct wilc_vif *)arg;
2707 struct host_if_msg msg;
2709 memset(&msg, 0, sizeof(struct host_if_msg));
2711 msg.id = HOST_IF_MSG_SCAN_TIMER_FIRED;
2713 wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
2716 static void TimerCB_Connect(unsigned long arg)
2718 struct wilc_vif *vif = (struct wilc_vif *)arg;
2719 struct host_if_msg msg;
2721 memset(&msg, 0, sizeof(struct host_if_msg));
2723 msg.id = HOST_IF_MSG_CONNECT_TIMER_FIRED;
2725 wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
2728 s32 wilc_remove_key(struct host_if_drv *hif_drv, const u8 *pu8StaAddress)
2732 wid.id = (u16)WID_REMOVE_KEY;
2734 wid.val = (s8 *)pu8StaAddress;
2740 int wilc_remove_wep_key(struct wilc_vif *vif, u8 index)
2743 struct host_if_msg msg;
2744 struct host_if_drv *hif_drv = vif->hif_drv;
2748 netdev_err(vif->ndev, "Failed to send setup multicast\n");
2752 memset(&msg, 0, sizeof(struct host_if_msg));
2754 msg.id = HOST_IF_MSG_KEY;
2755 msg.body.key_info.type = WEP;
2756 msg.body.key_info.action = REMOVEKEY;
2758 msg.body.key_info.attr.wep.index = index;
2760 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
2762 netdev_err(vif->ndev, "Request to remove WEP key\n");
2763 down(&hif_drv->sem_test_key_block);
2768 int wilc_set_wep_default_keyid(struct wilc_vif *vif, u8 index)
2771 struct host_if_msg msg;
2772 struct host_if_drv *hif_drv = vif->hif_drv;
2776 netdev_err(vif->ndev, "driver is null\n");
2780 memset(&msg, 0, sizeof(struct host_if_msg));
2782 msg.id = HOST_IF_MSG_KEY;
2783 msg.body.key_info.type = WEP;
2784 msg.body.key_info.action = DEFAULTKEY;
2786 msg.body.key_info.attr.wep.index = index;
2788 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
2790 netdev_err(vif->ndev, "Default key index\n");
2791 down(&hif_drv->sem_test_key_block);
2796 int wilc_add_wep_key_bss_sta(struct wilc_vif *vif, const u8 *key, u8 len,
2800 struct host_if_msg msg;
2801 struct host_if_drv *hif_drv = vif->hif_drv;
2804 netdev_err(vif->ndev, "driver is null\n");
2808 memset(&msg, 0, sizeof(struct host_if_msg));
2810 msg.id = HOST_IF_MSG_KEY;
2811 msg.body.key_info.type = WEP;
2812 msg.body.key_info.action = ADDKEY;
2814 msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL);
2815 if (!msg.body.key_info.attr.wep.key)
2818 msg.body.key_info.attr.wep.key_len = len;
2819 msg.body.key_info.attr.wep.index = index;
2821 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
2823 netdev_err(vif->ndev, "STA - WEP Key\n");
2824 down(&hif_drv->sem_test_key_block);
2829 int wilc_add_wep_key_bss_ap(struct wilc_vif *vif, const u8 *key, u8 len,
2830 u8 index, u8 mode, enum AUTHTYPE auth_type)
2833 struct host_if_msg msg;
2834 struct host_if_drv *hif_drv = vif->hif_drv;
2837 netdev_err(vif->ndev, "driver is null\n");
2841 memset(&msg, 0, sizeof(struct host_if_msg));
2843 msg.id = HOST_IF_MSG_KEY;
2844 msg.body.key_info.type = WEP;
2845 msg.body.key_info.action = ADDKEY_AP;
2847 msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL);
2848 if (!msg.body.key_info.attr.wep.key)
2851 msg.body.key_info.attr.wep.key_len = len;
2852 msg.body.key_info.attr.wep.index = index;
2853 msg.body.key_info.attr.wep.mode = mode;
2854 msg.body.key_info.attr.wep.auth_type = auth_type;
2856 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
2859 netdev_err(vif->ndev, "AP - WEP Key\n");
2860 down(&hif_drv->sem_test_key_block);
2865 int wilc_add_ptk(struct wilc_vif *vif, const u8 *ptk, u8 ptk_key_len,
2866 const u8 *mac_addr, const u8 *rx_mic, const u8 *tx_mic,
2867 u8 mode, u8 cipher_mode, u8 index)
2870 struct host_if_msg msg;
2871 struct host_if_drv *hif_drv = vif->hif_drv;
2872 u8 key_len = ptk_key_len;
2875 netdev_err(vif->ndev, "driver is null\n");
2880 key_len += RX_MIC_KEY_LEN;
2883 key_len += TX_MIC_KEY_LEN;
2885 memset(&msg, 0, sizeof(struct host_if_msg));
2887 msg.id = HOST_IF_MSG_KEY;
2888 msg.body.key_info.type = WPA_PTK;
2889 if (mode == AP_MODE) {
2890 msg.body.key_info.action = ADDKEY_AP;
2891 msg.body.key_info.attr.wpa.index = index;
2893 if (mode == STATION_MODE)
2894 msg.body.key_info.action = ADDKEY;
2896 msg.body.key_info.attr.wpa.key = kmemdup(ptk, ptk_key_len, GFP_KERNEL);
2897 if (!msg.body.key_info.attr.wpa.key)
2901 memcpy(msg.body.key_info.attr.wpa.key + 16, rx_mic, RX_MIC_KEY_LEN);
2904 memcpy(msg.body.key_info.attr.wpa.key + 24, tx_mic, TX_MIC_KEY_LEN);
2906 msg.body.key_info.attr.wpa.key_len = key_len;
2907 msg.body.key_info.attr.wpa.mac_addr = mac_addr;
2908 msg.body.key_info.attr.wpa.mode = cipher_mode;
2911 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
2914 netdev_err(vif->ndev, "PTK Key\n");
2916 down(&hif_drv->sem_test_key_block);
2921 int wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *rx_gtk, u8 gtk_key_len,
2922 u8 index, u32 key_rsc_len, const u8 *key_rsc,
2923 const u8 *rx_mic, const u8 *tx_mic, u8 mode,
2927 struct host_if_msg msg;
2928 struct host_if_drv *hif_drv = vif->hif_drv;
2929 u8 key_len = gtk_key_len;
2932 netdev_err(vif->ndev, "driver is null\n");
2935 memset(&msg, 0, sizeof(struct host_if_msg));
2938 key_len += RX_MIC_KEY_LEN;
2941 key_len += TX_MIC_KEY_LEN;
2944 msg.body.key_info.attr.wpa.seq = kmemdup(key_rsc,
2947 if (!msg.body.key_info.attr.wpa.seq)
2951 msg.id = HOST_IF_MSG_KEY;
2952 msg.body.key_info.type = WPA_RX_GTK;
2955 if (mode == AP_MODE) {
2956 msg.body.key_info.action = ADDKEY_AP;
2957 msg.body.key_info.attr.wpa.mode = cipher_mode;
2959 if (mode == STATION_MODE)
2960 msg.body.key_info.action = ADDKEY;
2962 msg.body.key_info.attr.wpa.key = kmemdup(rx_gtk,
2965 if (!msg.body.key_info.attr.wpa.key)
2969 memcpy(msg.body.key_info.attr.wpa.key + 16, rx_mic,
2973 memcpy(msg.body.key_info.attr.wpa.key + 24, tx_mic,
2976 msg.body.key_info.attr.wpa.index = index;
2977 msg.body.key_info.attr.wpa.key_len = key_len;
2978 msg.body.key_info.attr.wpa.seq_len = key_rsc_len;
2980 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
2982 netdev_err(vif->ndev, "RX GTK\n");
2984 down(&hif_drv->sem_test_key_block);
2989 int wilc_set_pmkid_info(struct wilc_vif *vif,
2990 struct host_if_pmkid_attr *pmkid)
2993 struct host_if_msg msg;
2994 struct host_if_drv *hif_drv = vif->hif_drv;
2998 netdev_err(vif->ndev, "driver is null\n");
3002 memset(&msg, 0, sizeof(struct host_if_msg));
3004 msg.id = HOST_IF_MSG_KEY;
3005 msg.body.key_info.type = PMKSA;
3006 msg.body.key_info.action = ADDKEY;
3009 for (i = 0; i < pmkid->numpmkid; i++) {
3010 memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].bssid,
3011 &pmkid->pmkidlist[i].bssid, ETH_ALEN);
3012 memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].pmkid,
3013 &pmkid->pmkidlist[i].pmkid, PMKID_LEN);
3016 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3018 netdev_err(vif->ndev, "PMKID Info\n");
3023 int wilc_get_mac_address(struct wilc_vif *vif, u8 *mac_addr)
3026 struct host_if_msg msg;
3028 memset(&msg, 0, sizeof(struct host_if_msg));
3030 msg.id = HOST_IF_MSG_GET_MAC_ADDRESS;
3031 msg.body.get_mac_info.mac_addr = mac_addr;
3034 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3036 netdev_err(vif->ndev, "Failed to send get mac address\n");
3040 down(&hif_sema_wait_response);
3044 int wilc_set_join_req(struct wilc_vif *vif, u8 *bssid, const u8 *ssid,
3045 size_t ssid_len, const u8 *ies, size_t ies_len,
3046 wilc_connect_result connect_result, void *user_arg,
3047 u8 security, enum AUTHTYPE auth_type,
3048 u8 channel, void *join_params)
3051 struct host_if_msg msg;
3052 struct host_if_drv *hif_drv = vif->hif_drv;
3054 if (!hif_drv || !connect_result) {
3055 netdev_err(vif->ndev, "Driver is null\n");
3060 netdev_err(vif->ndev, "Unable to Join - JoinParams is NULL\n");
3064 memset(&msg, 0, sizeof(struct host_if_msg));
3066 msg.id = HOST_IF_MSG_CONNECT;
3068 msg.body.con_info.security = security;
3069 msg.body.con_info.auth_type = auth_type;
3070 msg.body.con_info.ch = channel;
3071 msg.body.con_info.result = connect_result;
3072 msg.body.con_info.arg = user_arg;
3073 msg.body.con_info.params = join_params;
3077 msg.body.con_info.bssid = kmemdup(bssid, 6, GFP_KERNEL);
3078 if (!msg.body.con_info.bssid)
3083 msg.body.con_info.ssid_len = ssid_len;
3084 msg.body.con_info.ssid = kmemdup(ssid, ssid_len, GFP_KERNEL);
3085 if (!msg.body.con_info.ssid)
3090 msg.body.con_info.ies_len = ies_len;
3091 msg.body.con_info.ies = kmemdup(ies, ies_len, GFP_KERNEL);
3092 if (!msg.body.con_info.ies)
3095 if (hif_drv->hif_state < HOST_IF_CONNECTING)
3096 hif_drv->hif_state = HOST_IF_CONNECTING;
3098 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3100 netdev_err(vif->ndev, "send message: Set join request\n");
3104 hif_drv->connect_timer.data = (unsigned long)vif;
3105 mod_timer(&hif_drv->connect_timer,
3106 jiffies + msecs_to_jiffies(HOST_IF_CONNECT_TIMEOUT));
3111 int wilc_disconnect(struct wilc_vif *vif, u16 reason_code)
3114 struct host_if_msg msg;
3115 struct host_if_drv *hif_drv = vif->hif_drv;
3118 netdev_err(vif->ndev, "Driver is null\n");
3122 memset(&msg, 0, sizeof(struct host_if_msg));
3124 msg.id = HOST_IF_MSG_DISCONNECT;
3127 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3129 netdev_err(vif->ndev, "Failed to send message: disconnect\n");
3131 down(&hif_drv->sem_test_disconn_block);
3136 static s32 host_int_get_assoc_res_info(struct wilc_vif *vif,
3137 u8 *pu8AssocRespInfo,
3138 u32 u32MaxAssocRespInfoLen,
3139 u32 *pu32RcvdAssocRespInfoLen)
3143 struct host_if_drv *hif_drv = vif->hif_drv;
3146 netdev_err(vif->ndev, "Driver is null\n");
3150 wid.id = (u16)WID_ASSOC_RES_INFO;
3152 wid.val = pu8AssocRespInfo;
3153 wid.size = u32MaxAssocRespInfoLen;
3155 result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
3156 wilc_get_vif_idx(vif));
3158 *pu32RcvdAssocRespInfoLen = 0;
3159 netdev_err(vif->ndev, "Failed to send association response\n");
3163 *pu32RcvdAssocRespInfoLen = wid.size;
3167 int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 channel)
3170 struct host_if_msg msg;
3171 struct host_if_drv *hif_drv = vif->hif_drv;
3174 netdev_err(vif->ndev, "driver is null\n");
3178 memset(&msg, 0, sizeof(struct host_if_msg));
3179 msg.id = HOST_IF_MSG_SET_CHANNEL;
3180 msg.body.channel_info.set_ch = channel;
3183 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3185 netdev_err(vif->ndev, "wilc mq send fail\n");
3192 int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mac_idx)
3195 struct host_if_msg msg;
3197 memset(&msg, 0, sizeof(struct host_if_msg));
3198 msg.id = HOST_IF_MSG_SET_WFIDRV_HANDLER;
3199 msg.body.drv.handler = index;
3200 msg.body.drv.mac_idx = mac_idx;
3203 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3205 netdev_err(vif->ndev, "wilc mq send fail\n");
3212 int wilc_set_operation_mode(struct wilc_vif *vif, u32 mode)
3215 struct host_if_msg msg;
3217 memset(&msg, 0, sizeof(struct host_if_msg));
3218 msg.id = HOST_IF_MSG_SET_OPERATION_MODE;
3219 msg.body.mode.mode = mode;
3222 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3224 netdev_err(vif->ndev, "wilc mq send fail\n");
3231 s32 wilc_get_inactive_time(struct wilc_vif *vif, const u8 *mac,
3232 u32 *pu32InactiveTime)
3235 struct host_if_msg msg;
3236 struct host_if_drv *hif_drv = vif->hif_drv;
3239 netdev_err(vif->ndev, "driver is null\n");
3243 memset(&msg, 0, sizeof(struct host_if_msg));
3244 memcpy(msg.body.mac_info.mac, mac, ETH_ALEN);
3246 msg.id = HOST_IF_MSG_GET_INACTIVETIME;
3249 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3251 netdev_err(vif->ndev, "Failed to send get host ch param\n");
3253 down(&hif_drv->sem_inactive_time);
3255 *pu32InactiveTime = inactive_time;
3260 int wilc_get_rssi(struct wilc_vif *vif, s8 *rssi_level)
3263 struct host_if_msg msg;
3264 struct host_if_drv *hif_drv = vif->hif_drv;
3266 memset(&msg, 0, sizeof(struct host_if_msg));
3267 msg.id = HOST_IF_MSG_GET_RSSI;
3270 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3272 netdev_err(vif->ndev, "Failed to send get host ch param\n");
3276 down(&hif_drv->sem_get_rssi);
3279 netdev_err(vif->ndev, "RSS pointer value is null\n");
3288 int wilc_get_statistics(struct wilc_vif *vif, struct rf_info *stats)
3291 struct host_if_msg msg;
3293 memset(&msg, 0, sizeof(struct host_if_msg));
3294 msg.id = HOST_IF_MSG_GET_STATISTICS;
3295 msg.body.data = (char *)stats;
3298 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3300 netdev_err(vif->ndev, "Failed to send get host channel\n");
3304 if (stats != &vif->wilc->dummy_statistics)
3305 down(&hif_sema_wait_response);
3309 int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 scan_type,
3310 u8 *ch_freq_list, u8 ch_list_len, const u8 *ies,
3311 size_t ies_len, wilc_scan_result scan_result, void *user_arg,
3312 struct hidden_network *hidden_network)
3315 struct host_if_msg msg;
3316 struct scan_attr *scan_info = &msg.body.scan_info;
3317 struct host_if_drv *hif_drv = vif->hif_drv;
3319 if (!hif_drv || !scan_result) {
3320 netdev_err(vif->ndev, "hif_drv or scan_result = NULL\n");
3324 memset(&msg, 0, sizeof(struct host_if_msg));
3326 msg.id = HOST_IF_MSG_SCAN;
3328 if (hidden_network) {
3329 scan_info->hidden_network.net_info = hidden_network->net_info;
3330 scan_info->hidden_network.n_ssids = hidden_network->n_ssids;
3334 scan_info->src = scan_source;
3335 scan_info->type = scan_type;
3336 scan_info->result = scan_result;
3337 scan_info->arg = user_arg;
3339 scan_info->ch_list_len = ch_list_len;
3340 scan_info->ch_freq_list = kmemdup(ch_freq_list,
3343 if (!scan_info->ch_freq_list)
3346 scan_info->ies_len = ies_len;
3347 scan_info->ies = kmemdup(ies, ies_len, GFP_KERNEL);
3348 if (!scan_info->ies)
3351 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3353 netdev_err(vif->ndev, "Error in sending message queue\n");
3357 hif_drv->scan_timer.data = (unsigned long)vif;
3358 mod_timer(&hif_drv->scan_timer,
3359 jiffies + msecs_to_jiffies(HOST_IF_SCAN_TIMEOUT));
3364 int wilc_hif_set_cfg(struct wilc_vif *vif,
3365 struct cfg_param_attr *cfg_param)
3368 struct host_if_msg msg;
3369 struct host_if_drv *hif_drv = vif->hif_drv;
3372 netdev_err(vif->ndev, "hif_drv NULL\n");
3376 memset(&msg, 0, sizeof(struct host_if_msg));
3377 msg.id = HOST_IF_MSG_CFG_PARAMS;
3378 msg.body.cfg_info = *cfg_param;
3381 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3386 static void GetPeriodicRSSI(unsigned long arg)
3388 struct wilc_vif *vif = (struct wilc_vif *)arg;
3390 if (!vif->hif_drv) {
3391 netdev_err(vif->ndev, "Driver handler is NULL\n");
3395 if (vif->hif_drv->hif_state == HOST_IF_CONNECTED)
3396 wilc_get_statistics(vif, &vif->wilc->dummy_statistics);
3398 periodic_rssi.data = (unsigned long)vif;
3399 mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
3402 int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
3405 struct host_if_drv *hif_drv;
3406 struct wilc_vif *vif;
3410 vif = netdev_priv(dev);
3413 scan_while_connected = false;
3415 sema_init(&hif_sema_wait_response, 0);
3417 hif_drv = kzalloc(sizeof(struct host_if_drv), GFP_KERNEL);
3422 *hif_drv_handler = hif_drv;
3423 for (i = 0; i < wilc->vif_num; i++)
3424 if (dev == wilc->vif[i]->ndev) {
3425 wilc->vif[i]->hif_drv = hif_drv;
3429 wilc_optaining_ip = false;
3431 if (clients_count == 0) {
3432 sema_init(&hif_sema_thread, 0);
3433 sema_init(&hif_sema_driver, 0);
3434 sema_init(&hif_sema_deinit, 1);
3437 sema_init(&hif_drv->sem_test_key_block, 0);
3438 sema_init(&hif_drv->sem_test_disconn_block, 0);
3439 sema_init(&hif_drv->sem_get_rssi, 0);
3440 sema_init(&hif_drv->sem_inactive_time, 0);
3442 if (clients_count == 0) {
3443 result = wilc_mq_create(&hif_msg_q);
3446 netdev_err(vif->ndev, "Failed to creat MQ\n");
3450 hif_thread_handler = kthread_run(hostIFthread, wilc,
3453 if (IS_ERR(hif_thread_handler)) {
3454 netdev_err(vif->ndev, "Failed to creat Thread\n");
3458 setup_timer(&periodic_rssi, GetPeriodicRSSI,
3459 (unsigned long)vif);
3460 mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
3463 setup_timer(&hif_drv->scan_timer, TimerCB_Scan, 0);
3464 setup_timer(&hif_drv->connect_timer, TimerCB_Connect, 0);
3465 setup_timer(&hif_drv->remain_on_ch_timer, ListenTimerCB, 0);
3467 sema_init(&hif_drv->sem_cfg_values, 1);
3468 down(&hif_drv->sem_cfg_values);
3470 hif_drv->hif_state = HOST_IF_IDLE;
3471 hif_drv->cfg_values.site_survey_enabled = SITE_SURVEY_OFF;
3472 hif_drv->cfg_values.scan_source = DEFAULT_SCAN;
3473 hif_drv->cfg_values.active_scan_time = ACTIVE_SCAN_TIME;
3474 hif_drv->cfg_values.passive_scan_time = PASSIVE_SCAN_TIME;
3475 hif_drv->cfg_values.curr_tx_rate = AUTORATE;
3477 hif_drv->p2p_timeout = 0;
3479 up(&hif_drv->sem_cfg_values);
3486 wilc_mq_destroy(&hif_msg_q);
3491 int wilc_deinit(struct wilc_vif *vif)
3494 struct host_if_msg msg;
3495 struct host_if_drv *hif_drv = vif->hif_drv;
3498 netdev_err(vif->ndev, "hif_drv = NULL\n");
3502 down(&hif_sema_deinit);
3504 terminated_handle = hif_drv;
3506 del_timer_sync(&hif_drv->scan_timer);
3507 del_timer_sync(&hif_drv->connect_timer);
3508 del_timer_sync(&periodic_rssi);
3509 del_timer_sync(&hif_drv->remain_on_ch_timer);
3511 wilc_set_wfi_drv_handler(vif, 0, 0);
3512 down(&hif_sema_driver);
3514 if (hif_drv->usr_scan_req.scan_result) {
3515 hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED, NULL,
3516 hif_drv->usr_scan_req.arg, NULL);
3517 hif_drv->usr_scan_req.scan_result = NULL;
3520 hif_drv->hif_state = HOST_IF_IDLE;
3522 scan_while_connected = false;
3524 memset(&msg, 0, sizeof(struct host_if_msg));
3526 if (clients_count == 1) {
3527 del_timer_sync(&periodic_rssi);
3528 msg.id = HOST_IF_MSG_EXIT;
3531 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3533 netdev_err(vif->ndev, "deinit : Error(%d)\n", result);
3535 down(&hif_sema_thread);
3537 wilc_mq_destroy(&hif_msg_q);
3543 terminated_handle = NULL;
3544 up(&hif_sema_deinit);
3548 void wilc_network_info_received(struct wilc *wilc, u8 *pu8Buffer,
3552 struct host_if_msg msg;
3554 struct host_if_drv *hif_drv = NULL;
3555 struct wilc_vif *vif;
3557 id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
3558 vif = wilc_get_vif_from_idx(wilc, id);
3561 hif_drv = vif->hif_drv;
3563 if (!hif_drv || hif_drv == terminated_handle) {
3564 netdev_err(vif->ndev, "driver not init[%p]\n", hif_drv);
3568 memset(&msg, 0, sizeof(struct host_if_msg));
3570 msg.id = HOST_IF_MSG_RCVD_NTWRK_INFO;
3573 msg.body.net_info.len = u32Length;
3574 msg.body.net_info.buffer = kmalloc(u32Length, GFP_KERNEL);
3575 memcpy(msg.body.net_info.buffer, pu8Buffer, u32Length);
3577 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3579 netdev_err(vif->ndev, "message parameters (%d)\n", result);
3582 void wilc_gnrl_async_info_received(struct wilc *wilc, u8 *pu8Buffer,
3586 struct host_if_msg msg;
3588 struct host_if_drv *hif_drv = NULL;
3589 struct wilc_vif *vif;
3591 down(&hif_sema_deinit);
3593 id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
3594 vif = wilc_get_vif_from_idx(wilc, id);
3596 up(&hif_sema_deinit);
3600 hif_drv = vif->hif_drv;
3602 if (!hif_drv || hif_drv == terminated_handle) {
3603 up(&hif_sema_deinit);
3607 if (!hif_drv->usr_conn_req.conn_result) {
3608 netdev_err(vif->ndev, "there is no current Connect Request\n");
3609 up(&hif_sema_deinit);
3613 memset(&msg, 0, sizeof(struct host_if_msg));
3615 msg.id = HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO;
3618 msg.body.async_info.len = u32Length;
3619 msg.body.async_info.buffer = kmalloc(u32Length, GFP_KERNEL);
3620 memcpy(msg.body.async_info.buffer, pu8Buffer, u32Length);
3622 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3624 netdev_err(vif->ndev, "synchronous info (%d)\n", result);
3626 up(&hif_sema_deinit);
3629 void wilc_scan_complete_received(struct wilc *wilc, u8 *pu8Buffer,
3633 struct host_if_msg msg;
3635 struct host_if_drv *hif_drv = NULL;
3636 struct wilc_vif *vif;
3638 id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
3639 vif = wilc_get_vif_from_idx(wilc, id);
3642 hif_drv = vif->hif_drv;
3644 if (!hif_drv || hif_drv == terminated_handle)
3647 if (hif_drv->usr_scan_req.scan_result) {
3648 memset(&msg, 0, sizeof(struct host_if_msg));
3650 msg.id = HOST_IF_MSG_RCVD_SCAN_COMPLETE;
3653 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3655 netdev_err(vif->ndev, "complete param (%d)\n", result);
3659 int wilc_remain_on_channel(struct wilc_vif *vif, u32 session_id,
3660 u32 duration, u16 chan,
3661 wilc_remain_on_chan_expired expired,
3662 wilc_remain_on_chan_ready ready,
3666 struct host_if_msg msg;
3667 struct host_if_drv *hif_drv = vif->hif_drv;
3670 netdev_err(vif->ndev, "driver is null\n");
3674 memset(&msg, 0, sizeof(struct host_if_msg));
3676 msg.id = HOST_IF_MSG_REMAIN_ON_CHAN;
3677 msg.body.remain_on_ch.ch = chan;
3678 msg.body.remain_on_ch.expired = expired;
3679 msg.body.remain_on_ch.ready = ready;
3680 msg.body.remain_on_ch.arg = user_arg;
3681 msg.body.remain_on_ch.duration = duration;
3682 msg.body.remain_on_ch.id = session_id;
3685 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3687 netdev_err(vif->ndev, "wilc mq send fail\n");
3692 int wilc_listen_state_expired(struct wilc_vif *vif, u32 session_id)
3695 struct host_if_msg msg;
3696 struct host_if_drv *hif_drv = vif->hif_drv;
3699 netdev_err(vif->ndev, "driver is null\n");
3703 del_timer(&hif_drv->remain_on_ch_timer);
3705 memset(&msg, 0, sizeof(struct host_if_msg));
3706 msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
3708 msg.body.remain_on_ch.id = session_id;
3710 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3712 netdev_err(vif->ndev, "wilc mq send fail\n");
3717 int wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg)
3720 struct host_if_msg msg;
3721 struct host_if_drv *hif_drv = vif->hif_drv;
3724 netdev_err(vif->ndev, "driver is null\n");
3728 memset(&msg, 0, sizeof(struct host_if_msg));
3730 msg.id = HOST_IF_MSG_REGISTER_FRAME;
3731 switch (frame_type) {
3733 msg.body.reg_frame.reg_id = ACTION_FRM_IDX;
3737 msg.body.reg_frame.reg_id = PROBE_REQ_IDX;
3743 msg.body.reg_frame.frame_type = frame_type;
3744 msg.body.reg_frame.reg = reg;
3747 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3749 netdev_err(vif->ndev, "wilc mq send fail\n");
3754 int wilc_add_beacon(struct wilc_vif *vif, u32 interval, u32 dtim_period,
3755 u32 head_len, u8 *head, u32 tail_len, u8 *tail)
3758 struct host_if_msg msg;
3759 struct beacon_attr *beacon_info = &msg.body.beacon_info;
3760 struct host_if_drv *hif_drv = vif->hif_drv;
3763 netdev_err(vif->ndev, "driver is null\n");
3767 memset(&msg, 0, sizeof(struct host_if_msg));
3769 msg.id = HOST_IF_MSG_ADD_BEACON;
3771 beacon_info->interval = interval;
3772 beacon_info->dtim_period = dtim_period;
3773 beacon_info->head_len = head_len;
3774 beacon_info->head = kmemdup(head, head_len, GFP_KERNEL);
3775 if (!beacon_info->head) {
3779 beacon_info->tail_len = tail_len;
3782 beacon_info->tail = kmemdup(tail, tail_len, GFP_KERNEL);
3783 if (!beacon_info->tail) {
3788 beacon_info->tail = NULL;
3791 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3793 netdev_err(vif->ndev, "wilc mq send fail\n");
3797 kfree(beacon_info->head);
3799 kfree(beacon_info->tail);
3805 int wilc_del_beacon(struct wilc_vif *vif)
3808 struct host_if_msg msg;
3809 struct host_if_drv *hif_drv = vif->hif_drv;
3812 netdev_err(vif->ndev, "driver is null\n");
3816 msg.id = HOST_IF_MSG_DEL_BEACON;
3819 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3821 netdev_err(vif->ndev, "wilc_mq_send fail\n");
3826 int wilc_add_station(struct wilc_vif *vif, struct add_sta_param *sta_param)
3829 struct host_if_msg msg;
3830 struct add_sta_param *add_sta_info = &msg.body.add_sta_info;
3831 struct host_if_drv *hif_drv = vif->hif_drv;
3834 netdev_err(vif->ndev, "driver is null\n");
3838 memset(&msg, 0, sizeof(struct host_if_msg));
3840 msg.id = HOST_IF_MSG_ADD_STATION;
3843 memcpy(add_sta_info, sta_param, sizeof(struct add_sta_param));
3844 if (add_sta_info->rates_len > 0) {
3845 add_sta_info->rates = kmemdup(sta_param->rates,
3846 add_sta_info->rates_len,
3848 if (!add_sta_info->rates)
3852 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3854 netdev_err(vif->ndev, "wilc_mq_send fail\n");
3858 int wilc_del_station(struct wilc_vif *vif, const u8 *mac_addr)
3861 struct host_if_msg msg;
3862 struct del_sta *del_sta_info = &msg.body.del_sta_info;
3863 struct host_if_drv *hif_drv = vif->hif_drv;
3866 netdev_err(vif->ndev, "driver is null\n");
3870 memset(&msg, 0, sizeof(struct host_if_msg));
3872 msg.id = HOST_IF_MSG_DEL_STATION;
3876 eth_broadcast_addr(del_sta_info->mac_addr);
3878 memcpy(del_sta_info->mac_addr, mac_addr, ETH_ALEN);
3880 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3882 netdev_err(vif->ndev, "wilc_mq_send fail\n");
3886 int wilc_del_allstation(struct wilc_vif *vif, u8 mac_addr[][ETH_ALEN])
3889 struct host_if_msg msg;
3890 struct del_all_sta *del_all_sta_info = &msg.body.del_all_sta_info;
3891 struct host_if_drv *hif_drv = vif->hif_drv;
3892 u8 zero_addr[ETH_ALEN] = {0};
3897 netdev_err(vif->ndev, "driver is null\n");
3901 memset(&msg, 0, sizeof(struct host_if_msg));
3903 msg.id = HOST_IF_MSG_DEL_ALL_STA;
3906 for (i = 0; i < MAX_NUM_STA; i++) {
3907 if (memcmp(mac_addr[i], zero_addr, ETH_ALEN)) {
3908 memcpy(del_all_sta_info->del_all_sta[i], mac_addr[i], ETH_ALEN);
3915 del_all_sta_info->assoc_sta = assoc_sta;
3916 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3919 netdev_err(vif->ndev, "wilc_mq_send fail\n");
3921 down(&hif_sema_wait_response);
3926 int wilc_edit_station(struct wilc_vif *vif,
3927 struct add_sta_param *sta_param)
3930 struct host_if_msg msg;
3931 struct add_sta_param *add_sta_info = &msg.body.add_sta_info;
3932 struct host_if_drv *hif_drv = vif->hif_drv;
3935 netdev_err(vif->ndev, "driver is null\n");
3939 memset(&msg, 0, sizeof(struct host_if_msg));
3941 msg.id = HOST_IF_MSG_EDIT_STATION;
3944 memcpy(add_sta_info, sta_param, sizeof(struct add_sta_param));
3945 if (add_sta_info->rates_len > 0) {
3946 add_sta_info->rates = kmemdup(sta_param->rates,
3947 add_sta_info->rates_len,
3949 if (!add_sta_info->rates)
3953 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3955 netdev_err(vif->ndev, "wilc_mq_send fail\n");
3960 int wilc_set_power_mgmt(struct wilc_vif *vif, bool enabled, u32 timeout)
3963 struct host_if_msg msg;
3964 struct power_mgmt_param *pwr_mgmt_info = &msg.body.pwr_mgmt_info;
3965 struct host_if_drv *hif_drv = vif->hif_drv;
3968 netdev_err(vif->ndev, "driver is null\n");
3972 if (wilc_wlan_get_num_conn_ifcs(vif->wilc) == 2 && enabled)
3975 memset(&msg, 0, sizeof(struct host_if_msg));
3977 msg.id = HOST_IF_MSG_POWER_MGMT;
3980 pwr_mgmt_info->enabled = enabled;
3981 pwr_mgmt_info->timeout = timeout;
3983 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3985 netdev_err(vif->ndev, "wilc_mq_send fail\n");
3989 int wilc_setup_multicast_filter(struct wilc_vif *vif, bool enabled,
3993 struct host_if_msg msg;
3994 struct set_multicast *multicast_filter_param = &msg.body.multicast_info;
3995 struct host_if_drv *hif_drv = vif->hif_drv;
3998 netdev_err(vif->ndev, "driver is null\n");
4002 memset(&msg, 0, sizeof(struct host_if_msg));
4004 msg.id = HOST_IF_MSG_SET_MULTICAST_FILTER;
4007 multicast_filter_param->enabled = enabled;
4008 multicast_filter_param->cnt = count;
4010 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4012 netdev_err(vif->ndev, "wilc_mq_send fail\n");
4016 static void *host_int_ParseJoinBssParam(struct network_info *ptstrNetworkInfo)
4018 struct join_bss_param *pNewJoinBssParam = NULL;
4027 u8 pcipherTotalCount = 0;
4028 u8 authTotalCount = 0;
4031 pu8IEs = ptstrNetworkInfo->ies;
4032 u16IEsLen = ptstrNetworkInfo->ies_len;
4034 pNewJoinBssParam = kzalloc(sizeof(struct join_bss_param), GFP_KERNEL);
4035 if (pNewJoinBssParam) {
4036 pNewJoinBssParam->dtim_period = ptstrNetworkInfo->dtim_period;
4037 pNewJoinBssParam->beacon_period = ptstrNetworkInfo->beacon_period;
4038 pNewJoinBssParam->cap_info = ptstrNetworkInfo->cap_info;
4039 memcpy(pNewJoinBssParam->bssid, ptstrNetworkInfo->bssid, 6);
4040 memcpy((u8 *)pNewJoinBssParam->ssid, ptstrNetworkInfo->ssid,
4041 ptstrNetworkInfo->ssid_len + 1);
4042 pNewJoinBssParam->ssid_len = ptstrNetworkInfo->ssid_len;
4043 memset(pNewJoinBssParam->rsn_pcip_policy, 0xFF, 3);
4044 memset(pNewJoinBssParam->rsn_auth_policy, 0xFF, 3);
4046 while (index < u16IEsLen) {
4047 if (pu8IEs[index] == SUPP_RATES_IE) {
4048 suppRatesNo = pu8IEs[index + 1];
4049 pNewJoinBssParam->supp_rates[0] = suppRatesNo;
4052 for (i = 0; i < suppRatesNo; i++)
4053 pNewJoinBssParam->supp_rates[i + 1] = pu8IEs[index + i];
4055 index += suppRatesNo;
4057 } else if (pu8IEs[index] == EXT_SUPP_RATES_IE) {
4058 extSuppRatesNo = pu8IEs[index + 1];
4059 if (extSuppRatesNo > (MAX_RATES_SUPPORTED - suppRatesNo))
4060 pNewJoinBssParam->supp_rates[0] = MAX_RATES_SUPPORTED;
4062 pNewJoinBssParam->supp_rates[0] += extSuppRatesNo;
4064 for (i = 0; i < (pNewJoinBssParam->supp_rates[0] - suppRatesNo); i++)
4065 pNewJoinBssParam->supp_rates[suppRatesNo + i + 1] = pu8IEs[index + i];
4067 index += extSuppRatesNo;
4069 } else if (pu8IEs[index] == HT_CAPABILITY_IE) {
4070 pNewJoinBssParam->ht_capable = true;
4071 index += pu8IEs[index + 1] + 2;
4073 } else if ((pu8IEs[index] == WMM_IE) &&
4074 (pu8IEs[index + 2] == 0x00) && (pu8IEs[index + 3] == 0x50) &&
4075 (pu8IEs[index + 4] == 0xF2) &&
4076 (pu8IEs[index + 5] == 0x02) &&
4077 ((pu8IEs[index + 6] == 0x00) || (pu8IEs[index + 6] == 0x01)) &&
4078 (pu8IEs[index + 7] == 0x01)) {
4079 pNewJoinBssParam->wmm_cap = true;
4081 if (pu8IEs[index + 8] & BIT(7))
4082 pNewJoinBssParam->uapsd_cap = true;
4083 index += pu8IEs[index + 1] + 2;
4085 } else if ((pu8IEs[index] == P2P_IE) &&
4086 (pu8IEs[index + 2] == 0x50) && (pu8IEs[index + 3] == 0x6f) &&
4087 (pu8IEs[index + 4] == 0x9a) &&
4088 (pu8IEs[index + 5] == 0x09) && (pu8IEs[index + 6] == 0x0c)) {
4091 pNewJoinBssParam->tsf = ptstrNetworkInfo->tsf_lo;
4092 pNewJoinBssParam->noa_enabled = 1;
4093 pNewJoinBssParam->idx = pu8IEs[index + 9];
4095 if (pu8IEs[index + 10] & BIT(7)) {
4096 pNewJoinBssParam->opp_enabled = 1;
4097 pNewJoinBssParam->ct_window = pu8IEs[index + 10];
4099 pNewJoinBssParam->opp_enabled = 0;
4102 pNewJoinBssParam->cnt = pu8IEs[index + 11];
4103 u16P2P_count = index + 12;
4105 memcpy(pNewJoinBssParam->duration, pu8IEs + u16P2P_count, 4);
4108 memcpy(pNewJoinBssParam->interval, pu8IEs + u16P2P_count, 4);
4111 memcpy(pNewJoinBssParam->start_time, pu8IEs + u16P2P_count, 4);
4113 index += pu8IEs[index + 1] + 2;
4116 } else if ((pu8IEs[index] == RSN_IE) ||
4117 ((pu8IEs[index] == WPA_IE) && (pu8IEs[index + 2] == 0x00) &&
4118 (pu8IEs[index + 3] == 0x50) && (pu8IEs[index + 4] == 0xF2) &&
4119 (pu8IEs[index + 5] == 0x01))) {
4120 u16 rsnIndex = index;
4122 if (pu8IEs[rsnIndex] == RSN_IE) {
4123 pNewJoinBssParam->mode_802_11i = 2;
4125 if (pNewJoinBssParam->mode_802_11i == 0)
4126 pNewJoinBssParam->mode_802_11i = 1;
4131 pNewJoinBssParam->rsn_grp_policy = pu8IEs[rsnIndex];
4133 jumpOffset = pu8IEs[rsnIndex] * 4;
4134 pcipherCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex];
4137 for (i = pcipherTotalCount, j = 0; i < pcipherCount + pcipherTotalCount && i < 3; i++, j++)
4138 pNewJoinBssParam->rsn_pcip_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1];
4140 pcipherTotalCount += pcipherCount;
4141 rsnIndex += jumpOffset;
4143 jumpOffset = pu8IEs[rsnIndex] * 4;
4145 authCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex];
4148 for (i = authTotalCount, j = 0; i < authTotalCount + authCount; i++, j++)
4149 pNewJoinBssParam->rsn_auth_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1];
4151 authTotalCount += authCount;
4152 rsnIndex += jumpOffset;
4154 if (pu8IEs[index] == RSN_IE) {
4155 pNewJoinBssParam->rsn_cap[0] = pu8IEs[rsnIndex];
4156 pNewJoinBssParam->rsn_cap[1] = pu8IEs[rsnIndex + 1];
4159 pNewJoinBssParam->rsn_found = true;
4160 index += pu8IEs[index + 1] + 2;
4163 index += pu8IEs[index + 1] + 2;
4167 return (void *)pNewJoinBssParam;
4170 int wilc_setup_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
4173 struct host_if_msg msg;
4174 struct host_if_drv *hif_drv = vif->hif_drv;
4177 netdev_err(vif->ndev, "driver is null\n");
4181 memset(&msg, 0, sizeof(struct host_if_msg));
4183 msg.id = HOST_IF_MSG_SET_IPADDRESS;
4185 msg.body.ip_info.ip_addr = ip_addr;
4187 msg.body.ip_info.idx = idx;
4189 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4191 netdev_err(vif->ndev, "wilc_mq_send fail\n");
4196 static int host_int_get_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
4199 struct host_if_msg msg;
4200 struct host_if_drv *hif_drv = vif->hif_drv;
4203 netdev_err(vif->ndev, "driver is null\n");
4207 memset(&msg, 0, sizeof(struct host_if_msg));
4209 msg.id = HOST_IF_MSG_GET_IPADDRESS;
4211 msg.body.ip_info.ip_addr = ip_addr;
4213 msg.body.ip_info.idx = idx;
4215 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4217 netdev_err(vif->ndev, "wilc_mq_send fail\n");
4222 int wilc_set_tx_power(struct wilc_vif *vif, u8 tx_power)
4225 struct host_if_msg msg;
4227 memset(&msg, 0, sizeof(struct host_if_msg));
4229 msg.id = HOST_IF_MSG_SET_TX_POWER;
4230 msg.body.tx_power.tx_pwr = tx_power;
4233 ret = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4235 netdev_err(vif->ndev, "wilc_mq_send fail\n");
4240 int wilc_get_tx_power(struct wilc_vif *vif, u8 *tx_power)
4243 struct host_if_msg msg;
4245 memset(&msg, 0, sizeof(struct host_if_msg));
4247 msg.id = HOST_IF_MSG_GET_TX_POWER;
4250 ret = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4252 netdev_err(vif->ndev, "Failed to get TX PWR\n");
4254 down(&hif_sema_wait_response);
4255 *tx_power = msg.body.tx_power.tx_pwr;