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 41053219ee957b5d6211878770447e364804727e..e322b528baafce39127cf9ea8decc681f5604e26 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 ddf15717d5046ce324b643deffbee33c177bc3b5..2e9661f4bea82425990eeb48251cb6450ae40ecc 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 f7cab50bdfd12b3cfc0b7ea915d47b0e5ffa65b4..a1e2729582e8eecc59f98c29038008e1deb29236 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 4e48407138b25f8afb92e252680eee165e509894..b399a7926ef5deaf53b0eb1c5b824d15f0539a85 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 8179d35dc310101c3346e15801f42b507922783c..547634f82183d6a7d9965cca27d7ae0e5e9d4b12 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 cc592e288188d07a95340828340d68aa6befeaa5..123fe9bba982adf8baa0e852f51e3314e74f4254 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 89b1c7a876608affbd76800623a257a381b304d6..a59d264a11c52f5174fe4475c6915bf5c49760d4 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 8bf82755ca4c647245fb4a92319be9fe3fdde8c3..758e380fdf1dd4991b9c4029499538835ebfcf9a 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 66bf92c164c30325fd78da7d420e675ac251cb57..db5041d23938bfc5bd9d21fc6bd372adbf112b13 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 0554946ed30e6d7b705c978742555d30b49897ad..2ea11a86d920a67937b289806b0869231991c913 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 fc223761e3afc98eb9ffa019ea1c4ce04c073cae..25c892ea9eb345180261015bdb842ff52cd76e61 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 f4be4af568be75bdda56cd43bda8ef412f4976cc..6bf223e6cd1a54aa432ef0bd41da48cd9316ffc5 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;