From: Ilan Peer <ilan.peer@xxxxxxxxx> 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@xxxxxxxxx> Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@xxxxxxxxx> --- 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 --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); -- 2.34.1