123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- From df8e3729ffc0aa645839693f74ee7b6d999cdf64 Mon Sep 17 00:00:00 2001
- From: Maharaja Kennadyrajan <quic_mkenna@quicinc.com>
- Date: Tue, 9 May 2023 20:07:24 +0300
- Subject: [PATCH] wifi: ath11k: Send HT fixed rate in WMI peer fixed param
- Due to the firmware behavior with HT fixed rate setting,
- HT fixed rate MCS with NSS > 1 are treated as NSS = 1
- HT rates in the firmware and enables the HT fixed rate of
- NSS = 1.
- This leads to HT fixed rate is always configured for NSS = 1
- even though the user sets NSS = 2 or > 1 HT fixed MCS in the
- set bitrate command.
- Currently HT fixed MCS is sent via WMI peer assoc command.
- Fix this issue, by sending the HT fixed rate MCS in WMI peer
- fixed param instead of sending in peer assoc command.
- Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
- Signed-off-by: Maharaja Kennadyrajan <quic_mkenna@quicinc.com>
- Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
- Link: https://lore.kernel.org/r/20230504092033.3542456-3-quic_mkenna@quicinc.com
- ---
- drivers/net/wireless/ath/ath11k/mac.c | 63 ++++++++++++++++++++++++++-
- 1 file changed, 61 insertions(+), 2 deletions(-)
- --- a/drivers/net/wireless/ath/ath11k/mac.c
- +++ b/drivers/net/wireless/ath/ath11k/mac.c
- @@ -4480,6 +4480,54 @@ ath11k_mac_set_peer_he_fixed_rate(struct
- return ret;
- }
-
- +static int
- +ath11k_mac_set_peer_ht_fixed_rate(struct ath11k_vif *arvif,
- + struct ieee80211_sta *sta,
- + const struct cfg80211_bitrate_mask *mask,
- + enum nl80211_band band)
- +{
- + struct ath11k *ar = arvif->ar;
- + u8 ht_rate, nss = 0;
- + u32 rate_code;
- + int ret, i;
- +
- + lockdep_assert_held(&ar->conf_mutex);
- +
- + for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
- + if (hweight8(mask->control[band].ht_mcs[i]) == 1) {
- + nss = i + 1;
- + ht_rate = ffs(mask->control[band].ht_mcs[i]) - 1;
- + }
- + }
- +
- + if (!nss) {
- + ath11k_warn(ar->ab, "No single HT Fixed rate found to set for %pM",
- + sta->addr);
- + return -EINVAL;
- + }
- +
- + /* Avoid updating invalid nss as fixed rate*/
- + if (nss > sta->deflink.rx_nss)
- + return -EINVAL;
- +
- + ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
- + "Setting Fixed HT Rate for peer %pM. Device will not switch to any other selected rates",
- + sta->addr);
- +
- + rate_code = ATH11K_HW_RATE_CODE(ht_rate, nss - 1,
- + WMI_RATE_PREAMBLE_HT);
- + ret = ath11k_wmi_set_peer_param(ar, sta->addr,
- + arvif->vdev_id,
- + WMI_PEER_PARAM_FIXED_RATE,
- + rate_code);
- + if (ret)
- + ath11k_warn(ar->ab,
- + "failed to update STA %pM HT Fixed Rate %d: %d\n",
- + sta->addr, rate_code, ret);
- +
- + return ret;
- +}
- +
- static int ath11k_station_assoc(struct ath11k *ar,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta,
- @@ -4491,7 +4539,7 @@ static int ath11k_station_assoc(struct a
- struct cfg80211_chan_def def;
- enum nl80211_band band;
- struct cfg80211_bitrate_mask *mask;
- - u8 num_vht_rates, num_he_rates;
- + u8 num_ht_rates, num_vht_rates, num_he_rates;
-
- lockdep_assert_held(&ar->conf_mutex);
-
- @@ -4519,6 +4567,7 @@ static int ath11k_station_assoc(struct a
-
- num_vht_rates = ath11k_mac_bitrate_mask_num_vht_rates(ar, band, mask);
- num_he_rates = ath11k_mac_bitrate_mask_num_he_rates(ar, band, mask);
- + num_ht_rates = ath11k_mac_bitrate_mask_num_ht_rates(ar, band, mask);
-
- /* If single VHT/HE rate is configured (by set_bitrate_mask()),
- * peer_assoc will disable VHT/HE. This is now enabled by a peer specific
- @@ -4535,6 +4584,11 @@ static int ath11k_station_assoc(struct a
- band);
- if (ret)
- return ret;
- + } else if (sta->deflink.ht_cap.ht_supported && num_ht_rates == 1) {
- + ret = ath11k_mac_set_peer_ht_fixed_rate(arvif, sta, mask,
- + band);
- + if (ret)
- + return ret;
- }
-
- /* Re-assoc is run only to update supported rates for given station. It
- @@ -4608,7 +4662,7 @@ static void ath11k_sta_rc_update_wk(stru
- const u16 *vht_mcs_mask;
- const u16 *he_mcs_mask;
- u32 changed, bw, nss, smps, bw_prev;
- - int err, num_vht_rates, num_he_rates;
- + int err, num_ht_rates, num_vht_rates, num_he_rates;
- const struct cfg80211_bitrate_mask *mask;
- struct peer_assoc_params peer_arg;
- enum wmi_phy_mode peer_phymode;
- @@ -4724,6 +4778,8 @@ static void ath11k_sta_rc_update_wk(stru
-
- if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) {
- mask = &arvif->bitrate_mask;
- + num_ht_rates = ath11k_mac_bitrate_mask_num_ht_rates(ar, band,
- + mask);
- num_vht_rates = ath11k_mac_bitrate_mask_num_vht_rates(ar, band,
- mask);
- num_he_rates = ath11k_mac_bitrate_mask_num_he_rates(ar, band,
- @@ -4746,6 +4802,9 @@ static void ath11k_sta_rc_update_wk(stru
- } else if (sta->deflink.he_cap.has_he && num_he_rates == 1) {
- ath11k_mac_set_peer_he_fixed_rate(arvif, sta, mask,
- band);
- + } else if (sta->deflink.ht_cap.ht_supported && num_ht_rates == 1) {
- + ath11k_mac_set_peer_ht_fixed_rate(arvif, sta, mask,
- + band);
- } else {
- /* If the peer is non-VHT/HE or no fixed VHT/HE rate
- * is provided in the new bitrate mask we set the
|