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 memcpy(hif_drv
->usr_conn_req
.bssid
, conn_attr
->bssid
, 6);
950 hif_drv
->usr_conn_req
.ssid_len
= conn_attr
->ssid_len
;
951 if (conn_attr
->ssid
) {
952 hif_drv
->usr_conn_req
.ssid
= kmalloc(conn_attr
->ssid_len
+ 1,
954 memcpy(hif_drv
->usr_conn_req
.ssid
,
956 conn_attr
->ssid_len
);
957 hif_drv
->usr_conn_req
.ssid
[conn_attr
->ssid_len
] = '\0';
960 hif_drv
->usr_conn_req
.ies_len
= conn_attr
->ies_len
;
961 if (conn_attr
->ies
) {
962 hif_drv
->usr_conn_req
.ies
= kmalloc(conn_attr
->ies_len
,
964 memcpy(hif_drv
->usr_conn_req
.ies
,
969 hif_drv
->usr_conn_req
.security
= conn_attr
->security
;
970 hif_drv
->usr_conn_req
.auth_type
= conn_attr
->auth_type
;
971 hif_drv
->usr_conn_req
.conn_result
= conn_attr
->result
;
972 hif_drv
->usr_conn_req
.arg
= conn_attr
->arg
;
974 wid_list
[wid_cnt
].id
= WID_SUCCESS_FRAME_COUNT
;
975 wid_list
[wid_cnt
].type
= WID_INT
;
976 wid_list
[wid_cnt
].size
= sizeof(u32
);
977 wid_list
[wid_cnt
].val
= (s8
*)(&(dummyval
));
980 wid_list
[wid_cnt
].id
= WID_RECEIVED_FRAGMENT_COUNT
;
981 wid_list
[wid_cnt
].type
= WID_INT
;
982 wid_list
[wid_cnt
].size
= sizeof(u32
);
983 wid_list
[wid_cnt
].val
= (s8
*)(&(dummyval
));
986 wid_list
[wid_cnt
].id
= WID_FAILED_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_INFO_ELEMENT_ASSOCIATE
;
993 wid_list
[wid_cnt
].type
= WID_BIN_DATA
;
994 wid_list
[wid_cnt
].val
= hif_drv
->usr_conn_req
.ies
;
995 wid_list
[wid_cnt
].size
= hif_drv
->usr_conn_req
.ies_len
;
998 if (memcmp("DIRECT-", conn_attr
->ssid
, 7)) {
999 info_element_size
= hif_drv
->usr_conn_req
.ies_len
;
1000 info_element
= kmalloc(info_element_size
, GFP_KERNEL
);
1001 memcpy(info_element
, hif_drv
->usr_conn_req
.ies
,
1004 wid_list
[wid_cnt
].id
= (u16
)WID_11I_MODE
;
1005 wid_list
[wid_cnt
].type
= WID_CHAR
;
1006 wid_list
[wid_cnt
].size
= sizeof(char);
1007 wid_list
[wid_cnt
].val
= (s8
*)&hif_drv
->usr_conn_req
.security
;
1010 if (memcmp("DIRECT-", conn_attr
->ssid
, 7))
1011 mode_11i
= hif_drv
->usr_conn_req
.security
;
1013 wid_list
[wid_cnt
].id
= (u16
)WID_AUTH_TYPE
;
1014 wid_list
[wid_cnt
].type
= WID_CHAR
;
1015 wid_list
[wid_cnt
].size
= sizeof(char);
1016 wid_list
[wid_cnt
].val
= (s8
*)&hif_drv
->usr_conn_req
.auth_type
;
1019 if (memcmp("DIRECT-", conn_attr
->ssid
, 7))
1020 auth_type
= (u8
)hif_drv
->usr_conn_req
.auth_type
;
1022 wid_list
[wid_cnt
].id
= (u16
)WID_JOIN_REQ_EXTENDED
;
1023 wid_list
[wid_cnt
].type
= WID_STR
;
1024 wid_list
[wid_cnt
].size
= 112;
1025 wid_list
[wid_cnt
].val
= kmalloc(wid_list
[wid_cnt
].size
, GFP_KERNEL
);
1027 if (memcmp("DIRECT-", conn_attr
->ssid
, 7)) {
1028 join_req_size
= wid_list
[wid_cnt
].size
;
1029 join_req
= kmalloc(join_req_size
, GFP_KERNEL
);
1031 if (!wid_list
[wid_cnt
].val
) {
1036 cur_byte
= wid_list
[wid_cnt
].val
;
1038 if (conn_attr
->ssid
) {
1039 memcpy(cur_byte
, conn_attr
->ssid
, conn_attr
->ssid_len
);
1040 cur_byte
[conn_attr
->ssid_len
] = '\0';
1042 cur_byte
+= MAX_SSID_LEN
;
1043 *(cur_byte
++) = INFRASTRUCTURE
;
1045 if (conn_attr
->ch
>= 1 && conn_attr
->ch
<= 14) {
1046 *(cur_byte
++) = conn_attr
->ch
;
1048 netdev_err(vif
->ndev
, "Channel out of range\n");
1049 *(cur_byte
++) = 0xFF;
1051 *(cur_byte
++) = (bss_param
->cap_info
) & 0xFF;
1052 *(cur_byte
++) = ((bss_param
->cap_info
) >> 8) & 0xFF;
1054 if (conn_attr
->bssid
)
1055 memcpy(cur_byte
, conn_attr
->bssid
, 6);
1058 if (conn_attr
->bssid
)
1059 memcpy(cur_byte
, conn_attr
->bssid
, 6);
1062 *(cur_byte
++) = (bss_param
->beacon_period
) & 0xFF;
1063 *(cur_byte
++) = ((bss_param
->beacon_period
) >> 8) & 0xFF;
1064 *(cur_byte
++) = bss_param
->dtim_period
;
1066 memcpy(cur_byte
, bss_param
->supp_rates
, MAX_RATES_SUPPORTED
+ 1);
1067 cur_byte
+= (MAX_RATES_SUPPORTED
+ 1);
1069 *(cur_byte
++) = bss_param
->wmm_cap
;
1070 *(cur_byte
++) = bss_param
->uapsd_cap
;
1072 *(cur_byte
++) = bss_param
->ht_capable
;
1073 hif_drv
->usr_conn_req
.ht_capable
= bss_param
->ht_capable
;
1075 *(cur_byte
++) = bss_param
->rsn_found
;
1076 *(cur_byte
++) = bss_param
->rsn_grp_policy
;
1077 *(cur_byte
++) = bss_param
->mode_802_11i
;
1079 memcpy(cur_byte
, bss_param
->rsn_pcip_policy
,
1080 sizeof(bss_param
->rsn_pcip_policy
));
1081 cur_byte
+= sizeof(bss_param
->rsn_pcip_policy
);
1083 memcpy(cur_byte
, bss_param
->rsn_auth_policy
,
1084 sizeof(bss_param
->rsn_auth_policy
));
1085 cur_byte
+= sizeof(bss_param
->rsn_auth_policy
);
1087 memcpy(cur_byte
, bss_param
->rsn_cap
, sizeof(bss_param
->rsn_cap
));
1088 cur_byte
+= sizeof(bss_param
->rsn_cap
);
1090 *(cur_byte
++) = REAL_JOIN_REQ
;
1091 *(cur_byte
++) = bss_param
->noa_enabled
;
1093 if (bss_param
->noa_enabled
) {
1094 *(cur_byte
++) = (bss_param
->tsf
) & 0xFF;
1095 *(cur_byte
++) = ((bss_param
->tsf
) >> 8) & 0xFF;
1096 *(cur_byte
++) = ((bss_param
->tsf
) >> 16) & 0xFF;
1097 *(cur_byte
++) = ((bss_param
->tsf
) >> 24) & 0xFF;
1099 *(cur_byte
++) = bss_param
->opp_enabled
;
1100 *(cur_byte
++) = bss_param
->idx
;
1102 if (bss_param
->opp_enabled
)
1103 *(cur_byte
++) = bss_param
->ct_window
;
1105 *(cur_byte
++) = bss_param
->cnt
;
1107 memcpy(cur_byte
, bss_param
->duration
,
1108 sizeof(bss_param
->duration
));
1109 cur_byte
+= sizeof(bss_param
->duration
);
1111 memcpy(cur_byte
, bss_param
->interval
,
1112 sizeof(bss_param
->interval
));
1113 cur_byte
+= sizeof(bss_param
->interval
);
1115 memcpy(cur_byte
, bss_param
->start_time
,
1116 sizeof(bss_param
->start_time
));
1117 cur_byte
+= sizeof(bss_param
->start_time
);
1120 cur_byte
= wid_list
[wid_cnt
].val
;
1123 if (memcmp("DIRECT-", conn_attr
->ssid
, 7)) {
1124 memcpy(join_req
, cur_byte
, join_req_size
);
1128 if (conn_attr
->bssid
)
1129 memcpy(wilc_connected_ssid
,
1130 conn_attr
->bssid
, ETH_ALEN
);
1132 result
= wilc_send_config_pkt(vif
, SET_CFG
, wid_list
,
1134 wilc_get_vif_idx(vif
));
1136 netdev_err(vif
->ndev
, "failed to send config packet\n");
1140 hif_drv
->hif_state
= HOST_IF_WAITING_CONN_RESP
;
1145 struct connect_info conn_info
;
1147 del_timer(&hif_drv
->connect_timer
);
1149 memset(&conn_info
, 0, sizeof(struct connect_info
));
1151 if (conn_attr
->result
) {
1152 if (conn_attr
->bssid
)
1153 memcpy(conn_info
.bssid
, conn_attr
->bssid
, 6);
1155 if (conn_attr
->ies
) {
1156 conn_info
.req_ies_len
= conn_attr
->ies_len
;
1157 conn_info
.req_ies
= kmalloc(conn_attr
->ies_len
,
1159 memcpy(conn_info
.req_ies
,
1161 conn_attr
->ies_len
);
1164 conn_attr
->result(CONN_DISCONN_EVENT_CONN_RESP
,
1169 hif_drv
->hif_state
= HOST_IF_IDLE
;
1170 kfree(conn_info
.req_ies
);
1171 conn_info
.req_ies
= NULL
;
1174 netdev_err(vif
->ndev
, "Connect callback is NULL\n");
1178 kfree(conn_attr
->bssid
);
1179 conn_attr
->bssid
= NULL
;
1181 kfree(conn_attr
->ssid
);
1182 conn_attr
->ssid
= NULL
;
1184 kfree(conn_attr
->ies
);
1185 conn_attr
->ies
= NULL
;
1191 static s32
handle_connect_timeout(struct wilc_vif
*vif
)
1194 struct connect_info info
;
1196 u16 dummy_reason_code
= 0;
1197 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
1200 netdev_err(vif
->ndev
, "Driver handler is NULL\n");
1204 hif_drv
->hif_state
= HOST_IF_IDLE
;
1206 scan_while_connected
= false;
1208 memset(&info
, 0, sizeof(struct connect_info
));
1210 if (hif_drv
->usr_conn_req
.conn_result
) {
1211 if (hif_drv
->usr_conn_req
.bssid
) {
1213 hif_drv
->usr_conn_req
.bssid
, 6);
1216 if (hif_drv
->usr_conn_req
.ies
) {
1217 info
.req_ies_len
= hif_drv
->usr_conn_req
.ies_len
;
1218 info
.req_ies
= kmalloc(hif_drv
->usr_conn_req
.ies_len
, GFP_KERNEL
);
1219 memcpy(info
.req_ies
,
1220 hif_drv
->usr_conn_req
.ies
,
1221 hif_drv
->usr_conn_req
.ies_len
);
1224 hif_drv
->usr_conn_req
.conn_result(CONN_DISCONN_EVENT_CONN_RESP
,
1228 hif_drv
->usr_conn_req
.arg
);
1230 kfree(info
.req_ies
);
1231 info
.req_ies
= NULL
;
1233 netdev_err(vif
->ndev
, "Connect callback is NULL\n");
1236 wid
.id
= (u16
)WID_DISCONNECT
;
1237 wid
.type
= WID_CHAR
;
1238 wid
.val
= (s8
*)&dummy_reason_code
;
1239 wid
.size
= sizeof(char);
1241 result
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
1242 wilc_get_vif_idx(vif
));
1244 netdev_err(vif
->ndev
, "Failed to send disconnect\n");
1246 hif_drv
->usr_conn_req
.ssid_len
= 0;
1247 kfree(hif_drv
->usr_conn_req
.ssid
);
1248 hif_drv
->usr_conn_req
.ssid
= NULL
;
1249 kfree(hif_drv
->usr_conn_req
.bssid
);
1250 hif_drv
->usr_conn_req
.bssid
= NULL
;
1251 hif_drv
->usr_conn_req
.ies_len
= 0;
1252 kfree(hif_drv
->usr_conn_req
.ies
);
1253 hif_drv
->usr_conn_req
.ies
= NULL
;
1255 eth_zero_addr(wilc_connected_ssid
);
1257 if (join_req
&& join_req_vif
== vif
) {
1262 if (info_element
&& join_req_vif
== vif
) {
1263 kfree(info_element
);
1264 info_element
= NULL
;
1270 static s32
handle_rcvd_ntwrk_info(struct wilc_vif
*vif
,
1271 struct rcvd_net_info
*rcvd_info
)
1276 struct network_info
*info
= NULL
;
1277 void *params
= NULL
;
1278 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
1279 struct user_scan_req
*scan_req
= &hif_drv
->usr_scan_req
;
1283 if (!scan_req
->scan_result
)
1286 wilc_parse_network_info(rcvd_info
->buffer
, &info
);
1287 if (!info
|| !scan_req
->scan_result
) {
1288 netdev_err(vif
->ndev
, "driver is null\n");
1293 for (i
= 0; i
< scan_req
->rcvd_ch_cnt
; i
++) {
1294 if (memcmp(scan_req
->net_info
[i
].bssid
, info
->bssid
, 6) == 0) {
1295 if (info
->rssi
<= scan_req
->net_info
[i
].rssi
) {
1298 scan_req
->net_info
[i
].rssi
= info
->rssi
;
1306 if (scan_req
->rcvd_ch_cnt
< MAX_NUM_SCANNED_NETWORKS
) {
1307 scan_req
->net_info
[scan_req
->rcvd_ch_cnt
].rssi
= info
->rssi
;
1309 memcpy(scan_req
->net_info
[scan_req
->rcvd_ch_cnt
].bssid
,
1312 scan_req
->rcvd_ch_cnt
++;
1314 info
->new_network
= true;
1315 params
= host_int_parse_join_bss_param(info
);
1317 scan_req
->scan_result(SCAN_EVENT_NETWORK_FOUND
, info
,
1318 scan_req
->arg
, params
);
1321 info
->new_network
= false;
1322 scan_req
->scan_result(SCAN_EVENT_NETWORK_FOUND
, info
,
1323 scan_req
->arg
, NULL
);
1327 kfree(rcvd_info
->buffer
);
1328 rcvd_info
->buffer
= NULL
;
1338 static s32
host_int_get_assoc_res_info(struct wilc_vif
*vif
,
1339 u8
*assoc_resp_info
,
1340 u32 max_assoc_resp_info_len
,
1341 u32
*rcvd_assoc_resp_info_len
);
1343 static s32
handle_rcvd_gnrl_async_info(struct wilc_vif
*vif
,
1344 struct rcvd_async_info
*rcvd_info
)
1350 u16 wid_id
= (u16
)WID_NIL
;
1353 u8 mac_status_reason_code
;
1354 u8 mac_status_additional_info
;
1355 struct connect_info conn_info
;
1356 struct disconnect_info disconn_info
;
1358 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
1361 netdev_err(vif
->ndev
, "Driver handler is NULL\n");
1365 if (hif_drv
->hif_state
== HOST_IF_WAITING_CONN_RESP
||
1366 hif_drv
->hif_state
== HOST_IF_CONNECTED
||
1367 hif_drv
->usr_scan_req
.scan_result
) {
1368 if (!rcvd_info
->buffer
||
1369 !hif_drv
->usr_conn_req
.conn_result
) {
1370 netdev_err(vif
->ndev
, "driver is null\n");
1374 msg_type
= rcvd_info
->buffer
[0];
1376 if ('I' != msg_type
) {
1377 netdev_err(vif
->ndev
, "Received Message incorrect.\n");
1381 msg_id
= rcvd_info
->buffer
[1];
1382 msg_len
= MAKE_WORD16(rcvd_info
->buffer
[2], rcvd_info
->buffer
[3]);
1383 wid_id
= MAKE_WORD16(rcvd_info
->buffer
[4], rcvd_info
->buffer
[5]);
1384 wid_len
= rcvd_info
->buffer
[6];
1385 mac_status
= rcvd_info
->buffer
[7];
1386 mac_status_reason_code
= rcvd_info
->buffer
[8];
1387 mac_status_additional_info
= rcvd_info
->buffer
[9];
1388 if (hif_drv
->hif_state
== HOST_IF_WAITING_CONN_RESP
) {
1389 u32 rcvd_assoc_resp_info_len
= 0;
1390 struct connect_resp_info
*connect_resp_info
= NULL
;
1392 memset(&conn_info
, 0, sizeof(struct connect_info
));
1394 if (mac_status
== MAC_CONNECTED
) {
1395 memset(rcv_assoc_resp
, 0, MAX_ASSOC_RESP_FRAME_SIZE
);
1397 host_int_get_assoc_res_info(vif
,
1399 MAX_ASSOC_RESP_FRAME_SIZE
,
1400 &rcvd_assoc_resp_info_len
);
1402 if (rcvd_assoc_resp_info_len
!= 0) {
1403 err
= wilc_parse_assoc_resp_info(rcv_assoc_resp
, rcvd_assoc_resp_info_len
,
1404 &connect_resp_info
);
1406 netdev_err(vif
->ndev
, "wilc_parse_assoc_resp_info() returned error %d\n", err
);
1408 conn_info
.status
= connect_resp_info
->status
;
1410 if (conn_info
.status
== SUCCESSFUL_STATUSCODE
&& connect_resp_info
->ies
) {
1411 conn_info
.resp_ies_len
= connect_resp_info
->ies_len
;
1412 conn_info
.resp_ies
= kmalloc(connect_resp_info
->ies_len
, GFP_KERNEL
);
1413 memcpy(conn_info
.resp_ies
, connect_resp_info
->ies
,
1414 connect_resp_info
->ies_len
);
1417 if (connect_resp_info
) {
1418 kfree(connect_resp_info
->ies
);
1419 kfree(connect_resp_info
);
1425 if (mac_status
== MAC_CONNECTED
&&
1426 conn_info
.status
!= SUCCESSFUL_STATUSCODE
) {
1427 netdev_err(vif
->ndev
, "Received MAC status is MAC_CONNECTED while the received status code in Asoc Resp is not SUCCESSFUL_STATUSCODE\n");
1428 eth_zero_addr(wilc_connected_ssid
);
1429 } else if (mac_status
== MAC_DISCONNECTED
) {
1430 netdev_err(vif
->ndev
, "Received MAC status is MAC_DISCONNECTED\n");
1431 eth_zero_addr(wilc_connected_ssid
);
1434 if (hif_drv
->usr_conn_req
.bssid
) {
1435 memcpy(conn_info
.bssid
, hif_drv
->usr_conn_req
.bssid
, 6);
1437 if (mac_status
== MAC_CONNECTED
&&
1438 conn_info
.status
== SUCCESSFUL_STATUSCODE
) {
1439 memcpy(hif_drv
->assoc_bssid
,
1440 hif_drv
->usr_conn_req
.bssid
, ETH_ALEN
);
1444 if (hif_drv
->usr_conn_req
.ies
) {
1445 conn_info
.req_ies_len
= hif_drv
->usr_conn_req
.ies_len
;
1446 conn_info
.req_ies
= kmalloc(hif_drv
->usr_conn_req
.ies_len
, GFP_KERNEL
);
1447 memcpy(conn_info
.req_ies
,
1448 hif_drv
->usr_conn_req
.ies
,
1449 hif_drv
->usr_conn_req
.ies_len
);
1452 del_timer(&hif_drv
->connect_timer
);
1453 hif_drv
->usr_conn_req
.conn_result(CONN_DISCONN_EVENT_CONN_RESP
,
1457 hif_drv
->usr_conn_req
.arg
);
1459 if (mac_status
== MAC_CONNECTED
&&
1460 conn_info
.status
== SUCCESSFUL_STATUSCODE
) {
1461 wilc_set_power_mgmt(vif
, 0, 0);
1463 hif_drv
->hif_state
= HOST_IF_CONNECTED
;
1465 wilc_optaining_ip
= true;
1466 mod_timer(&wilc_during_ip_timer
,
1467 jiffies
+ msecs_to_jiffies(10000));
1469 hif_drv
->hif_state
= HOST_IF_IDLE
;
1470 scan_while_connected
= false;
1473 kfree(conn_info
.resp_ies
);
1474 conn_info
.resp_ies
= NULL
;
1476 kfree(conn_info
.req_ies
);
1477 conn_info
.req_ies
= NULL
;
1478 hif_drv
->usr_conn_req
.ssid_len
= 0;
1479 kfree(hif_drv
->usr_conn_req
.ssid
);
1480 hif_drv
->usr_conn_req
.ssid
= NULL
;
1481 kfree(hif_drv
->usr_conn_req
.bssid
);
1482 hif_drv
->usr_conn_req
.bssid
= NULL
;
1483 hif_drv
->usr_conn_req
.ies_len
= 0;
1484 kfree(hif_drv
->usr_conn_req
.ies
);
1485 hif_drv
->usr_conn_req
.ies
= NULL
;
1486 } else if ((mac_status
== MAC_DISCONNECTED
) &&
1487 (hif_drv
->hif_state
== HOST_IF_CONNECTED
)) {
1488 memset(&disconn_info
, 0, sizeof(struct disconnect_info
));
1490 if (hif_drv
->usr_scan_req
.scan_result
) {
1491 del_timer(&hif_drv
->scan_timer
);
1492 handle_scan_done(vif
, SCAN_EVENT_ABORTED
);
1495 disconn_info
.reason
= 0;
1496 disconn_info
.ie
= NULL
;
1497 disconn_info
.ie_len
= 0;
1499 if (hif_drv
->usr_conn_req
.conn_result
) {
1500 wilc_optaining_ip
= false;
1501 wilc_set_power_mgmt(vif
, 0, 0);
1503 hif_drv
->usr_conn_req
.conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF
,
1507 hif_drv
->usr_conn_req
.arg
);
1509 netdev_err(vif
->ndev
, "Connect result NULL\n");
1512 eth_zero_addr(hif_drv
->assoc_bssid
);
1514 hif_drv
->usr_conn_req
.ssid_len
= 0;
1515 kfree(hif_drv
->usr_conn_req
.ssid
);
1516 hif_drv
->usr_conn_req
.ssid
= NULL
;
1517 kfree(hif_drv
->usr_conn_req
.bssid
);
1518 hif_drv
->usr_conn_req
.bssid
= NULL
;
1519 hif_drv
->usr_conn_req
.ies_len
= 0;
1520 kfree(hif_drv
->usr_conn_req
.ies
);
1521 hif_drv
->usr_conn_req
.ies
= NULL
;
1523 if (join_req
&& join_req_vif
== vif
) {
1528 if (info_element
&& join_req_vif
== vif
) {
1529 kfree(info_element
);
1530 info_element
= NULL
;
1533 hif_drv
->hif_state
= HOST_IF_IDLE
;
1534 scan_while_connected
= false;
1536 } else if ((mac_status
== MAC_DISCONNECTED
) &&
1537 (hif_drv
->usr_scan_req
.scan_result
)) {
1538 del_timer(&hif_drv
->scan_timer
);
1539 if (hif_drv
->usr_scan_req
.scan_result
)
1540 handle_scan_done(vif
, SCAN_EVENT_ABORTED
);
1544 kfree(rcvd_info
->buffer
);
1545 rcvd_info
->buffer
= NULL
;
1550 static int handle_key(struct wilc_vif
*vif
, struct key_attr
*hif_key
)
1554 struct wid wid_list
[5];
1559 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
1561 switch (hif_key
->type
) {
1564 if (hif_key
->action
& ADDKEY_AP
) {
1565 wid_list
[0].id
= (u16
)WID_11I_MODE
;
1566 wid_list
[0].type
= WID_CHAR
;
1567 wid_list
[0].size
= sizeof(char);
1568 wid_list
[0].val
= (s8
*)&hif_key
->attr
.wep
.mode
;
1570 wid_list
[1].id
= WID_AUTH_TYPE
;
1571 wid_list
[1].type
= WID_CHAR
;
1572 wid_list
[1].size
= sizeof(char);
1573 wid_list
[1].val
= (s8
*)&hif_key
->attr
.wep
.auth_type
;
1575 key_buf
= kmalloc(hif_key
->attr
.wep
.key_len
+ 2,
1580 key_buf
[0] = hif_key
->attr
.wep
.index
;
1581 key_buf
[1] = hif_key
->attr
.wep
.key_len
;
1583 memcpy(&key_buf
[2], hif_key
->attr
.wep
.key
,
1584 hif_key
->attr
.wep
.key_len
);
1586 kfree(hif_key
->attr
.wep
.key
);
1588 wid_list
[2].id
= (u16
)WID_WEP_KEY_VALUE
;
1589 wid_list
[2].type
= WID_STR
;
1590 wid_list
[2].size
= hif_key
->attr
.wep
.key_len
+ 2;
1591 wid_list
[2].val
= (s8
*)key_buf
;
1593 result
= wilc_send_config_pkt(vif
, SET_CFG
,
1595 wilc_get_vif_idx(vif
));
1597 } else if (hif_key
->action
& ADDKEY
) {
1598 key_buf
= kmalloc(hif_key
->attr
.wep
.key_len
+ 2, GFP_KERNEL
);
1601 key_buf
[0] = hif_key
->attr
.wep
.index
;
1602 memcpy(key_buf
+ 1, &hif_key
->attr
.wep
.key_len
, 1);
1603 memcpy(key_buf
+ 2, hif_key
->attr
.wep
.key
,
1604 hif_key
->attr
.wep
.key_len
);
1605 kfree(hif_key
->attr
.wep
.key
);
1607 wid
.id
= (u16
)WID_ADD_WEP_KEY
;
1609 wid
.val
= (s8
*)key_buf
;
1610 wid
.size
= hif_key
->attr
.wep
.key_len
+ 2;
1612 result
= wilc_send_config_pkt(vif
, SET_CFG
,
1614 wilc_get_vif_idx(vif
));
1616 } else if (hif_key
->action
& REMOVEKEY
) {
1617 wid
.id
= (u16
)WID_REMOVE_WEP_KEY
;
1620 s8idxarray
[0] = (s8
)hif_key
->attr
.wep
.index
;
1621 wid
.val
= s8idxarray
;
1624 result
= wilc_send_config_pkt(vif
, SET_CFG
,
1626 wilc_get_vif_idx(vif
));
1627 } else if (hif_key
->action
& DEFAULTKEY
) {
1628 wid
.id
= (u16
)WID_KEY_ID
;
1629 wid
.type
= WID_CHAR
;
1630 wid
.val
= (s8
*)&hif_key
->attr
.wep
.index
;
1631 wid
.size
= sizeof(char);
1633 result
= wilc_send_config_pkt(vif
, SET_CFG
,
1635 wilc_get_vif_idx(vif
));
1637 complete(&hif_drv
->comp_test_key_block
);
1641 if (hif_key
->action
& ADDKEY_AP
) {
1642 key_buf
= kzalloc(RX_MIC_KEY_MSG_LEN
, GFP_KERNEL
);
1645 goto out_wpa_rx_gtk
;
1648 if (hif_key
->attr
.wpa
.seq
)
1649 memcpy(key_buf
+ 6, hif_key
->attr
.wpa
.seq
, 8);
1651 memcpy(key_buf
+ 14, &hif_key
->attr
.wpa
.index
, 1);
1652 memcpy(key_buf
+ 15, &hif_key
->attr
.wpa
.key_len
, 1);
1653 memcpy(key_buf
+ 16, hif_key
->attr
.wpa
.key
,
1654 hif_key
->attr
.wpa
.key_len
);
1656 wid_list
[0].id
= (u16
)WID_11I_MODE
;
1657 wid_list
[0].type
= WID_CHAR
;
1658 wid_list
[0].size
= sizeof(char);
1659 wid_list
[0].val
= (s8
*)&hif_key
->attr
.wpa
.mode
;
1661 wid_list
[1].id
= (u16
)WID_ADD_RX_GTK
;
1662 wid_list
[1].type
= WID_STR
;
1663 wid_list
[1].val
= (s8
*)key_buf
;
1664 wid_list
[1].size
= RX_MIC_KEY_MSG_LEN
;
1666 result
= wilc_send_config_pkt(vif
, SET_CFG
,
1668 wilc_get_vif_idx(vif
));
1671 complete(&hif_drv
->comp_test_key_block
);
1672 } else if (hif_key
->action
& ADDKEY
) {
1673 key_buf
= kzalloc(RX_MIC_KEY_MSG_LEN
, GFP_KERNEL
);
1676 goto out_wpa_rx_gtk
;
1679 if (hif_drv
->hif_state
== HOST_IF_CONNECTED
)
1680 memcpy(key_buf
, hif_drv
->assoc_bssid
, ETH_ALEN
);
1682 netdev_err(vif
->ndev
, "Couldn't handle\n");
1684 memcpy(key_buf
+ 6, hif_key
->attr
.wpa
.seq
, 8);
1685 memcpy(key_buf
+ 14, &hif_key
->attr
.wpa
.index
, 1);
1686 memcpy(key_buf
+ 15, &hif_key
->attr
.wpa
.key_len
, 1);
1687 memcpy(key_buf
+ 16, hif_key
->attr
.wpa
.key
,
1688 hif_key
->attr
.wpa
.key_len
);
1690 wid
.id
= (u16
)WID_ADD_RX_GTK
;
1692 wid
.val
= (s8
*)key_buf
;
1693 wid
.size
= RX_MIC_KEY_MSG_LEN
;
1695 result
= wilc_send_config_pkt(vif
, SET_CFG
,
1697 wilc_get_vif_idx(vif
));
1700 complete(&hif_drv
->comp_test_key_block
);
1703 kfree(hif_key
->attr
.wpa
.key
);
1704 kfree(hif_key
->attr
.wpa
.seq
);
1711 if (hif_key
->action
& ADDKEY_AP
) {
1712 key_buf
= kmalloc(PTK_KEY_MSG_LEN
+ 1, GFP_KERNEL
);
1718 memcpy(key_buf
, hif_key
->attr
.wpa
.mac_addr
, 6);
1719 memcpy(key_buf
+ 6, &hif_key
->attr
.wpa
.index
, 1);
1720 memcpy(key_buf
+ 7, &hif_key
->attr
.wpa
.key_len
, 1);
1721 memcpy(key_buf
+ 8, hif_key
->attr
.wpa
.key
,
1722 hif_key
->attr
.wpa
.key_len
);
1724 wid_list
[0].id
= (u16
)WID_11I_MODE
;
1725 wid_list
[0].type
= WID_CHAR
;
1726 wid_list
[0].size
= sizeof(char);
1727 wid_list
[0].val
= (s8
*)&hif_key
->attr
.wpa
.mode
;
1729 wid_list
[1].id
= (u16
)WID_ADD_PTK
;
1730 wid_list
[1].type
= WID_STR
;
1731 wid_list
[1].val
= (s8
*)key_buf
;
1732 wid_list
[1].size
= PTK_KEY_MSG_LEN
+ 1;
1734 result
= wilc_send_config_pkt(vif
, SET_CFG
,
1736 wilc_get_vif_idx(vif
));
1738 complete(&hif_drv
->comp_test_key_block
);
1739 } else if (hif_key
->action
& ADDKEY
) {
1740 key_buf
= kmalloc(PTK_KEY_MSG_LEN
, GFP_KERNEL
);
1742 netdev_err(vif
->ndev
, "No buffer send PTK\n");
1747 memcpy(key_buf
, hif_key
->attr
.wpa
.mac_addr
, 6);
1748 memcpy(key_buf
+ 6, &hif_key
->attr
.wpa
.key_len
, 1);
1749 memcpy(key_buf
+ 7, hif_key
->attr
.wpa
.key
,
1750 hif_key
->attr
.wpa
.key_len
);
1752 wid
.id
= (u16
)WID_ADD_PTK
;
1754 wid
.val
= (s8
*)key_buf
;
1755 wid
.size
= PTK_KEY_MSG_LEN
;
1757 result
= wilc_send_config_pkt(vif
, SET_CFG
,
1759 wilc_get_vif_idx(vif
));
1761 complete(&hif_drv
->comp_test_key_block
);
1765 kfree(hif_key
->attr
.wpa
.key
);
1772 key_buf
= kmalloc((hif_key
->attr
.pmkid
.numpmkid
* PMKSA_KEY_LEN
) + 1, GFP_KERNEL
);
1776 key_buf
[0] = hif_key
->attr
.pmkid
.numpmkid
;
1778 for (i
= 0; i
< hif_key
->attr
.pmkid
.numpmkid
; i
++) {
1779 memcpy(key_buf
+ ((PMKSA_KEY_LEN
* i
) + 1), hif_key
->attr
.pmkid
.pmkidlist
[i
].bssid
, ETH_ALEN
);
1780 memcpy(key_buf
+ ((PMKSA_KEY_LEN
* i
) + ETH_ALEN
+ 1), hif_key
->attr
.pmkid
.pmkidlist
[i
].pmkid
, PMKID_LEN
);
1783 wid
.id
= (u16
)WID_PMKID_INFO
;
1785 wid
.val
= (s8
*)key_buf
;
1786 wid
.size
= (hif_key
->attr
.pmkid
.numpmkid
* PMKSA_KEY_LEN
) + 1;
1788 result
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
1789 wilc_get_vif_idx(vif
));
1796 netdev_err(vif
->ndev
, "Failed to send key config packet\n");
1801 static void handle_disconnect(struct wilc_vif
*vif
)
1804 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
1805 struct disconnect_info disconn_info
;
1806 struct user_scan_req
*scan_req
;
1807 struct user_conn_req
*conn_req
;
1809 u16 dummy_reason_code
= 0;
1811 wid
.id
= (u16
)WID_DISCONNECT
;
1812 wid
.type
= WID_CHAR
;
1813 wid
.val
= (s8
*)&dummy_reason_code
;
1814 wid
.size
= sizeof(char);
1816 wilc_optaining_ip
= false;
1817 wilc_set_power_mgmt(vif
, 0, 0);
1819 eth_zero_addr(wilc_connected_ssid
);
1821 result
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
1822 wilc_get_vif_idx(vif
));
1825 netdev_err(vif
->ndev
, "Failed to send dissconect\n");
1829 memset(&disconn_info
, 0, sizeof(struct disconnect_info
));
1831 disconn_info
.reason
= 0;
1832 disconn_info
.ie
= NULL
;
1833 disconn_info
.ie_len
= 0;
1834 scan_req
= &hif_drv
->usr_scan_req
;
1835 conn_req
= &hif_drv
->usr_conn_req
;
1837 if (scan_req
->scan_result
) {
1838 del_timer(&hif_drv
->scan_timer
);
1839 scan_req
->scan_result(SCAN_EVENT_ABORTED
, NULL
, scan_req
->arg
,
1841 scan_req
->scan_result
= NULL
;
1844 if (conn_req
->conn_result
) {
1845 if (hif_drv
->hif_state
== HOST_IF_WAITING_CONN_RESP
)
1846 del_timer(&hif_drv
->connect_timer
);
1848 conn_req
->conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF
, NULL
,
1849 0, &disconn_info
, conn_req
->arg
);
1851 netdev_err(vif
->ndev
, "conn_result = NULL\n");
1854 scan_while_connected
= false;
1856 hif_drv
->hif_state
= HOST_IF_IDLE
;
1858 eth_zero_addr(hif_drv
->assoc_bssid
);
1860 conn_req
->ssid_len
= 0;
1861 kfree(conn_req
->ssid
);
1862 conn_req
->ssid
= NULL
;
1863 kfree(conn_req
->bssid
);
1864 conn_req
->bssid
= NULL
;
1865 conn_req
->ies_len
= 0;
1866 kfree(conn_req
->ies
);
1867 conn_req
->ies
= NULL
;
1869 if (join_req
&& join_req_vif
== vif
) {
1874 if (info_element
&& join_req_vif
== vif
) {
1875 kfree(info_element
);
1876 info_element
= NULL
;
1881 complete(&hif_drv
->comp_test_disconn_block
);
1884 void wilc_resolve_disconnect_aberration(struct wilc_vif
*vif
)
1888 if (vif
->hif_drv
->hif_state
== HOST_IF_WAITING_CONN_RESP
||
1889 vif
->hif_drv
->hif_state
== HOST_IF_CONNECTING
)
1890 wilc_disconnect(vif
, 1);
1893 static void handle_get_rssi(struct wilc_vif
*vif
)
1898 wid
.id
= (u16
)WID_RSSI
;
1899 wid
.type
= WID_CHAR
;
1901 wid
.size
= sizeof(char);
1903 result
= wilc_send_config_pkt(vif
, GET_CFG
, &wid
, 1,
1904 wilc_get_vif_idx(vif
));
1906 netdev_err(vif
->ndev
, "Failed to get RSSI value\n");
1910 complete(&vif
->hif_drv
->comp_get_rssi
);
1913 static s32
handle_get_statistics(struct wilc_vif
*vif
,
1914 struct rf_info
*stats
)
1916 struct wid wid_list
[5];
1917 u32 wid_cnt
= 0, result
= 0;
1919 wid_list
[wid_cnt
].id
= WID_LINKSPEED
;
1920 wid_list
[wid_cnt
].type
= WID_CHAR
;
1921 wid_list
[wid_cnt
].size
= sizeof(char);
1922 wid_list
[wid_cnt
].val
= (s8
*)&stats
->link_speed
;
1925 wid_list
[wid_cnt
].id
= WID_RSSI
;
1926 wid_list
[wid_cnt
].type
= WID_CHAR
;
1927 wid_list
[wid_cnt
].size
= sizeof(char);
1928 wid_list
[wid_cnt
].val
= (s8
*)&stats
->rssi
;
1931 wid_list
[wid_cnt
].id
= WID_SUCCESS_FRAME_COUNT
;
1932 wid_list
[wid_cnt
].type
= WID_INT
;
1933 wid_list
[wid_cnt
].size
= sizeof(u32
);
1934 wid_list
[wid_cnt
].val
= (s8
*)&stats
->tx_cnt
;
1937 wid_list
[wid_cnt
].id
= WID_RECEIVED_FRAGMENT_COUNT
;
1938 wid_list
[wid_cnt
].type
= WID_INT
;
1939 wid_list
[wid_cnt
].size
= sizeof(u32
);
1940 wid_list
[wid_cnt
].val
= (s8
*)&stats
->rx_cnt
;
1943 wid_list
[wid_cnt
].id
= WID_FAILED_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_fail_cnt
;
1949 result
= wilc_send_config_pkt(vif
, GET_CFG
, wid_list
,
1951 wilc_get_vif_idx(vif
));
1954 netdev_err(vif
->ndev
, "Failed to send scan parameters\n");
1956 if (stats
->link_speed
> TCP_ACK_FILTER_LINK_SPEED_THRESH
&&
1957 stats
->link_speed
!= DEFAULT_LINK_SPEED
)
1958 wilc_enable_tcp_ack_filter(true);
1959 else if (stats
->link_speed
!= DEFAULT_LINK_SPEED
)
1960 wilc_enable_tcp_ack_filter(false);
1962 if (stats
!= &vif
->wilc
->dummy_statistics
)
1963 complete(&hif_wait_response
);
1967 static s32
handle_get_inactive_time(struct wilc_vif
*vif
,
1968 struct sta_inactive_t
*hif_sta_inactive
)
1973 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
1975 wid
.id
= (u16
)WID_SET_STA_MAC_INACTIVE_TIME
;
1977 wid
.size
= ETH_ALEN
;
1978 wid
.val
= kmalloc(wid
.size
, GFP_KERNEL
);
1983 ether_addr_copy(stamac
, hif_sta_inactive
->mac
);
1985 result
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
1986 wilc_get_vif_idx(vif
));
1989 netdev_err(vif
->ndev
, "Failed to SET inactive time\n");
1993 wid
.id
= (u16
)WID_GET_INACTIVE_TIME
;
1995 wid
.val
= (s8
*)&inactive_time
;
1996 wid
.size
= sizeof(u32
);
1998 result
= wilc_send_config_pkt(vif
, GET_CFG
, &wid
, 1,
1999 wilc_get_vif_idx(vif
));
2002 netdev_err(vif
->ndev
, "Failed to get inactive time\n");
2006 complete(&hif_drv
->comp_inactive_time
);
2011 static void handle_add_beacon(struct wilc_vif
*vif
, struct beacon_attr
*param
)
2017 wid
.id
= (u16
)WID_ADD_BEACON
;
2019 wid
.size
= param
->head_len
+ param
->tail_len
+ 16;
2020 wid
.val
= kmalloc(wid
.size
, GFP_KERNEL
);
2025 *cur_byte
++ = (param
->interval
& 0xFF);
2026 *cur_byte
++ = ((param
->interval
>> 8) & 0xFF);
2027 *cur_byte
++ = ((param
->interval
>> 16) & 0xFF);
2028 *cur_byte
++ = ((param
->interval
>> 24) & 0xFF);
2030 *cur_byte
++ = (param
->dtim_period
& 0xFF);
2031 *cur_byte
++ = ((param
->dtim_period
>> 8) & 0xFF);
2032 *cur_byte
++ = ((param
->dtim_period
>> 16) & 0xFF);
2033 *cur_byte
++ = ((param
->dtim_period
>> 24) & 0xFF);
2035 *cur_byte
++ = (param
->head_len
& 0xFF);
2036 *cur_byte
++ = ((param
->head_len
>> 8) & 0xFF);
2037 *cur_byte
++ = ((param
->head_len
>> 16) & 0xFF);
2038 *cur_byte
++ = ((param
->head_len
>> 24) & 0xFF);
2040 memcpy(cur_byte
, param
->head
, param
->head_len
);
2041 cur_byte
+= param
->head_len
;
2043 *cur_byte
++ = (param
->tail_len
& 0xFF);
2044 *cur_byte
++ = ((param
->tail_len
>> 8) & 0xFF);
2045 *cur_byte
++ = ((param
->tail_len
>> 16) & 0xFF);
2046 *cur_byte
++ = ((param
->tail_len
>> 24) & 0xFF);
2049 memcpy(cur_byte
, param
->tail
, param
->tail_len
);
2050 cur_byte
+= param
->tail_len
;
2052 result
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
2053 wilc_get_vif_idx(vif
));
2055 netdev_err(vif
->ndev
, "Failed to send add beacon\n");
2063 static void handle_del_beacon(struct wilc_vif
*vif
)
2069 wid
.id
= (u16
)WID_DEL_BEACON
;
2070 wid
.type
= WID_CHAR
;
2071 wid
.size
= sizeof(char);
2072 wid
.val
= &del_beacon
;
2079 result
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
2080 wilc_get_vif_idx(vif
));
2082 netdev_err(vif
->ndev
, "Failed to send delete beacon\n");
2085 static u32
wilc_hif_pack_sta_param(u8
*buff
, struct add_sta_param
*param
)
2091 memcpy(cur_byte
, param
->bssid
, ETH_ALEN
);
2092 cur_byte
+= ETH_ALEN
;
2094 *cur_byte
++ = param
->aid
& 0xFF;
2095 *cur_byte
++ = (param
->aid
>> 8) & 0xFF;
2097 *cur_byte
++ = param
->rates_len
;
2098 if (param
->rates_len
> 0)
2099 memcpy(cur_byte
, param
->rates
, param
->rates_len
);
2100 cur_byte
+= param
->rates_len
;
2102 *cur_byte
++ = param
->ht_supported
;
2103 memcpy(cur_byte
, ¶m
->ht_capa
, sizeof(struct ieee80211_ht_cap
));
2104 cur_byte
+= sizeof(struct ieee80211_ht_cap
);
2106 *cur_byte
++ = param
->flags_mask
& 0xFF;
2107 *cur_byte
++ = (param
->flags_mask
>> 8) & 0xFF;
2109 *cur_byte
++ = param
->flags_set
& 0xFF;
2110 *cur_byte
++ = (param
->flags_set
>> 8) & 0xFF;
2112 return cur_byte
- buff
;
2115 static void handle_add_station(struct wilc_vif
*vif
,
2116 struct add_sta_param
*param
)
2122 wid
.id
= (u16
)WID_ADD_STA
;
2124 wid
.size
= WILC_ADD_STA_LENGTH
+ param
->rates_len
;
2126 wid
.val
= kmalloc(wid
.size
, GFP_KERNEL
);
2131 cur_byte
+= wilc_hif_pack_sta_param(cur_byte
, param
);
2133 result
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
2134 wilc_get_vif_idx(vif
));
2136 netdev_err(vif
->ndev
, "Failed to send add station\n");
2139 kfree(param
->rates
);
2143 static void handle_del_all_sta(struct wilc_vif
*vif
,
2144 struct del_all_sta
*param
)
2150 u8 zero_buff
[6] = {0};
2152 wid
.id
= (u16
)WID_DEL_ALL_STA
;
2154 wid
.size
= (param
->assoc_sta
* ETH_ALEN
) + 1;
2156 wid
.val
= kmalloc((param
->assoc_sta
* ETH_ALEN
) + 1, GFP_KERNEL
);
2160 curr_byte
= wid
.val
;
2162 *(curr_byte
++) = param
->assoc_sta
;
2164 for (i
= 0; i
< MAX_NUM_STA
; i
++) {
2165 if (memcmp(param
->del_all_sta
[i
], zero_buff
, ETH_ALEN
))
2166 memcpy(curr_byte
, param
->del_all_sta
[i
], ETH_ALEN
);
2170 curr_byte
+= ETH_ALEN
;
2173 result
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
2174 wilc_get_vif_idx(vif
));
2176 netdev_err(vif
->ndev
, "Failed to send add station\n");
2181 complete(&hif_wait_response
);
2184 static void handle_del_station(struct wilc_vif
*vif
, struct del_sta
*param
)
2190 wid
.id
= (u16
)WID_REMOVE_STA
;
2192 wid
.size
= ETH_ALEN
;
2194 wid
.val
= kmalloc(wid
.size
, GFP_KERNEL
);
2200 ether_addr_copy(cur_byte
, param
->mac_addr
);
2202 result
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
2203 wilc_get_vif_idx(vif
));
2205 netdev_err(vif
->ndev
, "Failed to send add station\n");
2211 static void handle_edit_station(struct wilc_vif
*vif
,
2212 struct add_sta_param
*param
)
2218 wid
.id
= (u16
)WID_EDIT_STA
;
2220 wid
.size
= WILC_ADD_STA_LENGTH
+ param
->rates_len
;
2222 wid
.val
= kmalloc(wid
.size
, GFP_KERNEL
);
2227 cur_byte
+= wilc_hif_pack_sta_param(cur_byte
, param
);
2229 result
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
2230 wilc_get_vif_idx(vif
));
2232 netdev_err(vif
->ndev
, "Failed to send edit station\n");
2235 kfree(param
->rates
);
2239 static int handle_remain_on_chan(struct wilc_vif
*vif
,
2240 struct remain_ch
*hif_remain_ch
)
2243 u8 remain_on_chan_flag
;
2245 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
2247 if (!hif_drv
->remain_on_ch_pending
) {
2248 hif_drv
->remain_on_ch
.arg
= hif_remain_ch
->arg
;
2249 hif_drv
->remain_on_ch
.expired
= hif_remain_ch
->expired
;
2250 hif_drv
->remain_on_ch
.ready
= hif_remain_ch
->ready
;
2251 hif_drv
->remain_on_ch
.ch
= hif_remain_ch
->ch
;
2252 hif_drv
->remain_on_ch
.id
= hif_remain_ch
->id
;
2254 hif_remain_ch
->ch
= hif_drv
->remain_on_ch
.ch
;
2257 if (hif_drv
->usr_scan_req
.scan_result
) {
2258 hif_drv
->remain_on_ch_pending
= 1;
2262 if (hif_drv
->hif_state
== HOST_IF_WAITING_CONN_RESP
) {
2267 if (wilc_optaining_ip
|| wilc_connecting
) {
2272 remain_on_chan_flag
= true;
2273 wid
.id
= (u16
)WID_REMAIN_ON_CHAN
;
2276 wid
.val
= kmalloc(wid
.size
, GFP_KERNEL
);
2282 wid
.val
[0] = remain_on_chan_flag
;
2283 wid
.val
[1] = (s8
)hif_remain_ch
->ch
;
2285 result
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
2286 wilc_get_vif_idx(vif
));
2288 netdev_err(vif
->ndev
, "Failed to set remain on channel\n");
2292 P2P_LISTEN_STATE
= 1;
2293 hif_drv
->remain_on_ch_timer_vif
= vif
;
2294 mod_timer(&hif_drv
->remain_on_ch_timer
,
2296 msecs_to_jiffies(hif_remain_ch
->duration
));
2298 if (hif_drv
->remain_on_ch
.ready
)
2299 hif_drv
->remain_on_ch
.ready(hif_drv
->remain_on_ch
.arg
);
2301 if (hif_drv
->remain_on_ch_pending
)
2302 hif_drv
->remain_on_ch_pending
= 0;
2308 static int handle_register_frame(struct wilc_vif
*vif
,
2309 struct reg_frame
*hif_reg_frame
)
2315 wid
.id
= (u16
)WID_REGISTER_FRAME
;
2317 wid
.val
= kmalloc(sizeof(u16
) + 2, GFP_KERNEL
);
2323 *cur_byte
++ = hif_reg_frame
->reg
;
2324 *cur_byte
++ = hif_reg_frame
->reg_id
;
2325 memcpy(cur_byte
, &hif_reg_frame
->frame_type
, sizeof(u16
));
2327 wid
.size
= sizeof(u16
) + 2;
2329 result
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
2330 wilc_get_vif_idx(vif
));
2332 netdev_err(vif
->ndev
, "Failed to frame register\n");
2339 static u32
handle_listen_state_expired(struct wilc_vif
*vif
,
2340 struct remain_ch
*hif_remain_ch
)
2342 u8 remain_on_chan_flag
;
2345 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
2347 if (P2P_LISTEN_STATE
) {
2348 remain_on_chan_flag
= false;
2349 wid
.id
= (u16
)WID_REMAIN_ON_CHAN
;
2352 wid
.val
= kmalloc(wid
.size
, GFP_KERNEL
);
2357 wid
.val
[0] = remain_on_chan_flag
;
2358 wid
.val
[1] = FALSE_FRMWR_CHANNEL
;
2360 result
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
2361 wilc_get_vif_idx(vif
));
2363 netdev_err(vif
->ndev
, "Failed to set remain channel\n");
2367 if (hif_drv
->remain_on_ch
.expired
) {
2368 hif_drv
->remain_on_ch
.expired(hif_drv
->remain_on_ch
.arg
,
2371 P2P_LISTEN_STATE
= 0;
2373 netdev_dbg(vif
->ndev
, "Not in listen state\n");
2381 static void listen_timer_cb(struct timer_list
*t
)
2383 struct host_if_drv
*hif_drv
= from_timer(hif_drv
, t
,
2384 remain_on_ch_timer
);
2385 struct wilc_vif
*vif
= hif_drv
->remain_on_ch_timer_vif
;
2387 struct host_if_msg msg
;
2389 del_timer(&vif
->hif_drv
->remain_on_ch_timer
);
2391 memset(&msg
, 0, sizeof(struct host_if_msg
));
2392 msg
.id
= HOST_IF_MSG_LISTEN_TIMER_FIRED
;
2394 msg
.body
.remain_on_ch
.id
= vif
->hif_drv
->remain_on_ch
.id
;
2396 result
= wilc_enqueue_cmd(&msg
);
2398 netdev_err(vif
->ndev
, "wilc_mq_send fail\n");
2401 static void handle_power_management(struct wilc_vif
*vif
,
2402 struct power_mgmt_param
*pm_param
)
2408 wid
.id
= (u16
)WID_POWER_MANAGEMENT
;
2410 if (pm_param
->enabled
)
2411 power_mode
= MIN_FAST_PS
;
2413 power_mode
= NO_POWERSAVE
;
2415 wid
.val
= &power_mode
;
2416 wid
.size
= sizeof(char);
2418 result
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
2419 wilc_get_vif_idx(vif
));
2421 netdev_err(vif
->ndev
, "Failed to send power management\n");
2424 static void handle_set_mcast_filter(struct wilc_vif
*vif
,
2425 struct set_multicast
*hif_set_mc
)
2431 wid
.id
= (u16
)WID_SETUP_MULTICAST_FILTER
;
2433 wid
.size
= sizeof(struct set_multicast
) + (hif_set_mc
->cnt
* ETH_ALEN
);
2434 wid
.val
= kmalloc(wid
.size
, GFP_KERNEL
);
2439 *cur_byte
++ = (hif_set_mc
->enabled
& 0xFF);
2444 *cur_byte
++ = (hif_set_mc
->cnt
& 0xFF);
2445 *cur_byte
++ = ((hif_set_mc
->cnt
>> 8) & 0xFF);
2446 *cur_byte
++ = ((hif_set_mc
->cnt
>> 16) & 0xFF);
2447 *cur_byte
++ = ((hif_set_mc
->cnt
>> 24) & 0xFF);
2449 if (hif_set_mc
->cnt
> 0)
2450 memcpy(cur_byte
, wilc_multicast_mac_addr_list
,
2451 ((hif_set_mc
->cnt
) * ETH_ALEN
));
2453 result
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
2454 wilc_get_vif_idx(vif
));
2456 netdev_err(vif
->ndev
, "Failed to send setup multicast\n");
2462 static void handle_set_tx_pwr(struct wilc_vif
*vif
, u8 tx_pwr
)
2467 wid
.id
= (u16
)WID_TX_POWER
;
2468 wid
.type
= WID_CHAR
;
2470 wid
.size
= sizeof(char);
2472 ret
= wilc_send_config_pkt(vif
, SET_CFG
, &wid
, 1,
2473 wilc_get_vif_idx(vif
));
2475 netdev_err(vif
->ndev
, "Failed to set TX PWR\n");
2478 static void handle_get_tx_pwr(struct wilc_vif
*vif
, u8
*tx_pwr
)
2483 wid
.id
= (u16
)WID_TX_POWER
;
2484 wid
.type
= WID_CHAR
;
2485 wid
.val
= (s8
*)tx_pwr
;
2486 wid
.size
= sizeof(char);
2488 ret
= wilc_send_config_pkt(vif
, GET_CFG
, &wid
, 1,
2489 wilc_get_vif_idx(vif
));
2491 netdev_err(vif
->ndev
, "Failed to get TX PWR\n");
2493 complete(&hif_wait_response
);
2496 static void host_if_work(struct work_struct
*work
)
2498 struct host_if_msg
*msg
;
2502 msg
= container_of(work
, struct host_if_msg
, work
);
2503 wilc
= msg
->vif
->wilc
;
2505 if (msg
->id
== HOST_IF_MSG_CONNECT
&&
2506 msg
->vif
->hif_drv
->usr_scan_req
.scan_result
) {
2507 wilc_enqueue_cmd(msg
);
2508 usleep_range(2 * 1000, 2 * 1000);
2512 case HOST_IF_MSG_SCAN
:
2513 handle_scan(msg
->vif
, &msg
->body
.scan_info
);
2516 case HOST_IF_MSG_CONNECT
:
2517 handle_connect(msg
->vif
, &msg
->body
.con_info
);
2520 case HOST_IF_MSG_RCVD_NTWRK_INFO
:
2521 handle_rcvd_ntwrk_info(msg
->vif
, &msg
->body
.net_info
);
2524 case HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO
:
2525 handle_rcvd_gnrl_async_info(msg
->vif
,
2526 &msg
->body
.async_info
);
2529 case HOST_IF_MSG_KEY
:
2530 handle_key(msg
->vif
, &msg
->body
.key_info
);
2533 case HOST_IF_MSG_CFG_PARAMS
:
2534 handle_cfg_param(msg
->vif
, &msg
->body
.cfg_info
);
2537 case HOST_IF_MSG_SET_CHANNEL
:
2538 handle_set_channel(msg
->vif
, &msg
->body
.channel_info
);
2541 case HOST_IF_MSG_DISCONNECT
:
2542 handle_disconnect(msg
->vif
);
2545 case HOST_IF_MSG_RCVD_SCAN_COMPLETE
:
2546 del_timer(&msg
->vif
->hif_drv
->scan_timer
);
2548 if (!wilc_wlan_get_num_conn_ifcs(wilc
))
2549 wilc_chip_sleep_manually(wilc
);
2551 handle_scan_done(msg
->vif
, SCAN_EVENT_DONE
);
2553 if (msg
->vif
->hif_drv
->remain_on_ch_pending
)
2554 handle_remain_on_chan(msg
->vif
,
2555 &msg
->body
.remain_on_ch
);
2559 case HOST_IF_MSG_GET_RSSI
:
2560 handle_get_rssi(msg
->vif
);
2563 case HOST_IF_MSG_GET_STATISTICS
:
2564 handle_get_statistics(msg
->vif
,
2565 (struct rf_info
*)msg
->body
.data
);
2568 case HOST_IF_MSG_ADD_BEACON
:
2569 handle_add_beacon(msg
->vif
, &msg
->body
.beacon_info
);
2572 case HOST_IF_MSG_DEL_BEACON
:
2573 handle_del_beacon(msg
->vif
);
2576 case HOST_IF_MSG_ADD_STATION
:
2577 handle_add_station(msg
->vif
, &msg
->body
.add_sta_info
);
2580 case HOST_IF_MSG_DEL_STATION
:
2581 handle_del_station(msg
->vif
, &msg
->body
.del_sta_info
);
2584 case HOST_IF_MSG_EDIT_STATION
:
2585 handle_edit_station(msg
->vif
, &msg
->body
.edit_sta_info
);
2588 case HOST_IF_MSG_GET_INACTIVETIME
:
2589 handle_get_inactive_time(msg
->vif
, &msg
->body
.mac_info
);
2592 case HOST_IF_MSG_SCAN_TIMER_FIRED
:
2593 handle_scan_done(msg
->vif
, SCAN_EVENT_ABORTED
);
2596 case HOST_IF_MSG_CONNECT_TIMER_FIRED
:
2597 handle_connect_timeout(msg
->vif
);
2600 case HOST_IF_MSG_POWER_MGMT
:
2601 handle_power_management(msg
->vif
,
2602 &msg
->body
.pwr_mgmt_info
);
2605 case HOST_IF_MSG_SET_WFIDRV_HANDLER
:
2606 ret
= handle_set_wfi_drv_handler(msg
->vif
, &msg
->body
.drv
);
2609 case HOST_IF_MSG_SET_OPERATION_MODE
:
2610 handle_set_operation_mode(msg
->vif
, &msg
->body
.mode
);
2613 case HOST_IF_MSG_SET_IPADDRESS
:
2614 handle_set_ip_address(msg
->vif
,
2615 msg
->body
.ip_info
.ip_addr
,
2616 msg
->body
.ip_info
.idx
);
2619 case HOST_IF_MSG_GET_IPADDRESS
:
2620 handle_get_ip_address(msg
->vif
, msg
->body
.ip_info
.idx
);
2623 case HOST_IF_MSG_GET_MAC_ADDRESS
:
2624 handle_get_mac_address(msg
->vif
,
2625 &msg
->body
.get_mac_info
);
2628 case HOST_IF_MSG_REMAIN_ON_CHAN
:
2629 handle_remain_on_chan(msg
->vif
, &msg
->body
.remain_on_ch
);
2632 case HOST_IF_MSG_REGISTER_FRAME
:
2633 handle_register_frame(msg
->vif
, &msg
->body
.reg_frame
);
2636 case HOST_IF_MSG_LISTEN_TIMER_FIRED
:
2637 handle_listen_state_expired(msg
->vif
, &msg
->body
.remain_on_ch
);
2640 case HOST_IF_MSG_SET_MULTICAST_FILTER
:
2641 handle_set_mcast_filter(msg
->vif
, &msg
->body
.multicast_info
);
2644 case HOST_IF_MSG_DEL_ALL_STA
:
2645 handle_del_all_sta(msg
->vif
, &msg
->body
.del_all_sta_info
);
2648 case HOST_IF_MSG_SET_TX_POWER
:
2649 handle_set_tx_pwr(msg
->vif
, msg
->body
.tx_power
.tx_pwr
);
2652 case HOST_IF_MSG_GET_TX_POWER
:
2653 handle_get_tx_pwr(msg
->vif
, &msg
->body
.tx_power
.tx_pwr
);
2656 netdev_err(msg
->vif
->ndev
, "[Host Interface] undefined\n");
2661 netdev_err(msg
->vif
->ndev
, "Host cmd %d failed\n", msg
->id
);
2663 complete(&hif_thread_comp
);
2666 static void timer_scan_cb(struct timer_list
*t
)
2668 struct host_if_drv
*hif_drv
= from_timer(hif_drv
, t
, scan_timer
);
2669 struct wilc_vif
*vif
= hif_drv
->scan_timer_vif
;
2670 struct host_if_msg msg
;
2672 memset(&msg
, 0, sizeof(struct host_if_msg
));
2674 msg
.id
= HOST_IF_MSG_SCAN_TIMER_FIRED
;
2676 wilc_enqueue_cmd(&msg
);
2679 static void timer_connect_cb(struct timer_list
*t
)
2681 struct host_if_drv
*hif_drv
= from_timer(hif_drv
, t
,
2683 struct wilc_vif
*vif
= hif_drv
->connect_timer_vif
;
2684 struct host_if_msg msg
;
2686 memset(&msg
, 0, sizeof(struct host_if_msg
));
2688 msg
.id
= HOST_IF_MSG_CONNECT_TIMER_FIRED
;
2690 wilc_enqueue_cmd(&msg
);
2693 s32
wilc_remove_key(struct host_if_drv
*hif_drv
, const u8
*sta_addr
)
2697 wid
.id
= (u16
)WID_REMOVE_KEY
;
2699 wid
.val
= (s8
*)sta_addr
;
2705 int wilc_remove_wep_key(struct wilc_vif
*vif
, u8 index
)
2708 struct host_if_msg msg
;
2709 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
2713 netdev_err(vif
->ndev
, "Failed to send setup multicast\n");
2717 memset(&msg
, 0, sizeof(struct host_if_msg
));
2719 msg
.id
= HOST_IF_MSG_KEY
;
2720 msg
.body
.key_info
.type
= WEP
;
2721 msg
.body
.key_info
.action
= REMOVEKEY
;
2723 msg
.body
.key_info
.attr
.wep
.index
= index
;
2725 result
= wilc_enqueue_cmd(&msg
);
2727 netdev_err(vif
->ndev
, "Request to remove WEP key\n");
2729 wait_for_completion(&hif_drv
->comp_test_key_block
);
2734 int wilc_set_wep_default_keyid(struct wilc_vif
*vif
, u8 index
)
2737 struct host_if_msg msg
;
2738 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
2742 netdev_err(vif
->ndev
, "driver is null\n");
2746 memset(&msg
, 0, sizeof(struct host_if_msg
));
2748 msg
.id
= HOST_IF_MSG_KEY
;
2749 msg
.body
.key_info
.type
= WEP
;
2750 msg
.body
.key_info
.action
= DEFAULTKEY
;
2752 msg
.body
.key_info
.attr
.wep
.index
= index
;
2754 result
= wilc_enqueue_cmd(&msg
);
2756 netdev_err(vif
->ndev
, "Default key index\n");
2758 wait_for_completion(&hif_drv
->comp_test_key_block
);
2763 int wilc_add_wep_key_bss_sta(struct wilc_vif
*vif
, const u8
*key
, u8 len
,
2767 struct host_if_msg msg
;
2768 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
2771 netdev_err(vif
->ndev
, "driver is null\n");
2775 memset(&msg
, 0, sizeof(struct host_if_msg
));
2777 msg
.id
= HOST_IF_MSG_KEY
;
2778 msg
.body
.key_info
.type
= WEP
;
2779 msg
.body
.key_info
.action
= ADDKEY
;
2781 msg
.body
.key_info
.attr
.wep
.key
= kmemdup(key
, len
, GFP_KERNEL
);
2782 if (!msg
.body
.key_info
.attr
.wep
.key
)
2785 msg
.body
.key_info
.attr
.wep
.key_len
= len
;
2786 msg
.body
.key_info
.attr
.wep
.index
= index
;
2788 result
= wilc_enqueue_cmd(&msg
);
2790 netdev_err(vif
->ndev
, "STA - WEP Key\n");
2791 wait_for_completion(&hif_drv
->comp_test_key_block
);
2796 int wilc_add_wep_key_bss_ap(struct wilc_vif
*vif
, const u8
*key
, u8 len
,
2797 u8 index
, u8 mode
, enum AUTHTYPE auth_type
)
2800 struct host_if_msg msg
;
2801 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
2804 netdev_err(vif
->ndev
, "driver is null\n");
2808 memset(&msg
, 0, sizeof(struct host_if_msg
));
2810 msg
.id
= HOST_IF_MSG_KEY
;
2811 msg
.body
.key_info
.type
= WEP
;
2812 msg
.body
.key_info
.action
= ADDKEY_AP
;
2814 msg
.body
.key_info
.attr
.wep
.key
= kmemdup(key
, len
, GFP_KERNEL
);
2815 if (!msg
.body
.key_info
.attr
.wep
.key
)
2818 msg
.body
.key_info
.attr
.wep
.key_len
= len
;
2819 msg
.body
.key_info
.attr
.wep
.index
= index
;
2820 msg
.body
.key_info
.attr
.wep
.mode
= mode
;
2821 msg
.body
.key_info
.attr
.wep
.auth_type
= auth_type
;
2823 result
= wilc_enqueue_cmd(&msg
);
2826 netdev_err(vif
->ndev
, "AP - WEP Key\n");
2828 wait_for_completion(&hif_drv
->comp_test_key_block
);
2833 int wilc_add_ptk(struct wilc_vif
*vif
, const u8
*ptk
, u8 ptk_key_len
,
2834 const u8
*mac_addr
, const u8
*rx_mic
, const u8
*tx_mic
,
2835 u8 mode
, u8 cipher_mode
, u8 index
)
2838 struct host_if_msg msg
;
2839 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
2840 u8 key_len
= ptk_key_len
;
2843 netdev_err(vif
->ndev
, "driver is null\n");
2848 key_len
+= RX_MIC_KEY_LEN
;
2851 key_len
+= TX_MIC_KEY_LEN
;
2853 memset(&msg
, 0, sizeof(struct host_if_msg
));
2855 msg
.id
= HOST_IF_MSG_KEY
;
2856 msg
.body
.key_info
.type
= WPA_PTK
;
2857 if (mode
== AP_MODE
) {
2858 msg
.body
.key_info
.action
= ADDKEY_AP
;
2859 msg
.body
.key_info
.attr
.wpa
.index
= index
;
2861 if (mode
== STATION_MODE
)
2862 msg
.body
.key_info
.action
= ADDKEY
;
2864 msg
.body
.key_info
.attr
.wpa
.key
= kmemdup(ptk
, ptk_key_len
, GFP_KERNEL
);
2865 if (!msg
.body
.key_info
.attr
.wpa
.key
)
2869 memcpy(msg
.body
.key_info
.attr
.wpa
.key
+ 16, rx_mic
,
2873 memcpy(msg
.body
.key_info
.attr
.wpa
.key
+ 24, tx_mic
,
2876 msg
.body
.key_info
.attr
.wpa
.key_len
= key_len
;
2877 msg
.body
.key_info
.attr
.wpa
.mac_addr
= mac_addr
;
2878 msg
.body
.key_info
.attr
.wpa
.mode
= cipher_mode
;
2881 result
= wilc_enqueue_cmd(&msg
);
2884 netdev_err(vif
->ndev
, "PTK Key\n");
2886 wait_for_completion(&hif_drv
->comp_test_key_block
);
2891 int wilc_add_rx_gtk(struct wilc_vif
*vif
, const u8
*rx_gtk
, u8 gtk_key_len
,
2892 u8 index
, u32 key_rsc_len
, const u8
*key_rsc
,
2893 const u8
*rx_mic
, const u8
*tx_mic
, u8 mode
,
2897 struct host_if_msg msg
;
2898 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
2899 u8 key_len
= gtk_key_len
;
2902 netdev_err(vif
->ndev
, "driver is null\n");
2905 memset(&msg
, 0, sizeof(struct host_if_msg
));
2908 key_len
+= RX_MIC_KEY_LEN
;
2911 key_len
+= TX_MIC_KEY_LEN
;
2914 msg
.body
.key_info
.attr
.wpa
.seq
= kmemdup(key_rsc
,
2917 if (!msg
.body
.key_info
.attr
.wpa
.seq
)
2921 msg
.id
= HOST_IF_MSG_KEY
;
2922 msg
.body
.key_info
.type
= WPA_RX_GTK
;
2925 if (mode
== AP_MODE
) {
2926 msg
.body
.key_info
.action
= ADDKEY_AP
;
2927 msg
.body
.key_info
.attr
.wpa
.mode
= cipher_mode
;
2929 if (mode
== STATION_MODE
)
2930 msg
.body
.key_info
.action
= ADDKEY
;
2932 msg
.body
.key_info
.attr
.wpa
.key
= kmemdup(rx_gtk
,
2935 if (!msg
.body
.key_info
.attr
.wpa
.key
)
2939 memcpy(msg
.body
.key_info
.attr
.wpa
.key
+ 16, rx_mic
,
2943 memcpy(msg
.body
.key_info
.attr
.wpa
.key
+ 24, tx_mic
,
2946 msg
.body
.key_info
.attr
.wpa
.index
= index
;
2947 msg
.body
.key_info
.attr
.wpa
.key_len
= key_len
;
2948 msg
.body
.key_info
.attr
.wpa
.seq_len
= key_rsc_len
;
2950 result
= wilc_enqueue_cmd(&msg
);
2952 netdev_err(vif
->ndev
, "RX GTK\n");
2954 wait_for_completion(&hif_drv
->comp_test_key_block
);
2959 int wilc_set_pmkid_info(struct wilc_vif
*vif
,
2960 struct host_if_pmkid_attr
*pmkid
)
2963 struct host_if_msg msg
;
2966 memset(&msg
, 0, sizeof(struct host_if_msg
));
2968 msg
.id
= HOST_IF_MSG_KEY
;
2969 msg
.body
.key_info
.type
= PMKSA
;
2970 msg
.body
.key_info
.action
= ADDKEY
;
2973 for (i
= 0; i
< pmkid
->numpmkid
; i
++) {
2974 memcpy(msg
.body
.key_info
.attr
.pmkid
.pmkidlist
[i
].bssid
,
2975 &pmkid
->pmkidlist
[i
].bssid
, ETH_ALEN
);
2976 memcpy(msg
.body
.key_info
.attr
.pmkid
.pmkidlist
[i
].pmkid
,
2977 &pmkid
->pmkidlist
[i
].pmkid
, PMKID_LEN
);
2980 result
= wilc_enqueue_cmd(&msg
);
2982 netdev_err(vif
->ndev
, "PMKID Info\n");
2987 int wilc_get_mac_address(struct wilc_vif
*vif
, u8
*mac_addr
)
2990 struct host_if_msg msg
;
2992 memset(&msg
, 0, sizeof(struct host_if_msg
));
2994 msg
.id
= HOST_IF_MSG_GET_MAC_ADDRESS
;
2995 msg
.body
.get_mac_info
.mac_addr
= mac_addr
;
2998 result
= wilc_enqueue_cmd(&msg
);
3000 netdev_err(vif
->ndev
, "Failed to send get mac address\n");
3004 wait_for_completion(&hif_wait_response
);
3008 int wilc_set_join_req(struct wilc_vif
*vif
, u8
*bssid
, const u8
*ssid
,
3009 size_t ssid_len
, const u8
*ies
, size_t ies_len
,
3010 wilc_connect_result connect_result
, void *user_arg
,
3011 u8 security
, enum AUTHTYPE auth_type
,
3012 u8 channel
, void *join_params
)
3015 struct host_if_msg msg
;
3016 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
3018 if (!hif_drv
|| !connect_result
) {
3019 netdev_err(vif
->ndev
, "Driver is null\n");
3024 netdev_err(vif
->ndev
, "Unable to Join - JoinParams is NULL\n");
3028 memset(&msg
, 0, sizeof(struct host_if_msg
));
3030 msg
.id
= HOST_IF_MSG_CONNECT
;
3032 msg
.body
.con_info
.security
= security
;
3033 msg
.body
.con_info
.auth_type
= auth_type
;
3034 msg
.body
.con_info
.ch
= channel
;
3035 msg
.body
.con_info
.result
= connect_result
;
3036 msg
.body
.con_info
.arg
= user_arg
;
3037 msg
.body
.con_info
.params
= join_params
;
3041 msg
.body
.con_info
.bssid
= kmemdup(bssid
, 6, GFP_KERNEL
);
3042 if (!msg
.body
.con_info
.bssid
)
3047 msg
.body
.con_info
.ssid_len
= ssid_len
;
3048 msg
.body
.con_info
.ssid
= kmemdup(ssid
, ssid_len
, GFP_KERNEL
);
3049 if (!msg
.body
.con_info
.ssid
)
3054 msg
.body
.con_info
.ies_len
= ies_len
;
3055 msg
.body
.con_info
.ies
= kmemdup(ies
, ies_len
, GFP_KERNEL
);
3056 if (!msg
.body
.con_info
.ies
)
3059 if (hif_drv
->hif_state
< HOST_IF_CONNECTING
)
3060 hif_drv
->hif_state
= HOST_IF_CONNECTING
;
3062 result
= wilc_enqueue_cmd(&msg
);
3064 netdev_err(vif
->ndev
, "send message: Set join request\n");
3068 hif_drv
->connect_timer_vif
= vif
;
3069 mod_timer(&hif_drv
->connect_timer
,
3070 jiffies
+ msecs_to_jiffies(HOST_IF_CONNECT_TIMEOUT
));
3075 int wilc_disconnect(struct wilc_vif
*vif
, u16 reason_code
)
3078 struct host_if_msg msg
;
3079 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
3082 netdev_err(vif
->ndev
, "Driver is null\n");
3086 memset(&msg
, 0, sizeof(struct host_if_msg
));
3088 msg
.id
= HOST_IF_MSG_DISCONNECT
;
3091 result
= wilc_enqueue_cmd(&msg
);
3093 netdev_err(vif
->ndev
, "Failed to send message: disconnect\n");
3095 wait_for_completion(&hif_drv
->comp_test_disconn_block
);
3100 static s32
host_int_get_assoc_res_info(struct wilc_vif
*vif
,
3101 u8
*assoc_resp_info
,
3102 u32 max_assoc_resp_info_len
,
3103 u32
*rcvd_assoc_resp_info_len
)
3108 wid
.id
= (u16
)WID_ASSOC_RES_INFO
;
3110 wid
.val
= assoc_resp_info
;
3111 wid
.size
= max_assoc_resp_info_len
;
3113 result
= wilc_send_config_pkt(vif
, GET_CFG
, &wid
, 1,
3114 wilc_get_vif_idx(vif
));
3116 *rcvd_assoc_resp_info_len
= 0;
3117 netdev_err(vif
->ndev
, "Failed to send association response\n");
3121 *rcvd_assoc_resp_info_len
= wid
.size
;
3125 int wilc_set_mac_chnl_num(struct wilc_vif
*vif
, u8 channel
)
3128 struct host_if_msg msg
;
3130 memset(&msg
, 0, sizeof(struct host_if_msg
));
3131 msg
.id
= HOST_IF_MSG_SET_CHANNEL
;
3132 msg
.body
.channel_info
.set_ch
= channel
;
3135 result
= wilc_enqueue_cmd(&msg
);
3137 netdev_err(vif
->ndev
, "wilc mq send fail\n");
3144 int wilc_set_wfi_drv_handler(struct wilc_vif
*vif
, int index
, u8 mode
,
3148 struct host_if_msg msg
;
3150 memset(&msg
, 0, sizeof(struct host_if_msg
));
3151 msg
.id
= HOST_IF_MSG_SET_WFIDRV_HANDLER
;
3152 msg
.body
.drv
.handler
= index
;
3153 msg
.body
.drv
.mode
= mode
;
3154 msg
.body
.drv
.name
= ifc_id
;
3157 result
= wilc_enqueue_cmd(&msg
);
3159 netdev_err(vif
->ndev
, "wilc mq send fail\n");
3166 int wilc_set_operation_mode(struct wilc_vif
*vif
, u32 mode
)
3169 struct host_if_msg msg
;
3171 memset(&msg
, 0, sizeof(struct host_if_msg
));
3172 msg
.id
= HOST_IF_MSG_SET_OPERATION_MODE
;
3173 msg
.body
.mode
.mode
= mode
;
3176 result
= wilc_enqueue_cmd(&msg
);
3178 netdev_err(vif
->ndev
, "wilc mq send fail\n");
3185 s32
wilc_get_inactive_time(struct wilc_vif
*vif
, const u8
*mac
,
3189 struct host_if_msg msg
;
3190 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
3193 netdev_err(vif
->ndev
, "driver is null\n");
3197 memset(&msg
, 0, sizeof(struct host_if_msg
));
3198 memcpy(msg
.body
.mac_info
.mac
, mac
, ETH_ALEN
);
3200 msg
.id
= HOST_IF_MSG_GET_INACTIVETIME
;
3203 result
= wilc_enqueue_cmd(&msg
);
3205 netdev_err(vif
->ndev
, "Failed to send get host ch param\n");
3207 wait_for_completion(&hif_drv
->comp_inactive_time
);
3209 *out_val
= inactive_time
;
3214 int wilc_get_rssi(struct wilc_vif
*vif
, s8
*rssi_level
)
3217 struct host_if_msg msg
;
3218 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
3220 memset(&msg
, 0, sizeof(struct host_if_msg
));
3221 msg
.id
= HOST_IF_MSG_GET_RSSI
;
3224 result
= wilc_enqueue_cmd(&msg
);
3226 netdev_err(vif
->ndev
, "Failed to send get host ch param\n");
3230 wait_for_completion(&hif_drv
->comp_get_rssi
);
3233 netdev_err(vif
->ndev
, "RSS pointer value is null\n");
3242 int wilc_get_statistics(struct wilc_vif
*vif
, struct rf_info
*stats
)
3245 struct host_if_msg msg
;
3247 memset(&msg
, 0, sizeof(struct host_if_msg
));
3248 msg
.id
= HOST_IF_MSG_GET_STATISTICS
;
3249 msg
.body
.data
= (char *)stats
;
3252 result
= wilc_enqueue_cmd(&msg
);
3254 netdev_err(vif
->ndev
, "Failed to send get host channel\n");
3258 if (stats
!= &vif
->wilc
->dummy_statistics
)
3259 wait_for_completion(&hif_wait_response
);
3263 int wilc_scan(struct wilc_vif
*vif
, u8 scan_source
, u8 scan_type
,
3264 u8
*ch_freq_list
, u8 ch_list_len
, const u8
*ies
,
3265 size_t ies_len
, wilc_scan_result scan_result
, void *user_arg
,
3266 struct hidden_network
*hidden_network
)
3269 struct host_if_msg msg
;
3270 struct scan_attr
*scan_info
= &msg
.body
.scan_info
;
3271 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
3273 if (!hif_drv
|| !scan_result
) {
3274 netdev_err(vif
->ndev
, "hif_drv or scan_result = NULL\n");
3278 memset(&msg
, 0, sizeof(struct host_if_msg
));
3280 msg
.id
= HOST_IF_MSG_SCAN
;
3282 if (hidden_network
) {
3283 scan_info
->hidden_network
.net_info
= hidden_network
->net_info
;
3284 scan_info
->hidden_network
.n_ssids
= hidden_network
->n_ssids
;
3288 scan_info
->src
= scan_source
;
3289 scan_info
->type
= scan_type
;
3290 scan_info
->result
= scan_result
;
3291 scan_info
->arg
= user_arg
;
3293 scan_info
->ch_list_len
= ch_list_len
;
3294 scan_info
->ch_freq_list
= kmemdup(ch_freq_list
,
3297 if (!scan_info
->ch_freq_list
)
3300 scan_info
->ies_len
= ies_len
;
3301 scan_info
->ies
= kmemdup(ies
, ies_len
, GFP_KERNEL
);
3302 if (!scan_info
->ies
)
3305 result
= wilc_enqueue_cmd(&msg
);
3307 netdev_err(vif
->ndev
, "Error in sending message queue\n");
3311 hif_drv
->scan_timer_vif
= vif
;
3312 mod_timer(&hif_drv
->scan_timer
,
3313 jiffies
+ msecs_to_jiffies(HOST_IF_SCAN_TIMEOUT
));
3318 int wilc_hif_set_cfg(struct wilc_vif
*vif
,
3319 struct cfg_param_attr
*cfg_param
)
3321 struct host_if_msg msg
;
3322 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
3325 netdev_err(vif
->ndev
, "hif_drv NULL\n");
3329 memset(&msg
, 0, sizeof(struct host_if_msg
));
3330 msg
.id
= HOST_IF_MSG_CFG_PARAMS
;
3331 msg
.body
.cfg_info
= *cfg_param
;
3334 return wilc_enqueue_cmd(&msg
);
3337 static void get_periodic_rssi(struct timer_list
*unused
)
3339 struct wilc_vif
*vif
= periodic_rssi_vif
;
3341 if (!vif
->hif_drv
) {
3342 netdev_err(vif
->ndev
, "Driver handler is NULL\n");
3346 if (vif
->hif_drv
->hif_state
== HOST_IF_CONNECTED
)
3347 wilc_get_statistics(vif
, &vif
->wilc
->dummy_statistics
);
3349 mod_timer(&periodic_rssi
, jiffies
+ msecs_to_jiffies(5000));
3352 int wilc_init(struct net_device
*dev
, struct host_if_drv
**hif_drv_handler
)
3355 struct host_if_drv
*hif_drv
;
3356 struct wilc_vif
*vif
;
3360 vif
= netdev_priv(dev
);
3363 scan_while_connected
= false;
3365 init_completion(&hif_wait_response
);
3367 hif_drv
= kzalloc(sizeof(*hif_drv
), GFP_KERNEL
);
3372 *hif_drv_handler
= hif_drv
;
3373 for (i
= 0; i
< wilc
->vif_num
; i
++)
3374 if (dev
== wilc
->vif
[i
]->ndev
) {
3375 wilc
->vif
[i
]->hif_drv
= hif_drv
;
3376 hif_drv
->driver_handler_id
= i
+ 1;
3380 wilc_optaining_ip
= false;
3382 if (clients_count
== 0) {
3383 init_completion(&hif_thread_comp
);
3384 init_completion(&hif_driver_comp
);
3385 mutex_init(&hif_deinit_lock
);
3388 init_completion(&hif_drv
->comp_test_key_block
);
3389 init_completion(&hif_drv
->comp_test_disconn_block
);
3390 init_completion(&hif_drv
->comp_get_rssi
);
3391 init_completion(&hif_drv
->comp_inactive_time
);
3393 if (clients_count
== 0) {
3394 hif_workqueue
= create_singlethread_workqueue("WILC_wq");
3395 if (!hif_workqueue
) {
3396 netdev_err(vif
->ndev
, "Failed to create workqueue\n");
3401 periodic_rssi_vif
= vif
;
3402 timer_setup(&periodic_rssi
, get_periodic_rssi
, 0);
3403 mod_timer(&periodic_rssi
, jiffies
+ msecs_to_jiffies(5000));
3406 timer_setup(&hif_drv
->scan_timer
, timer_scan_cb
, 0);
3407 timer_setup(&hif_drv
->connect_timer
, timer_connect_cb
, 0);
3408 timer_setup(&hif_drv
->remain_on_ch_timer
, listen_timer_cb
, 0);
3410 mutex_init(&hif_drv
->cfg_values_lock
);
3411 mutex_lock(&hif_drv
->cfg_values_lock
);
3413 hif_drv
->hif_state
= HOST_IF_IDLE
;
3414 hif_drv
->cfg_values
.site_survey_enabled
= SITE_SURVEY_OFF
;
3415 hif_drv
->cfg_values
.scan_source
= DEFAULT_SCAN
;
3416 hif_drv
->cfg_values
.active_scan_time
= ACTIVE_SCAN_TIME
;
3417 hif_drv
->cfg_values
.passive_scan_time
= PASSIVE_SCAN_TIME
;
3418 hif_drv
->cfg_values
.curr_tx_rate
= AUTORATE
;
3420 hif_drv
->p2p_timeout
= 0;
3422 mutex_unlock(&hif_drv
->cfg_values_lock
);
3430 int wilc_deinit(struct wilc_vif
*vif
)
3433 struct host_if_msg msg
;
3434 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
3437 netdev_err(vif
->ndev
, "hif_drv = NULL\n");
3441 mutex_lock(&hif_deinit_lock
);
3443 terminated_handle
= hif_drv
;
3445 del_timer_sync(&hif_drv
->scan_timer
);
3446 del_timer_sync(&hif_drv
->connect_timer
);
3447 del_timer_sync(&periodic_rssi
);
3448 del_timer_sync(&hif_drv
->remain_on_ch_timer
);
3450 wilc_set_wfi_drv_handler(vif
, 0, 0, 0);
3451 wait_for_completion(&hif_driver_comp
);
3453 if (hif_drv
->usr_scan_req
.scan_result
) {
3454 hif_drv
->usr_scan_req
.scan_result(SCAN_EVENT_ABORTED
, NULL
,
3455 hif_drv
->usr_scan_req
.arg
,
3457 hif_drv
->usr_scan_req
.scan_result
= NULL
;
3460 hif_drv
->hif_state
= HOST_IF_IDLE
;
3462 scan_while_connected
= false;
3464 memset(&msg
, 0, sizeof(struct host_if_msg
));
3466 if (clients_count
== 1) {
3467 msg
.id
= HOST_IF_MSG_EXIT
;
3470 result
= wilc_enqueue_cmd(&msg
);
3472 netdev_err(vif
->ndev
, "deinit : Error(%d)\n", result
);
3474 wait_for_completion(&hif_thread_comp
);
3476 destroy_workqueue(hif_workqueue
);
3482 terminated_handle
= NULL
;
3483 mutex_unlock(&hif_deinit_lock
);
3487 void wilc_network_info_received(struct wilc
*wilc
, u8
*buffer
, u32 length
)
3490 struct host_if_msg msg
;
3492 struct host_if_drv
*hif_drv
= NULL
;
3493 struct wilc_vif
*vif
;
3495 id
= buffer
[length
- 4];
3496 id
|= (buffer
[length
- 3] << 8);
3497 id
|= (buffer
[length
- 2] << 16);
3498 id
|= (buffer
[length
- 1] << 24);
3499 vif
= wilc_get_vif_from_idx(wilc
, id
);
3502 hif_drv
= vif
->hif_drv
;
3504 if (!hif_drv
|| hif_drv
== terminated_handle
) {
3505 netdev_err(vif
->ndev
, "driver not init[%p]\n", hif_drv
);
3509 memset(&msg
, 0, sizeof(struct host_if_msg
));
3511 msg
.id
= HOST_IF_MSG_RCVD_NTWRK_INFO
;
3514 msg
.body
.net_info
.len
= length
;
3515 msg
.body
.net_info
.buffer
= kmalloc(length
, GFP_KERNEL
);
3516 memcpy(msg
.body
.net_info
.buffer
, buffer
, length
);
3518 result
= wilc_enqueue_cmd(&msg
);
3520 netdev_err(vif
->ndev
, "message parameters (%d)\n", result
);
3523 void wilc_gnrl_async_info_received(struct wilc
*wilc
, u8
*buffer
, u32 length
)
3526 struct host_if_msg msg
;
3528 struct host_if_drv
*hif_drv
= NULL
;
3529 struct wilc_vif
*vif
;
3531 mutex_lock(&hif_deinit_lock
);
3533 id
= buffer
[length
- 4];
3534 id
|= (buffer
[length
- 3] << 8);
3535 id
|= (buffer
[length
- 2] << 16);
3536 id
|= (buffer
[length
- 1] << 24);
3537 vif
= wilc_get_vif_from_idx(wilc
, id
);
3539 mutex_unlock(&hif_deinit_lock
);
3543 hif_drv
= vif
->hif_drv
;
3545 if (!hif_drv
|| hif_drv
== terminated_handle
) {
3546 mutex_unlock(&hif_deinit_lock
);
3550 if (!hif_drv
->usr_conn_req
.conn_result
) {
3551 netdev_err(vif
->ndev
, "there is no current Connect Request\n");
3552 mutex_unlock(&hif_deinit_lock
);
3556 memset(&msg
, 0, sizeof(struct host_if_msg
));
3558 msg
.id
= HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO
;
3561 msg
.body
.async_info
.len
= length
;
3562 msg
.body
.async_info
.buffer
= kmalloc(length
, GFP_KERNEL
);
3563 memcpy(msg
.body
.async_info
.buffer
, buffer
, length
);
3565 result
= wilc_enqueue_cmd(&msg
);
3567 netdev_err(vif
->ndev
, "synchronous info (%d)\n", result
);
3569 mutex_unlock(&hif_deinit_lock
);
3572 void wilc_scan_complete_received(struct wilc
*wilc
, u8
*buffer
, u32 length
)
3575 struct host_if_msg msg
;
3577 struct host_if_drv
*hif_drv
= NULL
;
3578 struct wilc_vif
*vif
;
3580 id
= buffer
[length
- 4];
3581 id
|= buffer
[length
- 3] << 8;
3582 id
|= buffer
[length
- 2] << 16;
3583 id
|= buffer
[length
- 1] << 24;
3584 vif
= wilc_get_vif_from_idx(wilc
, id
);
3587 hif_drv
= vif
->hif_drv
;
3589 if (!hif_drv
|| hif_drv
== terminated_handle
)
3592 if (hif_drv
->usr_scan_req
.scan_result
) {
3593 memset(&msg
, 0, sizeof(struct host_if_msg
));
3595 msg
.id
= HOST_IF_MSG_RCVD_SCAN_COMPLETE
;
3598 result
= wilc_enqueue_cmd(&msg
);
3600 netdev_err(vif
->ndev
, "complete param (%d)\n", result
);
3604 int wilc_remain_on_channel(struct wilc_vif
*vif
, u32 session_id
,
3605 u32 duration
, u16 chan
,
3606 wilc_remain_on_chan_expired expired
,
3607 wilc_remain_on_chan_ready ready
,
3611 struct host_if_msg msg
;
3613 memset(&msg
, 0, sizeof(struct host_if_msg
));
3615 msg
.id
= HOST_IF_MSG_REMAIN_ON_CHAN
;
3616 msg
.body
.remain_on_ch
.ch
= chan
;
3617 msg
.body
.remain_on_ch
.expired
= expired
;
3618 msg
.body
.remain_on_ch
.ready
= ready
;
3619 msg
.body
.remain_on_ch
.arg
= user_arg
;
3620 msg
.body
.remain_on_ch
.duration
= duration
;
3621 msg
.body
.remain_on_ch
.id
= session_id
;
3624 result
= wilc_enqueue_cmd(&msg
);
3626 netdev_err(vif
->ndev
, "wilc mq send fail\n");
3631 int wilc_listen_state_expired(struct wilc_vif
*vif
, u32 session_id
)
3634 struct host_if_msg msg
;
3635 struct host_if_drv
*hif_drv
= vif
->hif_drv
;
3638 netdev_err(vif
->ndev
, "driver is null\n");
3642 del_timer(&hif_drv
->remain_on_ch_timer
);
3644 memset(&msg
, 0, sizeof(struct host_if_msg
));
3645 msg
.id
= HOST_IF_MSG_LISTEN_TIMER_FIRED
;
3647 msg
.body
.remain_on_ch
.id
= session_id
;
3649 result
= wilc_enqueue_cmd(&msg
);
3651 netdev_err(vif
->ndev
, "wilc mq send fail\n");
3656 int wilc_frame_register(struct wilc_vif
*vif
, u16 frame_type
, bool reg
)
3659 struct host_if_msg msg
;
3661 memset(&msg
, 0, sizeof(struct host_if_msg
));
3663 msg
.id
= HOST_IF_MSG_REGISTER_FRAME
;
3664 switch (frame_type
) {
3666 msg
.body
.reg_frame
.reg_id
= ACTION_FRM_IDX
;
3670 msg
.body
.reg_frame
.reg_id
= PROBE_REQ_IDX
;
3676 msg
.body
.reg_frame
.frame_type
= frame_type
;
3677 msg
.body
.reg_frame
.reg
= reg
;
3680 result
= wilc_enqueue_cmd(&msg
);
3682 netdev_err(vif
->ndev
, "wilc mq send fail\n");
3687 int wilc_add_beacon(struct wilc_vif
*vif
, u32 interval
, u32 dtim_period
,
3688 u32 head_len
, u8
*head
, u32 tail_len
, u8
*tail
)
3691 struct host_if_msg msg
;
3692 struct beacon_attr
*beacon_info
= &msg
.body
.beacon_info
;
3694 memset(&msg
, 0, sizeof(struct host_if_msg
));
3696 msg
.id
= HOST_IF_MSG_ADD_BEACON
;
3698 beacon_info
->interval
= interval
;
3699 beacon_info
->dtim_period
= dtim_period
;
3700 beacon_info
->head_len
= head_len
;
3701 beacon_info
->head
= kmemdup(head
, head_len
, GFP_KERNEL
);
3702 if (!beacon_info
->head
) {
3706 beacon_info
->tail_len
= tail_len
;
3709 beacon_info
->tail
= kmemdup(tail
, tail_len
, GFP_KERNEL
);
3710 if (!beacon_info
->tail
) {
3715 beacon_info
->tail
= NULL
;
3718 result
= wilc_enqueue_cmd(&msg
);
3720 netdev_err(vif
->ndev
, "wilc mq send fail\n");
3724 kfree(beacon_info
->head
);
3726 kfree(beacon_info
->tail
);
3732 int wilc_del_beacon(struct wilc_vif
*vif
)
3735 struct host_if_msg msg
;
3737 msg
.id
= HOST_IF_MSG_DEL_BEACON
;
3740 result
= wilc_enqueue_cmd(&msg
);
3742 netdev_err(vif
->ndev
, "wilc_mq_send fail\n");
3747 int wilc_add_station(struct wilc_vif
*vif
, struct add_sta_param
*sta_param
)
3750 struct host_if_msg msg
;
3751 struct add_sta_param
*add_sta_info
= &msg
.body
.add_sta_info
;
3753 memset(&msg
, 0, sizeof(struct host_if_msg
));
3755 msg
.id
= HOST_IF_MSG_ADD_STATION
;
3758 memcpy(add_sta_info
, sta_param
, sizeof(struct add_sta_param
));
3759 if (add_sta_info
->rates_len
> 0) {
3760 add_sta_info
->rates
= kmemdup(sta_param
->rates
,
3761 add_sta_info
->rates_len
,
3763 if (!add_sta_info
->rates
)
3767 result
= wilc_enqueue_cmd(&msg
);
3769 netdev_err(vif
->ndev
, "wilc_mq_send fail\n");
3773 int wilc_del_station(struct wilc_vif
*vif
, const u8
*mac_addr
)
3776 struct host_if_msg msg
;
3777 struct del_sta
*del_sta_info
= &msg
.body
.del_sta_info
;
3779 memset(&msg
, 0, sizeof(struct host_if_msg
));
3781 msg
.id
= HOST_IF_MSG_DEL_STATION
;
3785 eth_broadcast_addr(del_sta_info
->mac_addr
);
3787 memcpy(del_sta_info
->mac_addr
, mac_addr
, ETH_ALEN
);
3789 result
= wilc_enqueue_cmd(&msg
);
3791 netdev_err(vif
->ndev
, "wilc_mq_send fail\n");
3795 int wilc_del_allstation(struct wilc_vif
*vif
, u8 mac_addr
[][ETH_ALEN
])
3798 struct host_if_msg msg
;
3799 struct del_all_sta
*del_all_sta_info
= &msg
.body
.del_all_sta_info
;
3800 u8 zero_addr
[ETH_ALEN
] = {0};
3804 memset(&msg
, 0, sizeof(struct host_if_msg
));
3806 msg
.id
= HOST_IF_MSG_DEL_ALL_STA
;
3809 for (i
= 0; i
< MAX_NUM_STA
; i
++) {
3810 if (memcmp(mac_addr
[i
], zero_addr
, ETH_ALEN
)) {
3811 memcpy(del_all_sta_info
->del_all_sta
[i
], mac_addr
[i
],
3819 del_all_sta_info
->assoc_sta
= assoc_sta
;
3820 result
= wilc_enqueue_cmd(&msg
);
3823 netdev_err(vif
->ndev
, "wilc_mq_send fail\n");
3825 wait_for_completion(&hif_wait_response
);
3830 int wilc_edit_station(struct wilc_vif
*vif
,
3831 struct add_sta_param
*sta_param
)
3834 struct host_if_msg msg
;
3835 struct add_sta_param
*add_sta_info
= &msg
.body
.add_sta_info
;
3837 memset(&msg
, 0, sizeof(struct host_if_msg
));
3839 msg
.id
= HOST_IF_MSG_EDIT_STATION
;
3842 memcpy(add_sta_info
, sta_param
, sizeof(struct add_sta_param
));
3843 if (add_sta_info
->rates_len
> 0) {
3844 add_sta_info
->rates
= kmemdup(sta_param
->rates
,
3845 add_sta_info
->rates_len
,
3847 if (!add_sta_info
->rates
)
3851 result
= wilc_enqueue_cmd(&msg
);
3853 netdev_err(vif
->ndev
, "wilc_mq_send fail\n");
3858 int wilc_set_power_mgmt(struct wilc_vif
*vif
, bool enabled
, u32 timeout
)
3861 struct host_if_msg msg
;
3862 struct power_mgmt_param
*pwr_mgmt_info
= &msg
.body
.pwr_mgmt_info
;
3864 if (wilc_wlan_get_num_conn_ifcs(vif
->wilc
) == 2 && enabled
)
3867 memset(&msg
, 0, sizeof(struct host_if_msg
));
3869 msg
.id
= HOST_IF_MSG_POWER_MGMT
;
3872 pwr_mgmt_info
->enabled
= enabled
;
3873 pwr_mgmt_info
->timeout
= timeout
;
3875 result
= wilc_enqueue_cmd(&msg
);
3877 netdev_err(vif
->ndev
, "wilc_mq_send fail\n");
3881 int wilc_setup_multicast_filter(struct wilc_vif
*vif
, bool enabled
,
3885 struct host_if_msg msg
;
3886 struct set_multicast
*multicast_filter_param
= &msg
.body
.multicast_info
;
3888 memset(&msg
, 0, sizeof(struct host_if_msg
));
3890 msg
.id
= HOST_IF_MSG_SET_MULTICAST_FILTER
;
3893 multicast_filter_param
->enabled
= enabled
;
3894 multicast_filter_param
->cnt
= count
;
3896 result
= wilc_enqueue_cmd(&msg
);
3898 netdev_err(vif
->ndev
, "wilc_mq_send fail\n");
3902 static void *host_int_parse_join_bss_param(struct network_info
*info
)
3904 struct join_bss_param
*param
= NULL
;
3913 u8 pcipher_total_cnt
= 0;
3914 u8 auth_total_cnt
= 0;
3918 ies_len
= info
->ies_len
;
3920 param
= kzalloc(sizeof(*param
), GFP_KERNEL
);
3924 param
->dtim_period
= info
->dtim_period
;
3925 param
->beacon_period
= info
->beacon_period
;
3926 param
->cap_info
= info
->cap_info
;
3927 memcpy(param
->bssid
, info
->bssid
, 6);
3928 memcpy((u8
*)param
->ssid
, info
->ssid
, info
->ssid_len
+ 1);
3929 param
->ssid_len
= info
->ssid_len
;
3930 memset(param
->rsn_pcip_policy
, 0xFF, 3);
3931 memset(param
->rsn_auth_policy
, 0xFF, 3);
3933 while (index
< ies_len
) {
3934 if (ies
[index
] == SUPP_RATES_IE
) {
3935 rates_no
= ies
[index
+ 1];
3936 param
->supp_rates
[0] = rates_no
;
3939 for (i
= 0; i
< rates_no
; i
++)
3940 param
->supp_rates
[i
+ 1] = ies
[index
+ i
];
3943 } else if (ies
[index
] == EXT_SUPP_RATES_IE
) {
3944 ext_rates_no
= ies
[index
+ 1];
3945 if (ext_rates_no
> (MAX_RATES_SUPPORTED
- rates_no
))
3946 param
->supp_rates
[0] = MAX_RATES_SUPPORTED
;
3948 param
->supp_rates
[0] += ext_rates_no
;
3950 for (i
= 0; i
< (param
->supp_rates
[0] - rates_no
); i
++)
3951 param
->supp_rates
[rates_no
+ i
+ 1] = ies
[index
+ i
];
3953 index
+= ext_rates_no
;
3954 } else if (ies
[index
] == HT_CAPABILITY_IE
) {
3955 param
->ht_capable
= true;
3956 index
+= ies
[index
+ 1] + 2;
3957 } else if ((ies
[index
] == WMM_IE
) &&
3958 (ies
[index
+ 2] == 0x00) && (ies
[index
+ 3] == 0x50) &&
3959 (ies
[index
+ 4] == 0xF2) &&
3960 (ies
[index
+ 5] == 0x02) &&
3961 ((ies
[index
+ 6] == 0x00) || (ies
[index
+ 6] == 0x01)) &&
3962 (ies
[index
+ 7] == 0x01)) {
3963 param
->wmm_cap
= true;
3965 if (ies
[index
+ 8] & BIT(7))
3966 param
->uapsd_cap
= true;
3967 index
+= ies
[index
+ 1] + 2;
3968 } else if ((ies
[index
] == P2P_IE
) &&
3969 (ies
[index
+ 2] == 0x50) && (ies
[index
+ 3] == 0x6f) &&
3970 (ies
[index
+ 4] == 0x9a) &&
3971 (ies
[index
+ 5] == 0x09) && (ies
[index
+ 6] == 0x0c)) {
3974 param
->tsf
= info
->tsf_lo
;
3975 param
->noa_enabled
= 1;
3976 param
->idx
= ies
[index
+ 9];
3978 if (ies
[index
+ 10] & BIT(7)) {
3979 param
->opp_enabled
= 1;
3980 param
->ct_window
= ies
[index
+ 10];
3982 param
->opp_enabled
= 0;
3985 param
->cnt
= ies
[index
+ 11];
3986 p2p_cnt
= index
+ 12;
3988 memcpy(param
->duration
, ies
+ p2p_cnt
, 4);
3991 memcpy(param
->interval
, ies
+ p2p_cnt
, 4);
3994 memcpy(param
->start_time
, ies
+ p2p_cnt
, 4);
3996 index
+= ies
[index
+ 1] + 2;
3997 } else if ((ies
[index
] == RSN_IE
) ||
3998 ((ies
[index
] == WPA_IE
) && (ies
[index
+ 2] == 0x00) &&
3999 (ies
[index
+ 3] == 0x50) && (ies
[index
+ 4] == 0xF2) &&
4000 (ies
[index
+ 5] == 0x01))) {
4001 u16 rsn_idx
= index
;
4003 if (ies
[rsn_idx
] == RSN_IE
) {
4004 param
->mode_802_11i
= 2;
4006 if (param
->mode_802_11i
== 0)
4007 param
->mode_802_11i
= 1;
4012 param
->rsn_grp_policy
= ies
[rsn_idx
];
4014 offset
= ies
[rsn_idx
] * 4;
4015 pcipher_cnt
= (ies
[rsn_idx
] > 3) ? 3 : ies
[rsn_idx
];
4018 for (i
= pcipher_total_cnt
, j
= 0; i
< pcipher_cnt
+ pcipher_total_cnt
&& i
< 3; i
++, j
++)
4019 param
->rsn_pcip_policy
[i
] = ies
[rsn_idx
+ ((j
+ 1) * 4) - 1];
4021 pcipher_total_cnt
+= pcipher_cnt
;
4024 offset
= ies
[rsn_idx
] * 4;
4026 auth_cnt
= (ies
[rsn_idx
] > 3) ? 3 : ies
[rsn_idx
];
4029 for (i
= auth_total_cnt
, j
= 0; i
< auth_total_cnt
+ auth_cnt
; i
++, j
++)
4030 param
->rsn_auth_policy
[i
] = ies
[rsn_idx
+ ((j
+ 1) * 4) - 1];
4032 auth_total_cnt
+= auth_cnt
;
4035 if (ies
[index
] == RSN_IE
) {
4036 param
->rsn_cap
[0] = ies
[rsn_idx
];
4037 param
->rsn_cap
[1] = ies
[rsn_idx
+ 1];
4040 param
->rsn_found
= true;
4041 index
+= ies
[index
+ 1] + 2;
4043 index
+= ies
[index
+ 1] + 2;
4047 return (void *)param
;
4050 int wilc_setup_ipaddress(struct wilc_vif
*vif
, u8
*ip_addr
, u8 idx
)
4053 struct host_if_msg msg
;
4055 memset(&msg
, 0, sizeof(struct host_if_msg
));
4057 msg
.id
= HOST_IF_MSG_SET_IPADDRESS
;
4059 msg
.body
.ip_info
.ip_addr
= ip_addr
;
4061 msg
.body
.ip_info
.idx
= idx
;
4063 result
= wilc_enqueue_cmd(&msg
);
4065 netdev_err(vif
->ndev
, "wilc_mq_send fail\n");
4070 static int host_int_get_ipaddress(struct wilc_vif
*vif
, u8
*ip_addr
, u8 idx
)
4073 struct host_if_msg msg
;
4075 memset(&msg
, 0, sizeof(struct host_if_msg
));
4077 msg
.id
= HOST_IF_MSG_GET_IPADDRESS
;
4079 msg
.body
.ip_info
.ip_addr
= ip_addr
;
4081 msg
.body
.ip_info
.idx
= idx
;
4083 result
= wilc_enqueue_cmd(&msg
);
4085 netdev_err(vif
->ndev
, "wilc_mq_send fail\n");
4090 int wilc_set_tx_power(struct wilc_vif
*vif
, u8 tx_power
)
4093 struct host_if_msg msg
;
4095 memset(&msg
, 0, sizeof(struct host_if_msg
));
4097 msg
.id
= HOST_IF_MSG_SET_TX_POWER
;
4098 msg
.body
.tx_power
.tx_pwr
= tx_power
;
4101 ret
= wilc_enqueue_cmd(&msg
);
4103 netdev_err(vif
->ndev
, "wilc_mq_send fail\n");
4108 int wilc_get_tx_power(struct wilc_vif
*vif
, u8
*tx_power
)
4111 struct host_if_msg msg
;
4113 memset(&msg
, 0, sizeof(struct host_if_msg
));
4115 msg
.id
= HOST_IF_MSG_GET_TX_POWER
;
4118 ret
= wilc_enqueue_cmd(&msg
);
4120 netdev_err(vif
->ndev
, "Failed to get TX PWR\n");
4122 wait_for_completion(&hif_wait_response
);
4123 *tx_power
= msg
.body
.tx_power
.tx_pwr
;