1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/slab.h>
3 #include <linux/time.h>
4 #include <linux/kthread.h>
5 #include <linux/delay.h>
6 #include <linux/completion.h>
7 #include <linux/list.h>
8 #include <linux/workqueue.h>
9 #include "host_interface.h"
10 #include <linux/spinlock.h>
11 #include <linux/errno.h>
12 #include "coreconfigurator.h"
13 #include "wilc_wlan.h"
14 #include "wilc_wlan_if.h"
15 #include <linux/etherdevice.h>
16 #include "wilc_wfi_netdevice.h"
18 #define HOST_IF_MSG_SCAN 0
19 #define HOST_IF_MSG_CONNECT 1
20 #define HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO 2
21 #define HOST_IF_MSG_KEY 3
22 #define HOST_IF_MSG_RCVD_NTWRK_INFO 4
23 #define HOST_IF_MSG_RCVD_SCAN_COMPLETE 5
24 #define HOST_IF_MSG_CFG_PARAMS 6
25 #define HOST_IF_MSG_SET_CHANNEL 7
26 #define HOST_IF_MSG_DISCONNECT 8
27 #define HOST_IF_MSG_GET_RSSI 9
28 #define HOST_IF_MSG_ADD_BEACON 11
29 #define HOST_IF_MSG_DEL_BEACON 12
30 #define HOST_IF_MSG_ADD_STATION 13
31 #define HOST_IF_MSG_DEL_STATION 14
32 #define HOST_IF_MSG_EDIT_STATION 15
33 #define HOST_IF_MSG_SCAN_TIMER_FIRED 16
34 #define HOST_IF_MSG_CONNECT_TIMER_FIRED 17
35 #define HOST_IF_MSG_POWER_MGMT 18
36 #define HOST_IF_MSG_GET_INACTIVETIME 19
37 #define HOST_IF_MSG_REMAIN_ON_CHAN 20
38 #define HOST_IF_MSG_REGISTER_FRAME 21
39 #define HOST_IF_MSG_LISTEN_TIMER_FIRED 22
40 #define HOST_IF_MSG_SET_WFIDRV_HANDLER 24
41 #define HOST_IF_MSG_GET_MAC_ADDRESS 26
42 #define HOST_IF_MSG_SET_OPERATION_MODE 27
43 #define HOST_IF_MSG_SET_IPADDRESS 28
44 #define HOST_IF_MSG_GET_IPADDRESS 29
45 #define HOST_IF_MSG_GET_STATISTICS 31
46 #define HOST_IF_MSG_SET_MULTICAST_FILTER 32
47 #define HOST_IF_MSG_DEL_BA_SESSION 34
48 #define HOST_IF_MSG_DEL_ALL_STA 36
49 #define HOST_IF_MSG_SET_TX_POWER 38
50 #define HOST_IF_MSG_GET_TX_POWER 39
51 #define HOST_IF_MSG_EXIT 100
53 #define HOST_IF_SCAN_TIMEOUT 4000
54 #define HOST_IF_CONNECT_TIMEOUT 9500
56 #define BA_SESSION_DEFAULT_BUFFER_SIZE 16
57 #define BA_SESSION_DEFAULT_TIMEOUT 1000
58 #define BLOCK_ACK_REQ_SIZE 0x14
59 #define FALSE_FRMWR_CHANNEL 100
61 #define TCP_ACK_FILTER_LINK_SPEED_THRESH 54
62 #define DEFAULT_LINK_SPEED 72
64 struct host_if_wpa_attr
{
74 struct host_if_wep_attr
{
79 enum AUTHTYPE auth_type
;
82 union host_if_key_attr
{
83 struct host_if_wep_attr wep
;
84 struct host_if_wpa_attr wpa
;
85 struct host_if_pmkid_attr pmkid
;
91 union host_if_key_attr attr
;
101 wilc_scan_result result
;
103 struct hidden_network hidden_network
;
106 struct connect_attr
{
113 wilc_connect_result result
;
115 enum AUTHTYPE auth_type
;
120 struct rcvd_async_info
{
125 struct channel_attr
{
138 struct set_multicast
{
144 u8 del_all_sta
[MAX_NUM_STA
][ETH_ALEN
];
149 u8 mac_addr
[ETH_ALEN
];
152 struct power_mgmt_param
{
162 struct sta_inactive_t
{
171 struct scan_attr scan_info
;
172 struct connect_attr con_info
;
173 struct rcvd_net_info net_info
;
174 struct rcvd_async_info async_info
;
175 struct key_attr key_info
;
176 struct cfg_param_attr cfg_info
;
177 struct channel_attr channel_info
;
178 struct beacon_attr beacon_info
;
179 struct add_sta_param add_sta_info
;
180 struct del_sta del_sta_info
;
181 struct add_sta_param edit_sta_info
;
182 struct power_mgmt_param pwr_mgmt_info
;
183 struct sta_inactive_t mac_info
;
184 struct set_ip_addr ip_info
;
185 struct drv_handler drv
;
186 struct set_multicast multicast_info
;
188 struct get_mac_addr get_mac_info
;
189 struct ba_session_info session_info
;
190 struct remain_ch remain_on_ch
;
191 struct reg_frame reg_frame
;
193 struct del_all_sta del_all_sta_info
;
194 struct tx_power tx_power
;
199 union message_body body
;
200 struct wilc_vif
*vif
;
201 struct work_struct work
;
204 struct join_bss_param
{
205 enum bss_types bss_type
;
210 char ssid
[MAX_SSID_LEN
];
212 u8 supp_rates
[MAX_RATES_SUPPORTED
+ 1];
219 u8 rsn_pcip_policy
[3];
220 u8 rsn_auth_policy
[3];
233 static struct host_if_drv
*terminated_handle
;
234 bool wilc_optaining_ip
;
235 static u8 P2P_LISTEN_STATE
;
236 static struct workqueue_struct
*hif_workqueue
;
237 static struct completion hif_thread_comp
;
238 static struct completion hif_driver_comp
;
239 static struct completion hif_wait_response
;
240 static struct mutex hif_deinit_lock
;
241 static struct timer_list periodic_rssi
;
242 static struct wilc_vif
*periodic_rssi_vif
;
244 u8 wilc_multicast_mac_addr_list
[WILC_MULTICAST_TABLE_SIZE
][ETH_ALEN
];
246 static u8 rcv_assoc_resp
[MAX_ASSOC_RESP_FRAME_SIZE
];
248 static bool scan_while_connected
;
251 static u8 set_ip
[2][4];
252 static u8 get_ip
[2][4];
253 static u32 inactive_time
;
254 static u8 del_beacon
;
255 static u32 clients_count
;
258 static u8
*info_element
;
261 static u32 join_req_size
;
262 static u32 info_element_size
;
263 static struct wilc_vif
*join_req_vif
;
264 #define REAL_JOIN_REQ 0
265 #define FLUSHED_JOIN_REQ 1
266 #define FLUSHED_BYTE_POS 79
268 static void *host_int_parse_join_bss_param(struct network_info
*info
);
269 static int host_int_get_ipaddress(struct wilc_vif
*vif
, u8
*ip_addr
, u8 idx
);
270 static s32
handle_scan_done(struct wilc_vif
*vif
, enum scan_event evt
);
271 static void host_if_work(struct work_struct
*work
);
276 * @note copied from FLO glue implementatuion
279 static int wilc_enqueue_cmd(struct host_if_msg
*msg
)
281 struct host_if_msg
*new_msg
;
283 new_msg
= kmemdup(msg
, sizeof(*new_msg
), GFP_ATOMIC
);
287 INIT_WORK(&new_msg
->work
, host_if_work
);
288 queue_work(hif_workqueue
, &new_msg
->work
);
292 /* The u8IfIdx starts from 0 to NUM_CONCURRENT_IFC -1, but 0 index used as
293 * special purpose in wilc device, so we add 1 to the index to starts from 1.
294 * As a result, the returned index will be 1 to NUM_CONCURRENT_IFC.
296 int wilc_get_vif_idx(struct wilc_vif
*vif
)
301 /* We need to minus 1 from idx which is from wilc device to get real index
302 * of wilc->vif[], because we add 1 when pass to wilc device in the function
304 * As a result, the index should be between 0 and NUM_CONCURRENT_IFC -1.
306 static struct wilc_vif
*wilc_get_vif_from_idx(struct wilc
*wilc
, int idx
)
310 if (index
< 0 || index
>= NUM_CONCURRENT_IFC
)
313 return wilc
->vif
[index
];
316 static void handle_set_channel(struct wilc_vif
*vif
,
317 struct channel_attr
*hif_set_ch
)
322 wid
.id
= (u16
)WID_CURRENT_CHANNEL
;
324 wid
.val
= (char *)&hif_set_ch
->set_ch
;
325 wid
.size
= sizeof(char);
327 ret
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
328 wilc_get_vif_idx(vif
));
331 netdev_err(vif
->ndev
, "Failed to set channel\n");
334 static int handle_set_wfi_drv_handler(struct wilc_vif
*vif
,
335 struct drv_handler
*hif_drv_handler
)
339 u8
*currbyte
, *buffer
;
340 struct host_if_drv
*hif_drv
= NULL
;
345 if (!hif_drv_handler
)
348 hif_drv
= vif
->hif_drv
;
350 buffer
= kzalloc(DRV_HANDLER_SIZE
, GFP_KERNEL
);
355 *currbyte
= hif_drv
->driver_handler_id
& DRV_HANDLER_MASK
;
357 *currbyte
= (u32
)0 & DRV_HANDLER_MASK
;
359 *currbyte
= (u32
)0 & DRV_HANDLER_MASK
;
361 *currbyte
= (u32
)0 & DRV_HANDLER_MASK
;
363 *currbyte
= (hif_drv_handler
->name
| (hif_drv_handler
->mode
<< 1));
365 wid
.id
= (u16
)WID_SET_DRV_HANDLER
;
367 wid
.val
= (s8
*)buffer
;
368 wid
.size
= DRV_HANDLER_SIZE
;
370 ret
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
371 hif_drv
->driver_handler_id
);
373 netdev_err(vif
->ndev
, "Failed to set driver handler\n");
374 complete(&hif_driver_comp
);
378 complete(&hif_driver_comp
);
383 static void handle_set_operation_mode(struct wilc_vif
*vif
,
384 struct op_mode
*hif_op_mode
)
389 wid
.id
= (u16
)WID_SET_OPERATION_MODE
;
391 wid
.val
= (s8
*)&hif_op_mode
->mode
;
392 wid
.size
= sizeof(u32
);
394 ret
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
395 wilc_get_vif_idx(vif
));
397 if (hif_op_mode
->mode
== IDLE_MODE
)
398 complete(&hif_driver_comp
);
401 netdev_err(vif
->ndev
, "Failed to set driver handler\n");
404 static void handle_set_ip_address(struct wilc_vif
*vif
, u8
*ip_addr
, u8 idx
)
408 char firmware_ip_addr
[4] = {0};
410 if (ip_addr
[0] < 192)
413 memcpy(set_ip
[idx
], ip_addr
, IP_ALEN
);
415 wid
.id
= (u16
)WID_IP_ADDRESS
;
420 ret
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
421 wilc_get_vif_idx(vif
));
423 host_int_get_ipaddress(vif
, firmware_ip_addr
, idx
);
426 netdev_err(vif
->ndev
, "Failed to set IP address\n");
429 static void handle_get_ip_address(struct wilc_vif
*vif
, u8 idx
)
434 wid
.id
= (u16
)WID_IP_ADDRESS
;
436 wid
.val
= kmalloc(IP_ALEN
, GFP_KERNEL
);
439 ret
= wilc_send_config_pkt(vif
, GET_CFG
, &wid
, 1,
440 wilc_get_vif_idx(vif
));
442 memcpy(get_ip
[idx
], wid
.val
, IP_ALEN
);
446 if (memcmp(get_ip
[idx
], set_ip
[idx
], IP_ALEN
) != 0)
447 wilc_setup_ipaddress(vif
, set_ip
[idx
], idx
);
450 netdev_err(vif
->ndev
, "Failed to get IP address\n");
453 static void handle_get_mac_address(struct wilc_vif
*vif
,
454 struct get_mac_addr
*get_mac_addr
)
459 wid
.id
= (u16
)WID_MAC_ADDR
;
461 wid
.val
= get_mac_addr
->mac_addr
;
464 ret
= wilc_send_config_pkt(vif
, GET_CFG
, &wid
, 1,
465 wilc_get_vif_idx(vif
));
468 netdev_err(vif
->ndev
, "Failed to get mac address\n");
469 complete(&hif_wait_response
);
472 static void handle_cfg_param(struct wilc_vif
*vif
, struct cfg_param_attr
*param
)
475 struct wid wid_list
[32];
476 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
479 mutex_lock(&hif_drv
->cfg_values_lock
);
481 if (param
->flag
& BSS_TYPE
) {
482 u8 bss_type
= param
->bss_type
;
485 wid_list
[i
].id
= WID_BSS_TYPE
;
486 wid_list
[i
].val
= (s8
*)¶m
->bss_type
;
487 wid_list
[i
].type
= WID_CHAR
;
488 wid_list
[i
].size
= sizeof(char);
489 hif_drv
->cfg_values
.bss_type
= bss_type
;
491 netdev_err(vif
->ndev
, "check value 6 over\n");
496 if (param
->flag
& AUTH_TYPE
) {
497 u8 auth_type
= param
->auth_type
;
499 if (auth_type
== 1 || auth_type
== 2 || auth_type
== 5) {
500 wid_list
[i
].id
= WID_AUTH_TYPE
;
501 wid_list
[i
].val
= (s8
*)¶m
->auth_type
;
502 wid_list
[i
].type
= WID_CHAR
;
503 wid_list
[i
].size
= sizeof(char);
504 hif_drv
->cfg_values
.auth_type
= auth_type
;
506 netdev_err(vif
->ndev
, "Impossible value\n");
511 if (param
->flag
& AUTHEN_TIMEOUT
) {
512 if (param
->auth_timeout
> 0) {
513 wid_list
[i
].id
= WID_AUTH_TIMEOUT
;
514 wid_list
[i
].val
= (s8
*)¶m
->auth_timeout
;
515 wid_list
[i
].type
= WID_SHORT
;
516 wid_list
[i
].size
= sizeof(u16
);
517 hif_drv
->cfg_values
.auth_timeout
= param
->auth_timeout
;
519 netdev_err(vif
->ndev
, "Range(1 ~ 65535) over\n");
524 if (param
->flag
& POWER_MANAGEMENT
) {
525 u8 pm_mode
= param
->power_mgmt_mode
;
528 wid_list
[i
].id
= WID_POWER_MANAGEMENT
;
529 wid_list
[i
].val
= (s8
*)¶m
->power_mgmt_mode
;
530 wid_list
[i
].type
= WID_CHAR
;
531 wid_list
[i
].size
= sizeof(char);
532 hif_drv
->cfg_values
.power_mgmt_mode
= pm_mode
;
534 netdev_err(vif
->ndev
, "Invalid power mode\n");
539 if (param
->flag
& RETRY_SHORT
) {
540 u16 retry_limit
= param
->short_retry_limit
;
542 if (retry_limit
> 0 && retry_limit
< 256) {
543 wid_list
[i
].id
= WID_SHORT_RETRY_LIMIT
;
544 wid_list
[i
].val
= (s8
*)¶m
->short_retry_limit
;
545 wid_list
[i
].type
= WID_SHORT
;
546 wid_list
[i
].size
= sizeof(u16
);
547 hif_drv
->cfg_values
.short_retry_limit
= retry_limit
;
549 netdev_err(vif
->ndev
, "Range(1~256) over\n");
554 if (param
->flag
& RETRY_LONG
) {
555 u16 limit
= param
->long_retry_limit
;
557 if (limit
> 0 && limit
< 256) {
558 wid_list
[i
].id
= WID_LONG_RETRY_LIMIT
;
559 wid_list
[i
].val
= (s8
*)¶m
->long_retry_limit
;
560 wid_list
[i
].type
= WID_SHORT
;
561 wid_list
[i
].size
= sizeof(u16
);
562 hif_drv
->cfg_values
.long_retry_limit
= limit
;
564 netdev_err(vif
->ndev
, "Range(1~256) over\n");
569 if (param
->flag
& FRAG_THRESHOLD
) {
570 u16 frag_th
= param
->frag_threshold
;
572 if (frag_th
> 255 && frag_th
< 7937) {
573 wid_list
[i
].id
= WID_FRAG_THRESHOLD
;
574 wid_list
[i
].val
= (s8
*)¶m
->frag_threshold
;
575 wid_list
[i
].type
= WID_SHORT
;
576 wid_list
[i
].size
= sizeof(u16
);
577 hif_drv
->cfg_values
.frag_threshold
= frag_th
;
579 netdev_err(vif
->ndev
, "Threshold Range fail\n");
584 if (param
->flag
& RTS_THRESHOLD
) {
585 u16 rts_th
= param
->rts_threshold
;
588 wid_list
[i
].id
= WID_RTS_THRESHOLD
;
589 wid_list
[i
].val
= (s8
*)¶m
->rts_threshold
;
590 wid_list
[i
].type
= WID_SHORT
;
591 wid_list
[i
].size
= sizeof(u16
);
592 hif_drv
->cfg_values
.rts_threshold
= rts_th
;
594 netdev_err(vif
->ndev
, "Threshold Range fail\n");
599 if (param
->flag
& PREAMBLE
) {
600 u16 preamble_type
= param
->preamble_type
;
602 if (param
->preamble_type
< 3) {
603 wid_list
[i
].id
= WID_PREAMBLE
;
604 wid_list
[i
].val
= (s8
*)¶m
->preamble_type
;
605 wid_list
[i
].type
= WID_CHAR
;
606 wid_list
[i
].size
= sizeof(char);
607 hif_drv
->cfg_values
.preamble_type
= preamble_type
;
609 netdev_err(vif
->ndev
, "Preamle Range(0~2) over\n");
614 if (param
->flag
& SHORT_SLOT_ALLOWED
) {
615 u8 slot_allowed
= param
->short_slot_allowed
;
617 if (slot_allowed
< 2) {
618 wid_list
[i
].id
= WID_SHORT_SLOT_ALLOWED
;
619 wid_list
[i
].val
= (s8
*)¶m
->short_slot_allowed
;
620 wid_list
[i
].type
= WID_CHAR
;
621 wid_list
[i
].size
= sizeof(char);
622 hif_drv
->cfg_values
.short_slot_allowed
= slot_allowed
;
624 netdev_err(vif
->ndev
, "Short slot(2) over\n");
629 if (param
->flag
& TXOP_PROT_DISABLE
) {
630 u8 prot_disabled
= param
->txop_prot_disabled
;
632 if (param
->txop_prot_disabled
< 2) {
633 wid_list
[i
].id
= WID_11N_TXOP_PROT_DISABLE
;
634 wid_list
[i
].val
= (s8
*)¶m
->txop_prot_disabled
;
635 wid_list
[i
].type
= WID_CHAR
;
636 wid_list
[i
].size
= sizeof(char);
637 hif_drv
->cfg_values
.txop_prot_disabled
= prot_disabled
;
639 netdev_err(vif
->ndev
, "TXOP prot disable\n");
644 if (param
->flag
& BEACON_INTERVAL
) {
645 u16 beacon_interval
= param
->beacon_interval
;
647 if (beacon_interval
> 0) {
648 wid_list
[i
].id
= WID_BEACON_INTERVAL
;
649 wid_list
[i
].val
= (s8
*)¶m
->beacon_interval
;
650 wid_list
[i
].type
= WID_SHORT
;
651 wid_list
[i
].size
= sizeof(u16
);
652 hif_drv
->cfg_values
.beacon_interval
= beacon_interval
;
654 netdev_err(vif
->ndev
, "Beacon interval(1~65535)fail\n");
659 if (param
->flag
& DTIM_PERIOD
) {
660 if (param
->dtim_period
> 0 && param
->dtim_period
< 256) {
661 wid_list
[i
].id
= WID_DTIM_PERIOD
;
662 wid_list
[i
].val
= (s8
*)¶m
->dtim_period
;
663 wid_list
[i
].type
= WID_CHAR
;
664 wid_list
[i
].size
= sizeof(char);
665 hif_drv
->cfg_values
.dtim_period
= param
->dtim_period
;
667 netdev_err(vif
->ndev
, "DTIM range(1~255) fail\n");
672 if (param
->flag
& SITE_SURVEY
) {
673 enum SITESURVEY enabled
= param
->site_survey_enabled
;
676 wid_list
[i
].id
= WID_SITE_SURVEY
;
677 wid_list
[i
].val
= (s8
*)¶m
->site_survey_enabled
;
678 wid_list
[i
].type
= WID_CHAR
;
679 wid_list
[i
].size
= sizeof(char);
680 hif_drv
->cfg_values
.site_survey_enabled
= enabled
;
682 netdev_err(vif
->ndev
, "Site survey disable\n");
687 if (param
->flag
& SITE_SURVEY_SCAN_TIME
) {
688 u16 scan_time
= param
->site_survey_scan_time
;
691 wid_list
[i
].id
= WID_SITE_SURVEY_SCAN_TIME
;
692 wid_list
[i
].val
= (s8
*)¶m
->site_survey_scan_time
;
693 wid_list
[i
].type
= WID_SHORT
;
694 wid_list
[i
].size
= sizeof(u16
);
695 hif_drv
->cfg_values
.site_survey_scan_time
= scan_time
;
697 netdev_err(vif
->ndev
, "Site scan time(1~65535) over\n");
702 if (param
->flag
& ACTIVE_SCANTIME
) {
703 u16 active_scan_time
= param
->active_scan_time
;
705 if (active_scan_time
> 0) {
706 wid_list
[i
].id
= WID_ACTIVE_SCAN_TIME
;
707 wid_list
[i
].val
= (s8
*)¶m
->active_scan_time
;
708 wid_list
[i
].type
= WID_SHORT
;
709 wid_list
[i
].size
= sizeof(u16
);
710 hif_drv
->cfg_values
.active_scan_time
= active_scan_time
;
712 netdev_err(vif
->ndev
, "Active time(1~65535) over\n");
717 if (param
->flag
& PASSIVE_SCANTIME
) {
718 u16 time
= param
->passive_scan_time
;
721 wid_list
[i
].id
= WID_PASSIVE_SCAN_TIME
;
722 wid_list
[i
].val
= (s8
*)¶m
->passive_scan_time
;
723 wid_list
[i
].type
= WID_SHORT
;
724 wid_list
[i
].size
= sizeof(u16
);
725 hif_drv
->cfg_values
.passive_scan_time
= time
;
727 netdev_err(vif
->ndev
, "Passive time(1~65535) over\n");
732 if (param
->flag
& CURRENT_TX_RATE
) {
733 enum CURRENT_TXRATE curr_tx_rate
= param
->curr_tx_rate
;
735 if (curr_tx_rate
== AUTORATE
|| curr_tx_rate
== MBPS_1
||
736 curr_tx_rate
== MBPS_2
|| curr_tx_rate
== MBPS_5_5
||
737 curr_tx_rate
== MBPS_11
|| curr_tx_rate
== MBPS_6
||
738 curr_tx_rate
== MBPS_9
|| curr_tx_rate
== MBPS_12
||
739 curr_tx_rate
== MBPS_18
|| curr_tx_rate
== MBPS_24
||
740 curr_tx_rate
== MBPS_36
|| curr_tx_rate
== MBPS_48
||
741 curr_tx_rate
== MBPS_54
) {
742 wid_list
[i
].id
= WID_CURRENT_TX_RATE
;
743 wid_list
[i
].val
= (s8
*)&curr_tx_rate
;
744 wid_list
[i
].type
= WID_SHORT
;
745 wid_list
[i
].size
= sizeof(u16
);
746 hif_drv
->cfg_values
.curr_tx_rate
= (u8
)curr_tx_rate
;
748 netdev_err(vif
->ndev
, "out of TX rate\n");
754 ret
= wilc_send_config_pkt(vif
, SET_CFG
, wid_list
,
755 i
, wilc_get_vif_idx(vif
));
758 netdev_err(vif
->ndev
, "Error in setting CFG params\n");
761 mutex_unlock(&hif_drv
->cfg_values_lock
);
764 static s32
handle_scan(struct wilc_vif
*vif
, struct scan_attr
*scan_info
)
767 struct wid wid_list
[5];
772 u8
*hdn_ntwk_wid_val
= NULL
;
773 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
774 struct hidden_network
*hidden_net
= &scan_info
->hidden_network
;
776 hif_drv
->usr_scan_req
.scan_result
= scan_info
->result
;
777 hif_drv
->usr_scan_req
.arg
= scan_info
->arg
;
779 if (hif_drv
->hif_state
>= HOST_IF_SCANNING
&&
780 hif_drv
->hif_state
< HOST_IF_CONNECTED
) {
781 netdev_err(vif
->ndev
, "Already scan\n");
786 if (wilc_optaining_ip
|| wilc_connecting
) {
787 netdev_err(vif
->ndev
, "Don't do obss scan\n");
792 hif_drv
->usr_scan_req
.rcvd_ch_cnt
= 0;
794 wid_list
[index
].id
= (u16
)WID_SSID_PROBE_REQ
;
795 wid_list
[index
].type
= WID_STR
;
797 for (i
= 0; i
< hidden_net
->n_ssids
; i
++)
798 valuesize
+= ((hidden_net
->net_info
[i
].ssid_len
) + 1);
799 hdn_ntwk_wid_val
= kmalloc(valuesize
+ 1, GFP_KERNEL
);
800 wid_list
[index
].val
= hdn_ntwk_wid_val
;
801 if (wid_list
[index
].val
) {
802 buffer
= wid_list
[index
].val
;
804 *buffer
++ = hidden_net
->n_ssids
;
806 for (i
= 0; i
< hidden_net
->n_ssids
; i
++) {
807 *buffer
++ = hidden_net
->net_info
[i
].ssid_len
;
808 memcpy(buffer
, hidden_net
->net_info
[i
].ssid
,
809 hidden_net
->net_info
[i
].ssid_len
);
810 buffer
+= hidden_net
->net_info
[i
].ssid_len
;
813 wid_list
[index
].size
= (s32
)(valuesize
+ 1);
817 wid_list
[index
].id
= WID_INFO_ELEMENT_PROBE
;
818 wid_list
[index
].type
= WID_BIN_DATA
;
819 wid_list
[index
].val
= scan_info
->ies
;
820 wid_list
[index
].size
= scan_info
->ies_len
;
823 wid_list
[index
].id
= WID_SCAN_TYPE
;
824 wid_list
[index
].type
= WID_CHAR
;
825 wid_list
[index
].size
= sizeof(char);
826 wid_list
[index
].val
= (s8
*)&scan_info
->type
;
829 wid_list
[index
].id
= WID_SCAN_CHANNEL_LIST
;
830 wid_list
[index
].type
= WID_BIN_DATA
;
832 if (scan_info
->ch_freq_list
&&
833 scan_info
->ch_list_len
> 0) {
836 for (i
= 0; i
< scan_info
->ch_list_len
; i
++) {
837 if (scan_info
->ch_freq_list
[i
] > 0)
838 scan_info
->ch_freq_list
[i
] -= 1;
842 wid_list
[index
].val
= scan_info
->ch_freq_list
;
843 wid_list
[index
].size
= scan_info
->ch_list_len
;
846 wid_list
[index
].id
= WID_START_SCAN_REQ
;
847 wid_list
[index
].type
= WID_CHAR
;
848 wid_list
[index
].size
= sizeof(char);
849 wid_list
[index
].val
= (s8
*)&scan_info
->src
;
852 if (hif_drv
->hif_state
== HOST_IF_CONNECTED
)
853 scan_while_connected
= true;
854 else if (hif_drv
->hif_state
== HOST_IF_IDLE
)
855 scan_while_connected
= false;
857 result
= wilc_send_config_pkt(vif
, SET_CFG
, wid_list
,
859 wilc_get_vif_idx(vif
));
862 netdev_err(vif
->ndev
, "Failed to send scan parameters\n");
866 del_timer(&hif_drv
->scan_timer
);
867 handle_scan_done(vif
, SCAN_EVENT_ABORTED
);
870 kfree(scan_info
->ch_freq_list
);
871 scan_info
->ch_freq_list
= NULL
;
873 kfree(scan_info
->ies
);
874 scan_info
->ies
= NULL
;
875 kfree(scan_info
->hidden_network
.net_info
);
876 scan_info
->hidden_network
.net_info
= NULL
;
878 kfree(hdn_ntwk_wid_val
);
883 static s32
handle_scan_done(struct wilc_vif
*vif
, enum scan_event evt
)
886 u8 abort_running_scan
;
888 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
889 struct user_scan_req
*scan_req
;
891 if (evt
== SCAN_EVENT_ABORTED
) {
892 abort_running_scan
= 1;
893 wid
.id
= (u16
)WID_ABORT_RUNNING_SCAN
;
895 wid
.val
= (s8
*)&abort_running_scan
;
896 wid
.size
= sizeof(char);
898 result
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
899 wilc_get_vif_idx(vif
));
902 netdev_err(vif
->ndev
, "Failed to set abort running\n");
908 netdev_err(vif
->ndev
, "Driver handler is NULL\n");
912 scan_req
= &hif_drv
->usr_scan_req
;
913 if (scan_req
->scan_result
) {
914 scan_req
->scan_result(evt
, NULL
, scan_req
->arg
, NULL
);
915 scan_req
->scan_result
= NULL
;
921 u8 wilc_connected_ssid
[6] = {0};
922 static s32
handle_connect(struct wilc_vif
*vif
,
923 struct connect_attr
*conn_attr
)
926 struct wid wid_list
[8];
927 u32 wid_cnt
= 0, dummyval
= 0;
929 struct join_bss_param
*bss_param
;
930 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
932 if (memcmp(conn_attr
->bssid
, wilc_connected_ssid
, ETH_ALEN
) == 0) {
934 netdev_err(vif
->ndev
, "Discard connect request\n");
938 bss_param
= conn_attr
->params
;
940 netdev_err(vif
->ndev
, "Required BSSID not found\n");
945 if (conn_attr
->bssid
) {
946 hif_drv
->usr_conn_req
.bssid
= kmalloc(6, GFP_KERNEL
);
947 if (!hif_drv
->usr_conn_req
.bssid
) {
951 memcpy(hif_drv
->usr_conn_req
.bssid
, conn_attr
->bssid
, 6);
954 hif_drv
->usr_conn_req
.ssid_len
= conn_attr
->ssid_len
;
955 if (conn_attr
->ssid
) {
956 hif_drv
->usr_conn_req
.ssid
= kmalloc(conn_attr
->ssid_len
+ 1,
958 if (!hif_drv
->usr_conn_req
.ssid
) {
962 memcpy(hif_drv
->usr_conn_req
.ssid
,
964 conn_attr
->ssid_len
);
965 hif_drv
->usr_conn_req
.ssid
[conn_attr
->ssid_len
] = '\0';
968 hif_drv
->usr_conn_req
.ies_len
= conn_attr
->ies_len
;
969 if (conn_attr
->ies
) {
970 hif_drv
->usr_conn_req
.ies
= kmalloc(conn_attr
->ies_len
,
972 if (!hif_drv
->usr_conn_req
.ies
) {
976 memcpy(hif_drv
->usr_conn_req
.ies
,
981 hif_drv
->usr_conn_req
.security
= conn_attr
->security
;
982 hif_drv
->usr_conn_req
.auth_type
= conn_attr
->auth_type
;
983 hif_drv
->usr_conn_req
.conn_result
= conn_attr
->result
;
984 hif_drv
->usr_conn_req
.arg
= conn_attr
->arg
;
986 wid_list
[wid_cnt
].id
= WID_SUCCESS_FRAME_COUNT
;
987 wid_list
[wid_cnt
].type
= WID_INT
;
988 wid_list
[wid_cnt
].size
= sizeof(u32
);
989 wid_list
[wid_cnt
].val
= (s8
*)(&(dummyval
));
992 wid_list
[wid_cnt
].id
= WID_RECEIVED_FRAGMENT_COUNT
;
993 wid_list
[wid_cnt
].type
= WID_INT
;
994 wid_list
[wid_cnt
].size
= sizeof(u32
);
995 wid_list
[wid_cnt
].val
= (s8
*)(&(dummyval
));
998 wid_list
[wid_cnt
].id
= WID_FAILED_COUNT
;
999 wid_list
[wid_cnt
].type
= WID_INT
;
1000 wid_list
[wid_cnt
].size
= sizeof(u32
);
1001 wid_list
[wid_cnt
].val
= (s8
*)(&(dummyval
));
1004 wid_list
[wid_cnt
].id
= WID_INFO_ELEMENT_ASSOCIATE
;
1005 wid_list
[wid_cnt
].type
= WID_BIN_DATA
;
1006 wid_list
[wid_cnt
].val
= hif_drv
->usr_conn_req
.ies
;
1007 wid_list
[wid_cnt
].size
= hif_drv
->usr_conn_req
.ies_len
;
1010 if (memcmp("DIRECT-", conn_attr
->ssid
, 7)) {
1011 info_element_size
= hif_drv
->usr_conn_req
.ies_len
;
1012 info_element
= kmalloc(info_element_size
, GFP_KERNEL
);
1013 memcpy(info_element
, hif_drv
->usr_conn_req
.ies
,
1016 wid_list
[wid_cnt
].id
= (u16
)WID_11I_MODE
;
1017 wid_list
[wid_cnt
].type
= WID_CHAR
;
1018 wid_list
[wid_cnt
].size
= sizeof(char);
1019 wid_list
[wid_cnt
].val
= (s8
*)&hif_drv
->usr_conn_req
.security
;
1022 if (memcmp("DIRECT-", conn_attr
->ssid
, 7))
1023 mode_11i
= hif_drv
->usr_conn_req
.security
;
1025 wid_list
[wid_cnt
].id
= (u16
)WID_AUTH_TYPE
;
1026 wid_list
[wid_cnt
].type
= WID_CHAR
;
1027 wid_list
[wid_cnt
].size
= sizeof(char);
1028 wid_list
[wid_cnt
].val
= (s8
*)&hif_drv
->usr_conn_req
.auth_type
;
1031 if (memcmp("DIRECT-", conn_attr
->ssid
, 7))
1032 auth_type
= (u8
)hif_drv
->usr_conn_req
.auth_type
;
1034 wid_list
[wid_cnt
].id
= (u16
)WID_JOIN_REQ_EXTENDED
;
1035 wid_list
[wid_cnt
].type
= WID_STR
;
1036 wid_list
[wid_cnt
].size
= 112;
1037 wid_list
[wid_cnt
].val
= kmalloc(wid_list
[wid_cnt
].size
, GFP_KERNEL
);
1039 if (memcmp("DIRECT-", conn_attr
->ssid
, 7)) {
1040 join_req_size
= wid_list
[wid_cnt
].size
;
1041 join_req
= kmalloc(join_req_size
, GFP_KERNEL
);
1043 if (!wid_list
[wid_cnt
].val
) {
1048 cur_byte
= wid_list
[wid_cnt
].val
;
1050 if (conn_attr
->ssid
) {
1051 memcpy(cur_byte
, conn_attr
->ssid
, conn_attr
->ssid_len
);
1052 cur_byte
[conn_attr
->ssid_len
] = '\0';
1054 cur_byte
+= MAX_SSID_LEN
;
1055 *(cur_byte
++) = INFRASTRUCTURE
;
1057 if (conn_attr
->ch
>= 1 && conn_attr
->ch
<= 14) {
1058 *(cur_byte
++) = conn_attr
->ch
;
1060 netdev_err(vif
->ndev
, "Channel out of range\n");
1061 *(cur_byte
++) = 0xFF;
1063 *(cur_byte
++) = (bss_param
->cap_info
) & 0xFF;
1064 *(cur_byte
++) = ((bss_param
->cap_info
) >> 8) & 0xFF;
1066 if (conn_attr
->bssid
)
1067 memcpy(cur_byte
, conn_attr
->bssid
, 6);
1070 if (conn_attr
->bssid
)
1071 memcpy(cur_byte
, conn_attr
->bssid
, 6);
1074 *(cur_byte
++) = (bss_param
->beacon_period
) & 0xFF;
1075 *(cur_byte
++) = ((bss_param
->beacon_period
) >> 8) & 0xFF;
1076 *(cur_byte
++) = bss_param
->dtim_period
;
1078 memcpy(cur_byte
, bss_param
->supp_rates
, MAX_RATES_SUPPORTED
+ 1);
1079 cur_byte
+= (MAX_RATES_SUPPORTED
+ 1);
1081 *(cur_byte
++) = bss_param
->wmm_cap
;
1082 *(cur_byte
++) = bss_param
->uapsd_cap
;
1084 *(cur_byte
++) = bss_param
->ht_capable
;
1085 hif_drv
->usr_conn_req
.ht_capable
= bss_param
->ht_capable
;
1087 *(cur_byte
++) = bss_param
->rsn_found
;
1088 *(cur_byte
++) = bss_param
->rsn_grp_policy
;
1089 *(cur_byte
++) = bss_param
->mode_802_11i
;
1091 memcpy(cur_byte
, bss_param
->rsn_pcip_policy
,
1092 sizeof(bss_param
->rsn_pcip_policy
));
1093 cur_byte
+= sizeof(bss_param
->rsn_pcip_policy
);
1095 memcpy(cur_byte
, bss_param
->rsn_auth_policy
,
1096 sizeof(bss_param
->rsn_auth_policy
));
1097 cur_byte
+= sizeof(bss_param
->rsn_auth_policy
);
1099 memcpy(cur_byte
, bss_param
->rsn_cap
, sizeof(bss_param
->rsn_cap
));
1100 cur_byte
+= sizeof(bss_param
->rsn_cap
);
1102 *(cur_byte
++) = REAL_JOIN_REQ
;
1103 *(cur_byte
++) = bss_param
->noa_enabled
;
1105 if (bss_param
->noa_enabled
) {
1106 *(cur_byte
++) = (bss_param
->tsf
) & 0xFF;
1107 *(cur_byte
++) = ((bss_param
->tsf
) >> 8) & 0xFF;
1108 *(cur_byte
++) = ((bss_param
->tsf
) >> 16) & 0xFF;
1109 *(cur_byte
++) = ((bss_param
->tsf
) >> 24) & 0xFF;
1111 *(cur_byte
++) = bss_param
->opp_enabled
;
1112 *(cur_byte
++) = bss_param
->idx
;
1114 if (bss_param
->opp_enabled
)
1115 *(cur_byte
++) = bss_param
->ct_window
;
1117 *(cur_byte
++) = bss_param
->cnt
;
1119 memcpy(cur_byte
, bss_param
->duration
,
1120 sizeof(bss_param
->duration
));
1121 cur_byte
+= sizeof(bss_param
->duration
);
1123 memcpy(cur_byte
, bss_param
->interval
,
1124 sizeof(bss_param
->interval
));
1125 cur_byte
+= sizeof(bss_param
->interval
);
1127 memcpy(cur_byte
, bss_param
->start_time
,
1128 sizeof(bss_param
->start_time
));
1129 cur_byte
+= sizeof(bss_param
->start_time
);
1132 cur_byte
= wid_list
[wid_cnt
].val
;
1135 if (memcmp("DIRECT-", conn_attr
->ssid
, 7)) {
1136 memcpy(join_req
, cur_byte
, join_req_size
);
1140 if (conn_attr
->bssid
)
1141 memcpy(wilc_connected_ssid
,
1142 conn_attr
->bssid
, ETH_ALEN
);
1144 result
= wilc_send_config_pkt(vif
, SET_CFG
, wid_list
,
1146 wilc_get_vif_idx(vif
));
1148 netdev_err(vif
->ndev
, "failed to send config packet\n");
1152 hif_drv
->hif_state
= HOST_IF_WAITING_CONN_RESP
;
1157 struct connect_info conn_info
;
1159 del_timer(&hif_drv
->connect_timer
);
1161 memset(&conn_info
, 0, sizeof(struct connect_info
));
1163 if (conn_attr
->result
) {
1164 if (conn_attr
->bssid
)
1165 memcpy(conn_info
.bssid
, conn_attr
->bssid
, 6);
1167 if (conn_attr
->ies
) {
1168 conn_info
.req_ies_len
= conn_attr
->ies_len
;
1169 conn_info
.req_ies
= kmalloc(conn_attr
->ies_len
,
1171 memcpy(conn_info
.req_ies
,
1173 conn_attr
->ies_len
);
1176 conn_attr
->result(CONN_DISCONN_EVENT_CONN_RESP
,
1181 hif_drv
->hif_state
= HOST_IF_IDLE
;
1182 kfree(conn_info
.req_ies
);
1183 conn_info
.req_ies
= NULL
;
1186 netdev_err(vif
->ndev
, "Connect callback is NULL\n");
1190 kfree(conn_attr
->bssid
);
1191 conn_attr
->bssid
= NULL
;
1193 kfree(conn_attr
->ssid
);
1194 conn_attr
->ssid
= NULL
;
1196 kfree(conn_attr
->ies
);
1197 conn_attr
->ies
= NULL
;
1203 static s32
handle_connect_timeout(struct wilc_vif
*vif
)
1206 struct connect_info info
;
1208 u16 dummy_reason_code
= 0;
1209 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
1212 netdev_err(vif
->ndev
, "Driver handler is NULL\n");
1216 hif_drv
->hif_state
= HOST_IF_IDLE
;
1218 scan_while_connected
= false;
1220 memset(&info
, 0, sizeof(struct connect_info
));
1222 if (hif_drv
->usr_conn_req
.conn_result
) {
1223 if (hif_drv
->usr_conn_req
.bssid
) {
1225 hif_drv
->usr_conn_req
.bssid
, 6);
1228 if (hif_drv
->usr_conn_req
.ies
) {
1229 info
.req_ies_len
= hif_drv
->usr_conn_req
.ies_len
;
1230 info
.req_ies
= kmalloc(hif_drv
->usr_conn_req
.ies_len
, GFP_KERNEL
);
1231 memcpy(info
.req_ies
,
1232 hif_drv
->usr_conn_req
.ies
,
1233 hif_drv
->usr_conn_req
.ies_len
);
1236 hif_drv
->usr_conn_req
.conn_result(CONN_DISCONN_EVENT_CONN_RESP
,
1240 hif_drv
->usr_conn_req
.arg
);
1242 kfree(info
.req_ies
);
1243 info
.req_ies
= NULL
;
1245 netdev_err(vif
->ndev
, "Connect callback is NULL\n");
1248 wid
.id
= (u16
)WID_DISCONNECT
;
1249 wid
.type
= WID_CHAR
;
1250 wid
.val
= (s8
*)&dummy_reason_code
;
1251 wid
.size
= sizeof(char);
1253 result
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
1254 wilc_get_vif_idx(vif
));
1256 netdev_err(vif
->ndev
, "Failed to send disconnect\n");
1258 hif_drv
->usr_conn_req
.ssid_len
= 0;
1259 kfree(hif_drv
->usr_conn_req
.ssid
);
1260 hif_drv
->usr_conn_req
.ssid
= NULL
;
1261 kfree(hif_drv
->usr_conn_req
.bssid
);
1262 hif_drv
->usr_conn_req
.bssid
= NULL
;
1263 hif_drv
->usr_conn_req
.ies_len
= 0;
1264 kfree(hif_drv
->usr_conn_req
.ies
);
1265 hif_drv
->usr_conn_req
.ies
= NULL
;
1267 eth_zero_addr(wilc_connected_ssid
);
1269 if (join_req
&& join_req_vif
== vif
) {
1274 if (info_element
&& join_req_vif
== vif
) {
1275 kfree(info_element
);
1276 info_element
= NULL
;
1282 static s32
handle_rcvd_ntwrk_info(struct wilc_vif
*vif
,
1283 struct rcvd_net_info
*rcvd_info
)
1288 struct network_info
*info
= NULL
;
1289 void *params
= NULL
;
1290 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
1291 struct user_scan_req
*scan_req
= &hif_drv
->usr_scan_req
;
1295 if (!scan_req
->scan_result
)
1298 wilc_parse_network_info(rcvd_info
->buffer
, &info
);
1299 if (!info
|| !scan_req
->scan_result
) {
1300 netdev_err(vif
->ndev
, "driver is null\n");
1305 for (i
= 0; i
< scan_req
->rcvd_ch_cnt
; i
++) {
1306 if (memcmp(scan_req
->net_info
[i
].bssid
, info
->bssid
, 6) == 0) {
1307 if (info
->rssi
<= scan_req
->net_info
[i
].rssi
) {
1310 scan_req
->net_info
[i
].rssi
= info
->rssi
;
1318 if (scan_req
->rcvd_ch_cnt
< MAX_NUM_SCANNED_NETWORKS
) {
1319 scan_req
->net_info
[scan_req
->rcvd_ch_cnt
].rssi
= info
->rssi
;
1321 memcpy(scan_req
->net_info
[scan_req
->rcvd_ch_cnt
].bssid
,
1324 scan_req
->rcvd_ch_cnt
++;
1326 info
->new_network
= true;
1327 params
= host_int_parse_join_bss_param(info
);
1329 scan_req
->scan_result(SCAN_EVENT_NETWORK_FOUND
, info
,
1330 scan_req
->arg
, params
);
1333 info
->new_network
= false;
1334 scan_req
->scan_result(SCAN_EVENT_NETWORK_FOUND
, info
,
1335 scan_req
->arg
, NULL
);
1339 kfree(rcvd_info
->buffer
);
1340 rcvd_info
->buffer
= NULL
;
1350 static s32
host_int_get_assoc_res_info(struct wilc_vif
*vif
,
1351 u8
*assoc_resp_info
,
1352 u32 max_assoc_resp_info_len
,
1353 u32
*rcvd_assoc_resp_info_len
);
1355 static s32
handle_rcvd_gnrl_async_info(struct wilc_vif
*vif
,
1356 struct rcvd_async_info
*rcvd_info
)
1362 u16 wid_id
= (u16
)WID_NIL
;
1365 u8 mac_status_reason_code
;
1366 u8 mac_status_additional_info
;
1367 struct connect_info conn_info
;
1368 struct disconnect_info disconn_info
;
1370 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
1373 netdev_err(vif
->ndev
, "Driver handler is NULL\n");
1377 if (hif_drv
->hif_state
== HOST_IF_WAITING_CONN_RESP
||
1378 hif_drv
->hif_state
== HOST_IF_CONNECTED
||
1379 hif_drv
->usr_scan_req
.scan_result
) {
1380 if (!rcvd_info
->buffer
||
1381 !hif_drv
->usr_conn_req
.conn_result
) {
1382 netdev_err(vif
->ndev
, "driver is null\n");
1386 msg_type
= rcvd_info
->buffer
[0];
1388 if ('I' != msg_type
) {
1389 netdev_err(vif
->ndev
, "Received Message incorrect.\n");
1393 msg_id
= rcvd_info
->buffer
[1];
1394 msg_len
= MAKE_WORD16(rcvd_info
->buffer
[2], rcvd_info
->buffer
[3]);
1395 wid_id
= MAKE_WORD16(rcvd_info
->buffer
[4], rcvd_info
->buffer
[5]);
1396 wid_len
= rcvd_info
->buffer
[6];
1397 mac_status
= rcvd_info
->buffer
[7];
1398 mac_status_reason_code
= rcvd_info
->buffer
[8];
1399 mac_status_additional_info
= rcvd_info
->buffer
[9];
1400 if (hif_drv
->hif_state
== HOST_IF_WAITING_CONN_RESP
) {
1401 u32 rcvd_assoc_resp_info_len
= 0;
1402 struct connect_resp_info
*connect_resp_info
= NULL
;
1404 memset(&conn_info
, 0, sizeof(struct connect_info
));
1406 if (mac_status
== MAC_CONNECTED
) {
1407 memset(rcv_assoc_resp
, 0, MAX_ASSOC_RESP_FRAME_SIZE
);
1409 host_int_get_assoc_res_info(vif
,
1411 MAX_ASSOC_RESP_FRAME_SIZE
,
1412 &rcvd_assoc_resp_info_len
);
1414 if (rcvd_assoc_resp_info_len
!= 0) {
1415 err
= wilc_parse_assoc_resp_info(rcv_assoc_resp
, rcvd_assoc_resp_info_len
,
1416 &connect_resp_info
);
1418 netdev_err(vif
->ndev
, "wilc_parse_assoc_resp_info() returned error %d\n", err
);
1420 conn_info
.status
= connect_resp_info
->status
;
1422 if (conn_info
.status
== SUCCESSFUL_STATUSCODE
&& connect_resp_info
->ies
) {
1423 conn_info
.resp_ies_len
= connect_resp_info
->ies_len
;
1424 conn_info
.resp_ies
= kmalloc(connect_resp_info
->ies_len
, GFP_KERNEL
);
1425 memcpy(conn_info
.resp_ies
, connect_resp_info
->ies
,
1426 connect_resp_info
->ies_len
);
1429 if (connect_resp_info
) {
1430 kfree(connect_resp_info
->ies
);
1431 kfree(connect_resp_info
);
1437 if (mac_status
== MAC_CONNECTED
&&
1438 conn_info
.status
!= SUCCESSFUL_STATUSCODE
) {
1439 netdev_err(vif
->ndev
, "Received MAC status is MAC_CONNECTED while the received status code in Asoc Resp is not SUCCESSFUL_STATUSCODE\n");
1440 eth_zero_addr(wilc_connected_ssid
);
1441 } else if (mac_status
== MAC_DISCONNECTED
) {
1442 netdev_err(vif
->ndev
, "Received MAC status is MAC_DISCONNECTED\n");
1443 eth_zero_addr(wilc_connected_ssid
);
1446 if (hif_drv
->usr_conn_req
.bssid
) {
1447 memcpy(conn_info
.bssid
, hif_drv
->usr_conn_req
.bssid
, 6);
1449 if (mac_status
== MAC_CONNECTED
&&
1450 conn_info
.status
== SUCCESSFUL_STATUSCODE
) {
1451 memcpy(hif_drv
->assoc_bssid
,
1452 hif_drv
->usr_conn_req
.bssid
, ETH_ALEN
);
1456 if (hif_drv
->usr_conn_req
.ies
) {
1457 conn_info
.req_ies_len
= hif_drv
->usr_conn_req
.ies_len
;
1458 conn_info
.req_ies
= kmalloc(hif_drv
->usr_conn_req
.ies_len
, GFP_KERNEL
);
1459 memcpy(conn_info
.req_ies
,
1460 hif_drv
->usr_conn_req
.ies
,
1461 hif_drv
->usr_conn_req
.ies_len
);
1464 del_timer(&hif_drv
->connect_timer
);
1465 hif_drv
->usr_conn_req
.conn_result(CONN_DISCONN_EVENT_CONN_RESP
,
1469 hif_drv
->usr_conn_req
.arg
);
1471 if (mac_status
== MAC_CONNECTED
&&
1472 conn_info
.status
== SUCCESSFUL_STATUSCODE
) {
1473 wilc_set_power_mgmt(vif
, 0, 0);
1475 hif_drv
->hif_state
= HOST_IF_CONNECTED
;
1477 wilc_optaining_ip
= true;
1478 mod_timer(&wilc_during_ip_timer
,
1479 jiffies
+ msecs_to_jiffies(10000));
1481 hif_drv
->hif_state
= HOST_IF_IDLE
;
1482 scan_while_connected
= false;
1485 kfree(conn_info
.resp_ies
);
1486 conn_info
.resp_ies
= NULL
;
1488 kfree(conn_info
.req_ies
);
1489 conn_info
.req_ies
= NULL
;
1490 hif_drv
->usr_conn_req
.ssid_len
= 0;
1491 kfree(hif_drv
->usr_conn_req
.ssid
);
1492 hif_drv
->usr_conn_req
.ssid
= NULL
;
1493 kfree(hif_drv
->usr_conn_req
.bssid
);
1494 hif_drv
->usr_conn_req
.bssid
= NULL
;
1495 hif_drv
->usr_conn_req
.ies_len
= 0;
1496 kfree(hif_drv
->usr_conn_req
.ies
);
1497 hif_drv
->usr_conn_req
.ies
= NULL
;
1498 } else if ((mac_status
== MAC_DISCONNECTED
) &&
1499 (hif_drv
->hif_state
== HOST_IF_CONNECTED
)) {
1500 memset(&disconn_info
, 0, sizeof(struct disconnect_info
));
1502 if (hif_drv
->usr_scan_req
.scan_result
) {
1503 del_timer(&hif_drv
->scan_timer
);
1504 handle_scan_done(vif
, SCAN_EVENT_ABORTED
);
1507 disconn_info
.reason
= 0;
1508 disconn_info
.ie
= NULL
;
1509 disconn_info
.ie_len
= 0;
1511 if (hif_drv
->usr_conn_req
.conn_result
) {
1512 wilc_optaining_ip
= false;
1513 wilc_set_power_mgmt(vif
, 0, 0);
1515 hif_drv
->usr_conn_req
.conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF
,
1519 hif_drv
->usr_conn_req
.arg
);
1521 netdev_err(vif
->ndev
, "Connect result NULL\n");
1524 eth_zero_addr(hif_drv
->assoc_bssid
);
1526 hif_drv
->usr_conn_req
.ssid_len
= 0;
1527 kfree(hif_drv
->usr_conn_req
.ssid
);
1528 hif_drv
->usr_conn_req
.ssid
= NULL
;
1529 kfree(hif_drv
->usr_conn_req
.bssid
);
1530 hif_drv
->usr_conn_req
.bssid
= NULL
;
1531 hif_drv
->usr_conn_req
.ies_len
= 0;
1532 kfree(hif_drv
->usr_conn_req
.ies
);
1533 hif_drv
->usr_conn_req
.ies
= NULL
;
1535 if (join_req
&& join_req_vif
== vif
) {
1540 if (info_element
&& join_req_vif
== vif
) {
1541 kfree(info_element
);
1542 info_element
= NULL
;
1545 hif_drv
->hif_state
= HOST_IF_IDLE
;
1546 scan_while_connected
= false;
1548 } else if ((mac_status
== MAC_DISCONNECTED
) &&
1549 (hif_drv
->usr_scan_req
.scan_result
)) {
1550 del_timer(&hif_drv
->scan_timer
);
1551 if (hif_drv
->usr_scan_req
.scan_result
)
1552 handle_scan_done(vif
, SCAN_EVENT_ABORTED
);
1556 kfree(rcvd_info
->buffer
);
1557 rcvd_info
->buffer
= NULL
;
1562 static int handle_key(struct wilc_vif
*vif
, struct key_attr
*hif_key
)
1566 struct wid wid_list
[5];
1571 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
1573 switch (hif_key
->type
) {
1576 if (hif_key
->action
& ADDKEY_AP
) {
1577 wid_list
[0].id
= (u16
)WID_11I_MODE
;
1578 wid_list
[0].type
= WID_CHAR
;
1579 wid_list
[0].size
= sizeof(char);
1580 wid_list
[0].val
= (s8
*)&hif_key
->attr
.wep
.mode
;
1582 wid_list
[1].id
= WID_AUTH_TYPE
;
1583 wid_list
[1].type
= WID_CHAR
;
1584 wid_list
[1].size
= sizeof(char);
1585 wid_list
[1].val
= (s8
*)&hif_key
->attr
.wep
.auth_type
;
1587 key_buf
= kmalloc(hif_key
->attr
.wep
.key_len
+ 2,
1592 key_buf
[0] = hif_key
->attr
.wep
.index
;
1593 key_buf
[1] = hif_key
->attr
.wep
.key_len
;
1595 memcpy(&key_buf
[2], hif_key
->attr
.wep
.key
,
1596 hif_key
->attr
.wep
.key_len
);
1598 kfree(hif_key
->attr
.wep
.key
);
1600 wid_list
[2].id
= (u16
)WID_WEP_KEY_VALUE
;
1601 wid_list
[2].type
= WID_STR
;
1602 wid_list
[2].size
= hif_key
->attr
.wep
.key_len
+ 2;
1603 wid_list
[2].val
= (s8
*)key_buf
;
1605 result
= wilc_send_config_pkt(vif
, SET_CFG
,
1607 wilc_get_vif_idx(vif
));
1609 } else if (hif_key
->action
& ADDKEY
) {
1610 key_buf
= kmalloc(hif_key
->attr
.wep
.key_len
+ 2, GFP_KERNEL
);
1613 key_buf
[0] = hif_key
->attr
.wep
.index
;
1614 memcpy(key_buf
+ 1, &hif_key
->attr
.wep
.key_len
, 1);
1615 memcpy(key_buf
+ 2, hif_key
->attr
.wep
.key
,
1616 hif_key
->attr
.wep
.key_len
);
1617 kfree(hif_key
->attr
.wep
.key
);
1619 wid
.id
= (u16
)WID_ADD_WEP_KEY
;
1621 wid
.val
= (s8
*)key_buf
;
1622 wid
.size
= hif_key
->attr
.wep
.key_len
+ 2;
1624 result
= wilc_send_config_pkt(vif
, SET_CFG
,
1626 wilc_get_vif_idx(vif
));
1628 } else if (hif_key
->action
& REMOVEKEY
) {
1629 wid
.id
= (u16
)WID_REMOVE_WEP_KEY
;
1632 s8idxarray
[0] = (s8
)hif_key
->attr
.wep
.index
;
1633 wid
.val
= s8idxarray
;
1636 result
= wilc_send_config_pkt(vif
, SET_CFG
,
1638 wilc_get_vif_idx(vif
));
1639 } else if (hif_key
->action
& DEFAULTKEY
) {
1640 wid
.id
= (u16
)WID_KEY_ID
;
1641 wid
.type
= WID_CHAR
;
1642 wid
.val
= (s8
*)&hif_key
->attr
.wep
.index
;
1643 wid
.size
= sizeof(char);
1645 result
= wilc_send_config_pkt(vif
, SET_CFG
,
1647 wilc_get_vif_idx(vif
));
1649 complete(&hif_drv
->comp_test_key_block
);
1653 if (hif_key
->action
& ADDKEY_AP
) {
1654 key_buf
= kzalloc(RX_MIC_KEY_MSG_LEN
, GFP_KERNEL
);
1657 goto out_wpa_rx_gtk
;
1660 if (hif_key
->attr
.wpa
.seq
)
1661 memcpy(key_buf
+ 6, hif_key
->attr
.wpa
.seq
, 8);
1663 memcpy(key_buf
+ 14, &hif_key
->attr
.wpa
.index
, 1);
1664 memcpy(key_buf
+ 15, &hif_key
->attr
.wpa
.key_len
, 1);
1665 memcpy(key_buf
+ 16, hif_key
->attr
.wpa
.key
,
1666 hif_key
->attr
.wpa
.key_len
);
1668 wid_list
[0].id
= (u16
)WID_11I_MODE
;
1669 wid_list
[0].type
= WID_CHAR
;
1670 wid_list
[0].size
= sizeof(char);
1671 wid_list
[0].val
= (s8
*)&hif_key
->attr
.wpa
.mode
;
1673 wid_list
[1].id
= (u16
)WID_ADD_RX_GTK
;
1674 wid_list
[1].type
= WID_STR
;
1675 wid_list
[1].val
= (s8
*)key_buf
;
1676 wid_list
[1].size
= RX_MIC_KEY_MSG_LEN
;
1678 result
= wilc_send_config_pkt(vif
, SET_CFG
,
1680 wilc_get_vif_idx(vif
));
1683 complete(&hif_drv
->comp_test_key_block
);
1684 } else if (hif_key
->action
& ADDKEY
) {
1685 key_buf
= kzalloc(RX_MIC_KEY_MSG_LEN
, GFP_KERNEL
);
1688 goto out_wpa_rx_gtk
;
1691 if (hif_drv
->hif_state
== HOST_IF_CONNECTED
)
1692 memcpy(key_buf
, hif_drv
->assoc_bssid
, ETH_ALEN
);
1694 netdev_err(vif
->ndev
, "Couldn't handle\n");
1696 memcpy(key_buf
+ 6, hif_key
->attr
.wpa
.seq
, 8);
1697 memcpy(key_buf
+ 14, &hif_key
->attr
.wpa
.index
, 1);
1698 memcpy(key_buf
+ 15, &hif_key
->attr
.wpa
.key_len
, 1);
1699 memcpy(key_buf
+ 16, hif_key
->attr
.wpa
.key
,
1700 hif_key
->attr
.wpa
.key_len
);
1702 wid
.id
= (u16
)WID_ADD_RX_GTK
;
1704 wid
.val
= (s8
*)key_buf
;
1705 wid
.size
= RX_MIC_KEY_MSG_LEN
;
1707 result
= wilc_send_config_pkt(vif
, SET_CFG
,
1709 wilc_get_vif_idx(vif
));
1712 complete(&hif_drv
->comp_test_key_block
);
1715 kfree(hif_key
->attr
.wpa
.key
);
1716 kfree(hif_key
->attr
.wpa
.seq
);
1723 if (hif_key
->action
& ADDKEY_AP
) {
1724 key_buf
= kmalloc(PTK_KEY_MSG_LEN
+ 1, GFP_KERNEL
);
1730 memcpy(key_buf
, hif_key
->attr
.wpa
.mac_addr
, 6);
1731 memcpy(key_buf
+ 6, &hif_key
->attr
.wpa
.index
, 1);
1732 memcpy(key_buf
+ 7, &hif_key
->attr
.wpa
.key_len
, 1);
1733 memcpy(key_buf
+ 8, hif_key
->attr
.wpa
.key
,
1734 hif_key
->attr
.wpa
.key_len
);
1736 wid_list
[0].id
= (u16
)WID_11I_MODE
;
1737 wid_list
[0].type
= WID_CHAR
;
1738 wid_list
[0].size
= sizeof(char);
1739 wid_list
[0].val
= (s8
*)&hif_key
->attr
.wpa
.mode
;
1741 wid_list
[1].id
= (u16
)WID_ADD_PTK
;
1742 wid_list
[1].type
= WID_STR
;
1743 wid_list
[1].val
= (s8
*)key_buf
;
1744 wid_list
[1].size
= PTK_KEY_MSG_LEN
+ 1;
1746 result
= wilc_send_config_pkt(vif
, SET_CFG
,
1748 wilc_get_vif_idx(vif
));
1750 complete(&hif_drv
->comp_test_key_block
);
1751 } else if (hif_key
->action
& ADDKEY
) {
1752 key_buf
= kmalloc(PTK_KEY_MSG_LEN
, GFP_KERNEL
);
1754 netdev_err(vif
->ndev
, "No buffer send PTK\n");
1759 memcpy(key_buf
, hif_key
->attr
.wpa
.mac_addr
, 6);
1760 memcpy(key_buf
+ 6, &hif_key
->attr
.wpa
.key_len
, 1);
1761 memcpy(key_buf
+ 7, hif_key
->attr
.wpa
.key
,
1762 hif_key
->attr
.wpa
.key_len
);
1764 wid
.id
= (u16
)WID_ADD_PTK
;
1766 wid
.val
= (s8
*)key_buf
;
1767 wid
.size
= PTK_KEY_MSG_LEN
;
1769 result
= wilc_send_config_pkt(vif
, SET_CFG
,
1771 wilc_get_vif_idx(vif
));
1773 complete(&hif_drv
->comp_test_key_block
);
1777 kfree(hif_key
->attr
.wpa
.key
);
1784 key_buf
= kmalloc((hif_key
->attr
.pmkid
.numpmkid
* PMKSA_KEY_LEN
) + 1, GFP_KERNEL
);
1788 key_buf
[0] = hif_key
->attr
.pmkid
.numpmkid
;
1790 for (i
= 0; i
< hif_key
->attr
.pmkid
.numpmkid
; i
++) {
1791 memcpy(key_buf
+ ((PMKSA_KEY_LEN
* i
) + 1), hif_key
->attr
.pmkid
.pmkidlist
[i
].bssid
, ETH_ALEN
);
1792 memcpy(key_buf
+ ((PMKSA_KEY_LEN
* i
) + ETH_ALEN
+ 1), hif_key
->attr
.pmkid
.pmkidlist
[i
].pmkid
, PMKID_LEN
);
1795 wid
.id
= (u16
)WID_PMKID_INFO
;
1797 wid
.val
= (s8
*)key_buf
;
1798 wid
.size
= (hif_key
->attr
.pmkid
.numpmkid
* PMKSA_KEY_LEN
) + 1;
1800 result
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
1801 wilc_get_vif_idx(vif
));
1808 netdev_err(vif
->ndev
, "Failed to send key config packet\n");
1813 static void handle_disconnect(struct wilc_vif
*vif
)
1816 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
1817 struct disconnect_info disconn_info
;
1818 struct user_scan_req
*scan_req
;
1819 struct user_conn_req
*conn_req
;
1821 u16 dummy_reason_code
= 0;
1823 wid
.id
= (u16
)WID_DISCONNECT
;
1824 wid
.type
= WID_CHAR
;
1825 wid
.val
= (s8
*)&dummy_reason_code
;
1826 wid
.size
= sizeof(char);
1828 wilc_optaining_ip
= false;
1829 wilc_set_power_mgmt(vif
, 0, 0);
1831 eth_zero_addr(wilc_connected_ssid
);
1833 result
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
1834 wilc_get_vif_idx(vif
));
1837 netdev_err(vif
->ndev
, "Failed to send dissconect\n");
1841 memset(&disconn_info
, 0, sizeof(struct disconnect_info
));
1843 disconn_info
.reason
= 0;
1844 disconn_info
.ie
= NULL
;
1845 disconn_info
.ie_len
= 0;
1846 scan_req
= &hif_drv
->usr_scan_req
;
1847 conn_req
= &hif_drv
->usr_conn_req
;
1849 if (scan_req
->scan_result
) {
1850 del_timer(&hif_drv
->scan_timer
);
1851 scan_req
->scan_result(SCAN_EVENT_ABORTED
, NULL
, scan_req
->arg
,
1853 scan_req
->scan_result
= NULL
;
1856 if (conn_req
->conn_result
) {
1857 if (hif_drv
->hif_state
== HOST_IF_WAITING_CONN_RESP
)
1858 del_timer(&hif_drv
->connect_timer
);
1860 conn_req
->conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF
, NULL
,
1861 0, &disconn_info
, conn_req
->arg
);
1863 netdev_err(vif
->ndev
, "conn_result = NULL\n");
1866 scan_while_connected
= false;
1868 hif_drv
->hif_state
= HOST_IF_IDLE
;
1870 eth_zero_addr(hif_drv
->assoc_bssid
);
1872 conn_req
->ssid_len
= 0;
1873 kfree(conn_req
->ssid
);
1874 conn_req
->ssid
= NULL
;
1875 kfree(conn_req
->bssid
);
1876 conn_req
->bssid
= NULL
;
1877 conn_req
->ies_len
= 0;
1878 kfree(conn_req
->ies
);
1879 conn_req
->ies
= NULL
;
1881 if (join_req
&& join_req_vif
== vif
) {
1886 if (info_element
&& join_req_vif
== vif
) {
1887 kfree(info_element
);
1888 info_element
= NULL
;
1893 complete(&hif_drv
->comp_test_disconn_block
);
1896 void wilc_resolve_disconnect_aberration(struct wilc_vif
*vif
)
1900 if (vif
->hif_drv
->hif_state
== HOST_IF_WAITING_CONN_RESP
||
1901 vif
->hif_drv
->hif_state
== HOST_IF_CONNECTING
)
1902 wilc_disconnect(vif
, 1);
1905 static void handle_get_rssi(struct wilc_vif
*vif
)
1910 wid
.id
= (u16
)WID_RSSI
;
1911 wid
.type
= WID_CHAR
;
1913 wid
.size
= sizeof(char);
1915 result
= wilc_send_config_pkt(vif
, GET_CFG
, &wid
, 1,
1916 wilc_get_vif_idx(vif
));
1918 netdev_err(vif
->ndev
, "Failed to get RSSI value\n");
1922 complete(&vif
->hif_drv
->comp_get_rssi
);
1925 static s32
handle_get_statistics(struct wilc_vif
*vif
,
1926 struct rf_info
*stats
)
1928 struct wid wid_list
[5];
1929 u32 wid_cnt
= 0, result
= 0;
1931 wid_list
[wid_cnt
].id
= WID_LINKSPEED
;
1932 wid_list
[wid_cnt
].type
= WID_CHAR
;
1933 wid_list
[wid_cnt
].size
= sizeof(char);
1934 wid_list
[wid_cnt
].val
= (s8
*)&stats
->link_speed
;
1937 wid_list
[wid_cnt
].id
= WID_RSSI
;
1938 wid_list
[wid_cnt
].type
= WID_CHAR
;
1939 wid_list
[wid_cnt
].size
= sizeof(char);
1940 wid_list
[wid_cnt
].val
= (s8
*)&stats
->rssi
;
1943 wid_list
[wid_cnt
].id
= WID_SUCCESS_FRAME_COUNT
;
1944 wid_list
[wid_cnt
].type
= WID_INT
;
1945 wid_list
[wid_cnt
].size
= sizeof(u32
);
1946 wid_list
[wid_cnt
].val
= (s8
*)&stats
->tx_cnt
;
1949 wid_list
[wid_cnt
].id
= WID_RECEIVED_FRAGMENT_COUNT
;
1950 wid_list
[wid_cnt
].type
= WID_INT
;
1951 wid_list
[wid_cnt
].size
= sizeof(u32
);
1952 wid_list
[wid_cnt
].val
= (s8
*)&stats
->rx_cnt
;
1955 wid_list
[wid_cnt
].id
= WID_FAILED_COUNT
;
1956 wid_list
[wid_cnt
].type
= WID_INT
;
1957 wid_list
[wid_cnt
].size
= sizeof(u32
);
1958 wid_list
[wid_cnt
].val
= (s8
*)&stats
->tx_fail_cnt
;
1961 result
= wilc_send_config_pkt(vif
, GET_CFG
, wid_list
,
1963 wilc_get_vif_idx(vif
));
1966 netdev_err(vif
->ndev
, "Failed to send scan parameters\n");
1968 if (stats
->link_speed
> TCP_ACK_FILTER_LINK_SPEED_THRESH
&&
1969 stats
->link_speed
!= DEFAULT_LINK_SPEED
)
1970 wilc_enable_tcp_ack_filter(true);
1971 else if (stats
->link_speed
!= DEFAULT_LINK_SPEED
)
1972 wilc_enable_tcp_ack_filter(false);
1974 if (stats
!= &vif
->wilc
->dummy_statistics
)
1975 complete(&hif_wait_response
);
1979 static s32
handle_get_inactive_time(struct wilc_vif
*vif
,
1980 struct sta_inactive_t
*hif_sta_inactive
)
1985 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
1987 wid
.id
= (u16
)WID_SET_STA_MAC_INACTIVE_TIME
;
1989 wid
.size
= ETH_ALEN
;
1990 wid
.val
= kmalloc(wid
.size
, GFP_KERNEL
);
1995 ether_addr_copy(stamac
, hif_sta_inactive
->mac
);
1997 result
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
1998 wilc_get_vif_idx(vif
));
2001 netdev_err(vif
->ndev
, "Failed to SET inactive time\n");
2005 wid
.id
= (u16
)WID_GET_INACTIVE_TIME
;
2007 wid
.val
= (s8
*)&inactive_time
;
2008 wid
.size
= sizeof(u32
);
2010 result
= wilc_send_config_pkt(vif
, GET_CFG
, &wid
, 1,
2011 wilc_get_vif_idx(vif
));
2014 netdev_err(vif
->ndev
, "Failed to get inactive time\n");
2018 complete(&hif_drv
->comp_inactive_time
);
2023 static void handle_add_beacon(struct wilc_vif
*vif
, struct beacon_attr
*param
)
2029 wid
.id
= (u16
)WID_ADD_BEACON
;
2031 wid
.size
= param
->head_len
+ param
->tail_len
+ 16;
2032 wid
.val
= kmalloc(wid
.size
, GFP_KERNEL
);
2037 *cur_byte
++ = (param
->interval
& 0xFF);
2038 *cur_byte
++ = ((param
->interval
>> 8) & 0xFF);
2039 *cur_byte
++ = ((param
->interval
>> 16) & 0xFF);
2040 *cur_byte
++ = ((param
->interval
>> 24) & 0xFF);
2042 *cur_byte
++ = (param
->dtim_period
& 0xFF);
2043 *cur_byte
++ = ((param
->dtim_period
>> 8) & 0xFF);
2044 *cur_byte
++ = ((param
->dtim_period
>> 16) & 0xFF);
2045 *cur_byte
++ = ((param
->dtim_period
>> 24) & 0xFF);
2047 *cur_byte
++ = (param
->head_len
& 0xFF);
2048 *cur_byte
++ = ((param
->head_len
>> 8) & 0xFF);
2049 *cur_byte
++ = ((param
->head_len
>> 16) & 0xFF);
2050 *cur_byte
++ = ((param
->head_len
>> 24) & 0xFF);
2052 memcpy(cur_byte
, param
->head
, param
->head_len
);
2053 cur_byte
+= param
->head_len
;
2055 *cur_byte
++ = (param
->tail_len
& 0xFF);
2056 *cur_byte
++ = ((param
->tail_len
>> 8) & 0xFF);
2057 *cur_byte
++ = ((param
->tail_len
>> 16) & 0xFF);
2058 *cur_byte
++ = ((param
->tail_len
>> 24) & 0xFF);
2061 memcpy(cur_byte
, param
->tail
, param
->tail_len
);
2062 cur_byte
+= param
->tail_len
;
2064 result
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
2065 wilc_get_vif_idx(vif
));
2067 netdev_err(vif
->ndev
, "Failed to send add beacon\n");
2075 static void handle_del_beacon(struct wilc_vif
*vif
)
2081 wid
.id
= (u16
)WID_DEL_BEACON
;
2082 wid
.type
= WID_CHAR
;
2083 wid
.size
= sizeof(char);
2084 wid
.val
= &del_beacon
;
2091 result
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
2092 wilc_get_vif_idx(vif
));
2094 netdev_err(vif
->ndev
, "Failed to send delete beacon\n");
2097 static u32
wilc_hif_pack_sta_param(u8
*buff
, struct add_sta_param
*param
)
2103 memcpy(cur_byte
, param
->bssid
, ETH_ALEN
);
2104 cur_byte
+= ETH_ALEN
;
2106 *cur_byte
++ = param
->aid
& 0xFF;
2107 *cur_byte
++ = (param
->aid
>> 8) & 0xFF;
2109 *cur_byte
++ = param
->rates_len
;
2110 if (param
->rates_len
> 0)
2111 memcpy(cur_byte
, param
->rates
, param
->rates_len
);
2112 cur_byte
+= param
->rates_len
;
2114 *cur_byte
++ = param
->ht_supported
;
2115 memcpy(cur_byte
, ¶m
->ht_capa
, sizeof(struct ieee80211_ht_cap
));
2116 cur_byte
+= sizeof(struct ieee80211_ht_cap
);
2118 *cur_byte
++ = param
->flags_mask
& 0xFF;
2119 *cur_byte
++ = (param
->flags_mask
>> 8) & 0xFF;
2121 *cur_byte
++ = param
->flags_set
& 0xFF;
2122 *cur_byte
++ = (param
->flags_set
>> 8) & 0xFF;
2124 return cur_byte
- buff
;
2127 static void handle_add_station(struct wilc_vif
*vif
,
2128 struct add_sta_param
*param
)
2134 wid
.id
= (u16
)WID_ADD_STA
;
2136 wid
.size
= WILC_ADD_STA_LENGTH
+ param
->rates_len
;
2138 wid
.val
= kmalloc(wid
.size
, GFP_KERNEL
);
2143 cur_byte
+= wilc_hif_pack_sta_param(cur_byte
, param
);
2145 result
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
2146 wilc_get_vif_idx(vif
));
2148 netdev_err(vif
->ndev
, "Failed to send add station\n");
2151 kfree(param
->rates
);
2155 static void handle_del_all_sta(struct wilc_vif
*vif
,
2156 struct del_all_sta
*param
)
2162 u8 zero_buff
[6] = {0};
2164 wid
.id
= (u16
)WID_DEL_ALL_STA
;
2166 wid
.size
= (param
->assoc_sta
* ETH_ALEN
) + 1;
2168 wid
.val
= kmalloc((param
->assoc_sta
* ETH_ALEN
) + 1, GFP_KERNEL
);
2172 curr_byte
= wid
.val
;
2174 *(curr_byte
++) = param
->assoc_sta
;
2176 for (i
= 0; i
< MAX_NUM_STA
; i
++) {
2177 if (memcmp(param
->del_all_sta
[i
], zero_buff
, ETH_ALEN
))
2178 memcpy(curr_byte
, param
->del_all_sta
[i
], ETH_ALEN
);
2182 curr_byte
+= ETH_ALEN
;
2185 result
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
2186 wilc_get_vif_idx(vif
));
2188 netdev_err(vif
->ndev
, "Failed to send add station\n");
2193 complete(&hif_wait_response
);
2196 static void handle_del_station(struct wilc_vif
*vif
, struct del_sta
*param
)
2202 wid
.id
= (u16
)WID_REMOVE_STA
;
2204 wid
.size
= ETH_ALEN
;
2206 wid
.val
= kmalloc(wid
.size
, GFP_KERNEL
);
2212 ether_addr_copy(cur_byte
, param
->mac_addr
);
2214 result
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
2215 wilc_get_vif_idx(vif
));
2217 netdev_err(vif
->ndev
, "Failed to send add station\n");
2223 static void handle_edit_station(struct wilc_vif
*vif
,
2224 struct add_sta_param
*param
)
2230 wid
.id
= (u16
)WID_EDIT_STA
;
2232 wid
.size
= WILC_ADD_STA_LENGTH
+ param
->rates_len
;
2234 wid
.val
= kmalloc(wid
.size
, GFP_KERNEL
);
2239 cur_byte
+= wilc_hif_pack_sta_param(cur_byte
, param
);
2241 result
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
2242 wilc_get_vif_idx(vif
));
2244 netdev_err(vif
->ndev
, "Failed to send edit station\n");
2247 kfree(param
->rates
);
2251 static int handle_remain_on_chan(struct wilc_vif
*vif
,
2252 struct remain_ch
*hif_remain_ch
)
2255 u8 remain_on_chan_flag
;
2257 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
2259 if (!hif_drv
->remain_on_ch_pending
) {
2260 hif_drv
->remain_on_ch
.arg
= hif_remain_ch
->arg
;
2261 hif_drv
->remain_on_ch
.expired
= hif_remain_ch
->expired
;
2262 hif_drv
->remain_on_ch
.ready
= hif_remain_ch
->ready
;
2263 hif_drv
->remain_on_ch
.ch
= hif_remain_ch
->ch
;
2264 hif_drv
->remain_on_ch
.id
= hif_remain_ch
->id
;
2266 hif_remain_ch
->ch
= hif_drv
->remain_on_ch
.ch
;
2269 if (hif_drv
->usr_scan_req
.scan_result
) {
2270 hif_drv
->remain_on_ch_pending
= 1;
2274 if (hif_drv
->hif_state
== HOST_IF_WAITING_CONN_RESP
) {
2279 if (wilc_optaining_ip
|| wilc_connecting
) {
2284 remain_on_chan_flag
= true;
2285 wid
.id
= (u16
)WID_REMAIN_ON_CHAN
;
2288 wid
.val
= kmalloc(wid
.size
, GFP_KERNEL
);
2294 wid
.val
[0] = remain_on_chan_flag
;
2295 wid
.val
[1] = (s8
)hif_remain_ch
->ch
;
2297 result
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
2298 wilc_get_vif_idx(vif
));
2300 netdev_err(vif
->ndev
, "Failed to set remain on channel\n");
2304 P2P_LISTEN_STATE
= 1;
2305 hif_drv
->remain_on_ch_timer_vif
= vif
;
2306 mod_timer(&hif_drv
->remain_on_ch_timer
,
2308 msecs_to_jiffies(hif_remain_ch
->duration
));
2310 if (hif_drv
->remain_on_ch
.ready
)
2311 hif_drv
->remain_on_ch
.ready(hif_drv
->remain_on_ch
.arg
);
2313 if (hif_drv
->remain_on_ch_pending
)
2314 hif_drv
->remain_on_ch_pending
= 0;
2320 static int handle_register_frame(struct wilc_vif
*vif
,
2321 struct reg_frame
*hif_reg_frame
)
2327 wid
.id
= (u16
)WID_REGISTER_FRAME
;
2329 wid
.val
= kmalloc(sizeof(u16
) + 2, GFP_KERNEL
);
2335 *cur_byte
++ = hif_reg_frame
->reg
;
2336 *cur_byte
++ = hif_reg_frame
->reg_id
;
2337 memcpy(cur_byte
, &hif_reg_frame
->frame_type
, sizeof(u16
));
2339 wid
.size
= sizeof(u16
) + 2;
2341 result
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
2342 wilc_get_vif_idx(vif
));
2344 netdev_err(vif
->ndev
, "Failed to frame register\n");
2351 static u32
handle_listen_state_expired(struct wilc_vif
*vif
,
2352 struct remain_ch
*hif_remain_ch
)
2354 u8 remain_on_chan_flag
;
2357 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
2359 if (P2P_LISTEN_STATE
) {
2360 remain_on_chan_flag
= false;
2361 wid
.id
= (u16
)WID_REMAIN_ON_CHAN
;
2364 wid
.val
= kmalloc(wid
.size
, GFP_KERNEL
);
2369 wid
.val
[0] = remain_on_chan_flag
;
2370 wid
.val
[1] = FALSE_FRMWR_CHANNEL
;
2372 result
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
2373 wilc_get_vif_idx(vif
));
2375 netdev_err(vif
->ndev
, "Failed to set remain channel\n");
2379 if (hif_drv
->remain_on_ch
.expired
) {
2380 hif_drv
->remain_on_ch
.expired(hif_drv
->remain_on_ch
.arg
,
2383 P2P_LISTEN_STATE
= 0;
2385 netdev_dbg(vif
->ndev
, "Not in listen state\n");
2393 static void listen_timer_cb(struct timer_list
*t
)
2395 struct host_if_drv
*hif_drv
= from_timer(hif_drv
, t
,
2396 remain_on_ch_timer
);
2397 struct wilc_vif
*vif
= hif_drv
->remain_on_ch_timer_vif
;
2399 struct host_if_msg msg
;
2401 del_timer(&vif
->hif_drv
->remain_on_ch_timer
);
2403 memset(&msg
, 0, sizeof(struct host_if_msg
));
2404 msg
.id
= HOST_IF_MSG_LISTEN_TIMER_FIRED
;
2406 msg
.body
.remain_on_ch
.id
= vif
->hif_drv
->remain_on_ch
.id
;
2408 result
= wilc_enqueue_cmd(&msg
);
2410 netdev_err(vif
->ndev
, "wilc_mq_send fail\n");
2413 static void handle_power_management(struct wilc_vif
*vif
,
2414 struct power_mgmt_param
*pm_param
)
2420 wid
.id
= (u16
)WID_POWER_MANAGEMENT
;
2422 if (pm_param
->enabled
)
2423 power_mode
= MIN_FAST_PS
;
2425 power_mode
= NO_POWERSAVE
;
2427 wid
.val
= &power_mode
;
2428 wid
.size
= sizeof(char);
2430 result
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
2431 wilc_get_vif_idx(vif
));
2433 netdev_err(vif
->ndev
, "Failed to send power management\n");
2436 static void handle_set_mcast_filter(struct wilc_vif
*vif
,
2437 struct set_multicast
*hif_set_mc
)
2443 wid
.id
= (u16
)WID_SETUP_MULTICAST_FILTER
;
2445 wid
.size
= sizeof(struct set_multicast
) + (hif_set_mc
->cnt
* ETH_ALEN
);
2446 wid
.val
= kmalloc(wid
.size
, GFP_KERNEL
);
2451 *cur_byte
++ = (hif_set_mc
->enabled
& 0xFF);
2456 *cur_byte
++ = (hif_set_mc
->cnt
& 0xFF);
2457 *cur_byte
++ = ((hif_set_mc
->cnt
>> 8) & 0xFF);
2458 *cur_byte
++ = ((hif_set_mc
->cnt
>> 16) & 0xFF);
2459 *cur_byte
++ = ((hif_set_mc
->cnt
>> 24) & 0xFF);
2461 if (hif_set_mc
->cnt
> 0)
2462 memcpy(cur_byte
, wilc_multicast_mac_addr_list
,
2463 ((hif_set_mc
->cnt
) * ETH_ALEN
));
2465 result
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
2466 wilc_get_vif_idx(vif
));
2468 netdev_err(vif
->ndev
, "Failed to send setup multicast\n");
2474 static void handle_set_tx_pwr(struct wilc_vif
*vif
, u8 tx_pwr
)
2479 wid
.id
= (u16
)WID_TX_POWER
;
2480 wid
.type
= WID_CHAR
;
2482 wid
.size
= sizeof(char);
2484 ret
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
2485 wilc_get_vif_idx(vif
));
2487 netdev_err(vif
->ndev
, "Failed to set TX PWR\n");
2490 static void handle_get_tx_pwr(struct wilc_vif
*vif
, u8
*tx_pwr
)
2495 wid
.id
= (u16
)WID_TX_POWER
;
2496 wid
.type
= WID_CHAR
;
2497 wid
.val
= (s8
*)tx_pwr
;
2498 wid
.size
= sizeof(char);
2500 ret
= wilc_send_config_pkt(vif
, GET_CFG
, &wid
, 1,
2501 wilc_get_vif_idx(vif
));
2503 netdev_err(vif
->ndev
, "Failed to get TX PWR\n");
2505 complete(&hif_wait_response
);
2508 static void host_if_work(struct work_struct
*work
)
2510 struct host_if_msg
*msg
;
2514 msg
= container_of(work
, struct host_if_msg
, work
);
2515 wilc
= msg
->vif
->wilc
;
2517 if (msg
->id
== HOST_IF_MSG_CONNECT
&&
2518 msg
->vif
->hif_drv
->usr_scan_req
.scan_result
) {
2519 wilc_enqueue_cmd(msg
);
2520 usleep_range(2 * 1000, 2 * 1000);
2524 case HOST_IF_MSG_SCAN
:
2525 handle_scan(msg
->vif
, &msg
->body
.scan_info
);
2528 case HOST_IF_MSG_CONNECT
:
2529 handle_connect(msg
->vif
, &msg
->body
.con_info
);
2532 case HOST_IF_MSG_RCVD_NTWRK_INFO
:
2533 handle_rcvd_ntwrk_info(msg
->vif
, &msg
->body
.net_info
);
2536 case HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO
:
2537 handle_rcvd_gnrl_async_info(msg
->vif
,
2538 &msg
->body
.async_info
);
2541 case HOST_IF_MSG_KEY
:
2542 handle_key(msg
->vif
, &msg
->body
.key_info
);
2545 case HOST_IF_MSG_CFG_PARAMS
:
2546 handle_cfg_param(msg
->vif
, &msg
->body
.cfg_info
);
2549 case HOST_IF_MSG_SET_CHANNEL
:
2550 handle_set_channel(msg
->vif
, &msg
->body
.channel_info
);
2553 case HOST_IF_MSG_DISCONNECT
:
2554 handle_disconnect(msg
->vif
);
2557 case HOST_IF_MSG_RCVD_SCAN_COMPLETE
:
2558 del_timer(&msg
->vif
->hif_drv
->scan_timer
);
2560 if (!wilc_wlan_get_num_conn_ifcs(wilc
))
2561 wilc_chip_sleep_manually(wilc
);
2563 handle_scan_done(msg
->vif
, SCAN_EVENT_DONE
);
2565 if (msg
->vif
->hif_drv
->remain_on_ch_pending
)
2566 handle_remain_on_chan(msg
->vif
,
2567 &msg
->body
.remain_on_ch
);
2571 case HOST_IF_MSG_GET_RSSI
:
2572 handle_get_rssi(msg
->vif
);
2575 case HOST_IF_MSG_GET_STATISTICS
:
2576 handle_get_statistics(msg
->vif
,
2577 (struct rf_info
*)msg
->body
.data
);
2580 case HOST_IF_MSG_ADD_BEACON
:
2581 handle_add_beacon(msg
->vif
, &msg
->body
.beacon_info
);
2584 case HOST_IF_MSG_DEL_BEACON
:
2585 handle_del_beacon(msg
->vif
);
2588 case HOST_IF_MSG_ADD_STATION
:
2589 handle_add_station(msg
->vif
, &msg
->body
.add_sta_info
);
2592 case HOST_IF_MSG_DEL_STATION
:
2593 handle_del_station(msg
->vif
, &msg
->body
.del_sta_info
);
2596 case HOST_IF_MSG_EDIT_STATION
:
2597 handle_edit_station(msg
->vif
, &msg
->body
.edit_sta_info
);
2600 case HOST_IF_MSG_GET_INACTIVETIME
:
2601 handle_get_inactive_time(msg
->vif
, &msg
->body
.mac_info
);
2604 case HOST_IF_MSG_SCAN_TIMER_FIRED
:
2605 handle_scan_done(msg
->vif
, SCAN_EVENT_ABORTED
);
2608 case HOST_IF_MSG_CONNECT_TIMER_FIRED
:
2609 handle_connect_timeout(msg
->vif
);
2612 case HOST_IF_MSG_POWER_MGMT
:
2613 handle_power_management(msg
->vif
,
2614 &msg
->body
.pwr_mgmt_info
);
2617 case HOST_IF_MSG_SET_WFIDRV_HANDLER
:
2618 ret
= handle_set_wfi_drv_handler(msg
->vif
, &msg
->body
.drv
);
2621 case HOST_IF_MSG_SET_OPERATION_MODE
:
2622 handle_set_operation_mode(msg
->vif
, &msg
->body
.mode
);
2625 case HOST_IF_MSG_SET_IPADDRESS
:
2626 handle_set_ip_address(msg
->vif
,
2627 msg
->body
.ip_info
.ip_addr
,
2628 msg
->body
.ip_info
.idx
);
2631 case HOST_IF_MSG_GET_IPADDRESS
:
2632 handle_get_ip_address(msg
->vif
, msg
->body
.ip_info
.idx
);
2635 case HOST_IF_MSG_GET_MAC_ADDRESS
:
2636 handle_get_mac_address(msg
->vif
,
2637 &msg
->body
.get_mac_info
);
2640 case HOST_IF_MSG_REMAIN_ON_CHAN
:
2641 handle_remain_on_chan(msg
->vif
, &msg
->body
.remain_on_ch
);
2644 case HOST_IF_MSG_REGISTER_FRAME
:
2645 handle_register_frame(msg
->vif
, &msg
->body
.reg_frame
);
2648 case HOST_IF_MSG_LISTEN_TIMER_FIRED
:
2649 handle_listen_state_expired(msg
->vif
, &msg
->body
.remain_on_ch
);
2652 case HOST_IF_MSG_SET_MULTICAST_FILTER
:
2653 handle_set_mcast_filter(msg
->vif
, &msg
->body
.multicast_info
);
2656 case HOST_IF_MSG_DEL_ALL_STA
:
2657 handle_del_all_sta(msg
->vif
, &msg
->body
.del_all_sta_info
);
2660 case HOST_IF_MSG_SET_TX_POWER
:
2661 handle_set_tx_pwr(msg
->vif
, msg
->body
.tx_power
.tx_pwr
);
2664 case HOST_IF_MSG_GET_TX_POWER
:
2665 handle_get_tx_pwr(msg
->vif
, &msg
->body
.tx_power
.tx_pwr
);
2668 netdev_err(msg
->vif
->ndev
, "[Host Interface] undefined\n");
2673 netdev_err(msg
->vif
->ndev
, "Host cmd %d failed\n", msg
->id
);
2675 complete(&hif_thread_comp
);
2678 static void timer_scan_cb(struct timer_list
*t
)
2680 struct host_if_drv
*hif_drv
= from_timer(hif_drv
, t
, scan_timer
);
2681 struct wilc_vif
*vif
= hif_drv
->scan_timer_vif
;
2682 struct host_if_msg msg
;
2684 memset(&msg
, 0, sizeof(struct host_if_msg
));
2686 msg
.id
= HOST_IF_MSG_SCAN_TIMER_FIRED
;
2688 wilc_enqueue_cmd(&msg
);
2691 static void timer_connect_cb(struct timer_list
*t
)
2693 struct host_if_drv
*hif_drv
= from_timer(hif_drv
, t
,
2695 struct wilc_vif
*vif
= hif_drv
->connect_timer_vif
;
2696 struct host_if_msg msg
;
2698 memset(&msg
, 0, sizeof(struct host_if_msg
));
2700 msg
.id
= HOST_IF_MSG_CONNECT_TIMER_FIRED
;
2702 wilc_enqueue_cmd(&msg
);
2705 s32
wilc_remove_key(struct host_if_drv
*hif_drv
, const u8
*sta_addr
)
2709 wid
.id
= (u16
)WID_REMOVE_KEY
;
2711 wid
.val
= (s8
*)sta_addr
;
2717 int wilc_remove_wep_key(struct wilc_vif
*vif
, u8 index
)
2720 struct host_if_msg msg
;
2721 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
2725 netdev_err(vif
->ndev
, "Failed to send setup multicast\n");
2729 memset(&msg
, 0, sizeof(struct host_if_msg
));
2731 msg
.id
= HOST_IF_MSG_KEY
;
2732 msg
.body
.key_info
.type
= WEP
;
2733 msg
.body
.key_info
.action
= REMOVEKEY
;
2735 msg
.body
.key_info
.attr
.wep
.index
= index
;
2737 result
= wilc_enqueue_cmd(&msg
);
2739 netdev_err(vif
->ndev
, "Request to remove WEP key\n");
2741 wait_for_completion(&hif_drv
->comp_test_key_block
);
2746 int wilc_set_wep_default_keyid(struct wilc_vif
*vif
, u8 index
)
2749 struct host_if_msg msg
;
2750 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
2754 netdev_err(vif
->ndev
, "driver is null\n");
2758 memset(&msg
, 0, sizeof(struct host_if_msg
));
2760 msg
.id
= HOST_IF_MSG_KEY
;
2761 msg
.body
.key_info
.type
= WEP
;
2762 msg
.body
.key_info
.action
= DEFAULTKEY
;
2764 msg
.body
.key_info
.attr
.wep
.index
= index
;
2766 result
= wilc_enqueue_cmd(&msg
);
2768 netdev_err(vif
->ndev
, "Default key index\n");
2770 wait_for_completion(&hif_drv
->comp_test_key_block
);
2775 int wilc_add_wep_key_bss_sta(struct wilc_vif
*vif
, const u8
*key
, u8 len
,
2779 struct host_if_msg msg
;
2780 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
2783 netdev_err(vif
->ndev
, "driver is null\n");
2787 memset(&msg
, 0, sizeof(struct host_if_msg
));
2789 msg
.id
= HOST_IF_MSG_KEY
;
2790 msg
.body
.key_info
.type
= WEP
;
2791 msg
.body
.key_info
.action
= ADDKEY
;
2793 msg
.body
.key_info
.attr
.wep
.key
= kmemdup(key
, len
, GFP_KERNEL
);
2794 if (!msg
.body
.key_info
.attr
.wep
.key
)
2797 msg
.body
.key_info
.attr
.wep
.key_len
= len
;
2798 msg
.body
.key_info
.attr
.wep
.index
= index
;
2800 result
= wilc_enqueue_cmd(&msg
);
2802 netdev_err(vif
->ndev
, "STA - WEP Key\n");
2803 wait_for_completion(&hif_drv
->comp_test_key_block
);
2808 int wilc_add_wep_key_bss_ap(struct wilc_vif
*vif
, const u8
*key
, u8 len
,
2809 u8 index
, u8 mode
, enum AUTHTYPE auth_type
)
2812 struct host_if_msg msg
;
2813 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
2816 netdev_err(vif
->ndev
, "driver is null\n");
2820 memset(&msg
, 0, sizeof(struct host_if_msg
));
2822 msg
.id
= HOST_IF_MSG_KEY
;
2823 msg
.body
.key_info
.type
= WEP
;
2824 msg
.body
.key_info
.action
= ADDKEY_AP
;
2826 msg
.body
.key_info
.attr
.wep
.key
= kmemdup(key
, len
, GFP_KERNEL
);
2827 if (!msg
.body
.key_info
.attr
.wep
.key
)
2830 msg
.body
.key_info
.attr
.wep
.key_len
= len
;
2831 msg
.body
.key_info
.attr
.wep
.index
= index
;
2832 msg
.body
.key_info
.attr
.wep
.mode
= mode
;
2833 msg
.body
.key_info
.attr
.wep
.auth_type
= auth_type
;
2835 result
= wilc_enqueue_cmd(&msg
);
2838 netdev_err(vif
->ndev
, "AP - WEP Key\n");
2840 wait_for_completion(&hif_drv
->comp_test_key_block
);
2845 int wilc_add_ptk(struct wilc_vif
*vif
, const u8
*ptk
, u8 ptk_key_len
,
2846 const u8
*mac_addr
, const u8
*rx_mic
, const u8
*tx_mic
,
2847 u8 mode
, u8 cipher_mode
, u8 index
)
2850 struct host_if_msg msg
;
2851 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
2852 u8 key_len
= ptk_key_len
;
2855 netdev_err(vif
->ndev
, "driver is null\n");
2860 key_len
+= RX_MIC_KEY_LEN
;
2863 key_len
+= TX_MIC_KEY_LEN
;
2865 memset(&msg
, 0, sizeof(struct host_if_msg
));
2867 msg
.id
= HOST_IF_MSG_KEY
;
2868 msg
.body
.key_info
.type
= WPA_PTK
;
2869 if (mode
== AP_MODE
) {
2870 msg
.body
.key_info
.action
= ADDKEY_AP
;
2871 msg
.body
.key_info
.attr
.wpa
.index
= index
;
2873 if (mode
== STATION_MODE
)
2874 msg
.body
.key_info
.action
= ADDKEY
;
2876 msg
.body
.key_info
.attr
.wpa
.key
= kmemdup(ptk
, ptk_key_len
, GFP_KERNEL
);
2877 if (!msg
.body
.key_info
.attr
.wpa
.key
)
2881 memcpy(msg
.body
.key_info
.attr
.wpa
.key
+ 16, rx_mic
,
2885 memcpy(msg
.body
.key_info
.attr
.wpa
.key
+ 24, tx_mic
,
2888 msg
.body
.key_info
.attr
.wpa
.key_len
= key_len
;
2889 msg
.body
.key_info
.attr
.wpa
.mac_addr
= mac_addr
;
2890 msg
.body
.key_info
.attr
.wpa
.mode
= cipher_mode
;
2893 result
= wilc_enqueue_cmd(&msg
);
2896 netdev_err(vif
->ndev
, "PTK Key\n");
2898 wait_for_completion(&hif_drv
->comp_test_key_block
);
2903 int wilc_add_rx_gtk(struct wilc_vif
*vif
, const u8
*rx_gtk
, u8 gtk_key_len
,
2904 u8 index
, u32 key_rsc_len
, const u8
*key_rsc
,
2905 const u8
*rx_mic
, const u8
*tx_mic
, u8 mode
,
2909 struct host_if_msg msg
;
2910 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
2911 u8 key_len
= gtk_key_len
;
2914 netdev_err(vif
->ndev
, "driver is null\n");
2917 memset(&msg
, 0, sizeof(struct host_if_msg
));
2920 key_len
+= RX_MIC_KEY_LEN
;
2923 key_len
+= TX_MIC_KEY_LEN
;
2926 msg
.body
.key_info
.attr
.wpa
.seq
= kmemdup(key_rsc
,
2929 if (!msg
.body
.key_info
.attr
.wpa
.seq
)
2933 msg
.id
= HOST_IF_MSG_KEY
;
2934 msg
.body
.key_info
.type
= WPA_RX_GTK
;
2937 if (mode
== AP_MODE
) {
2938 msg
.body
.key_info
.action
= ADDKEY_AP
;
2939 msg
.body
.key_info
.attr
.wpa
.mode
= cipher_mode
;
2941 if (mode
== STATION_MODE
)
2942 msg
.body
.key_info
.action
= ADDKEY
;
2944 msg
.body
.key_info
.attr
.wpa
.key
= kmemdup(rx_gtk
,
2947 if (!msg
.body
.key_info
.attr
.wpa
.key
)
2951 memcpy(msg
.body
.key_info
.attr
.wpa
.key
+ 16, rx_mic
,
2955 memcpy(msg
.body
.key_info
.attr
.wpa
.key
+ 24, tx_mic
,
2958 msg
.body
.key_info
.attr
.wpa
.index
= index
;
2959 msg
.body
.key_info
.attr
.wpa
.key_len
= key_len
;
2960 msg
.body
.key_info
.attr
.wpa
.seq_len
= key_rsc_len
;
2962 result
= wilc_enqueue_cmd(&msg
);
2964 netdev_err(vif
->ndev
, "RX GTK\n");
2966 wait_for_completion(&hif_drv
->comp_test_key_block
);
2971 int wilc_set_pmkid_info(struct wilc_vif
*vif
,
2972 struct host_if_pmkid_attr
*pmkid
)
2975 struct host_if_msg msg
;
2978 memset(&msg
, 0, sizeof(struct host_if_msg
));
2980 msg
.id
= HOST_IF_MSG_KEY
;
2981 msg
.body
.key_info
.type
= PMKSA
;
2982 msg
.body
.key_info
.action
= ADDKEY
;
2985 for (i
= 0; i
< pmkid
->numpmkid
; i
++) {
2986 memcpy(msg
.body
.key_info
.attr
.pmkid
.pmkidlist
[i
].bssid
,
2987 &pmkid
->pmkidlist
[i
].bssid
, ETH_ALEN
);
2988 memcpy(msg
.body
.key_info
.attr
.pmkid
.pmkidlist
[i
].pmkid
,
2989 &pmkid
->pmkidlist
[i
].pmkid
, PMKID_LEN
);
2992 result
= wilc_enqueue_cmd(&msg
);
2994 netdev_err(vif
->ndev
, "PMKID Info\n");
2999 int wilc_get_mac_address(struct wilc_vif
*vif
, u8
*mac_addr
)
3002 struct host_if_msg msg
;
3004 memset(&msg
, 0, sizeof(struct host_if_msg
));
3006 msg
.id
= HOST_IF_MSG_GET_MAC_ADDRESS
;
3007 msg
.body
.get_mac_info
.mac_addr
= mac_addr
;
3010 result
= wilc_enqueue_cmd(&msg
);
3012 netdev_err(vif
->ndev
, "Failed to send get mac address\n");
3016 wait_for_completion(&hif_wait_response
);
3020 int wilc_set_join_req(struct wilc_vif
*vif
, u8
*bssid
, const u8
*ssid
,
3021 size_t ssid_len
, const u8
*ies
, size_t ies_len
,
3022 wilc_connect_result connect_result
, void *user_arg
,
3023 u8 security
, enum AUTHTYPE auth_type
,
3024 u8 channel
, void *join_params
)
3027 struct host_if_msg msg
;
3028 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
3030 if (!hif_drv
|| !connect_result
) {
3031 netdev_err(vif
->ndev
, "Driver is null\n");
3036 netdev_err(vif
->ndev
, "Unable to Join - JoinParams is NULL\n");
3040 memset(&msg
, 0, sizeof(struct host_if_msg
));
3042 msg
.id
= HOST_IF_MSG_CONNECT
;
3044 msg
.body
.con_info
.security
= security
;
3045 msg
.body
.con_info
.auth_type
= auth_type
;
3046 msg
.body
.con_info
.ch
= channel
;
3047 msg
.body
.con_info
.result
= connect_result
;
3048 msg
.body
.con_info
.arg
= user_arg
;
3049 msg
.body
.con_info
.params
= join_params
;
3053 msg
.body
.con_info
.bssid
= kmemdup(bssid
, 6, GFP_KERNEL
);
3054 if (!msg
.body
.con_info
.bssid
)
3059 msg
.body
.con_info
.ssid_len
= ssid_len
;
3060 msg
.body
.con_info
.ssid
= kmemdup(ssid
, ssid_len
, GFP_KERNEL
);
3061 if (!msg
.body
.con_info
.ssid
)
3066 msg
.body
.con_info
.ies_len
= ies_len
;
3067 msg
.body
.con_info
.ies
= kmemdup(ies
, ies_len
, GFP_KERNEL
);
3068 if (!msg
.body
.con_info
.ies
)
3071 if (hif_drv
->hif_state
< HOST_IF_CONNECTING
)
3072 hif_drv
->hif_state
= HOST_IF_CONNECTING
;
3074 result
= wilc_enqueue_cmd(&msg
);
3076 netdev_err(vif
->ndev
, "send message: Set join request\n");
3080 hif_drv
->connect_timer_vif
= vif
;
3081 mod_timer(&hif_drv
->connect_timer
,
3082 jiffies
+ msecs_to_jiffies(HOST_IF_CONNECT_TIMEOUT
));
3087 int wilc_disconnect(struct wilc_vif
*vif
, u16 reason_code
)
3090 struct host_if_msg msg
;
3091 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
3094 netdev_err(vif
->ndev
, "Driver is null\n");
3098 memset(&msg
, 0, sizeof(struct host_if_msg
));
3100 msg
.id
= HOST_IF_MSG_DISCONNECT
;
3103 result
= wilc_enqueue_cmd(&msg
);
3105 netdev_err(vif
->ndev
, "Failed to send message: disconnect\n");
3107 wait_for_completion(&hif_drv
->comp_test_disconn_block
);
3112 static s32
host_int_get_assoc_res_info(struct wilc_vif
*vif
,
3113 u8
*assoc_resp_info
,
3114 u32 max_assoc_resp_info_len
,
3115 u32
*rcvd_assoc_resp_info_len
)
3120 wid
.id
= (u16
)WID_ASSOC_RES_INFO
;
3122 wid
.val
= assoc_resp_info
;
3123 wid
.size
= max_assoc_resp_info_len
;
3125 result
= wilc_send_config_pkt(vif
, GET_CFG
, &wid
, 1,
3126 wilc_get_vif_idx(vif
));
3128 *rcvd_assoc_resp_info_len
= 0;
3129 netdev_err(vif
->ndev
, "Failed to send association response\n");
3133 *rcvd_assoc_resp_info_len
= wid
.size
;
3137 int wilc_set_mac_chnl_num(struct wilc_vif
*vif
, u8 channel
)
3140 struct host_if_msg msg
;
3142 memset(&msg
, 0, sizeof(struct host_if_msg
));
3143 msg
.id
= HOST_IF_MSG_SET_CHANNEL
;
3144 msg
.body
.channel_info
.set_ch
= channel
;
3147 result
= wilc_enqueue_cmd(&msg
);
3149 netdev_err(vif
->ndev
, "wilc mq send fail\n");
3156 int wilc_set_wfi_drv_handler(struct wilc_vif
*vif
, int index
, u8 mode
,
3160 struct host_if_msg msg
;
3162 memset(&msg
, 0, sizeof(struct host_if_msg
));
3163 msg
.id
= HOST_IF_MSG_SET_WFIDRV_HANDLER
;
3164 msg
.body
.drv
.handler
= index
;
3165 msg
.body
.drv
.mode
= mode
;
3166 msg
.body
.drv
.name
= ifc_id
;
3169 result
= wilc_enqueue_cmd(&msg
);
3171 netdev_err(vif
->ndev
, "wilc mq send fail\n");
3178 int wilc_set_operation_mode(struct wilc_vif
*vif
, u32 mode
)
3181 struct host_if_msg msg
;
3183 memset(&msg
, 0, sizeof(struct host_if_msg
));
3184 msg
.id
= HOST_IF_MSG_SET_OPERATION_MODE
;
3185 msg
.body
.mode
.mode
= mode
;
3188 result
= wilc_enqueue_cmd(&msg
);
3190 netdev_err(vif
->ndev
, "wilc mq send fail\n");
3197 s32
wilc_get_inactive_time(struct wilc_vif
*vif
, const u8
*mac
,
3201 struct host_if_msg msg
;
3202 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
3205 netdev_err(vif
->ndev
, "driver is null\n");
3209 memset(&msg
, 0, sizeof(struct host_if_msg
));
3210 memcpy(msg
.body
.mac_info
.mac
, mac
, ETH_ALEN
);
3212 msg
.id
= HOST_IF_MSG_GET_INACTIVETIME
;
3215 result
= wilc_enqueue_cmd(&msg
);
3217 netdev_err(vif
->ndev
, "Failed to send get host ch param\n");
3219 wait_for_completion(&hif_drv
->comp_inactive_time
);
3221 *out_val
= inactive_time
;
3226 int wilc_get_rssi(struct wilc_vif
*vif
, s8
*rssi_level
)
3229 struct host_if_msg msg
;
3230 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
3232 memset(&msg
, 0, sizeof(struct host_if_msg
));
3233 msg
.id
= HOST_IF_MSG_GET_RSSI
;
3236 result
= wilc_enqueue_cmd(&msg
);
3238 netdev_err(vif
->ndev
, "Failed to send get host ch param\n");
3242 wait_for_completion(&hif_drv
->comp_get_rssi
);
3245 netdev_err(vif
->ndev
, "RSS pointer value is null\n");
3254 int wilc_get_statistics(struct wilc_vif
*vif
, struct rf_info
*stats
)
3257 struct host_if_msg msg
;
3259 memset(&msg
, 0, sizeof(struct host_if_msg
));
3260 msg
.id
= HOST_IF_MSG_GET_STATISTICS
;
3261 msg
.body
.data
= (char *)stats
;
3264 result
= wilc_enqueue_cmd(&msg
);
3266 netdev_err(vif
->ndev
, "Failed to send get host channel\n");
3270 if (stats
!= &vif
->wilc
->dummy_statistics
)
3271 wait_for_completion(&hif_wait_response
);
3275 int wilc_scan(struct wilc_vif
*vif
, u8 scan_source
, u8 scan_type
,
3276 u8
*ch_freq_list
, u8 ch_list_len
, const u8
*ies
,
3277 size_t ies_len
, wilc_scan_result scan_result
, void *user_arg
,
3278 struct hidden_network
*hidden_network
)
3281 struct host_if_msg msg
;
3282 struct scan_attr
*scan_info
= &msg
.body
.scan_info
;
3283 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
3285 if (!hif_drv
|| !scan_result
) {
3286 netdev_err(vif
->ndev
, "hif_drv or scan_result = NULL\n");
3290 memset(&msg
, 0, sizeof(struct host_if_msg
));
3292 msg
.id
= HOST_IF_MSG_SCAN
;
3294 if (hidden_network
) {
3295 scan_info
->hidden_network
.net_info
= hidden_network
->net_info
;
3296 scan_info
->hidden_network
.n_ssids
= hidden_network
->n_ssids
;
3300 scan_info
->src
= scan_source
;
3301 scan_info
->type
= scan_type
;
3302 scan_info
->result
= scan_result
;
3303 scan_info
->arg
= user_arg
;
3305 scan_info
->ch_list_len
= ch_list_len
;
3306 scan_info
->ch_freq_list
= kmemdup(ch_freq_list
,
3309 if (!scan_info
->ch_freq_list
)
3312 scan_info
->ies_len
= ies_len
;
3313 scan_info
->ies
= kmemdup(ies
, ies_len
, GFP_KERNEL
);
3314 if (!scan_info
->ies
)
3317 result
= wilc_enqueue_cmd(&msg
);
3319 netdev_err(vif
->ndev
, "Error in sending message queue\n");
3323 hif_drv
->scan_timer_vif
= vif
;
3324 mod_timer(&hif_drv
->scan_timer
,
3325 jiffies
+ msecs_to_jiffies(HOST_IF_SCAN_TIMEOUT
));
3330 int wilc_hif_set_cfg(struct wilc_vif
*vif
,
3331 struct cfg_param_attr
*cfg_param
)
3333 struct host_if_msg msg
;
3334 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
3337 netdev_err(vif
->ndev
, "hif_drv NULL\n");
3341 memset(&msg
, 0, sizeof(struct host_if_msg
));
3342 msg
.id
= HOST_IF_MSG_CFG_PARAMS
;
3343 msg
.body
.cfg_info
= *cfg_param
;
3346 return wilc_enqueue_cmd(&msg
);
3349 static void get_periodic_rssi(struct timer_list
*unused
)
3351 struct wilc_vif
*vif
= periodic_rssi_vif
;
3353 if (!vif
->hif_drv
) {
3354 netdev_err(vif
->ndev
, "Driver handler is NULL\n");
3358 if (vif
->hif_drv
->hif_state
== HOST_IF_CONNECTED
)
3359 wilc_get_statistics(vif
, &vif
->wilc
->dummy_statistics
);
3361 mod_timer(&periodic_rssi
, jiffies
+ msecs_to_jiffies(5000));
3364 int wilc_init(struct net_device
*dev
, struct host_if_drv
**hif_drv_handler
)
3367 struct host_if_drv
*hif_drv
;
3368 struct wilc_vif
*vif
;
3372 vif
= netdev_priv(dev
);
3375 scan_while_connected
= false;
3377 init_completion(&hif_wait_response
);
3379 hif_drv
= kzalloc(sizeof(*hif_drv
), GFP_KERNEL
);
3384 *hif_drv_handler
= hif_drv
;
3385 for (i
= 0; i
< wilc
->vif_num
; i
++)
3386 if (dev
== wilc
->vif
[i
]->ndev
) {
3387 wilc
->vif
[i
]->hif_drv
= hif_drv
;
3388 hif_drv
->driver_handler_id
= i
+ 1;
3392 wilc_optaining_ip
= false;
3394 if (clients_count
== 0) {
3395 init_completion(&hif_thread_comp
);
3396 init_completion(&hif_driver_comp
);
3397 mutex_init(&hif_deinit_lock
);
3400 init_completion(&hif_drv
->comp_test_key_block
);
3401 init_completion(&hif_drv
->comp_test_disconn_block
);
3402 init_completion(&hif_drv
->comp_get_rssi
);
3403 init_completion(&hif_drv
->comp_inactive_time
);
3405 if (clients_count
== 0) {
3406 hif_workqueue
= create_singlethread_workqueue("WILC_wq");
3407 if (!hif_workqueue
) {
3408 netdev_err(vif
->ndev
, "Failed to create workqueue\n");
3413 periodic_rssi_vif
= vif
;
3414 timer_setup(&periodic_rssi
, get_periodic_rssi
, 0);
3415 mod_timer(&periodic_rssi
, jiffies
+ msecs_to_jiffies(5000));
3418 timer_setup(&hif_drv
->scan_timer
, timer_scan_cb
, 0);
3419 timer_setup(&hif_drv
->connect_timer
, timer_connect_cb
, 0);
3420 timer_setup(&hif_drv
->remain_on_ch_timer
, listen_timer_cb
, 0);
3422 mutex_init(&hif_drv
->cfg_values_lock
);
3423 mutex_lock(&hif_drv
->cfg_values_lock
);
3425 hif_drv
->hif_state
= HOST_IF_IDLE
;
3426 hif_drv
->cfg_values
.site_survey_enabled
= SITE_SURVEY_OFF
;
3427 hif_drv
->cfg_values
.scan_source
= DEFAULT_SCAN
;
3428 hif_drv
->cfg_values
.active_scan_time
= ACTIVE_SCAN_TIME
;
3429 hif_drv
->cfg_values
.passive_scan_time
= PASSIVE_SCAN_TIME
;
3430 hif_drv
->cfg_values
.curr_tx_rate
= AUTORATE
;
3432 hif_drv
->p2p_timeout
= 0;
3434 mutex_unlock(&hif_drv
->cfg_values_lock
);
3442 int wilc_deinit(struct wilc_vif
*vif
)
3445 struct host_if_msg msg
;
3446 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
3449 netdev_err(vif
->ndev
, "hif_drv = NULL\n");
3453 mutex_lock(&hif_deinit_lock
);
3455 terminated_handle
= hif_drv
;
3457 del_timer_sync(&hif_drv
->scan_timer
);
3458 del_timer_sync(&hif_drv
->connect_timer
);
3459 del_timer_sync(&periodic_rssi
);
3460 del_timer_sync(&hif_drv
->remain_on_ch_timer
);
3462 wilc_set_wfi_drv_handler(vif
, 0, 0, 0);
3463 wait_for_completion(&hif_driver_comp
);
3465 if (hif_drv
->usr_scan_req
.scan_result
) {
3466 hif_drv
->usr_scan_req
.scan_result(SCAN_EVENT_ABORTED
, NULL
,
3467 hif_drv
->usr_scan_req
.arg
,
3469 hif_drv
->usr_scan_req
.scan_result
= NULL
;
3472 hif_drv
->hif_state
= HOST_IF_IDLE
;
3474 scan_while_connected
= false;
3476 memset(&msg
, 0, sizeof(struct host_if_msg
));
3478 if (clients_count
== 1) {
3479 msg
.id
= HOST_IF_MSG_EXIT
;
3482 result
= wilc_enqueue_cmd(&msg
);
3484 netdev_err(vif
->ndev
, "deinit : Error(%d)\n", result
);
3486 wait_for_completion(&hif_thread_comp
);
3488 destroy_workqueue(hif_workqueue
);
3494 terminated_handle
= NULL
;
3495 mutex_unlock(&hif_deinit_lock
);
3499 void wilc_network_info_received(struct wilc
*wilc
, u8
*buffer
, u32 length
)
3502 struct host_if_msg msg
;
3504 struct host_if_drv
*hif_drv
= NULL
;
3505 struct wilc_vif
*vif
;
3507 id
= buffer
[length
- 4];
3508 id
|= (buffer
[length
- 3] << 8);
3509 id
|= (buffer
[length
- 2] << 16);
3510 id
|= (buffer
[length
- 1] << 24);
3511 vif
= wilc_get_vif_from_idx(wilc
, id
);
3514 hif_drv
= vif
->hif_drv
;
3516 if (!hif_drv
|| hif_drv
== terminated_handle
) {
3517 netdev_err(vif
->ndev
, "driver not init[%p]\n", hif_drv
);
3521 memset(&msg
, 0, sizeof(struct host_if_msg
));
3523 msg
.id
= HOST_IF_MSG_RCVD_NTWRK_INFO
;
3526 msg
.body
.net_info
.len
= length
;
3527 msg
.body
.net_info
.buffer
= kmalloc(length
, GFP_KERNEL
);
3528 memcpy(msg
.body
.net_info
.buffer
, buffer
, length
);
3530 result
= wilc_enqueue_cmd(&msg
);
3532 netdev_err(vif
->ndev
, "message parameters (%d)\n", result
);
3535 void wilc_gnrl_async_info_received(struct wilc
*wilc
, u8
*buffer
, u32 length
)
3538 struct host_if_msg msg
;
3540 struct host_if_drv
*hif_drv
= NULL
;
3541 struct wilc_vif
*vif
;
3543 mutex_lock(&hif_deinit_lock
);
3545 id
= buffer
[length
- 4];
3546 id
|= (buffer
[length
- 3] << 8);
3547 id
|= (buffer
[length
- 2] << 16);
3548 id
|= (buffer
[length
- 1] << 24);
3549 vif
= wilc_get_vif_from_idx(wilc
, id
);
3551 mutex_unlock(&hif_deinit_lock
);
3555 hif_drv
= vif
->hif_drv
;
3557 if (!hif_drv
|| hif_drv
== terminated_handle
) {
3558 mutex_unlock(&hif_deinit_lock
);
3562 if (!hif_drv
->usr_conn_req
.conn_result
) {
3563 netdev_err(vif
->ndev
, "there is no current Connect Request\n");
3564 mutex_unlock(&hif_deinit_lock
);
3568 memset(&msg
, 0, sizeof(struct host_if_msg
));
3570 msg
.id
= HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO
;
3573 msg
.body
.async_info
.len
= length
;
3574 msg
.body
.async_info
.buffer
= kmalloc(length
, GFP_KERNEL
);
3575 memcpy(msg
.body
.async_info
.buffer
, buffer
, length
);
3577 result
= wilc_enqueue_cmd(&msg
);
3579 netdev_err(vif
->ndev
, "synchronous info (%d)\n", result
);
3581 mutex_unlock(&hif_deinit_lock
);
3584 void wilc_scan_complete_received(struct wilc
*wilc
, u8
*buffer
, u32 length
)
3587 struct host_if_msg msg
;
3589 struct host_if_drv
*hif_drv
= NULL
;
3590 struct wilc_vif
*vif
;
3592 id
= buffer
[length
- 4];
3593 id
|= buffer
[length
- 3] << 8;
3594 id
|= buffer
[length
- 2] << 16;
3595 id
|= buffer
[length
- 1] << 24;
3596 vif
= wilc_get_vif_from_idx(wilc
, id
);
3599 hif_drv
= vif
->hif_drv
;
3601 if (!hif_drv
|| hif_drv
== terminated_handle
)
3604 if (hif_drv
->usr_scan_req
.scan_result
) {
3605 memset(&msg
, 0, sizeof(struct host_if_msg
));
3607 msg
.id
= HOST_IF_MSG_RCVD_SCAN_COMPLETE
;
3610 result
= wilc_enqueue_cmd(&msg
);
3612 netdev_err(vif
->ndev
, "complete param (%d)\n", result
);
3616 int wilc_remain_on_channel(struct wilc_vif
*vif
, u32 session_id
,
3617 u32 duration
, u16 chan
,
3618 wilc_remain_on_chan_expired expired
,
3619 wilc_remain_on_chan_ready ready
,
3623 struct host_if_msg msg
;
3625 memset(&msg
, 0, sizeof(struct host_if_msg
));
3627 msg
.id
= HOST_IF_MSG_REMAIN_ON_CHAN
;
3628 msg
.body
.remain_on_ch
.ch
= chan
;
3629 msg
.body
.remain_on_ch
.expired
= expired
;
3630 msg
.body
.remain_on_ch
.ready
= ready
;
3631 msg
.body
.remain_on_ch
.arg
= user_arg
;
3632 msg
.body
.remain_on_ch
.duration
= duration
;
3633 msg
.body
.remain_on_ch
.id
= session_id
;
3636 result
= wilc_enqueue_cmd(&msg
);
3638 netdev_err(vif
->ndev
, "wilc mq send fail\n");
3643 int wilc_listen_state_expired(struct wilc_vif
*vif
, u32 session_id
)
3646 struct host_if_msg msg
;
3647 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
3650 netdev_err(vif
->ndev
, "driver is null\n");
3654 del_timer(&hif_drv
->remain_on_ch_timer
);
3656 memset(&msg
, 0, sizeof(struct host_if_msg
));
3657 msg
.id
= HOST_IF_MSG_LISTEN_TIMER_FIRED
;
3659 msg
.body
.remain_on_ch
.id
= session_id
;
3661 result
= wilc_enqueue_cmd(&msg
);
3663 netdev_err(vif
->ndev
, "wilc mq send fail\n");
3668 int wilc_frame_register(struct wilc_vif
*vif
, u16 frame_type
, bool reg
)
3671 struct host_if_msg msg
;
3673 memset(&msg
, 0, sizeof(struct host_if_msg
));
3675 msg
.id
= HOST_IF_MSG_REGISTER_FRAME
;
3676 switch (frame_type
) {
3678 msg
.body
.reg_frame
.reg_id
= ACTION_FRM_IDX
;
3682 msg
.body
.reg_frame
.reg_id
= PROBE_REQ_IDX
;
3688 msg
.body
.reg_frame
.frame_type
= frame_type
;
3689 msg
.body
.reg_frame
.reg
= reg
;
3692 result
= wilc_enqueue_cmd(&msg
);
3694 netdev_err(vif
->ndev
, "wilc mq send fail\n");
3699 int wilc_add_beacon(struct wilc_vif
*vif
, u32 interval
, u32 dtim_period
,
3700 u32 head_len
, u8
*head
, u32 tail_len
, u8
*tail
)
3703 struct host_if_msg msg
;
3704 struct beacon_attr
*beacon_info
= &msg
.body
.beacon_info
;
3706 memset(&msg
, 0, sizeof(struct host_if_msg
));
3708 msg
.id
= HOST_IF_MSG_ADD_BEACON
;
3710 beacon_info
->interval
= interval
;
3711 beacon_info
->dtim_period
= dtim_period
;
3712 beacon_info
->head_len
= head_len
;
3713 beacon_info
->head
= kmemdup(head
, head_len
, GFP_KERNEL
);
3714 if (!beacon_info
->head
) {
3718 beacon_info
->tail_len
= tail_len
;
3721 beacon_info
->tail
= kmemdup(tail
, tail_len
, GFP_KERNEL
);
3722 if (!beacon_info
->tail
) {
3727 beacon_info
->tail
= NULL
;
3730 result
= wilc_enqueue_cmd(&msg
);
3732 netdev_err(vif
->ndev
, "wilc mq send fail\n");
3736 kfree(beacon_info
->head
);
3738 kfree(beacon_info
->tail
);
3744 int wilc_del_beacon(struct wilc_vif
*vif
)
3747 struct host_if_msg msg
;
3749 msg
.id
= HOST_IF_MSG_DEL_BEACON
;
3752 result
= wilc_enqueue_cmd(&msg
);
3754 netdev_err(vif
->ndev
, "wilc_mq_send fail\n");
3759 int wilc_add_station(struct wilc_vif
*vif
, struct add_sta_param
*sta_param
)
3762 struct host_if_msg msg
;
3763 struct add_sta_param
*add_sta_info
= &msg
.body
.add_sta_info
;
3765 memset(&msg
, 0, sizeof(struct host_if_msg
));
3767 msg
.id
= HOST_IF_MSG_ADD_STATION
;
3770 memcpy(add_sta_info
, sta_param
, sizeof(struct add_sta_param
));
3771 if (add_sta_info
->rates_len
> 0) {
3772 add_sta_info
->rates
= kmemdup(sta_param
->rates
,
3773 add_sta_info
->rates_len
,
3775 if (!add_sta_info
->rates
)
3779 result
= wilc_enqueue_cmd(&msg
);
3781 netdev_err(vif
->ndev
, "wilc_mq_send fail\n");
3785 int wilc_del_station(struct wilc_vif
*vif
, const u8
*mac_addr
)
3788 struct host_if_msg msg
;
3789 struct del_sta
*del_sta_info
= &msg
.body
.del_sta_info
;
3791 memset(&msg
, 0, sizeof(struct host_if_msg
));
3793 msg
.id
= HOST_IF_MSG_DEL_STATION
;
3797 eth_broadcast_addr(del_sta_info
->mac_addr
);
3799 memcpy(del_sta_info
->mac_addr
, mac_addr
, ETH_ALEN
);
3801 result
= wilc_enqueue_cmd(&msg
);
3803 netdev_err(vif
->ndev
, "wilc_mq_send fail\n");
3807 int wilc_del_allstation(struct wilc_vif
*vif
, u8 mac_addr
[][ETH_ALEN
])
3810 struct host_if_msg msg
;
3811 struct del_all_sta
*del_all_sta_info
= &msg
.body
.del_all_sta_info
;
3812 u8 zero_addr
[ETH_ALEN
] = {0};
3816 memset(&msg
, 0, sizeof(struct host_if_msg
));
3818 msg
.id
= HOST_IF_MSG_DEL_ALL_STA
;
3821 for (i
= 0; i
< MAX_NUM_STA
; i
++) {
3822 if (memcmp(mac_addr
[i
], zero_addr
, ETH_ALEN
)) {
3823 memcpy(del_all_sta_info
->del_all_sta
[i
], mac_addr
[i
],
3831 del_all_sta_info
->assoc_sta
= assoc_sta
;
3832 result
= wilc_enqueue_cmd(&msg
);
3835 netdev_err(vif
->ndev
, "wilc_mq_send fail\n");
3837 wait_for_completion(&hif_wait_response
);
3842 int wilc_edit_station(struct wilc_vif
*vif
,
3843 struct add_sta_param
*sta_param
)
3846 struct host_if_msg msg
;
3847 struct add_sta_param
*add_sta_info
= &msg
.body
.add_sta_info
;
3849 memset(&msg
, 0, sizeof(struct host_if_msg
));
3851 msg
.id
= HOST_IF_MSG_EDIT_STATION
;
3854 memcpy(add_sta_info
, sta_param
, sizeof(struct add_sta_param
));
3855 if (add_sta_info
->rates_len
> 0) {
3856 add_sta_info
->rates
= kmemdup(sta_param
->rates
,
3857 add_sta_info
->rates_len
,
3859 if (!add_sta_info
->rates
)
3863 result
= wilc_enqueue_cmd(&msg
);
3865 netdev_err(vif
->ndev
, "wilc_mq_send fail\n");
3870 int wilc_set_power_mgmt(struct wilc_vif
*vif
, bool enabled
, u32 timeout
)
3873 struct host_if_msg msg
;
3874 struct power_mgmt_param
*pwr_mgmt_info
= &msg
.body
.pwr_mgmt_info
;
3876 if (wilc_wlan_get_num_conn_ifcs(vif
->wilc
) == 2 && enabled
)
3879 memset(&msg
, 0, sizeof(struct host_if_msg
));
3881 msg
.id
= HOST_IF_MSG_POWER_MGMT
;
3884 pwr_mgmt_info
->enabled
= enabled
;
3885 pwr_mgmt_info
->timeout
= timeout
;
3887 result
= wilc_enqueue_cmd(&msg
);
3889 netdev_err(vif
->ndev
, "wilc_mq_send fail\n");
3893 int wilc_setup_multicast_filter(struct wilc_vif
*vif
, bool enabled
,
3897 struct host_if_msg msg
;
3898 struct set_multicast
*multicast_filter_param
= &msg
.body
.multicast_info
;
3900 memset(&msg
, 0, sizeof(struct host_if_msg
));
3902 msg
.id
= HOST_IF_MSG_SET_MULTICAST_FILTER
;
3905 multicast_filter_param
->enabled
= enabled
;
3906 multicast_filter_param
->cnt
= count
;
3908 result
= wilc_enqueue_cmd(&msg
);
3910 netdev_err(vif
->ndev
, "wilc_mq_send fail\n");
3914 static void *host_int_parse_join_bss_param(struct network_info
*info
)
3916 struct join_bss_param
*param
= NULL
;
3925 u8 pcipher_total_cnt
= 0;
3926 u8 auth_total_cnt
= 0;
3930 ies_len
= info
->ies_len
;
3932 param
= kzalloc(sizeof(*param
), GFP_KERNEL
);
3936 param
->dtim_period
= info
->dtim_period
;
3937 param
->beacon_period
= info
->beacon_period
;
3938 param
->cap_info
= info
->cap_info
;
3939 memcpy(param
->bssid
, info
->bssid
, 6);
3940 memcpy((u8
*)param
->ssid
, info
->ssid
, info
->ssid_len
+ 1);
3941 param
->ssid_len
= info
->ssid_len
;
3942 memset(param
->rsn_pcip_policy
, 0xFF, 3);
3943 memset(param
->rsn_auth_policy
, 0xFF, 3);
3945 while (index
< ies_len
) {
3946 if (ies
[index
] == SUPP_RATES_IE
) {
3947 rates_no
= ies
[index
+ 1];
3948 param
->supp_rates
[0] = rates_no
;
3951 for (i
= 0; i
< rates_no
; i
++)
3952 param
->supp_rates
[i
+ 1] = ies
[index
+ i
];
3955 } else if (ies
[index
] == EXT_SUPP_RATES_IE
) {
3956 ext_rates_no
= ies
[index
+ 1];
3957 if (ext_rates_no
> (MAX_RATES_SUPPORTED
- rates_no
))
3958 param
->supp_rates
[0] = MAX_RATES_SUPPORTED
;
3960 param
->supp_rates
[0] += ext_rates_no
;
3962 for (i
= 0; i
< (param
->supp_rates
[0] - rates_no
); i
++)
3963 param
->supp_rates
[rates_no
+ i
+ 1] = ies
[index
+ i
];
3965 index
+= ext_rates_no
;
3966 } else if (ies
[index
] == HT_CAPABILITY_IE
) {
3967 param
->ht_capable
= true;
3968 index
+= ies
[index
+ 1] + 2;
3969 } else if ((ies
[index
] == WMM_IE
) &&
3970 (ies
[index
+ 2] == 0x00) && (ies
[index
+ 3] == 0x50) &&
3971 (ies
[index
+ 4] == 0xF2) &&
3972 (ies
[index
+ 5] == 0x02) &&
3973 ((ies
[index
+ 6] == 0x00) || (ies
[index
+ 6] == 0x01)) &&
3974 (ies
[index
+ 7] == 0x01)) {
3975 param
->wmm_cap
= true;
3977 if (ies
[index
+ 8] & BIT(7))
3978 param
->uapsd_cap
= true;
3979 index
+= ies
[index
+ 1] + 2;
3980 } else if ((ies
[index
] == P2P_IE
) &&
3981 (ies
[index
+ 2] == 0x50) && (ies
[index
+ 3] == 0x6f) &&
3982 (ies
[index
+ 4] == 0x9a) &&
3983 (ies
[index
+ 5] == 0x09) && (ies
[index
+ 6] == 0x0c)) {
3986 param
->tsf
= info
->tsf_lo
;
3987 param
->noa_enabled
= 1;
3988 param
->idx
= ies
[index
+ 9];
3990 if (ies
[index
+ 10] & BIT(7)) {
3991 param
->opp_enabled
= 1;
3992 param
->ct_window
= ies
[index
+ 10];
3994 param
->opp_enabled
= 0;
3997 param
->cnt
= ies
[index
+ 11];
3998 p2p_cnt
= index
+ 12;
4000 memcpy(param
->duration
, ies
+ p2p_cnt
, 4);
4003 memcpy(param
->interval
, ies
+ p2p_cnt
, 4);
4006 memcpy(param
->start_time
, ies
+ p2p_cnt
, 4);
4008 index
+= ies
[index
+ 1] + 2;
4009 } else if ((ies
[index
] == RSN_IE
) ||
4010 ((ies
[index
] == WPA_IE
) && (ies
[index
+ 2] == 0x00) &&
4011 (ies
[index
+ 3] == 0x50) && (ies
[index
+ 4] == 0xF2) &&
4012 (ies
[index
+ 5] == 0x01))) {
4013 u16 rsn_idx
= index
;
4015 if (ies
[rsn_idx
] == RSN_IE
) {
4016 param
->mode_802_11i
= 2;
4018 if (param
->mode_802_11i
== 0)
4019 param
->mode_802_11i
= 1;
4024 param
->rsn_grp_policy
= ies
[rsn_idx
];
4026 offset
= ies
[rsn_idx
] * 4;
4027 pcipher_cnt
= (ies
[rsn_idx
] > 3) ? 3 : ies
[rsn_idx
];
4030 for (i
= pcipher_total_cnt
, j
= 0; i
< pcipher_cnt
+ pcipher_total_cnt
&& i
< 3; i
++, j
++)
4031 param
->rsn_pcip_policy
[i
] = ies
[rsn_idx
+ ((j
+ 1) * 4) - 1];
4033 pcipher_total_cnt
+= pcipher_cnt
;
4036 offset
= ies
[rsn_idx
] * 4;
4038 auth_cnt
= (ies
[rsn_idx
] > 3) ? 3 : ies
[rsn_idx
];
4041 for (i
= auth_total_cnt
, j
= 0; i
< auth_total_cnt
+ auth_cnt
; i
++, j
++)
4042 param
->rsn_auth_policy
[i
] = ies
[rsn_idx
+ ((j
+ 1) * 4) - 1];
4044 auth_total_cnt
+= auth_cnt
;
4047 if (ies
[index
] == RSN_IE
) {
4048 param
->rsn_cap
[0] = ies
[rsn_idx
];
4049 param
->rsn_cap
[1] = ies
[rsn_idx
+ 1];
4052 param
->rsn_found
= true;
4053 index
+= ies
[index
+ 1] + 2;
4055 index
+= ies
[index
+ 1] + 2;
4059 return (void *)param
;
4062 int wilc_setup_ipaddress(struct wilc_vif
*vif
, u8
*ip_addr
, u8 idx
)
4065 struct host_if_msg msg
;
4067 memset(&msg
, 0, sizeof(struct host_if_msg
));
4069 msg
.id
= HOST_IF_MSG_SET_IPADDRESS
;
4071 msg
.body
.ip_info
.ip_addr
= ip_addr
;
4073 msg
.body
.ip_info
.idx
= idx
;
4075 result
= wilc_enqueue_cmd(&msg
);
4077 netdev_err(vif
->ndev
, "wilc_mq_send fail\n");
4082 static int host_int_get_ipaddress(struct wilc_vif
*vif
, u8
*ip_addr
, u8 idx
)
4085 struct host_if_msg msg
;
4087 memset(&msg
, 0, sizeof(struct host_if_msg
));
4089 msg
.id
= HOST_IF_MSG_GET_IPADDRESS
;
4091 msg
.body
.ip_info
.ip_addr
= ip_addr
;
4093 msg
.body
.ip_info
.idx
= idx
;
4095 result
= wilc_enqueue_cmd(&msg
);
4097 netdev_err(vif
->ndev
, "wilc_mq_send fail\n");
4102 int wilc_set_tx_power(struct wilc_vif
*vif
, u8 tx_power
)
4105 struct host_if_msg msg
;
4107 memset(&msg
, 0, sizeof(struct host_if_msg
));
4109 msg
.id
= HOST_IF_MSG_SET_TX_POWER
;
4110 msg
.body
.tx_power
.tx_pwr
= tx_power
;
4113 ret
= wilc_enqueue_cmd(&msg
);
4115 netdev_err(vif
->ndev
, "wilc_mq_send fail\n");
4120 int wilc_get_tx_power(struct wilc_vif
*vif
, u8
*tx_power
)
4123 struct host_if_msg msg
;
4125 memset(&msg
, 0, sizeof(struct host_if_msg
));
4127 msg
.id
= HOST_IF_MSG_GET_TX_POWER
;
4130 ret
= wilc_enqueue_cmd(&msg
);
4132 netdev_err(vif
->ndev
, "Failed to get TX PWR\n");
4134 wait_for_completion(&hif_wait_response
);
4135 *tx_power
= msg
.body
.tx_power
.tx_pwr
;