1 // SPDX-License-Identifier: GPL-2.0-only
3 * Implementation of mac80211 API.
5 * Copyright (c) 2017-2019, Silicon Laboratories, Inc.
6 * Copyright (c) 2010, ST-Ericsson
8 #include <net/mac80211.h>
18 #include "hif_tx_mib.h"
20 #define HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES 2
22 static u32
wfx_rate_mask_to_hw(struct wfx_dev
*wdev
, u32 rates
)
26 // WFx only support 2GHz
27 struct ieee80211_supported_band
*sband
= wdev
->hw
->wiphy
->bands
[NL80211_BAND_2GHZ
];
29 for (i
= 0; i
< sband
->n_bitrates
; i
++) {
31 if (i
>= sband
->n_bitrates
)
32 dev_warn(wdev
->dev
, "unsupported basic rate\n");
34 ret
|= BIT(sband
->bitrates
[i
].hw_value
);
40 static void __wfx_free_event_queue(struct list_head
*list
)
42 struct wfx_hif_event
*event
, *tmp
;
44 list_for_each_entry_safe(event
, tmp
, list
, link
) {
45 list_del(&event
->link
);
50 static void wfx_free_event_queue(struct wfx_vif
*wvif
)
54 spin_lock(&wvif
->event_queue_lock
);
55 list_splice_init(&wvif
->event_queue
, &list
);
56 spin_unlock(&wvif
->event_queue_lock
);
58 __wfx_free_event_queue(&list
);
61 void wfx_cqm_bssloss_sm(struct wfx_vif
*wvif
, int init
, int good
, int bad
)
65 mutex_lock(&wvif
->bss_loss_lock
);
66 cancel_work_sync(&wvif
->bss_params_work
);
69 schedule_delayed_work(&wvif
->bss_loss_work
, HZ
);
70 wvif
->bss_loss_state
= 0;
72 if (!atomic_read(&wvif
->wdev
->tx_lock
))
75 cancel_delayed_work_sync(&wvif
->bss_loss_work
);
76 wvif
->bss_loss_state
= 0;
77 schedule_work(&wvif
->bss_params_work
);
79 /* FIXME Should we just keep going until we time out? */
80 if (wvif
->bss_loss_state
< 3)
83 cancel_delayed_work_sync(&wvif
->bss_loss_work
);
84 wvif
->bss_loss_state
= 0;
87 /* Spit out a NULL packet to our AP if necessary */
88 // FIXME: call ieee80211_beacon_loss/ieee80211_connection_loss instead
92 wvif
->bss_loss_state
++;
94 skb
= ieee80211_nullfunc_get(wvif
->wdev
->hw
, wvif
->vif
, false);
97 memset(IEEE80211_SKB_CB(skb
), 0,
98 sizeof(*IEEE80211_SKB_CB(skb
)));
99 IEEE80211_SKB_CB(skb
)->control
.vif
= wvif
->vif
;
100 IEEE80211_SKB_CB(skb
)->driver_rates
[0].idx
= 0;
101 IEEE80211_SKB_CB(skb
)->driver_rates
[0].count
= 1;
102 IEEE80211_SKB_CB(skb
)->driver_rates
[1].idx
= -1;
103 wfx_tx(wvif
->wdev
->hw
, NULL
, skb
);
106 mutex_unlock(&wvif
->bss_loss_lock
);
109 int wfx_fwd_probe_req(struct wfx_vif
*wvif
, bool enable
)
111 wvif
->fwd_probe_req
= enable
;
112 return hif_set_rx_filter(wvif
, wvif
->filter_bssid
,
113 wvif
->fwd_probe_req
);
116 static int wfx_set_mcast_filter(struct wfx_vif
*wvif
,
117 struct wfx_grp_addr_table
*fp
)
120 struct hif_mib_config_data_filter config
= { };
121 struct hif_mib_set_data_filtering filter_data
= { };
122 struct hif_mib_mac_addr_data_frame_condition filter_addr_val
= { };
123 struct hif_mib_uc_mc_bc_data_frame_condition filter_addr_type
= { };
125 // Temporary workaround for filters
126 return hif_set_data_filtering(wvif
, &filter_data
);
129 filter_data
.enable
= 0;
130 return hif_set_data_filtering(wvif
, &filter_data
);
133 // A1 Address match on list
134 for (i
= 0; i
< fp
->num_addresses
; i
++) {
135 filter_addr_val
.condition_idx
= i
;
136 filter_addr_val
.address_type
= HIF_MAC_ADDR_A1
;
137 ether_addr_copy(filter_addr_val
.mac_address
,
138 fp
->address_list
[i
]);
139 ret
= hif_set_mac_addr_condition(wvif
,
143 config
.mac_cond
|= 1 << i
;
146 // Accept unicast and broadcast
147 filter_addr_type
.condition_idx
= 0;
148 filter_addr_type
.param
.bits
.type_unicast
= 1;
149 filter_addr_type
.param
.bits
.type_broadcast
= 1;
150 ret
= hif_set_uc_mc_bc_condition(wvif
, &filter_addr_type
);
154 config
.uc_mc_bc_cond
= 1;
155 config
.filter_idx
= 0; // TODO #define MULTICAST_FILTERING 0
157 ret
= hif_set_config_data_filter(wvif
, &config
);
161 // discard all data frames except match filter
162 filter_data
.enable
= 1;
163 filter_data
.default_filter
= 1; // discard all
164 ret
= hif_set_data_filtering(wvif
, &filter_data
);
169 void wfx_update_filtering(struct wfx_vif
*wvif
)
172 bool is_sta
= wvif
->vif
&& NL80211_IFTYPE_STATION
== wvif
->vif
->type
;
173 bool filter_bssid
= wvif
->filter_bssid
;
174 bool fwd_probe_req
= wvif
->fwd_probe_req
;
175 struct hif_mib_bcn_filter_enable bf_ctrl
;
176 struct hif_ie_table_entry filter_ies
[] = {
178 .ie_id
= WLAN_EID_VENDOR_SPECIFIC
,
182 .oui
= { 0x50, 0x6F, 0x9A },
184 .ie_id
= WLAN_EID_HT_OPERATION
,
189 .ie_id
= WLAN_EID_ERP_INFO
,
197 if (wvif
->state
== WFX_STATE_PASSIVE
)
200 if (wvif
->disable_beacon_filter
) {
202 bf_ctrl
.bcn_count
= 1;
204 } else if (!is_sta
) {
205 bf_ctrl
.enable
= HIF_BEACON_FILTER_ENABLE
|
206 HIF_BEACON_FILTER_AUTO_ERP
;
207 bf_ctrl
.bcn_count
= 0;
210 bf_ctrl
.enable
= HIF_BEACON_FILTER_ENABLE
;
211 bf_ctrl
.bcn_count
= 0;
215 ret
= hif_set_rx_filter(wvif
, filter_bssid
, fwd_probe_req
);
217 ret
= hif_set_beacon_filter_table(wvif
, n_filter_ies
,
220 ret
= hif_beacon_filter_control(wvif
, bf_ctrl
.enable
,
223 ret
= wfx_set_mcast_filter(wvif
, &wvif
->mcast_filter
);
225 dev_err(wvif
->wdev
->dev
, "update filtering failed: %d\n", ret
);
228 static void wfx_update_filtering_work(struct work_struct
*work
)
230 struct wfx_vif
*wvif
= container_of(work
, struct wfx_vif
,
231 update_filtering_work
);
233 wfx_update_filtering(wvif
);
236 u64
wfx_prepare_multicast(struct ieee80211_hw
*hw
,
237 struct netdev_hw_addr_list
*mc_list
)
240 struct netdev_hw_addr
*ha
;
241 struct wfx_vif
*wvif
= NULL
;
242 struct wfx_dev
*wdev
= hw
->priv
;
243 int count
= netdev_hw_addr_list_count(mc_list
);
245 while ((wvif
= wvif_iterate(wdev
, wvif
)) != NULL
) {
246 memset(&wvif
->mcast_filter
, 0x00, sizeof(wvif
->mcast_filter
));
248 count
> ARRAY_SIZE(wvif
->mcast_filter
.address_list
))
252 netdev_hw_addr_list_for_each(ha
, mc_list
) {
253 ether_addr_copy(wvif
->mcast_filter
.address_list
[i
],
257 wvif
->mcast_filter
.enable
= true;
258 wvif
->mcast_filter
.num_addresses
= count
;
264 void wfx_configure_filter(struct ieee80211_hw
*hw
,
265 unsigned int changed_flags
,
266 unsigned int *total_flags
,
269 struct wfx_vif
*wvif
= NULL
;
270 struct wfx_dev
*wdev
= hw
->priv
;
272 *total_flags
&= FIF_OTHER_BSS
| FIF_FCSFAIL
| FIF_PROBE_REQ
;
274 while ((wvif
= wvif_iterate(wdev
, wvif
)) != NULL
) {
275 mutex_lock(&wvif
->scan_lock
);
276 wvif
->filter_bssid
= (*total_flags
&
277 (FIF_OTHER_BSS
| FIF_PROBE_REQ
)) ? 0 : 1;
278 wvif
->disable_beacon_filter
= !(*total_flags
& FIF_PROBE_REQ
);
279 wfx_fwd_probe_req(wvif
, true);
280 wfx_update_filtering(wvif
);
281 mutex_unlock(&wvif
->scan_lock
);
285 static int wfx_update_pm(struct wfx_vif
*wvif
)
287 struct ieee80211_conf
*conf
= &wvif
->wdev
->hw
->conf
;
288 bool ps
= conf
->flags
& IEEE80211_CONF_PS
;
289 int ps_timeout
= conf
->dynamic_ps_timeout
;
291 WARN_ON(conf
->dynamic_ps_timeout
< 0);
292 if (wvif
->state
!= WFX_STATE_STA
|| !wvif
->bss_params
.aid
)
296 if (wvif
->uapsd_mask
)
299 // Kernel disable PowerSave when multiple vifs are in use. In contrary,
300 // it is absolutly necessary to enable PowerSave for WF200
301 // FIXME: only if channel vif0 != channel vif1
302 if (wvif_count(wvif
->wdev
) > 1) {
307 if (!wait_for_completion_timeout(&wvif
->set_pm_mode_complete
,
309 dev_warn(wvif
->wdev
->dev
,
310 "timeout while waiting of set_pm_mode_complete\n");
311 return hif_set_pm(wvif
, ps
, ps_timeout
);
314 int wfx_conf_tx(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
,
315 u16 queue
, const struct ieee80211_tx_queue_params
*params
)
317 struct wfx_dev
*wdev
= hw
->priv
;
318 struct wfx_vif
*wvif
= (struct wfx_vif
*) vif
->drv_priv
;
321 WARN_ON(queue
>= hw
->queues
);
323 mutex_lock(&wdev
->conf_mutex
);
324 assign_bit(queue
, &wvif
->uapsd_mask
, params
->uapsd
);
325 memcpy(&wvif
->edca_params
[queue
], params
, sizeof(*params
));
326 hif_set_edca_queue_params(wvif
, queue
, params
);
327 if (wvif
->vif
->type
== NL80211_IFTYPE_STATION
) {
328 hif_set_uapsd_info(wvif
, wvif
->uapsd_mask
);
329 if (wvif
->setbssparams_done
&& wvif
->state
== WFX_STATE_STA
)
330 ret
= wfx_update_pm(wvif
);
332 mutex_unlock(&wdev
->conf_mutex
);
336 int wfx_set_rts_threshold(struct ieee80211_hw
*hw
, u32 value
)
338 struct wfx_dev
*wdev
= hw
->priv
;
339 struct wfx_vif
*wvif
= NULL
;
341 while ((wvif
= wvif_iterate(wdev
, wvif
)) != NULL
)
342 hif_rts_threshold(wvif
, value
);
346 /* If successful, LOCKS the TX queue! */
347 static int __wfx_flush(struct wfx_dev
*wdev
, bool drop
)
353 wfx_tx_queues_clear(wdev
);
355 ret
= wait_event_timeout(
356 wdev
->tx_queue_stats
.wait_link_id_empty
,
357 wfx_tx_queues_is_empty(wdev
),
361 if (!drop
&& ret
<= 0) {
367 wfx_tx_lock_flush(wdev
);
368 if (!wfx_tx_queues_is_empty(wdev
)) {
369 /* Highly unlikely: WSM requeued frames. */
378 void wfx_flush(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
,
379 u32 queues
, bool drop
)
381 struct wfx_dev
*wdev
= hw
->priv
;
382 struct wfx_vif
*wvif
;
385 wvif
= (struct wfx_vif
*) vif
->drv_priv
;
386 if (wvif
->vif
->type
== NL80211_IFTYPE_MONITOR
)
388 if (wvif
->vif
->type
== NL80211_IFTYPE_AP
&&
389 !wvif
->enable_beacon
)
393 // FIXME: only flush requested vif
394 if (!__wfx_flush(wdev
, drop
))
400 static void wfx_event_report_rssi(struct wfx_vif
*wvif
, u8 raw_rcpi_rssi
)
402 /* RSSI: signed Q8.0, RCPI: unsigned Q7.1
403 * RSSI = RCPI / 2 - 110
408 rcpi_rssi
= raw_rcpi_rssi
/ 2 - 110;
409 if (rcpi_rssi
<= wvif
->cqm_rssi_thold
)
410 cqm_evt
= NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW
;
412 cqm_evt
= NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH
;
413 ieee80211_cqm_rssi_notify(wvif
->vif
, cqm_evt
, rcpi_rssi
, GFP_KERNEL
);
416 static void wfx_event_handler_work(struct work_struct
*work
)
418 struct wfx_vif
*wvif
=
419 container_of(work
, struct wfx_vif
, event_handler_work
);
420 struct wfx_hif_event
*event
;
424 spin_lock(&wvif
->event_queue_lock
);
425 list_splice_init(&wvif
->event_queue
, &list
);
426 spin_unlock(&wvif
->event_queue_lock
);
428 list_for_each_entry(event
, &list
, link
) {
429 switch (event
->evt
.event_id
) {
430 case HIF_EVENT_IND_BSSLOST
:
431 cancel_work_sync(&wvif
->unjoin_work
);
432 mutex_lock(&wvif
->scan_lock
);
433 wfx_cqm_bssloss_sm(wvif
, 1, 0, 0);
434 mutex_unlock(&wvif
->scan_lock
);
436 case HIF_EVENT_IND_BSSREGAINED
:
437 wfx_cqm_bssloss_sm(wvif
, 0, 0, 0);
438 cancel_work_sync(&wvif
->unjoin_work
);
440 case HIF_EVENT_IND_RCPI_RSSI
:
441 wfx_event_report_rssi(wvif
,
442 event
->evt
.event_data
.rcpi_rssi
);
444 case HIF_EVENT_IND_PS_MODE_ERROR
:
445 dev_warn(wvif
->wdev
->dev
,
446 "error while processing power save request\n");
449 dev_warn(wvif
->wdev
->dev
,
450 "unhandled event indication: %.2x\n",
451 event
->evt
.event_id
);
455 __wfx_free_event_queue(&list
);
458 static void wfx_bss_loss_work(struct work_struct
*work
)
460 struct wfx_vif
*wvif
= container_of(work
, struct wfx_vif
,
463 ieee80211_connection_loss(wvif
->vif
);
466 static void wfx_bss_params_work(struct work_struct
*work
)
468 struct wfx_vif
*wvif
= container_of(work
, struct wfx_vif
,
471 mutex_lock(&wvif
->wdev
->conf_mutex
);
472 wvif
->bss_params
.bss_flags
.lost_count_only
= 1;
473 hif_set_bss_params(wvif
, &wvif
->bss_params
);
474 wvif
->bss_params
.bss_flags
.lost_count_only
= 0;
475 mutex_unlock(&wvif
->wdev
->conf_mutex
);
478 static void wfx_set_beacon_wakeup_period_work(struct work_struct
*work
)
480 struct wfx_vif
*wvif
= container_of(work
, struct wfx_vif
,
481 set_beacon_wakeup_period_work
);
483 hif_set_beacon_wakeup_period(wvif
, wvif
->dtim_period
,
487 static void wfx_do_unjoin(struct wfx_vif
*wvif
)
489 mutex_lock(&wvif
->wdev
->conf_mutex
);
494 if (wvif
->state
== WFX_STATE_AP
)
497 cancel_work_sync(&wvif
->update_filtering_work
);
498 cancel_work_sync(&wvif
->set_beacon_wakeup_period_work
);
499 wvif
->state
= WFX_STATE_PASSIVE
;
501 /* Unjoin is a reset. */
502 wfx_tx_flush(wvif
->wdev
);
503 hif_keep_alive_period(wvif
, 0);
504 hif_reset(wvif
, false);
505 wfx_tx_policy_init(wvif
);
506 hif_set_output_power(wvif
, wvif
->wdev
->output_power
* 10);
507 wvif
->dtim_period
= 0;
508 hif_set_macaddr(wvif
, wvif
->vif
->addr
);
509 wfx_free_event_queue(wvif
);
510 cancel_work_sync(&wvif
->event_handler_work
);
511 wfx_cqm_bssloss_sm(wvif
, 0, 0, 0);
513 /* Disable Block ACKs */
514 hif_set_block_ack_policy(wvif
, 0, 0);
516 wvif
->disable_beacon_filter
= false;
517 wfx_update_filtering(wvif
);
518 memset(&wvif
->bss_params
, 0, sizeof(wvif
->bss_params
));
519 wvif
->setbssparams_done
= false;
520 memset(&wvif
->ht_info
, 0, sizeof(wvif
->ht_info
));
523 mutex_unlock(&wvif
->wdev
->conf_mutex
);
526 static void wfx_set_mfp(struct wfx_vif
*wvif
,
527 struct cfg80211_bss
*bss
)
529 const int pairwise_cipher_suite_count_offset
= 8 / sizeof(u16
);
530 const int pairwise_cipher_suite_size
= 4 / sizeof(u16
);
531 const int akm_suite_size
= 4 / sizeof(u16
);
532 const u16
*ptr
= NULL
;
536 /* 802.11w protected mgmt frames */
538 /* retrieve MFPC and MFPR flags from beacon or PBRSP */
542 ptr
= (const u16
*) ieee80211_bss_get_ie(bss
,
546 ptr
+= pairwise_cipher_suite_count_offset
;
547 ptr
+= 1 + pairwise_cipher_suite_size
* *ptr
;
548 ptr
+= 1 + akm_suite_size
* *ptr
;
549 mfpr
= *ptr
& BIT(6);
550 mfpc
= *ptr
& BIT(7);
554 hif_set_mfp(wvif
, mfpc
, mfpr
);
557 static void wfx_do_join(struct wfx_vif
*wvif
)
560 struct ieee80211_bss_conf
*conf
= &wvif
->vif
->bss_conf
;
561 struct cfg80211_bss
*bss
= NULL
;
562 struct hif_req_join join
= {
563 .infrastructure_bss_mode
= !conf
->ibss_joined
,
564 .short_preamble
= conf
->use_short_preamble
,
567 .basic_rate_set
= wfx_rate_mask_to_hw(wvif
->wdev
,
571 wfx_tx_lock_flush(wvif
->wdev
);
573 if (wvif
->channel
->flags
& IEEE80211_CHAN_NO_IR
)
574 join
.probe_for_join
= 0;
579 bssid
= wvif
->vif
->bss_conf
.bssid
;
581 bss
= cfg80211_get_bss(wvif
->wdev
->hw
->wiphy
, wvif
->channel
,
583 IEEE80211_BSS_TYPE_ANY
, IEEE80211_PRIVACY_ANY
);
585 if (!bss
&& !conf
->ibss_joined
) {
586 wfx_tx_unlock(wvif
->wdev
);
590 mutex_lock(&wvif
->wdev
->conf_mutex
);
592 /* Sanity check basic rates */
593 if (!join
.basic_rate_set
)
594 join
.basic_rate_set
= 7;
596 /* Sanity check beacon interval */
597 if (!wvif
->beacon_int
)
598 wvif
->beacon_int
= 1;
600 join
.beacon_interval
= wvif
->beacon_int
;
602 // DTIM period will be set on first Beacon
603 wvif
->dtim_period
= 0;
605 join
.channel_number
= wvif
->channel
->hw_value
;
606 memcpy(join
.bssid
, bssid
, sizeof(join
.bssid
));
608 if (!conf
->ibss_joined
) {
612 ssidie
= ieee80211_bss_get_ie(bss
, WLAN_EID_SSID
);
614 join
.ssid_length
= ssidie
[1];
615 memcpy(join
.ssid
, &ssidie
[2], join
.ssid_length
);
620 wfx_tx_flush(wvif
->wdev
);
622 if (wvif_count(wvif
->wdev
) <= 1)
623 hif_set_block_ack_policy(wvif
, 0xFF, 0xFF);
625 wfx_set_mfp(wvif
, bss
);
627 /* Perform actual join */
628 wvif
->wdev
->tx_burst_idx
= -1;
629 if (hif_join(wvif
, &join
)) {
630 ieee80211_connection_loss(wvif
->vif
);
631 wvif
->join_complete_status
= -1;
632 /* Tx lock still held, unjoin will clear it. */
633 if (!schedule_work(&wvif
->unjoin_work
))
634 wfx_tx_unlock(wvif
->wdev
);
636 wvif
->join_complete_status
= 0;
637 if (wvif
->vif
->type
== NL80211_IFTYPE_ADHOC
)
638 wvif
->state
= WFX_STATE_IBSS
;
640 wvif
->state
= WFX_STATE_PRE_STA
;
641 wfx_tx_unlock(wvif
->wdev
);
644 wfx_upload_keys(wvif
);
646 /* Due to beacon filtering it is possible that the
647 * AP's beacon is not known for the mac80211 stack.
648 * Disable filtering temporary to make sure the stack
649 * receives at least one
651 wvif
->disable_beacon_filter
= true;
653 wfx_update_filtering(wvif
);
655 mutex_unlock(&wvif
->wdev
->conf_mutex
);
657 cfg80211_put_bss(wvif
->wdev
->hw
->wiphy
, bss
);
660 static void wfx_unjoin_work(struct work_struct
*work
)
662 struct wfx_vif
*wvif
= container_of(work
, struct wfx_vif
, unjoin_work
);
665 wfx_tx_unlock(wvif
->wdev
);
668 int wfx_sta_add(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
,
669 struct ieee80211_sta
*sta
)
671 struct wfx_dev
*wdev
= hw
->priv
;
672 struct wfx_vif
*wvif
= (struct wfx_vif
*) vif
->drv_priv
;
673 struct wfx_sta_priv
*sta_priv
= (struct wfx_sta_priv
*) &sta
->drv_priv
;
674 struct wfx_link_entry
*entry
;
677 if (wvif
->vif
->type
!= NL80211_IFTYPE_AP
)
680 sta_priv
->vif_id
= wvif
->id
;
681 sta_priv
->link_id
= wfx_find_link_id(wvif
, sta
->addr
);
682 if (!sta_priv
->link_id
) {
683 dev_warn(wdev
->dev
, "mo more link-id available\n");
687 entry
= &wvif
->link_id_db
[sta_priv
->link_id
- 1];
688 spin_lock_bh(&wvif
->ps_state_lock
);
689 if ((sta
->uapsd_queues
& IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK
) ==
690 IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK
)
691 wvif
->sta_asleep_mask
|= BIT(sta_priv
->link_id
);
692 entry
->status
= WFX_LINK_HARD
;
693 while ((skb
= skb_dequeue(&entry
->rx_queue
)))
694 ieee80211_rx_irqsafe(wdev
->hw
, skb
);
695 spin_unlock_bh(&wvif
->ps_state_lock
);
699 int wfx_sta_remove(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
,
700 struct ieee80211_sta
*sta
)
702 struct wfx_dev
*wdev
= hw
->priv
;
703 struct wfx_vif
*wvif
= (struct wfx_vif
*) vif
->drv_priv
;
704 struct wfx_sta_priv
*sta_priv
= (struct wfx_sta_priv
*) &sta
->drv_priv
;
705 struct wfx_link_entry
*entry
;
707 if (wvif
->vif
->type
!= NL80211_IFTYPE_AP
|| !sta_priv
->link_id
)
710 entry
= &wvif
->link_id_db
[sta_priv
->link_id
- 1];
711 spin_lock_bh(&wvif
->ps_state_lock
);
712 entry
->status
= WFX_LINK_RESERVE
;
713 entry
->timestamp
= jiffies
;
715 if (!schedule_work(&wvif
->link_id_work
))
717 spin_unlock_bh(&wvif
->ps_state_lock
);
718 flush_work(&wvif
->link_id_work
);
722 static void wfx_set_cts_work(struct work_struct
*work
)
724 struct wfx_vif
*wvif
= container_of(work
, struct wfx_vif
, set_cts_work
);
725 u8 erp_ie
[3] = { WLAN_EID_ERP_INFO
, 1, 0 };
726 struct hif_ie_flags target_frame
= {
730 mutex_lock(&wvif
->wdev
->conf_mutex
);
731 erp_ie
[2] = wvif
->erp_info
;
732 mutex_unlock(&wvif
->wdev
->conf_mutex
);
734 hif_erp_use_protection(wvif
, erp_ie
[2] & WLAN_ERP_USE_PROTECTION
);
736 if (wvif
->vif
->type
!= NL80211_IFTYPE_STATION
)
737 hif_update_ie(wvif
, &target_frame
, erp_ie
, sizeof(erp_ie
));
740 static int wfx_start_ap(struct wfx_vif
*wvif
)
743 struct ieee80211_bss_conf
*conf
= &wvif
->vif
->bss_conf
;
744 struct hif_req_start start
= {
745 .channel_number
= wvif
->channel
->hw_value
,
746 .beacon_interval
= conf
->beacon_int
,
747 .dtim_period
= conf
->dtim_period
,
748 .short_preamble
= conf
->use_short_preamble
,
749 .basic_rate_set
= wfx_rate_mask_to_hw(wvif
->wdev
,
753 memset(start
.ssid
, 0, sizeof(start
.ssid
));
754 if (!conf
->hidden_ssid
) {
755 start
.ssid_length
= conf
->ssid_len
;
756 memcpy(start
.ssid
, conf
->ssid
, start
.ssid_length
);
759 wvif
->beacon_int
= conf
->beacon_int
;
760 wvif
->dtim_period
= conf
->dtim_period
;
762 memset(&wvif
->link_id_db
, 0, sizeof(wvif
->link_id_db
));
764 wvif
->wdev
->tx_burst_idx
= -1;
765 ret
= hif_start(wvif
, &start
);
767 ret
= wfx_upload_keys(wvif
);
769 if (wvif_count(wvif
->wdev
) <= 1)
770 hif_set_block_ack_policy(wvif
, 0xFF, 0xFF);
771 wvif
->state
= WFX_STATE_AP
;
772 wfx_update_filtering(wvif
);
777 static int wfx_update_beaconing(struct wfx_vif
*wvif
)
779 struct ieee80211_bss_conf
*conf
= &wvif
->vif
->bss_conf
;
781 if (wvif
->vif
->type
== NL80211_IFTYPE_AP
) {
782 /* TODO: check if changed channel, band */
783 if (wvif
->state
!= WFX_STATE_AP
||
784 wvif
->beacon_int
!= conf
->beacon_int
) {
785 wfx_tx_lock_flush(wvif
->wdev
);
786 if (wvif
->state
!= WFX_STATE_PASSIVE
) {
787 hif_reset(wvif
, false);
788 wfx_tx_policy_init(wvif
);
790 wvif
->state
= WFX_STATE_PASSIVE
;
792 wfx_tx_unlock(wvif
->wdev
);
799 static int wfx_upload_beacon(struct wfx_vif
*wvif
)
802 struct ieee80211_mgmt
*mgmt
;
804 if (wvif
->vif
->type
== NL80211_IFTYPE_STATION
||
805 wvif
->vif
->type
== NL80211_IFTYPE_MONITOR
||
806 wvif
->vif
->type
== NL80211_IFTYPE_UNSPECIFIED
)
809 skb
= ieee80211_beacon_get(wvif
->wdev
->hw
, wvif
->vif
);
812 hif_set_template_frame(wvif
, skb
, HIF_TMPLT_BCN
,
813 API_RATE_INDEX_B_1MBPS
);
815 /* TODO: Distill probe resp; remove TIM and any other beacon-specific
818 mgmt
= (void *)skb
->data
;
819 mgmt
->frame_control
=
820 cpu_to_le16(IEEE80211_FTYPE_MGMT
| IEEE80211_STYPE_PROBE_RESP
);
822 hif_set_template_frame(wvif
, skb
, HIF_TMPLT_PRBRES
,
823 API_RATE_INDEX_B_1MBPS
);
824 wfx_fwd_probe_req(wvif
, false);
829 static int wfx_is_ht(const struct wfx_ht_info
*ht_info
)
831 return ht_info
->channel_type
!= NL80211_CHAN_NO_HT
;
834 static int wfx_ht_greenfield(const struct wfx_ht_info
*ht_info
)
836 return wfx_is_ht(ht_info
) &&
837 (ht_info
->ht_cap
.cap
& IEEE80211_HT_CAP_GRN_FLD
) &&
838 !(ht_info
->operation_mode
&
839 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT
);
842 static int wfx_ht_ampdu_density(const struct wfx_ht_info
*ht_info
)
844 if (!wfx_is_ht(ht_info
))
846 return ht_info
->ht_cap
.ampdu_density
;
849 static void wfx_join_finalize(struct wfx_vif
*wvif
,
850 struct ieee80211_bss_conf
*info
)
852 struct ieee80211_sta
*sta
= NULL
;
853 struct hif_mib_set_association_mode association_mode
= { };
855 if (info
->dtim_period
)
856 wvif
->dtim_period
= info
->dtim_period
;
857 wvif
->beacon_int
= info
->beacon_int
;
860 if (info
->bssid
&& !info
->ibss_joined
)
861 sta
= ieee80211_find_sta(wvif
->vif
, info
->bssid
);
863 wvif
->ht_info
.ht_cap
= sta
->ht_cap
;
864 wvif
->bss_params
.operational_rate_set
=
865 wfx_rate_mask_to_hw(wvif
->wdev
, sta
->supp_rates
[wvif
->channel
->band
]);
866 wvif
->ht_info
.operation_mode
= info
->ht_operation_mode
;
868 memset(&wvif
->ht_info
, 0, sizeof(wvif
->ht_info
));
869 wvif
->bss_params
.operational_rate_set
= -1;
873 /* Non Greenfield stations present */
874 if (wvif
->ht_info
.operation_mode
&
875 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT
)
876 hif_dual_cts_protection(wvif
, true);
878 hif_dual_cts_protection(wvif
, false);
880 association_mode
.preambtype_use
= 1;
881 association_mode
.mode
= 1;
882 association_mode
.rateset
= 1;
883 association_mode
.spacing
= 1;
884 association_mode
.short_preamble
= info
->use_short_preamble
;
885 association_mode
.basic_rate_set
= cpu_to_le32(wfx_rate_mask_to_hw(wvif
->wdev
, info
->basic_rates
));
886 association_mode
.greenfield
= wfx_ht_greenfield(&wvif
->ht_info
);
887 association_mode
.mpdu_start_spacing
= wfx_ht_ampdu_density(&wvif
->ht_info
);
889 wfx_cqm_bssloss_sm(wvif
, 0, 0, 0);
890 cancel_work_sync(&wvif
->unjoin_work
);
892 wvif
->bss_params
.beacon_lost_count
= 20;
893 wvif
->bss_params
.aid
= info
->aid
;
895 if (wvif
->dtim_period
< 1)
896 wvif
->dtim_period
= 1;
898 hif_set_association_mode(wvif
, &association_mode
);
900 if (!info
->ibss_joined
) {
901 hif_keep_alive_period(wvif
, 30 /* sec */);
902 hif_set_bss_params(wvif
, &wvif
->bss_params
);
903 wvif
->setbssparams_done
= true;
904 wfx_set_beacon_wakeup_period_work(&wvif
->set_beacon_wakeup_period_work
);
909 void wfx_bss_info_changed(struct ieee80211_hw
*hw
,
910 struct ieee80211_vif
*vif
,
911 struct ieee80211_bss_conf
*info
,
914 struct wfx_dev
*wdev
= hw
->priv
;
915 struct wfx_vif
*wvif
= (struct wfx_vif
*) vif
->drv_priv
;
916 bool do_join
= false;
920 mutex_lock(&wdev
->conf_mutex
);
922 /* TODO: BSS_CHANGED_QOS */
923 if (changed
& BSS_CHANGED_ARP_FILTER
) {
924 struct hif_mib_arp_ip_addr_table filter
= { };
926 nb_arp_addr
= info
->arp_addr_cnt
;
927 if (nb_arp_addr
<= 0 || nb_arp_addr
> HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES
)
930 for (i
= 0; i
< HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES
; i
++) {
931 filter
.condition_idx
= i
;
932 if (i
< nb_arp_addr
) {
933 // Caution: type of arp_addr_list[i] is __be32
934 memcpy(filter
.ipv4_address
,
935 &info
->arp_addr_list
[i
],
936 sizeof(filter
.ipv4_address
));
937 filter
.arp_enable
= HIF_ARP_NS_FILTERING_ENABLE
;
939 filter
.arp_enable
= HIF_ARP_NS_FILTERING_DISABLE
;
941 hif_set_arp_ipv4_filter(wvif
, &filter
);
945 if (changed
& BSS_CHANGED_BEACON
||
946 changed
& BSS_CHANGED_AP_PROBE_RESP
||
947 changed
& BSS_CHANGED_BSSID
||
948 changed
& BSS_CHANGED_SSID
||
949 changed
& BSS_CHANGED_IBSS
) {
950 wvif
->beacon_int
= info
->beacon_int
;
951 wfx_update_beaconing(wvif
);
952 wfx_upload_beacon(wvif
);
955 if (changed
& BSS_CHANGED_BEACON_ENABLED
&&
956 wvif
->state
!= WFX_STATE_IBSS
) {
957 if (wvif
->enable_beacon
!= info
->enable_beacon
) {
958 hif_beacon_transmit(wvif
, info
->enable_beacon
);
959 wvif
->enable_beacon
= info
->enable_beacon
;
963 /* assoc/disassoc, or maybe AID changed */
964 if (changed
& BSS_CHANGED_ASSOC
) {
965 wfx_tx_lock_flush(wdev
);
966 wvif
->wep_default_key_id
= -1;
970 if (changed
& BSS_CHANGED_ASSOC
&& !info
->assoc
&&
971 (wvif
->state
== WFX_STATE_STA
|| wvif
->state
== WFX_STATE_IBSS
)) {
972 /* Shedule unjoin work */
974 if (!schedule_work(&wvif
->unjoin_work
))
977 if (changed
& BSS_CHANGED_BEACON_INT
) {
978 if (info
->ibss_joined
)
980 else if (wvif
->state
== WFX_STATE_AP
)
981 wfx_update_beaconing(wvif
);
984 if (changed
& BSS_CHANGED_BSSID
)
987 if (changed
& BSS_CHANGED_ASSOC
||
988 changed
& BSS_CHANGED_BSSID
||
989 changed
& BSS_CHANGED_IBSS
||
990 changed
& BSS_CHANGED_BASIC_RATES
||
991 changed
& BSS_CHANGED_HT
) {
993 if (wvif
->state
< WFX_STATE_PRE_STA
) {
994 ieee80211_connection_loss(vif
);
995 mutex_unlock(&wdev
->conf_mutex
);
997 } else if (wvif
->state
== WFX_STATE_PRE_STA
) {
998 wvif
->state
= WFX_STATE_STA
;
1004 if (info
->assoc
|| info
->ibss_joined
)
1005 wfx_join_finalize(wvif
, info
);
1007 memset(&wvif
->bss_params
, 0,
1008 sizeof(wvif
->bss_params
));
1012 /* ERP Protection */
1013 if (changed
& BSS_CHANGED_ASSOC
||
1014 changed
& BSS_CHANGED_ERP_CTS_PROT
||
1015 changed
& BSS_CHANGED_ERP_PREAMBLE
) {
1016 u32 prev_erp_info
= wvif
->erp_info
;
1018 if (info
->use_cts_prot
)
1019 wvif
->erp_info
|= WLAN_ERP_USE_PROTECTION
;
1020 else if (!(prev_erp_info
& WLAN_ERP_NON_ERP_PRESENT
))
1021 wvif
->erp_info
&= ~WLAN_ERP_USE_PROTECTION
;
1023 if (info
->use_short_preamble
)
1024 wvif
->erp_info
|= WLAN_ERP_BARKER_PREAMBLE
;
1026 wvif
->erp_info
&= ~WLAN_ERP_BARKER_PREAMBLE
;
1028 if (prev_erp_info
!= wvif
->erp_info
)
1029 schedule_work(&wvif
->set_cts_work
);
1032 if (changed
& BSS_CHANGED_ASSOC
|| changed
& BSS_CHANGED_ERP_SLOT
)
1033 hif_slot_time(wvif
, info
->use_short_slot
? 9 : 20);
1035 if (changed
& BSS_CHANGED_ASSOC
|| changed
& BSS_CHANGED_CQM
) {
1036 struct hif_mib_rcpi_rssi_threshold th
= {
1037 .rolling_average_count
= 8,
1041 wvif
->cqm_rssi_thold
= info
->cqm_rssi_thold
;
1043 if (!info
->cqm_rssi_thold
&& !info
->cqm_rssi_hyst
) {
1047 /* FIXME It's not a correct way of setting threshold.
1048 * Upper and lower must be set equal here and adjusted
1049 * in callback. However current implementation is much
1050 * more reliable and stable.
1052 /* RSSI: signed Q8.0, RCPI: unsigned Q7.1
1053 * RSSI = RCPI / 2 - 110
1055 th
.upper_threshold
= info
->cqm_rssi_thold
+ info
->cqm_rssi_hyst
;
1056 th
.upper_threshold
= (th
.upper_threshold
+ 110) * 2;
1057 th
.lower_threshold
= info
->cqm_rssi_thold
;
1058 th
.lower_threshold
= (th
.lower_threshold
+ 110) * 2;
1060 hif_set_rcpi_rssi_threshold(wvif
, &th
);
1063 if (changed
& BSS_CHANGED_TXPOWER
&&
1064 info
->txpower
!= wdev
->output_power
) {
1065 wdev
->output_power
= info
->txpower
;
1066 hif_set_output_power(wvif
, wdev
->output_power
* 10);
1068 mutex_unlock(&wdev
->conf_mutex
);
1074 static void wfx_ps_notify(struct wfx_vif
*wvif
, enum sta_notify_cmd notify_cmd
,
1079 spin_lock_bh(&wvif
->ps_state_lock
);
1080 /* Zero link id means "for all link IDs" */
1083 } else if (notify_cmd
!= STA_NOTIFY_AWAKE
) {
1084 dev_warn(wvif
->wdev
->dev
, "unsupported notify command\n");
1087 bit
= wvif
->link_id_map
;
1089 prev
= wvif
->sta_asleep_mask
& bit
;
1091 switch (notify_cmd
) {
1092 case STA_NOTIFY_SLEEP
:
1094 if (wvif
->mcast_buffered
&& !wvif
->sta_asleep_mask
)
1095 schedule_work(&wvif
->mcast_start_work
);
1096 wvif
->sta_asleep_mask
|= bit
;
1099 case STA_NOTIFY_AWAKE
:
1101 wvif
->sta_asleep_mask
&= ~bit
;
1102 wvif
->pspoll_mask
&= ~bit
;
1103 if (link_id
&& !wvif
->sta_asleep_mask
)
1104 schedule_work(&wvif
->mcast_stop_work
);
1105 wfx_bh_request_tx(wvif
->wdev
);
1109 spin_unlock_bh(&wvif
->ps_state_lock
);
1112 void wfx_sta_notify(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
,
1113 enum sta_notify_cmd notify_cmd
, struct ieee80211_sta
*sta
)
1115 struct wfx_vif
*wvif
= (struct wfx_vif
*) vif
->drv_priv
;
1116 struct wfx_sta_priv
*sta_priv
= (struct wfx_sta_priv
*) &sta
->drv_priv
;
1118 wfx_ps_notify(wvif
, notify_cmd
, sta_priv
->link_id
);
1121 static int wfx_set_tim_impl(struct wfx_vif
*wvif
, bool aid0_bit_set
)
1123 struct sk_buff
*skb
;
1124 struct hif_ie_flags target_frame
= {
1127 u16 tim_offset
, tim_length
;
1130 skb
= ieee80211_beacon_get_tim(wvif
->wdev
->hw
, wvif
->vif
,
1131 &tim_offset
, &tim_length
);
1133 if (!__wfx_flush(wvif
->wdev
, true))
1134 wfx_tx_unlock(wvif
->wdev
);
1137 tim_ptr
= skb
->data
+ tim_offset
;
1139 if (tim_offset
&& tim_length
>= 6) {
1140 /* Ignore DTIM count from mac80211:
1141 * firmware handles DTIM internally.
1145 /* Set/reset aid0 bit */
1152 hif_update_ie(wvif
, &target_frame
, tim_ptr
, tim_length
);
1158 static void wfx_set_tim_work(struct work_struct
*work
)
1160 struct wfx_vif
*wvif
= container_of(work
, struct wfx_vif
, set_tim_work
);
1162 wfx_set_tim_impl(wvif
, wvif
->aid0_bit_set
);
1165 int wfx_set_tim(struct ieee80211_hw
*hw
, struct ieee80211_sta
*sta
, bool set
)
1167 struct wfx_dev
*wdev
= hw
->priv
;
1168 struct wfx_sta_priv
*sta_dev
= (struct wfx_sta_priv
*) &sta
->drv_priv
;
1169 struct wfx_vif
*wvif
= wdev_to_wvif(wdev
, sta_dev
->vif_id
);
1171 schedule_work(&wvif
->set_tim_work
);
1175 static void wfx_mcast_start_work(struct work_struct
*work
)
1177 struct wfx_vif
*wvif
= container_of(work
, struct wfx_vif
,
1179 long tmo
= wvif
->dtim_period
* TU_TO_JIFFIES(wvif
->beacon_int
+ 20);
1181 cancel_work_sync(&wvif
->mcast_stop_work
);
1182 if (!wvif
->aid0_bit_set
) {
1183 wfx_tx_lock_flush(wvif
->wdev
);
1184 wfx_set_tim_impl(wvif
, true);
1185 wvif
->aid0_bit_set
= true;
1186 mod_timer(&wvif
->mcast_timeout
, jiffies
+ tmo
);
1187 wfx_tx_unlock(wvif
->wdev
);
1191 static void wfx_mcast_stop_work(struct work_struct
*work
)
1193 struct wfx_vif
*wvif
= container_of(work
, struct wfx_vif
,
1196 if (wvif
->aid0_bit_set
) {
1197 del_timer_sync(&wvif
->mcast_timeout
);
1198 wfx_tx_lock_flush(wvif
->wdev
);
1199 wvif
->aid0_bit_set
= false;
1200 wfx_set_tim_impl(wvif
, false);
1201 wfx_tx_unlock(wvif
->wdev
);
1205 static void wfx_mcast_timeout(struct timer_list
*t
)
1207 struct wfx_vif
*wvif
= from_timer(wvif
, t
, mcast_timeout
);
1209 dev_warn(wvif
->wdev
->dev
, "multicast delivery timeout\n");
1210 spin_lock_bh(&wvif
->ps_state_lock
);
1211 wvif
->mcast_tx
= wvif
->aid0_bit_set
&& wvif
->mcast_buffered
;
1213 wfx_bh_request_tx(wvif
->wdev
);
1214 spin_unlock_bh(&wvif
->ps_state_lock
);
1217 int wfx_ampdu_action(struct ieee80211_hw
*hw
,
1218 struct ieee80211_vif
*vif
,
1219 struct ieee80211_ampdu_params
*params
)
1221 /* Aggregation is implemented fully in firmware,
1222 * including block ack negotiation. Do not allow
1223 * mac80211 stack to do anything: it interferes with
1227 /* Note that we still need this function stubbed. */
1232 void wfx_suspend_resume(struct wfx_vif
*wvif
,
1233 const struct hif_ind_suspend_resume_tx
*arg
)
1235 if (arg
->suspend_resume_flags
.bc_mc_only
) {
1236 bool cancel_tmo
= false;
1238 spin_lock_bh(&wvif
->ps_state_lock
);
1239 if (!arg
->suspend_resume_flags
.resume
)
1240 wvif
->mcast_tx
= false;
1242 wvif
->mcast_tx
= wvif
->aid0_bit_set
&&
1243 wvif
->mcast_buffered
;
1244 if (wvif
->mcast_tx
) {
1246 wfx_bh_request_tx(wvif
->wdev
);
1248 spin_unlock_bh(&wvif
->ps_state_lock
);
1250 del_timer_sync(&wvif
->mcast_timeout
);
1251 } else if (arg
->suspend_resume_flags
.resume
) {
1252 // FIXME: should change each station status independently
1253 wfx_ps_notify(wvif
, STA_NOTIFY_AWAKE
, 0);
1254 wfx_bh_request_tx(wvif
->wdev
);
1256 // FIXME: should change each station status independently
1257 wfx_ps_notify(wvif
, STA_NOTIFY_SLEEP
, 0);
1261 int wfx_add_chanctx(struct ieee80211_hw
*hw
,
1262 struct ieee80211_chanctx_conf
*conf
)
1267 void wfx_remove_chanctx(struct ieee80211_hw
*hw
,
1268 struct ieee80211_chanctx_conf
*conf
)
1272 void wfx_change_chanctx(struct ieee80211_hw
*hw
,
1273 struct ieee80211_chanctx_conf
*conf
,
1278 int wfx_assign_vif_chanctx(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
,
1279 struct ieee80211_chanctx_conf
*conf
)
1281 struct wfx_vif
*wvif
= (struct wfx_vif
*) vif
->drv_priv
;
1282 struct ieee80211_channel
*ch
= conf
->def
.chan
;
1284 WARN(wvif
->channel
, "channel overwrite");
1286 wvif
->ht_info
.channel_type
= cfg80211_get_chandef_type(&conf
->def
);
1291 void wfx_unassign_vif_chanctx(struct ieee80211_hw
*hw
,
1292 struct ieee80211_vif
*vif
,
1293 struct ieee80211_chanctx_conf
*conf
)
1295 struct wfx_vif
*wvif
= (struct wfx_vif
*) vif
->drv_priv
;
1296 struct ieee80211_channel
*ch
= conf
->def
.chan
;
1298 WARN(wvif
->channel
!= ch
, "channel mismatch");
1299 wvif
->channel
= NULL
;
1302 int wfx_config(struct ieee80211_hw
*hw
, u32 changed
)
1305 struct wfx_dev
*wdev
= hw
->priv
;
1306 struct ieee80211_conf
*conf
= &hw
->conf
;
1307 struct wfx_vif
*wvif
;
1309 // FIXME: Interface id should not been hardcoded
1310 wvif
= wdev_to_wvif(wdev
, 0);
1312 WARN(1, "interface 0 does not exist anymore");
1316 mutex_lock(&wvif
->scan_lock
);
1317 mutex_lock(&wdev
->conf_mutex
);
1318 if (changed
& IEEE80211_CONF_CHANGE_POWER
) {
1319 wdev
->output_power
= conf
->power_level
;
1320 hif_set_output_power(wvif
, wdev
->output_power
* 10);
1323 if (changed
& IEEE80211_CONF_CHANGE_PS
) {
1325 while ((wvif
= wvif_iterate(wdev
, wvif
)) != NULL
)
1326 ret
= wfx_update_pm(wvif
);
1327 wvif
= wdev_to_wvif(wdev
, 0);
1330 mutex_unlock(&wdev
->conf_mutex
);
1331 mutex_unlock(&wvif
->scan_lock
);
1335 int wfx_add_interface(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
)
1338 struct wfx_dev
*wdev
= hw
->priv
;
1339 struct wfx_vif
*wvif
= (struct wfx_vif
*) vif
->drv_priv
;
1341 vif
->driver_flags
|= IEEE80211_VIF_BEACON_FILTER
|
1342 IEEE80211_VIF_SUPPORTS_UAPSD
|
1343 IEEE80211_VIF_SUPPORTS_CQM_RSSI
;
1345 mutex_lock(&wdev
->conf_mutex
);
1347 switch (vif
->type
) {
1348 case NL80211_IFTYPE_STATION
:
1349 case NL80211_IFTYPE_ADHOC
:
1350 case NL80211_IFTYPE_AP
:
1353 mutex_unlock(&wdev
->conf_mutex
);
1357 for (i
= 0; i
< ARRAY_SIZE(wdev
->vif
); i
++) {
1358 if (!wdev
->vif
[i
]) {
1364 if (i
== ARRAY_SIZE(wdev
->vif
)) {
1365 mutex_unlock(&wdev
->conf_mutex
);
1368 // FIXME: prefer use of container_of() to get vif
1372 INIT_WORK(&wvif
->link_id_work
, wfx_link_id_work
);
1373 INIT_DELAYED_WORK(&wvif
->link_id_gc_work
, wfx_link_id_gc_work
);
1375 spin_lock_init(&wvif
->ps_state_lock
);
1376 INIT_WORK(&wvif
->set_tim_work
, wfx_set_tim_work
);
1378 INIT_WORK(&wvif
->mcast_start_work
, wfx_mcast_start_work
);
1379 INIT_WORK(&wvif
->mcast_stop_work
, wfx_mcast_stop_work
);
1380 timer_setup(&wvif
->mcast_timeout
, wfx_mcast_timeout
, 0);
1382 wvif
->setbssparams_done
= false;
1383 mutex_init(&wvif
->bss_loss_lock
);
1384 INIT_DELAYED_WORK(&wvif
->bss_loss_work
, wfx_bss_loss_work
);
1386 wvif
->wep_default_key_id
= -1;
1387 INIT_WORK(&wvif
->wep_key_work
, wfx_wep_key_work
);
1389 spin_lock_init(&wvif
->event_queue_lock
);
1390 INIT_LIST_HEAD(&wvif
->event_queue
);
1391 INIT_WORK(&wvif
->event_handler_work
, wfx_event_handler_work
);
1393 init_completion(&wvif
->set_pm_mode_complete
);
1394 complete(&wvif
->set_pm_mode_complete
);
1395 INIT_WORK(&wvif
->set_beacon_wakeup_period_work
,
1396 wfx_set_beacon_wakeup_period_work
);
1397 INIT_WORK(&wvif
->update_filtering_work
, wfx_update_filtering_work
);
1398 INIT_WORK(&wvif
->bss_params_work
, wfx_bss_params_work
);
1399 INIT_WORK(&wvif
->set_cts_work
, wfx_set_cts_work
);
1400 INIT_WORK(&wvif
->unjoin_work
, wfx_unjoin_work
);
1401 INIT_WORK(&wvif
->tx_policy_upload_work
, wfx_tx_policy_upload_work
);
1403 mutex_init(&wvif
->scan_lock
);
1404 init_completion(&wvif
->scan_complete
);
1405 INIT_WORK(&wvif
->scan_work
, wfx_hw_scan_work
);
1407 INIT_WORK(&wvif
->tx_policy_upload_work
, wfx_tx_policy_upload_work
);
1408 mutex_unlock(&wdev
->conf_mutex
);
1410 hif_set_macaddr(wvif
, vif
->addr
);
1412 wfx_tx_policy_init(wvif
);
1414 while ((wvif
= wvif_iterate(wdev
, wvif
)) != NULL
) {
1415 // Combo mode does not support Block Acks. We can re-enable them
1416 if (wvif_count(wdev
) == 1)
1417 hif_set_block_ack_policy(wvif
, 0xFF, 0xFF);
1419 hif_set_block_ack_policy(wvif
, 0x00, 0x00);
1420 // Combo force powersave mode. We can re-enable it now
1421 ret
= wfx_update_pm(wvif
);
1426 void wfx_remove_interface(struct ieee80211_hw
*hw
,
1427 struct ieee80211_vif
*vif
)
1429 struct wfx_dev
*wdev
= hw
->priv
;
1430 struct wfx_vif
*wvif
= (struct wfx_vif
*) vif
->drv_priv
;
1433 wait_for_completion_timeout(&wvif
->set_pm_mode_complete
, msecs_to_jiffies(300));
1435 mutex_lock(&wdev
->conf_mutex
);
1436 switch (wvif
->state
) {
1437 case WFX_STATE_PRE_STA
:
1439 case WFX_STATE_IBSS
:
1440 wfx_tx_lock_flush(wdev
);
1441 if (!schedule_work(&wvif
->unjoin_work
))
1442 wfx_tx_unlock(wdev
);
1445 for (i
= 0; wvif
->link_id_map
; ++i
) {
1446 if (wvif
->link_id_map
& BIT(i
)) {
1447 wfx_unmap_link(wvif
, i
);
1448 wvif
->link_id_map
&= ~BIT(i
);
1451 memset(wvif
->link_id_db
, 0, sizeof(wvif
->link_id_db
));
1452 wvif
->sta_asleep_mask
= 0;
1453 wvif
->enable_beacon
= false;
1454 wvif
->mcast_tx
= false;
1455 wvif
->aid0_bit_set
= false;
1456 wvif
->mcast_buffered
= false;
1457 wvif
->pspoll_mask
= 0;
1458 /* reset.link_id = 0; */
1459 hif_reset(wvif
, false);
1465 wvif
->state
= WFX_STATE_PASSIVE
;
1466 wfx_tx_queues_wait_empty_vif(wvif
);
1467 wfx_tx_unlock(wdev
);
1469 /* FIXME: In add to reset MAC address, try to reset interface */
1470 hif_set_macaddr(wvif
, NULL
);
1472 wfx_cqm_bssloss_sm(wvif
, 0, 0, 0);
1473 cancel_work_sync(&wvif
->unjoin_work
);
1474 cancel_delayed_work_sync(&wvif
->link_id_gc_work
);
1475 del_timer_sync(&wvif
->mcast_timeout
);
1476 wfx_free_event_queue(wvif
);
1478 wdev
->vif
[wvif
->id
] = NULL
;
1481 mutex_unlock(&wdev
->conf_mutex
);
1483 while ((wvif
= wvif_iterate(wdev
, wvif
)) != NULL
) {
1484 // Combo mode does not support Block Acks. We can re-enable them
1485 if (wvif_count(wdev
) == 1)
1486 hif_set_block_ack_policy(wvif
, 0xFF, 0xFF);
1488 hif_set_block_ack_policy(wvif
, 0x00, 0x00);
1489 // Combo force powersave mode. We can re-enable it now
1490 wfx_update_pm(wvif
);
1494 int wfx_start(struct ieee80211_hw
*hw
)
1499 void wfx_stop(struct ieee80211_hw
*hw
)
1501 struct wfx_dev
*wdev
= hw
->priv
;
1503 wfx_tx_lock_flush(wdev
);
1504 mutex_lock(&wdev
->conf_mutex
);
1505 wfx_tx_queues_clear(wdev
);
1506 mutex_unlock(&wdev
->conf_mutex
);
1507 wfx_tx_unlock(wdev
);
1508 WARN(atomic_read(&wdev
->tx_lock
), "tx_lock is locked");