diff mbox series

[wireless-next,12/15] wifi: iwlwifi: mld: Correctly configure the A-MSDU max lengths

Message ID 20250308235203.afc842633002.I68153b6b0c5d976f2c7525009631f8fa28e9987c@changeid
State New
Headers show
Series wifi: iwlwifi: updates - 2025-03-08 | expand

Commit Message

Miri Korenblit March 8, 2025, 10:01 p.m. UTC
From: Ilan Peer <ilan.peer@intel.com>

Refactor the setting of the A-MSDU maximal lengths as follows:

- Move the setting of the maximal A-MSDU length in case of HT from TLC
  logic to the station logic as it is not related to TLC.
- As long as the station is not associated, set RC A-MSDU maximal
  lengths to 1, to prevent iwlmld and mac80211 from building A-MSDUs.
- Update the RC and the TID specific A-MSDU maximal lengths based on
  the FW TLC notifications.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mld/sta.c | 24 +++++++++++
 drivers/net/wireless/intel/iwlwifi/mld/tlc.c | 43 ++++++--------------
 2 files changed, 37 insertions(+), 30 deletions(-)
diff mbox series

Patch

diff --git a/drivers/net/wireless/intel/iwlwifi/mld/sta.c b/drivers/net/wireless/intel/iwlwifi/mld/sta.c
index 994d4561518b..332a7aecec2d 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/sta.c
@@ -606,6 +606,25 @@  iwl_mld_remove_link_sta(struct iwl_mld *mld,
 		kfree_rcu(mld_link_sta, rcu_head);
 }
 
+static void iwl_mld_set_max_amsdu_len(struct iwl_mld *mld,
+				      struct ieee80211_link_sta *link_sta)
+{
+	const struct ieee80211_sta_ht_cap *ht_cap = &link_sta->ht_cap;
+
+	/* For EHT, HE and VHT we can use the value as it was calculated by
+	 * mac80211. For HT, mac80211 doesn't enforce to 4095, so force it
+	 * here
+	 */
+	if (link_sta->eht_cap.has_eht || link_sta->he_cap.has_he ||
+	    link_sta->vht_cap.vht_supported ||
+	    !ht_cap->ht_supported ||
+	    !(ht_cap->cap & IEEE80211_HT_CAP_MAX_AMSDU))
+		return;
+
+	link_sta->agg.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_HT_BA;
+	ieee80211_sta_recalc_aggregates(link_sta->sta);
+}
+
 int iwl_mld_update_all_link_stations(struct iwl_mld *mld,
 				     struct ieee80211_sta *sta)
 {
@@ -618,6 +637,9 @@  int iwl_mld_update_all_link_stations(struct iwl_mld *mld,
 
 		if (ret)
 			return ret;
+
+		if (mld_sta->sta_state == IEEE80211_STA_ASSOC)
+			iwl_mld_set_max_amsdu_len(mld, link_sta);
 	}
 	return 0;
 }
@@ -1222,6 +1244,8 @@  int iwl_mld_update_link_stas(struct iwl_mld *mld,
 
 		link = link_conf_dereference_protected(mld_sta->vif,
 						       link_sta->link_id);
+
+		iwl_mld_set_max_amsdu_len(mld, link_sta);
 		iwl_mld_config_tlc_link(mld, vif, link, link_sta);
 
 		sta_mask_added |= BIT(mld_link_sta->fw_id);
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/tlc.c b/drivers/net/wireless/intel/iwlwifi/mld/tlc.c
index 85ec358f1417..f054cc921d9d 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/tlc.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/tlc.c
@@ -1,6 +1,6 @@ 
 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
 /*
- * Copyright (C) 2024 Intel Corporation
+ * Copyright (C) 2024-2025 Intel Corporation
  */
 
 #include <net/mac80211.h>
@@ -467,7 +467,7 @@  static void iwl_mld_send_tlc_cmd(struct iwl_mld *mld,
 						   own_he_cap, own_eht_cap),
 		.chains = iwl_mld_get_fw_chains(mld),
 		.sgi_ch_width_supp = iwl_mld_get_fw_sgi(link_sta),
-		.max_mpdu_len = cpu_to_le16(link_sta->agg.max_rc_amsdu_len),
+		.max_mpdu_len = cpu_to_le16(link_sta->agg.max_amsdu_len),
 	};
 	int fw_sta_id = iwl_mld_fw_sta_id_from_link_sta(mld, link_sta);
 	int ret;
@@ -493,30 +493,6 @@  static void iwl_mld_send_tlc_cmd(struct iwl_mld *mld,
 		IWL_ERR(mld, "Failed to send TLC cmd (%d)\n", ret);
 }
 
-static void iwl_mld_recalc_amsdu_len(struct iwl_mld *mld,
-				     struct ieee80211_link_sta *link_sta)
-{
-	const struct ieee80211_sta_ht_cap *ht_cap = &link_sta->ht_cap;
-
-	/* For EHT, HE and VHT - we can use the value as it was calculated by
-	 * mac80211.
-	 */
-	if (link_sta->eht_cap.has_eht || link_sta->he_cap.has_he ||
-	    link_sta->vht_cap.vht_supported)
-		goto recalc;
-
-	/* But for HT, mac80211 doesn't enforce to 4095, so force it here */
-	if (ht_cap->ht_supported && ht_cap->cap & IEEE80211_HT_CAP_MAX_AMSDU)
-		/* Agg is offloaded, so we need to assume that agg are enabled
-		 * and max mpdu in ampdu is 4095 (spec 802.11-2016 9.3.2.1)
-		 */
-		link_sta->agg.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_HT_BA;
-
-recalc:
-	link_sta->agg.max_rc_amsdu_len = link_sta->agg.max_amsdu_len;
-	ieee80211_sta_recalc_aggregates(link_sta->sta);
-}
-
 int iwl_mld_send_tlc_dhc(struct iwl_mld *mld, u8 sta_id, u32 type, u32 data)
 {
 	struct {
@@ -547,15 +523,22 @@  void iwl_mld_config_tlc_link(struct iwl_mld *mld,
 			     struct ieee80211_bss_conf *link_conf,
 			     struct ieee80211_link_sta *link_sta)
 {
+	struct iwl_mld_sta *mld_sta = iwl_mld_sta_from_mac80211(link_sta->sta);
 	enum nl80211_band band;
 
 	if (WARN_ON_ONCE(!link_conf->chanreq.oper.chan))
 		return;
 
-	band = link_conf->chanreq.oper.chan->band;
-
-	iwl_mld_recalc_amsdu_len(mld, link_sta);
+	/* Before we have information about a station, configure the A-MSDU RC
+	 * limit such that iwlmd and mac80211 would not be allowed to build
+	 * A-MSDUs.
+	 */
+	if (mld_sta->sta_state < IEEE80211_STA_ASSOC) {
+		link_sta->agg.max_rc_amsdu_len = 1;
+		ieee80211_sta_recalc_aggregates(link_sta->sta);
+	}
 
+	band = link_conf->chanreq.oper.chan->band;
 	iwl_mld_send_tlc_cmd(mld, vif, link_sta, band);
 }
 
@@ -706,7 +689,7 @@  void iwl_mld_handle_tlc_notif(struct iwl_mld *mld,
 			link_sta->agg.max_tid_amsdu_len[i] =
 				iwl_mld_get_amsdu_size_of_tid(mld, link_sta, i);
 		else
-			link_sta->agg.max_tid_amsdu_len[i] = 0;
+			link_sta->agg.max_tid_amsdu_len[i] = 1;
 	}
 
 	ieee80211_sta_recalc_aggregates(link_sta->sta);