wifi: mac80211: check beacon countdown is complete on per link basis
authorAditya Kumar Singh <quic_adisi@quicinc.com>
Fri, 16 Feb 2024 14:46:20 +0000 (20:16 +0530)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 21 Feb 2024 14:19:03 +0000 (15:19 +0100)
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>
12 files changed:
drivers/net/wireless/ath/ath10k/mac.c
drivers/net/wireless/ath/ath10k/wmi.c
drivers/net/wireless/ath/ath11k/mac.c
drivers/net/wireless/ath/ath9k/beacon.c
drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
drivers/net/wireless/mediatek/mt76/mac80211.c
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
drivers/net/wireless/virtual/mac80211_hwsim.c
include/net/mac80211.h
net/mac80211/tx.c

index 4105321..e322b52 100644 (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);
index ddf1571..2e9661f 100644 (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;
                }
index f7cab50..a1e2729 100644 (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;
index 4e48407..b399a79 100644 (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);
index 8179d35..547634f 100644 (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);
index cc592e2..123fe9b 100644 (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,
index 89b1c7a..a59d264 100644 (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;
        }
index 8bf8275..758e380 100644 (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)
index 66bf92c..db5041d 100644 (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;
                }
index 0554946..2ea11a8 100644 (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);
 }
 
index fc22376..25c892e 100644 (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
index f4be4af..6bf223e 100644 (file)
@@ -5095,9 +5095,11 @@ unlock:
 }
 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;