From: Johannes Berg Date: Fri, 20 Mar 2026 08:09:04 +0000 (+0200) Subject: wifi: iwlwifi: mld: enable UHR in TLC X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=364273359ef354d315157f78fef1b72f75d08468;p=thirdparty%2Flinux.git wifi: iwlwifi: mld: enable UHR in TLC Tell the firmware if UHR is supported, including ELR (enhanced long range) MCS support. Note that the spec currently doesn't differentiate between 1.5 and 3 Mbps ELR MCSes, unlike the firmware. Signed-off-by: Johannes Berg Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20260320100746.7117009d7c39.If4e8cdc63fdf4c5f14d923a5c59fb7b43df72a67@changeid --- diff --git a/drivers/net/wireless/intel/iwlwifi/mld/tlc.c b/drivers/net/wireless/intel/iwlwifi/mld/tlc.c index 62a54c37a98c5..ede385909e38f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/tlc.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/tlc.c @@ -36,7 +36,8 @@ iwl_mld_get_tlc_cmd_flags(struct iwl_mld *mld, struct ieee80211_vif *vif, struct ieee80211_link_sta *link_sta, const struct ieee80211_sta_he_cap *own_he_cap, - const struct ieee80211_sta_eht_cap *own_eht_cap) + const struct ieee80211_sta_eht_cap *own_eht_cap, + const struct ieee80211_sta_uhr_cap *own_uhr_cap) { struct ieee80211_sta_ht_cap *ht_cap = &link_sta->ht_cap; struct ieee80211_sta_vht_cap *vht_cap = &link_sta->vht_cap; @@ -90,6 +91,12 @@ iwl_mld_get_tlc_cmd_flags(struct iwl_mld *mld, flags |= IWL_TLC_MNG_CFG_FLAGS_EHT_EXTRA_LTF_MSK; } + if (link_sta->uhr_cap.has_uhr && own_uhr_cap && + link_sta->uhr_cap.phy.cap & IEEE80211_UHR_PHY_CAP_ELR_RX && + own_uhr_cap->phy.cap & IEEE80211_UHR_PHY_CAP_ELR_TX) + flags |= IWL_TLC_MNG_CFG_FLAGS_UHR_ELR_1_5_MBPS_MSK | + IWL_TLC_MNG_CFG_FLAGS_UHR_ELR_3_MBPS_MSK; + return cpu_to_le16(flags); } @@ -406,6 +413,7 @@ iwl_mld_fill_supp_rates(struct iwl_mld *mld, struct ieee80211_vif *vif, struct ieee80211_supported_band *sband, const struct ieee80211_sta_he_cap *own_he_cap, const struct ieee80211_sta_eht_cap *own_eht_cap, + const struct ieee80211_sta_uhr_cap *own_uhr_cap, struct iwl_tlc_config_cmd *cmd) { int i; @@ -423,7 +431,16 @@ iwl_mld_fill_supp_rates(struct iwl_mld *mld, struct ieee80211_vif *vif, cmd->non_ht_rates = cpu_to_le16(non_ht_rates); cmd->mode = IWL_TLC_MNG_MODE_NON_HT; - if (link_sta->eht_cap.has_eht && own_he_cap && own_eht_cap) { + if (link_sta->uhr_cap.has_uhr && own_uhr_cap) { + cmd->mode = IWL_TLC_MNG_MODE_UHR; + /* + * FIXME: spec currently inherits from EHT but has no + * finer MCS bits. Once that's there, need to add them + * to the bitmaps (and maybe copy this to UHR, or so.) + */ + iwl_mld_fill_eht_rates(vif, link_sta, own_he_cap, + own_eht_cap, cmd); + } else if (link_sta->eht_cap.has_eht && own_he_cap && own_eht_cap) { cmd->mode = IWL_TLC_MNG_MODE_EHT; iwl_mld_fill_eht_rates(vif, link_sta, own_he_cap, own_eht_cap, cmd); @@ -519,13 +536,16 @@ static void iwl_mld_send_tlc_cmd(struct iwl_mld *mld, ieee80211_get_he_iftype_cap_vif(sband, vif); const struct ieee80211_sta_eht_cap *own_eht_cap = ieee80211_get_eht_iftype_cap_vif(sband, vif); + const struct ieee80211_sta_uhr_cap *own_uhr_cap = + ieee80211_get_uhr_iftype_cap_vif(sband, vif); struct iwl_tlc_config_cmd cmd = { /* For AP mode, use 20 MHz until the STA is authorized */ .max_ch_width = mld_sta->sta_state > IEEE80211_STA_ASSOC ? iwl_mld_fw_bw_from_sta_bw(link_sta) : IWL_TLC_MNG_CH_WIDTH_20MHZ, .flags = iwl_mld_get_tlc_cmd_flags(mld, vif, link_sta, - own_he_cap, own_eht_cap), + own_he_cap, own_eht_cap, + own_uhr_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_amsdu_len), @@ -555,7 +575,7 @@ static void iwl_mld_send_tlc_cmd(struct iwl_mld *mld, iwl_mld_fill_supp_rates(mld, vif, link_sta, sband, own_he_cap, own_eht_cap, - &cmd); + own_uhr_cap, &cmd); if (cmd_ver == 6) { cmd_ptr = &cmd;