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 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
91 struct ieee80211_hdr
*hdr
;
92 struct ieee80211_tx_control control
= { };
94 wvif
->bss_loss_state
++;
96 skb
= ieee80211_nullfunc_get(wvif
->wdev
->hw
, wvif
->vif
, false);
99 hdr
= (struct ieee80211_hdr
*)skb
->data
;
100 memset(IEEE80211_SKB_CB(skb
), 0,
101 sizeof(*IEEE80211_SKB_CB(skb
)));
102 IEEE80211_SKB_CB(skb
)->control
.vif
= wvif
->vif
;
103 IEEE80211_SKB_CB(skb
)->driver_rates
[0].idx
= 0;
104 IEEE80211_SKB_CB(skb
)->driver_rates
[0].count
= 1;
105 IEEE80211_SKB_CB(skb
)->driver_rates
[1].idx
= -1;
106 rcu_read_lock(); // protect control.sta
107 control
.sta
= ieee80211_find_sta(wvif
->vif
, hdr
->addr1
);
108 wfx_tx(wvif
->wdev
->hw
, &control
, skb
);
112 mutex_unlock(&wvif
->bss_loss_lock
);
115 int wfx_fwd_probe_req(struct wfx_vif
*wvif
, bool enable
)
117 wvif
->fwd_probe_req
= enable
;
118 return hif_set_rx_filter(wvif
, wvif
->filter_bssid
,
119 wvif
->fwd_probe_req
);
122 static int wfx_set_mcast_filter(struct wfx_vif
*wvif
,
123 struct wfx_grp_addr_table
*fp
)
127 // Temporary workaround for filters
128 return hif_set_data_filtering(wvif
, false, true);
131 return hif_set_data_filtering(wvif
, false, true);
133 for (i
= 0; i
< fp
->num_addresses
; i
++)
134 hif_set_mac_addr_condition(wvif
, i
, fp
->address_list
[i
]);
135 hif_set_uc_mc_bc_condition(wvif
, 0,
136 HIF_FILTER_UNICAST
| HIF_FILTER_BROADCAST
);
137 hif_set_config_data_filter(wvif
, true, 0, BIT(1),
138 BIT(fp
->num_addresses
) - 1);
139 hif_set_data_filtering(wvif
, true, true);
144 void wfx_update_filtering(struct wfx_vif
*wvif
)
150 struct hif_ie_table_entry filter_ies
[] = {
152 .ie_id
= WLAN_EID_VENDOR_SPECIFIC
,
156 .oui
= { 0x50, 0x6F, 0x9A },
158 .ie_id
= WLAN_EID_HT_OPERATION
,
163 .ie_id
= WLAN_EID_ERP_INFO
,
170 if (wvif
->state
== WFX_STATE_PASSIVE
)
173 if (wvif
->disable_beacon_filter
) {
177 } else if (wvif
->vif
->type
!= NL80211_IFTYPE_STATION
) {
178 bf_enable
= HIF_BEACON_FILTER_ENABLE
| HIF_BEACON_FILTER_AUTO_ERP
;
182 bf_enable
= HIF_BEACON_FILTER_ENABLE
;
187 ret
= hif_set_rx_filter(wvif
, wvif
->filter_bssid
, wvif
->fwd_probe_req
);
189 ret
= hif_set_beacon_filter_table(wvif
, n_filter_ies
, filter_ies
);
191 ret
= hif_beacon_filter_control(wvif
, bf_enable
, bf_count
);
193 ret
= wfx_set_mcast_filter(wvif
, &wvif
->mcast_filter
);
195 dev_err(wvif
->wdev
->dev
, "update filtering failed: %d\n", ret
);
198 static void wfx_update_filtering_work(struct work_struct
*work
)
200 struct wfx_vif
*wvif
= container_of(work
, struct wfx_vif
,
201 update_filtering_work
);
203 wfx_update_filtering(wvif
);
206 u64
wfx_prepare_multicast(struct ieee80211_hw
*hw
,
207 struct netdev_hw_addr_list
*mc_list
)
210 struct netdev_hw_addr
*ha
;
211 struct wfx_vif
*wvif
= NULL
;
212 struct wfx_dev
*wdev
= hw
->priv
;
213 int count
= netdev_hw_addr_list_count(mc_list
);
215 while ((wvif
= wvif_iterate(wdev
, wvif
)) != NULL
) {
216 memset(&wvif
->mcast_filter
, 0x00, sizeof(wvif
->mcast_filter
));
218 count
> ARRAY_SIZE(wvif
->mcast_filter
.address_list
))
222 netdev_hw_addr_list_for_each(ha
, mc_list
) {
223 ether_addr_copy(wvif
->mcast_filter
.address_list
[i
],
227 wvif
->mcast_filter
.enable
= true;
228 wvif
->mcast_filter
.num_addresses
= count
;
234 void wfx_configure_filter(struct ieee80211_hw
*hw
,
235 unsigned int changed_flags
,
236 unsigned int *total_flags
,
239 struct wfx_vif
*wvif
= NULL
;
240 struct wfx_dev
*wdev
= hw
->priv
;
242 *total_flags
&= FIF_OTHER_BSS
| FIF_FCSFAIL
| FIF_PROBE_REQ
;
244 while ((wvif
= wvif_iterate(wdev
, wvif
)) != NULL
) {
245 mutex_lock(&wvif
->scan_lock
);
246 wvif
->filter_bssid
= (*total_flags
&
247 (FIF_OTHER_BSS
| FIF_PROBE_REQ
)) ? 0 : 1;
248 wvif
->disable_beacon_filter
= !(*total_flags
& FIF_PROBE_REQ
);
249 wfx_fwd_probe_req(wvif
, true);
250 wfx_update_filtering(wvif
);
251 mutex_unlock(&wvif
->scan_lock
);
255 static int wfx_update_pm(struct wfx_vif
*wvif
)
257 struct ieee80211_conf
*conf
= &wvif
->wdev
->hw
->conf
;
258 bool ps
= conf
->flags
& IEEE80211_CONF_PS
;
259 int ps_timeout
= conf
->dynamic_ps_timeout
;
260 struct ieee80211_channel
*chan0
= NULL
, *chan1
= NULL
;
262 WARN_ON(conf
->dynamic_ps_timeout
< 0);
263 if (wvif
->state
!= WFX_STATE_STA
|| !wvif
->bss_params
.aid
)
267 if (wvif
->uapsd_mask
)
270 // Kernel disable powersave when an AP is in use. In contrary, it is
271 // absolutely necessary to enable legacy powersave for WF200 if channels
273 if (wdev_to_wvif(wvif
->wdev
, 0))
274 chan0
= wdev_to_wvif(wvif
->wdev
, 0)->vif
->bss_conf
.chandef
.chan
;
275 if (wdev_to_wvif(wvif
->wdev
, 1))
276 chan1
= wdev_to_wvif(wvif
->wdev
, 1)->vif
->bss_conf
.chandef
.chan
;
277 if (chan0
&& chan1
&& chan0
->hw_value
!= chan1
->hw_value
&&
278 wvif
->vif
->type
!= NL80211_IFTYPE_AP
) {
283 if (!wait_for_completion_timeout(&wvif
->set_pm_mode_complete
,
285 dev_warn(wvif
->wdev
->dev
,
286 "timeout while waiting of set_pm_mode_complete\n");
287 return hif_set_pm(wvif
, ps
, ps_timeout
);
290 int wfx_conf_tx(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
,
291 u16 queue
, const struct ieee80211_tx_queue_params
*params
)
293 struct wfx_dev
*wdev
= hw
->priv
;
294 struct wfx_vif
*wvif
= (struct wfx_vif
*) vif
->drv_priv
;
295 int old_uapsd
= wvif
->uapsd_mask
;
298 WARN_ON(queue
>= hw
->queues
);
300 mutex_lock(&wdev
->conf_mutex
);
301 assign_bit(queue
, &wvif
->uapsd_mask
, params
->uapsd
);
302 memcpy(&wvif
->edca_params
[queue
], params
, sizeof(*params
));
303 hif_set_edca_queue_params(wvif
, queue
, params
);
304 if (wvif
->vif
->type
== NL80211_IFTYPE_STATION
&&
305 old_uapsd
!= wvif
->uapsd_mask
) {
306 hif_set_uapsd_info(wvif
, wvif
->uapsd_mask
);
309 mutex_unlock(&wdev
->conf_mutex
);
313 int wfx_set_rts_threshold(struct ieee80211_hw
*hw
, u32 value
)
315 struct wfx_dev
*wdev
= hw
->priv
;
316 struct wfx_vif
*wvif
= NULL
;
318 while ((wvif
= wvif_iterate(wdev
, wvif
)) != NULL
)
319 hif_rts_threshold(wvif
, value
);
323 static int __wfx_flush(struct wfx_dev
*wdev
, bool drop
)
327 wfx_tx_queues_clear(wdev
);
328 if (wait_event_timeout(wdev
->tx_queue_stats
.wait_link_id_empty
,
329 wfx_tx_queues_is_empty(wdev
),
333 if (wfx_tx_queues_is_empty(wdev
))
335 dev_warn(wdev
->dev
, "frames queued while flushing tx queues");
339 void wfx_flush(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
,
340 u32 queues
, bool drop
)
342 // FIXME: only flush requested vif and queues
343 __wfx_flush(hw
->priv
, drop
);
348 static void wfx_event_report_rssi(struct wfx_vif
*wvif
, u8 raw_rcpi_rssi
)
350 /* RSSI: signed Q8.0, RCPI: unsigned Q7.1
351 * RSSI = RCPI / 2 - 110
356 rcpi_rssi
= raw_rcpi_rssi
/ 2 - 110;
357 if (rcpi_rssi
<= wvif
->vif
->bss_conf
.cqm_rssi_thold
)
358 cqm_evt
= NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW
;
360 cqm_evt
= NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH
;
361 ieee80211_cqm_rssi_notify(wvif
->vif
, cqm_evt
, rcpi_rssi
, GFP_KERNEL
);
364 static void wfx_event_handler_work(struct work_struct
*work
)
366 struct wfx_vif
*wvif
=
367 container_of(work
, struct wfx_vif
, event_handler_work
);
368 struct wfx_hif_event
*event
;
372 spin_lock(&wvif
->event_queue_lock
);
373 list_splice_init(&wvif
->event_queue
, &list
);
374 spin_unlock(&wvif
->event_queue_lock
);
376 list_for_each_entry(event
, &list
, link
) {
377 switch (event
->evt
.event_id
) {
378 case HIF_EVENT_IND_BSSLOST
:
379 cancel_work_sync(&wvif
->unjoin_work
);
380 mutex_lock(&wvif
->scan_lock
);
381 wfx_cqm_bssloss_sm(wvif
, 1, 0, 0);
382 mutex_unlock(&wvif
->scan_lock
);
384 case HIF_EVENT_IND_BSSREGAINED
:
385 wfx_cqm_bssloss_sm(wvif
, 0, 0, 0);
386 cancel_work_sync(&wvif
->unjoin_work
);
388 case HIF_EVENT_IND_RCPI_RSSI
:
389 wfx_event_report_rssi(wvif
,
390 event
->evt
.event_data
.rcpi_rssi
);
392 case HIF_EVENT_IND_PS_MODE_ERROR
:
393 dev_warn(wvif
->wdev
->dev
,
394 "error while processing power save request\n");
397 dev_warn(wvif
->wdev
->dev
,
398 "unhandled event indication: %.2x\n",
399 event
->evt
.event_id
);
403 __wfx_free_event_queue(&list
);
406 static void wfx_bss_loss_work(struct work_struct
*work
)
408 struct wfx_vif
*wvif
= container_of(work
, struct wfx_vif
,
411 ieee80211_connection_loss(wvif
->vif
);
414 static void wfx_bss_params_work(struct work_struct
*work
)
416 struct wfx_vif
*wvif
= container_of(work
, struct wfx_vif
,
419 mutex_lock(&wvif
->wdev
->conf_mutex
);
420 wvif
->bss_params
.bss_flags
.lost_count_only
= 1;
421 hif_set_bss_params(wvif
, &wvif
->bss_params
);
422 wvif
->bss_params
.bss_flags
.lost_count_only
= 0;
423 mutex_unlock(&wvif
->wdev
->conf_mutex
);
426 static void wfx_do_unjoin(struct wfx_vif
*wvif
)
428 mutex_lock(&wvif
->wdev
->conf_mutex
);
433 if (wvif
->state
== WFX_STATE_AP
)
436 cancel_work_sync(&wvif
->update_filtering_work
);
437 wvif
->state
= WFX_STATE_PASSIVE
;
439 /* Unjoin is a reset. */
440 wfx_tx_flush(wvif
->wdev
);
441 hif_keep_alive_period(wvif
, 0);
442 hif_reset(wvif
, false);
443 wfx_tx_policy_init(wvif
);
444 hif_set_macaddr(wvif
, wvif
->vif
->addr
);
445 wfx_free_event_queue(wvif
);
446 cancel_work_sync(&wvif
->event_handler_work
);
447 wfx_cqm_bssloss_sm(wvif
, 0, 0, 0);
449 /* Disable Block ACKs */
450 hif_set_block_ack_policy(wvif
, 0, 0);
452 wvif
->disable_beacon_filter
= false;
453 wfx_update_filtering(wvif
);
454 memset(&wvif
->bss_params
, 0, sizeof(wvif
->bss_params
));
457 mutex_unlock(&wvif
->wdev
->conf_mutex
);
460 static void wfx_set_mfp(struct wfx_vif
*wvif
,
461 struct cfg80211_bss
*bss
)
463 const int pairwise_cipher_suite_count_offset
= 8 / sizeof(u16
);
464 const int pairwise_cipher_suite_size
= 4 / sizeof(u16
);
465 const int akm_suite_size
= 4 / sizeof(u16
);
466 const u16
*ptr
= NULL
;
470 /* 802.11w protected mgmt frames */
472 /* retrieve MFPC and MFPR flags from beacon or PBRSP */
476 ptr
= (const u16
*) ieee80211_bss_get_ie(bss
,
480 ptr
+= pairwise_cipher_suite_count_offset
;
481 ptr
+= 1 + pairwise_cipher_suite_size
* *ptr
;
482 ptr
+= 1 + akm_suite_size
* *ptr
;
483 mfpr
= *ptr
& BIT(6);
484 mfpc
= *ptr
& BIT(7);
488 hif_set_mfp(wvif
, mfpc
, mfpr
);
491 static void wfx_do_join(struct wfx_vif
*wvif
)
495 struct ieee80211_bss_conf
*conf
= &wvif
->vif
->bss_conf
;
496 struct cfg80211_bss
*bss
= NULL
;
498 wfx_tx_lock_flush(wvif
->wdev
);
503 bss
= cfg80211_get_bss(wvif
->wdev
->hw
->wiphy
, wvif
->channel
,
504 conf
->bssid
, NULL
, 0,
505 IEEE80211_BSS_TYPE_ANY
, IEEE80211_PRIVACY_ANY
);
506 if (!bss
&& !conf
->ibss_joined
) {
507 wfx_tx_unlock(wvif
->wdev
);
511 mutex_lock(&wvif
->wdev
->conf_mutex
);
513 /* Sanity check beacon interval */
514 if (!wvif
->beacon_int
)
515 wvif
->beacon_int
= 1;
518 if (!conf
->ibss_joined
)
519 ssidie
= ieee80211_bss_get_ie(bss
, WLAN_EID_SSID
);
523 wfx_tx_flush(wvif
->wdev
);
525 if (wvif_count(wvif
->wdev
) <= 1)
526 hif_set_block_ack_policy(wvif
, 0xFF, 0xFF);
528 wfx_set_mfp(wvif
, bss
);
530 /* Perform actual join */
531 wvif
->wdev
->tx_burst_idx
= -1;
532 ret
= hif_join(wvif
, conf
, wvif
->channel
, ssidie
);
535 ieee80211_connection_loss(wvif
->vif
);
536 wvif
->join_complete_status
= -1;
537 /* Tx lock still held, unjoin will clear it. */
538 if (!schedule_work(&wvif
->unjoin_work
))
539 wfx_tx_unlock(wvif
->wdev
);
541 wvif
->join_complete_status
= 0;
542 if (wvif
->vif
->type
== NL80211_IFTYPE_ADHOC
)
543 wvif
->state
= WFX_STATE_IBSS
;
545 wvif
->state
= WFX_STATE_PRE_STA
;
546 wfx_tx_unlock(wvif
->wdev
);
549 wfx_upload_keys(wvif
);
551 /* Due to beacon filtering it is possible that the
552 * AP's beacon is not known for the mac80211 stack.
553 * Disable filtering temporary to make sure the stack
554 * receives at least one
556 wvif
->disable_beacon_filter
= true;
558 wfx_update_filtering(wvif
);
560 mutex_unlock(&wvif
->wdev
->conf_mutex
);
562 cfg80211_put_bss(wvif
->wdev
->hw
->wiphy
, bss
);
565 static void wfx_unjoin_work(struct work_struct
*work
)
567 struct wfx_vif
*wvif
= container_of(work
, struct wfx_vif
, unjoin_work
);
570 wfx_tx_unlock(wvif
->wdev
);
573 int wfx_sta_add(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
,
574 struct ieee80211_sta
*sta
)
576 struct wfx_vif
*wvif
= (struct wfx_vif
*) vif
->drv_priv
;
577 struct wfx_sta_priv
*sta_priv
= (struct wfx_sta_priv
*) &sta
->drv_priv
;
579 spin_lock_init(&sta_priv
->lock
);
580 sta_priv
->vif_id
= wvif
->id
;
582 // FIXME: in station mode, the current API interprets new link-id as a
584 if (vif
->type
== NL80211_IFTYPE_STATION
)
586 sta_priv
->link_id
= ffz(wvif
->link_id_map
);
587 wvif
->link_id_map
|= BIT(sta_priv
->link_id
);
588 WARN_ON(!sta_priv
->link_id
);
589 WARN_ON(sta_priv
->link_id
>= WFX_MAX_STA_IN_AP_MODE
);
590 hif_map_link(wvif
, sta
->addr
, 0, sta_priv
->link_id
);
592 spin_lock_bh(&wvif
->ps_state_lock
);
593 if ((sta
->uapsd_queues
& IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK
) ==
594 IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK
)
595 wvif
->sta_asleep_mask
|= BIT(sta_priv
->link_id
);
596 spin_unlock_bh(&wvif
->ps_state_lock
);
600 int wfx_sta_remove(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
,
601 struct ieee80211_sta
*sta
)
603 struct wfx_vif
*wvif
= (struct wfx_vif
*) vif
->drv_priv
;
604 struct wfx_sta_priv
*sta_priv
= (struct wfx_sta_priv
*) &sta
->drv_priv
;
607 for (i
= 0; i
< ARRAY_SIZE(sta_priv
->buffered
); i
++)
608 WARN(sta_priv
->buffered
[i
], "release station while Tx is in progress");
609 // FIXME: see note in wfx_sta_add()
610 if (vif
->type
== NL80211_IFTYPE_STATION
)
612 // FIXME add a mutex?
613 hif_map_link(wvif
, sta
->addr
, 1, sta_priv
->link_id
);
614 wvif
->link_id_map
&= ~BIT(sta_priv
->link_id
);
618 static int wfx_start_ap(struct wfx_vif
*wvif
)
622 wvif
->beacon_int
= wvif
->vif
->bss_conf
.beacon_int
;
623 wvif
->wdev
->tx_burst_idx
= -1;
624 ret
= hif_start(wvif
, &wvif
->vif
->bss_conf
, wvif
->channel
);
627 ret
= wfx_upload_keys(wvif
);
630 if (wvif_count(wvif
->wdev
) <= 1)
631 hif_set_block_ack_policy(wvif
, 0xFF, 0xFF);
632 wvif
->state
= WFX_STATE_AP
;
633 wfx_update_filtering(wvif
);
637 static int wfx_update_beaconing(struct wfx_vif
*wvif
)
639 if (wvif
->vif
->type
!= NL80211_IFTYPE_AP
)
641 if (wvif
->state
== WFX_STATE_AP
&&
642 wvif
->beacon_int
== wvif
->vif
->bss_conf
.beacon_int
)
644 wfx_tx_lock_flush(wvif
->wdev
);
645 hif_reset(wvif
, false);
646 wfx_tx_policy_init(wvif
);
647 wvif
->state
= WFX_STATE_PASSIVE
;
649 wfx_tx_unlock(wvif
->wdev
);
653 static int wfx_upload_ap_templates(struct wfx_vif
*wvif
)
657 if (wvif
->vif
->type
== NL80211_IFTYPE_STATION
||
658 wvif
->vif
->type
== NL80211_IFTYPE_MONITOR
||
659 wvif
->vif
->type
== NL80211_IFTYPE_UNSPECIFIED
)
662 skb
= ieee80211_beacon_get(wvif
->wdev
->hw
, wvif
->vif
);
665 hif_set_template_frame(wvif
, skb
, HIF_TMPLT_BCN
,
666 API_RATE_INDEX_B_1MBPS
);
669 skb
= ieee80211_proberesp_get(wvif
->wdev
->hw
, wvif
->vif
);
672 hif_set_template_frame(wvif
, skb
, HIF_TMPLT_PRBRES
,
673 API_RATE_INDEX_B_1MBPS
);
678 static void wfx_join_finalize(struct wfx_vif
*wvif
,
679 struct ieee80211_bss_conf
*info
)
681 struct ieee80211_sta
*sta
= NULL
;
683 wvif
->beacon_int
= info
->beacon_int
;
684 rcu_read_lock(); // protect sta
685 if (info
->bssid
&& !info
->ibss_joined
)
686 sta
= ieee80211_find_sta(wvif
->vif
, info
->bssid
);
688 wvif
->bss_params
.operational_rate_set
=
689 wfx_rate_mask_to_hw(wvif
->wdev
, sta
->supp_rates
[wvif
->channel
->band
]);
691 wvif
->bss_params
.operational_rate_set
= -1;
693 info
->ht_operation_mode
& IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT
)
694 hif_dual_cts_protection(wvif
, true);
696 hif_dual_cts_protection(wvif
, false);
698 wfx_cqm_bssloss_sm(wvif
, 0, 0, 0);
699 cancel_work_sync(&wvif
->unjoin_work
);
701 wvif
->bss_params
.beacon_lost_count
= 20;
702 wvif
->bss_params
.aid
= info
->aid
;
704 hif_set_association_mode(wvif
, info
, sta
? &sta
->ht_cap
: NULL
);
707 if (!info
->ibss_joined
) {
708 hif_keep_alive_period(wvif
, 30 /* sec */);
709 hif_set_bss_params(wvif
, &wvif
->bss_params
);
710 hif_set_beacon_wakeup_period(wvif
, info
->dtim_period
,
716 void wfx_bss_info_changed(struct ieee80211_hw
*hw
,
717 struct ieee80211_vif
*vif
,
718 struct ieee80211_bss_conf
*info
,
721 struct wfx_dev
*wdev
= hw
->priv
;
722 struct wfx_vif
*wvif
= (struct wfx_vif
*) vif
->drv_priv
;
723 bool do_join
= false;
726 mutex_lock(&wdev
->conf_mutex
);
728 /* TODO: BSS_CHANGED_QOS */
729 if (changed
& BSS_CHANGED_ARP_FILTER
) {
730 for (i
= 0; i
< HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES
; i
++) {
731 __be32
*arp_addr
= &info
->arp_addr_list
[i
];
733 if (info
->arp_addr_cnt
> HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES
)
735 if (i
>= info
->arp_addr_cnt
)
737 hif_set_arp_ipv4_filter(wvif
, i
, arp_addr
);
741 if (changed
& BSS_CHANGED_BEACON
||
742 changed
& BSS_CHANGED_AP_PROBE_RESP
||
743 changed
& BSS_CHANGED_BSSID
||
744 changed
& BSS_CHANGED_SSID
||
745 changed
& BSS_CHANGED_IBSS
) {
746 wvif
->beacon_int
= info
->beacon_int
;
747 wfx_update_beaconing(wvif
);
748 wfx_upload_ap_templates(wvif
);
749 wfx_fwd_probe_req(wvif
, false);
752 if (changed
& BSS_CHANGED_BEACON_ENABLED
&&
753 wvif
->state
!= WFX_STATE_IBSS
)
754 hif_beacon_transmit(wvif
, info
->enable_beacon
);
756 if (changed
& BSS_CHANGED_BEACON_INFO
)
757 hif_set_beacon_wakeup_period(wvif
, info
->dtim_period
,
760 /* assoc/disassoc, or maybe AID changed */
761 if (changed
& BSS_CHANGED_ASSOC
) {
762 wfx_tx_lock_flush(wdev
);
763 wvif
->wep_default_key_id
= -1;
767 if (changed
& BSS_CHANGED_ASSOC
&& !info
->assoc
&&
768 (wvif
->state
== WFX_STATE_STA
|| wvif
->state
== WFX_STATE_IBSS
)) {
769 /* Shedule unjoin work */
771 if (!schedule_work(&wvif
->unjoin_work
))
774 if (changed
& BSS_CHANGED_BEACON_INT
) {
775 if (info
->ibss_joined
)
777 else if (wvif
->state
== WFX_STATE_AP
)
778 wfx_update_beaconing(wvif
);
781 if (changed
& BSS_CHANGED_BSSID
)
784 if (changed
& BSS_CHANGED_ASSOC
||
785 changed
& BSS_CHANGED_BSSID
||
786 changed
& BSS_CHANGED_IBSS
||
787 changed
& BSS_CHANGED_BASIC_RATES
||
788 changed
& BSS_CHANGED_HT
) {
790 if (wvif
->state
< WFX_STATE_PRE_STA
) {
791 ieee80211_connection_loss(vif
);
792 mutex_unlock(&wdev
->conf_mutex
);
794 } else if (wvif
->state
== WFX_STATE_PRE_STA
) {
795 wvif
->state
= WFX_STATE_STA
;
801 if (info
->assoc
|| info
->ibss_joined
)
802 wfx_join_finalize(wvif
, info
);
804 memset(&wvif
->bss_params
, 0,
805 sizeof(wvif
->bss_params
));
809 if (changed
& BSS_CHANGED_ASSOC
||
810 changed
& BSS_CHANGED_ERP_CTS_PROT
||
811 changed
& BSS_CHANGED_ERP_PREAMBLE
) {
812 u8 erp_ie
[3] = { WLAN_EID_ERP_INFO
, 1, 0 };
814 hif_erp_use_protection(wvif
, info
->use_cts_prot
);
815 if (info
->use_cts_prot
)
816 erp_ie
[2] |= WLAN_ERP_USE_PROTECTION
;
817 if (info
->use_short_preamble
)
818 erp_ie
[2] |= WLAN_ERP_BARKER_PREAMBLE
;
819 if (wvif
->vif
->type
!= NL80211_IFTYPE_STATION
)
820 hif_update_ie_beacon(wvif
, erp_ie
, sizeof(erp_ie
));
823 if (changed
& BSS_CHANGED_ASSOC
|| changed
& BSS_CHANGED_ERP_SLOT
)
824 hif_slot_time(wvif
, info
->use_short_slot
? 9 : 20);
826 if (changed
& BSS_CHANGED_ASSOC
|| changed
& BSS_CHANGED_CQM
)
827 hif_set_rcpi_rssi_threshold(wvif
, info
->cqm_rssi_thold
,
828 info
->cqm_rssi_hyst
);
830 if (changed
& BSS_CHANGED_TXPOWER
)
831 hif_set_output_power(wvif
, info
->txpower
);
833 if (changed
& BSS_CHANGED_PS
)
836 mutex_unlock(&wdev
->conf_mutex
);
842 static void wfx_ps_notify_sta(struct wfx_vif
*wvif
,
843 enum sta_notify_cmd notify_cmd
, int link_id
)
845 spin_lock_bh(&wvif
->ps_state_lock
);
846 if (notify_cmd
== STA_NOTIFY_SLEEP
)
847 wvif
->sta_asleep_mask
|= BIT(link_id
);
848 else // notify_cmd == STA_NOTIFY_AWAKE
849 wvif
->sta_asleep_mask
&= ~BIT(link_id
);
850 spin_unlock_bh(&wvif
->ps_state_lock
);
851 if (notify_cmd
== STA_NOTIFY_AWAKE
)
852 wfx_bh_request_tx(wvif
->wdev
);
855 void wfx_sta_notify(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
,
856 enum sta_notify_cmd notify_cmd
, struct ieee80211_sta
*sta
)
858 struct wfx_vif
*wvif
= (struct wfx_vif
*) vif
->drv_priv
;
859 struct wfx_sta_priv
*sta_priv
= (struct wfx_sta_priv
*) &sta
->drv_priv
;
861 wfx_ps_notify_sta(wvif
, notify_cmd
, sta_priv
->link_id
);
864 static int wfx_update_tim(struct wfx_vif
*wvif
)
867 u16 tim_offset
, tim_length
;
870 skb
= ieee80211_beacon_get_tim(wvif
->wdev
->hw
, wvif
->vif
,
871 &tim_offset
, &tim_length
);
873 __wfx_flush(wvif
->wdev
, true);
876 tim_ptr
= skb
->data
+ tim_offset
;
878 if (tim_offset
&& tim_length
>= 6) {
879 /* Ignore DTIM count from mac80211:
880 * firmware handles DTIM internally.
884 /* Set/reset aid0 bit */
885 if (wfx_tx_queues_get_after_dtim(wvif
))
891 hif_update_ie_beacon(wvif
, tim_ptr
, tim_length
);
897 static void wfx_update_tim_work(struct work_struct
*work
)
899 struct wfx_vif
*wvif
= container_of(work
, struct wfx_vif
, update_tim_work
);
901 wfx_update_tim(wvif
);
904 int wfx_set_tim(struct ieee80211_hw
*hw
, struct ieee80211_sta
*sta
, bool set
)
906 struct wfx_dev
*wdev
= hw
->priv
;
907 struct wfx_sta_priv
*sta_dev
= (struct wfx_sta_priv
*) &sta
->drv_priv
;
908 struct wfx_vif
*wvif
= wdev_to_wvif(wdev
, sta_dev
->vif_id
);
910 schedule_work(&wvif
->update_tim_work
);
914 void wfx_suspend_resume_mc(struct wfx_vif
*wvif
, enum sta_notify_cmd notify_cmd
)
916 WARN(!wfx_tx_queues_get_after_dtim(wvif
), "incorrect sequence");
917 WARN(wvif
->after_dtim_tx_allowed
, "incorrect sequence");
918 wvif
->after_dtim_tx_allowed
= true;
919 wfx_bh_request_tx(wvif
->wdev
);
922 int wfx_ampdu_action(struct ieee80211_hw
*hw
,
923 struct ieee80211_vif
*vif
,
924 struct ieee80211_ampdu_params
*params
)
926 /* Aggregation is implemented fully in firmware,
927 * including block ack negotiation. Do not allow
928 * mac80211 stack to do anything: it interferes with
932 /* Note that we still need this function stubbed. */
937 int wfx_add_chanctx(struct ieee80211_hw
*hw
,
938 struct ieee80211_chanctx_conf
*conf
)
943 void wfx_remove_chanctx(struct ieee80211_hw
*hw
,
944 struct ieee80211_chanctx_conf
*conf
)
948 void wfx_change_chanctx(struct ieee80211_hw
*hw
,
949 struct ieee80211_chanctx_conf
*conf
,
954 int wfx_assign_vif_chanctx(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
,
955 struct ieee80211_chanctx_conf
*conf
)
957 struct wfx_vif
*wvif
= (struct wfx_vif
*) vif
->drv_priv
;
958 struct ieee80211_channel
*ch
= conf
->def
.chan
;
960 WARN(wvif
->channel
, "channel overwrite");
966 void wfx_unassign_vif_chanctx(struct ieee80211_hw
*hw
,
967 struct ieee80211_vif
*vif
,
968 struct ieee80211_chanctx_conf
*conf
)
970 struct wfx_vif
*wvif
= (struct wfx_vif
*) vif
->drv_priv
;
971 struct ieee80211_channel
*ch
= conf
->def
.chan
;
973 WARN(wvif
->channel
!= ch
, "channel mismatch");
974 wvif
->channel
= NULL
;
977 int wfx_config(struct ieee80211_hw
*hw
, u32 changed
)
982 int wfx_add_interface(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
)
985 struct wfx_dev
*wdev
= hw
->priv
;
986 struct wfx_vif
*wvif
= (struct wfx_vif
*) vif
->drv_priv
;
988 vif
->driver_flags
|= IEEE80211_VIF_BEACON_FILTER
|
989 IEEE80211_VIF_SUPPORTS_UAPSD
|
990 IEEE80211_VIF_SUPPORTS_CQM_RSSI
;
992 mutex_lock(&wdev
->conf_mutex
);
995 case NL80211_IFTYPE_STATION
:
996 case NL80211_IFTYPE_ADHOC
:
997 case NL80211_IFTYPE_AP
:
1000 mutex_unlock(&wdev
->conf_mutex
);
1004 for (i
= 0; i
< ARRAY_SIZE(wdev
->vif
); i
++) {
1005 if (!wdev
->vif
[i
]) {
1011 if (i
== ARRAY_SIZE(wdev
->vif
)) {
1012 mutex_unlock(&wdev
->conf_mutex
);
1015 // FIXME: prefer use of container_of() to get vif
1019 wvif
->link_id_map
= 1; // link-id 0 is reserved for multicast
1020 spin_lock_init(&wvif
->ps_state_lock
);
1021 INIT_WORK(&wvif
->update_tim_work
, wfx_update_tim_work
);
1023 memset(&wvif
->bss_params
, 0, sizeof(wvif
->bss_params
));
1025 mutex_init(&wvif
->bss_loss_lock
);
1026 INIT_DELAYED_WORK(&wvif
->bss_loss_work
, wfx_bss_loss_work
);
1028 wvif
->wep_default_key_id
= -1;
1029 INIT_WORK(&wvif
->wep_key_work
, wfx_wep_key_work
);
1031 spin_lock_init(&wvif
->event_queue_lock
);
1032 INIT_LIST_HEAD(&wvif
->event_queue
);
1033 INIT_WORK(&wvif
->event_handler_work
, wfx_event_handler_work
);
1035 init_completion(&wvif
->set_pm_mode_complete
);
1036 complete(&wvif
->set_pm_mode_complete
);
1037 INIT_WORK(&wvif
->update_filtering_work
, wfx_update_filtering_work
);
1038 INIT_WORK(&wvif
->bss_params_work
, wfx_bss_params_work
);
1039 INIT_WORK(&wvif
->unjoin_work
, wfx_unjoin_work
);
1040 INIT_WORK(&wvif
->tx_policy_upload_work
, wfx_tx_policy_upload_work
);
1042 mutex_init(&wvif
->scan_lock
);
1043 init_completion(&wvif
->scan_complete
);
1044 INIT_WORK(&wvif
->scan_work
, wfx_hw_scan_work
);
1046 INIT_WORK(&wvif
->tx_policy_upload_work
, wfx_tx_policy_upload_work
);
1047 mutex_unlock(&wdev
->conf_mutex
);
1049 hif_set_macaddr(wvif
, vif
->addr
);
1051 wfx_tx_policy_init(wvif
);
1053 while ((wvif
= wvif_iterate(wdev
, wvif
)) != NULL
) {
1054 // Combo mode does not support Block Acks. We can re-enable them
1055 if (wvif_count(wdev
) == 1)
1056 hif_set_block_ack_policy(wvif
, 0xFF, 0xFF);
1058 hif_set_block_ack_policy(wvif
, 0x00, 0x00);
1059 // Combo force powersave mode. We can re-enable it now
1060 ret
= wfx_update_pm(wvif
);
1065 void wfx_remove_interface(struct ieee80211_hw
*hw
,
1066 struct ieee80211_vif
*vif
)
1068 struct wfx_dev
*wdev
= hw
->priv
;
1069 struct wfx_vif
*wvif
= (struct wfx_vif
*) vif
->drv_priv
;
1071 wait_for_completion_timeout(&wvif
->set_pm_mode_complete
, msecs_to_jiffies(300));
1073 mutex_lock(&wdev
->conf_mutex
);
1074 WARN(wvif
->link_id_map
!= 1, "corrupted state");
1075 switch (wvif
->state
) {
1076 case WFX_STATE_PRE_STA
:
1078 case WFX_STATE_IBSS
:
1079 wfx_tx_lock_flush(wdev
);
1080 if (!schedule_work(&wvif
->unjoin_work
))
1081 wfx_tx_unlock(wdev
);
1084 wvif
->sta_asleep_mask
= 0;
1085 /* reset.link_id = 0; */
1086 hif_reset(wvif
, false);
1092 wvif
->state
= WFX_STATE_PASSIVE
;
1093 wfx_tx_queues_wait_empty_vif(wvif
);
1094 wfx_tx_unlock(wdev
);
1096 /* FIXME: In add to reset MAC address, try to reset interface */
1097 hif_set_macaddr(wvif
, NULL
);
1099 wfx_cqm_bssloss_sm(wvif
, 0, 0, 0);
1100 cancel_work_sync(&wvif
->unjoin_work
);
1101 wfx_free_event_queue(wvif
);
1103 wdev
->vif
[wvif
->id
] = NULL
;
1106 mutex_unlock(&wdev
->conf_mutex
);
1108 while ((wvif
= wvif_iterate(wdev
, wvif
)) != NULL
) {
1109 // Combo mode does not support Block Acks. We can re-enable them
1110 if (wvif_count(wdev
) == 1)
1111 hif_set_block_ack_policy(wvif
, 0xFF, 0xFF);
1113 hif_set_block_ack_policy(wvif
, 0x00, 0x00);
1114 // Combo force powersave mode. We can re-enable it now
1115 wfx_update_pm(wvif
);
1119 int wfx_start(struct ieee80211_hw
*hw
)
1124 void wfx_stop(struct ieee80211_hw
*hw
)
1126 struct wfx_dev
*wdev
= hw
->priv
;
1128 wfx_tx_lock_flush(wdev
);
1129 mutex_lock(&wdev
->conf_mutex
);
1130 wfx_tx_queues_clear(wdev
);
1131 mutex_unlock(&wdev
->conf_mutex
);
1132 wfx_tx_unlock(wdev
);
1133 WARN(atomic_read(&wdev
->tx_lock
), "tx_lock is locked");