wifi: mac80211: check beacon countdown is complete on per link basis

Currently, function to check if beacon countdown is complete uses deflink
to fetch the beacon and check the counter. However, with MLO, there is
a need to check the counter for the beacon in a particular link.

Add support to use link_id in order to fetch the beacon from a particular
link data.

Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
Link: https://msgid.link/20240216144621.514385-2-quic_adisi@quicinc.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Aditya Kumar Singh 2024-02-16 20:16:20 +05:30 committed by Johannes Berg
parent e199c4ba82
commit 6030b3a469
12 changed files with 26 additions and 14 deletions

View file

@ -2034,7 +2034,7 @@ static void ath10k_mac_vif_ap_csa_count_down(struct ath10k_vif *arvif)
if (!arvif->is_up)
return;
if (!ieee80211_beacon_cntdwn_is_complete(vif)) {
if (!ieee80211_beacon_cntdwn_is_complete(vif, 0)) {
ieee80211_beacon_update_cntdwn(vif, 0);
ret = ath10k_mac_setup_bcn_tmpl(arvif);

View file

@ -3884,7 +3884,7 @@ void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
* actual channel switch is done
*/
if (arvif->vif->bss_conf.csa_active &&
ieee80211_beacon_cntdwn_is_complete(arvif->vif)) {
ieee80211_beacon_cntdwn_is_complete(arvif->vif, 0)) {
ieee80211_csa_finish(arvif->vif, 0);
continue;
}

View file

@ -1577,7 +1577,7 @@ void ath11k_mac_bcn_tx_event(struct ath11k_vif *arvif)
return;
if (vif->bss_conf.color_change_active &&
ieee80211_beacon_cntdwn_is_complete(vif)) {
ieee80211_beacon_cntdwn_is_complete(vif, 0)) {
arvif->bcca_zero_sent = true;
ieee80211_color_change_finish(vif);
return;

View file

@ -365,7 +365,7 @@ bool ath9k_csa_is_finished(struct ath_softc *sc, struct ieee80211_vif *vif)
if (!vif || !vif->bss_conf.csa_active)
return false;
if (!ieee80211_beacon_cntdwn_is_complete(vif))
if (!ieee80211_beacon_cntdwn_is_complete(vif, 0))
return false;
ieee80211_csa_finish(vif, 0);

View file

@ -514,7 +514,7 @@ bool ath9k_htc_csa_is_finished(struct ath9k_htc_priv *priv)
if (!vif || !vif->bss_conf.csa_active)
return false;
if (!ieee80211_beacon_cntdwn_is_complete(vif))
if (!ieee80211_beacon_cntdwn_is_complete(vif, 0))
return false;
ieee80211_csa_finish(vif, 0);

View file

@ -1466,7 +1466,7 @@ static void iwl_mvm_csa_count_down(struct iwl_mvm *mvm,
mvmvif->csa_countdown = true;
if (!ieee80211_beacon_cntdwn_is_complete(csa_vif)) {
if (!ieee80211_beacon_cntdwn_is_complete(csa_vif, 0)) {
int c = ieee80211_beacon_update_cntdwn(csa_vif, 0);
iwl_mvm_mac_ctxt_beacon_changed(mvm, csa_vif,

View file

@ -156,7 +156,7 @@ static void iwl_mvm_csa_noa_start(struct iwl_mvm *mvm)
* So we just do nothing here and the switch
* will be performed on the last TBTT.
*/
if (!ieee80211_beacon_cntdwn_is_complete(csa_vif)) {
if (!ieee80211_beacon_cntdwn_is_complete(csa_vif, 0)) {
IWL_WARN(mvm, "CSA NOA started too early\n");
goto out_unlock;
}

View file

@ -1613,7 +1613,7 @@ EXPORT_SYMBOL_GPL(mt76_get_sar_power);
static void
__mt76_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)
{
if (vif->bss_conf.csa_active && ieee80211_beacon_cntdwn_is_complete(vif))
if (vif->bss_conf.csa_active && ieee80211_beacon_cntdwn_is_complete(vif, 0))
ieee80211_csa_finish(vif, 0);
}
@ -1638,7 +1638,7 @@ __mt76_csa_check(void *priv, u8 *mac, struct ieee80211_vif *vif)
if (!vif->bss_conf.csa_active)
return;
dev->csa_complete |= ieee80211_beacon_cntdwn_is_complete(vif);
dev->csa_complete |= ieee80211_beacon_cntdwn_is_complete(vif, 0);
}
void mt76_csa_check(struct mt76_dev *dev)

View file

@ -5739,7 +5739,7 @@ static void rtl8xxxu_update_beacon_work_callback(struct work_struct *work)
}
if (vif->bss_conf.csa_active) {
if (ieee80211_beacon_cntdwn_is_complete(vif)) {
if (ieee80211_beacon_cntdwn_is_complete(vif, 0)) {
ieee80211_csa_finish(vif, 0);
return;
}

View file

@ -2305,7 +2305,7 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
rcu_dereference(link_conf->chanctx_conf)->def.chan);
}
if (link_conf->csa_active && ieee80211_beacon_cntdwn_is_complete(vif))
if (link_conf->csa_active && ieee80211_beacon_cntdwn_is_complete(vif, link_id))
ieee80211_csa_finish(vif, link_id);
}

View file

@ -5566,10 +5566,12 @@ void ieee80211_csa_finish(struct ieee80211_vif *vif, unsigned int link_id);
/**
* ieee80211_beacon_cntdwn_is_complete - find out if countdown reached 1
* @vif: &struct ieee80211_vif pointer from the add_interface callback.
* @link_id: valid link_id during MLO or 0 for non-MLO
*
* This function returns whether the countdown reached zero.
*/
bool ieee80211_beacon_cntdwn_is_complete(struct ieee80211_vif *vif);
bool ieee80211_beacon_cntdwn_is_complete(struct ieee80211_vif *vif,
unsigned int link_id);
/**
* ieee80211_color_change_finish - notify mac80211 about color change

View file

@ -5095,9 +5095,11 @@ void ieee80211_beacon_set_cntdwn(struct ieee80211_vif *vif, u8 counter)
}
EXPORT_SYMBOL(ieee80211_beacon_set_cntdwn);
bool ieee80211_beacon_cntdwn_is_complete(struct ieee80211_vif *vif)
bool ieee80211_beacon_cntdwn_is_complete(struct ieee80211_vif *vif,
unsigned int link_id)
{
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
struct ieee80211_link_data *link;
struct beacon_data *beacon = NULL;
u8 *beacon_data;
size_t beacon_data_len;
@ -5106,9 +5108,17 @@ bool ieee80211_beacon_cntdwn_is_complete(struct ieee80211_vif *vif)
if (!ieee80211_sdata_running(sdata))
return false;
if (WARN_ON(link_id >= IEEE80211_MLD_MAX_NUM_LINKS))
return 0;
rcu_read_lock();
link = rcu_dereference(sdata->link[link_id]);
if (!link)
goto out;
if (vif->type == NL80211_IFTYPE_AP) {
beacon = rcu_dereference(sdata->deflink.u.ap.beacon);
beacon = rcu_dereference(link->u.ap.beacon);
if (WARN_ON(!beacon || !beacon->tail))
goto out;
beacon_data = beacon->tail;