wifi: mac80211: aggregation: remove deflink accesses for MLO
authorJohannes Berg <johannes.berg@intel.com>
Wed, 5 Feb 2025 09:39:24 +0000 (11:39 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 11 Feb 2025 10:59:08 +0000 (11:59 +0100)
If a station has connected with MLO (as indicated by valid_links
being non-zero, even if that may have just a single bit set), it
necessarily supports EHT/aggregation, so we don't need to check
the deflink for those cases.

Add conditions so we can support removing the link it/we used to
associate on.

Note that we still use the statistics in the deflink, but that's
a whole different story we will need to address separately.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20250205110958.daf2a9e367f2.Id2c2dfbbe7451cc900ed88c5a81b33c55b4ab1cf@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/agg-rx.c
net/mac80211/agg-tx.c
net/mac80211/tx.c

index f3fbe5a..aeb99d1 100644 (file)
@@ -9,7 +9,7 @@
  * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
  * Copyright 2007-2010, Intel Corporation
  * Copyright(c) 2015-2017 Intel Deutschland GmbH
- * Copyright (C) 2018-2023 Intel Corporation
+ * Copyright (C) 2018-2024 Intel Corporation
  */
 
 /**
@@ -206,17 +206,19 @@ u8 ieee80211_retrieve_addba_ext_data(struct sta_info *sta,
 
        elems = ieee802_11_parse_elems(elem_data, elem_len, true, NULL);
 
-       if (elems && !elems->parse_error && elems->addba_ext_ie) {
-               data = elems->addba_ext_ie->data;
+       if (!elems || elems->parse_error || !elems->addba_ext_ie)
+               goto free;
 
-               if (!sta->sta.deflink.eht_cap.has_eht || !buf_size)
-                       goto free;
+       data = elems->addba_ext_ie->data;
 
+       if (buf_size &&
+           (sta->sta.valid_links || sta->sta.deflink.eht_cap.has_eht)) {
                buf_size_1k = u8_get_bits(elems->addba_ext_ie->data,
                                          IEEE80211_ADDBA_EXT_BUF_SIZE_MASK);
                *buf_size |= (u16)buf_size_1k <<
                             IEEE80211_ADDBA_EXT_BUF_SIZE_SHIFT;
        }
+
 free:
        kfree(elems);
 
@@ -258,7 +260,7 @@ static void ieee80211_send_addba_resp(struct sta_info *sta, u8 *da, u16 tid,
        mgmt->u.action.u.addba_resp.timeout = cpu_to_le16(timeout);
        mgmt->u.action.u.addba_resp.status = cpu_to_le16(status);
 
-       if (sta->sta.deflink.he_cap.has_he)
+       if (sta->sta.valid_links || sta->sta.deflink.he_cap.has_he)
                ieee80211_add_addbaext(skb, req_addba_ext_data, buf_size);
 
        ieee80211_tx_skb(sdata, skb);
@@ -293,7 +295,8 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
                goto end;
        }
 
-       if (!sta->sta.deflink.ht_cap.ht_supported &&
+       if (!sta->sta.valid_links &&
+           !sta->sta.deflink.ht_cap.ht_supported &&
            !sta->sta.deflink.he_cap.has_he) {
                ht_dbg(sta->sdata,
                       "STA %pM erroneously requests BA session on tid %d w/o HT\n",
@@ -309,7 +312,7 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
                goto end;
        }
 
-       if (sta->sta.deflink.eht_cap.has_eht)
+       if (sta->sta.valid_links || sta->sta.deflink.eht_cap.has_eht)
                max_buf_size = IEEE80211_MAX_AMPDU_BUF_EHT;
        else if (sta->sta.deflink.he_cap.has_he)
                max_buf_size = IEEE80211_MAX_AMPDU_BUF_HE;
@@ -321,7 +324,8 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
         * and if buffer size does not exceeds max value */
        /* XXX: check own ht delayed BA capability?? */
        if (((ba_policy != 1) &&
-            (!(sta->sta.deflink.ht_cap.cap & IEEE80211_HT_CAP_DELAY_BA))) ||
+            (sta->sta.valid_links ||
+             !(sta->sta.deflink.ht_cap.cap & IEEE80211_HT_CAP_DELAY_BA))) ||
            (buf_size > max_buf_size)) {
                status = WLAN_STATUS_INVALID_QOS_PARAM;
                ht_dbg_ratelimited(sta->sdata,
index 92120f9..63a5e48 100644 (file)
@@ -464,7 +464,8 @@ static void ieee80211_send_addba_with_timeout(struct sta_info *sta,
        sta->ampdu_mlme.addba_req_num[tid]++;
        spin_unlock_bh(&sta->lock);
 
-       if (sta->sta.deflink.eht_cap.has_eht ||
+       if (sta->sta.valid_links ||
+           sta->sta.deflink.eht_cap.has_eht ||
            ieee80211_hw_check(&local->hw, STRICT)) {
                buf_size = local->hw.max_tx_aggregation_subframes;
        } else if (sta->sta.deflink.he_cap.has_he) {
@@ -609,7 +610,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
                 "Requested to start BA session on reserved tid=%d", tid))
                return -EINVAL;
 
-       if (!pubsta->deflink.ht_cap.ht_supported &&
+       if (!pubsta->valid_links &&
+           !pubsta->deflink.ht_cap.ht_supported &&
            !pubsta->deflink.vht_cap.vht_supported &&
            !pubsta->deflink.he_cap.has_he &&
            !pubsta->deflink.eht_cap.has_eht)
index 1289df3..20179db 100644 (file)
@@ -1182,7 +1182,8 @@ void ieee80211_aggr_check(struct ieee80211_sub_if_data *sdata,
        if (!ref || !(ref->ops->capa & RATE_CTRL_CAPA_AMPDU_TRIGGER))
                return;
 
-       if (!sta || !sta->sta.deflink.ht_cap.ht_supported ||
+       if (!sta ||
+           (!sta->sta.valid_links && !sta->sta.deflink.ht_cap.ht_supported) ||
            !sta->sta.wme || skb_get_queue_mapping(skb) == IEEE80211_AC_VO ||
            skb->protocol == sdata->control_port_protocol)
                return;