wlan-ap-Telecominfraproject/feeds/wifi-ax/mac80211/patches/qca/207-ath11k-allow-multiple-single-rates.patch
John Crispin 528a778e38 open-converged-wireless: Import 21.02 based uCentral tree
Signed-off-by: John Crispin <john@phrozen.org>
2021-03-25 12:19:47 +01:00

270 lines
9.5 KiB
Diff

From ddf4f23a95dd44931d695eb615c6b4e3869a0a56 Mon Sep 17 00:00:00 2001
From: Venkateswara Naralasetty <vnaralas@codeaurora.org>
Date: Fri, 9 Oct 2020 15:15:46 +0530
Subject: [PATCH] ath11k: allow multiple single rates from fixed rate settings
Ath11k driver allows user to set either range of rates like
1:0-9 2:0-9 3:0-9 4:0-9 or single fixed rate like 1:9 from
set bitrates command.
This change allows user to set multiple vht/he single rates
from set bitrates command like 1:9 2:9 3:9 4:9. And rate will
be applied based on the best nss supported by the peer using
peer fixed rate command.
Signed-off-by: Venkateswara Naralasetty <vnaralas@codeaurora.org>
---
drivers/net/wireless/ath/ath11k/mac.c | 130 ++++++++++++++++++++++------------
1 file changed, 84 insertions(+), 46 deletions(-)
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -3581,6 +3581,28 @@ exit:
}
static int
+ath11k_mac_bitrate_num_vht_single_rates(struct ath11k *ar,
+ enum nl80211_band band,
+ const struct cfg80211_bitrate_mask *mask,
+ struct ieee80211_sta *sta)
+{
+ int num_single_rates = 0;
+ int i;
+ int rates;
+ int nss;
+
+ nss = sta ? sta->rx_nss : ARRAY_SIZE(mask->control[band].vht_mcs);
+
+ for (i = 0; i < nss; i++) {
+ rates = hweight16(mask->control[band].vht_mcs[i]);
+ if (rates == 1)
+ num_single_rates++;
+ }
+
+ return num_single_rates;
+}
+
+static int
ath11k_mac_bitrate_mask_num_vht_rates(struct ath11k *ar,
enum nl80211_band band,
const struct cfg80211_bitrate_mask *mask)
@@ -3595,6 +3617,28 @@ ath11k_mac_bitrate_mask_num_vht_rates(st
}
static int
+ath11k_mac_bitrate_num_he_single_rates(struct ath11k *ar,
+ enum nl80211_band band,
+ const struct cfg80211_bitrate_mask *mask,
+ struct ieee80211_sta *sta)
+{
+ int num_single_rates = 0;
+ int i;
+ int rates;
+ int nss;
+
+ nss = sta ? sta->rx_nss : ARRAY_SIZE(mask->control[band].he_mcs);
+
+ for (i = 0; i < nss; i++) {
+ rates = hweight16(mask->control[band].he_mcs[i]);
+ if (rates == 1)
+ num_single_rates++;
+ }
+
+ return num_single_rates;
+}
+
+static int
ath11k_mac_bitrate_mask_num_he_rates(struct ath11k *ar,
enum nl80211_band band,
const struct cfg80211_bitrate_mask *mask)
@@ -3623,7 +3667,7 @@ ath11k_mac_set_peer_vht_fixed_rate(struc
nss = 0;
- for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
+ for (i = 0; i < sta->rx_nss; i++) {
if (hweight16(mask->control[band].vht_mcs[i]) == 1) {
nss = i + 1;
vht_rate = ffs(mask->control[band].vht_mcs[i]) - 1;
@@ -3636,10 +3680,6 @@ ath11k_mac_set_peer_vht_fixed_rate(struc
return -EINVAL;
}
- /* Avoid updating invalid nss as fixed rate*/
- if (nss > sta->rx_nss)
- return -EINVAL;
-
ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
"Setting Fixed VHT Rate for peer %pM. Device will not switch to any other selected rates",
sta->addr);
@@ -3673,7 +3713,7 @@ ath11k_mac_set_peer_he_fixed_rate(struct
nss = 0;
- for (i = 0; i < ARRAY_SIZE(mask->control[band].he_mcs); i++) {
+ for (i = 0; i < sta->rx_nss; i++) {
if (hweight16(mask->control[band].he_mcs[i]) == 1) {
nss = i + 1;
he_rate = ffs(mask->control[band].he_mcs[i]) - 1;
@@ -3686,11 +3726,6 @@ ath11k_mac_set_peer_he_fixed_rate(struct
return -EINVAL;
}
- /* Avoid updating invalid nss as fixed rate*/
- if (nss > sta->rx_nss)
- return -EINVAL;
-
-
ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
"Setting Fixed HE Rate for peer %pM. Device will not switch to any other selected rates",
sta->addr);
@@ -3720,7 +3755,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_vht_single_rates, num_he_single_rates;
lockdep_assert_held(&ar->conf_mutex);
@@ -3745,22 +3780,23 @@ static int ath11k_station_assoc(struct a
return -ETIMEDOUT;
}
- 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_vht_single_rates = ath11k_mac_bitrate_num_vht_single_rates(ar, band,
+ mask, sta);
+ num_he_single_rates = ath11k_mac_bitrate_num_he_single_rates(ar, band,
+ mask, sta);
/* 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
- * fixed param.
+ * fixed param. If multiple single VHT/HE rates like(1:9 2:9 3:9 4:9)
+ * are configured, apply rate with the best nss supported by the peer.
* Note that all other rates and NSS will be disabled for this peer.
*/
- if (sta->vht_cap.vht_supported && num_vht_rates == 1) {
- ret = ath11k_mac_set_peer_vht_fixed_rate(arvif, sta, mask,
- band);
+ if (sta->vht_cap.vht_supported && num_vht_single_rates >= 1) {
+ ret = ath11k_mac_set_peer_vht_fixed_rate(arvif, sta, mask, band);
if (ret)
return ret;
- } else if (sta->he_cap.has_he && num_he_rates == 1) {
- ret = ath11k_mac_set_peer_he_fixed_rate(arvif, sta, mask,
- band);
+ } else if (sta->he_cap.has_he && num_he_single_rates >= 1) {
+ ret = ath11k_mac_set_peer_he_fixed_rate(arvif, sta, mask, band);
if (ret)
return ret;
}
@@ -3835,7 +3871,7 @@ static void ath11k_sta_rc_update_wk(stru
const u16 *vht_mcs_mask;
const u16 *he_mcs_mask;
u32 changed, bw, nss, smps;
- int err, num_vht_rates, num_he_rates;
+ int err, num_vht_single_rates, num_he_single_rates;
const struct cfg80211_bitrate_mask *mask;
struct peer_assoc_params peer_arg;
@@ -3902,26 +3938,27 @@ static void ath11k_sta_rc_update_wk(stru
if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) {
mask = &arvif->bitrate_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,
- mask);
+ num_vht_single_rates = ath11k_mac_bitrate_num_vht_single_rates(ar, band,
+ mask, sta);
+ num_he_single_rates = ath11k_mac_bitrate_num_he_single_rates(ar, band,
+ mask, sta);
/* Peer_assoc_prepare will reject vht rates in
* bitrate_mask if its not available in range format and
- * sets vht tx_rateset as unsupported. So multiple VHT MCS
- * setting(eg. MCS 4,5,6) per peer is not supported here.
- * But, Single rate in VHT mask can be set as per-peer
- * fixed rate. But even if any HT rates are configured in
- * the bitrate mask, device will not switch to those rates
- * when per-peer Fixed rate is set.
+ * sets vht tx_rateset as unsupported. If multiple VHT MCS
+ * and NSS (or) single fixed rate are configured from set_bitrate()
+ * setting(eg. 1:9 2:9 3:9 4:9) select the best rate based on NSS
+ * supported by the peer and apply it as peer fixed rate. Also,
+ * if rate is configured as 1:9 2:0-9 will select 1:9 here.
+ * But even if any HT rates are configured in the bitrate mask,
+ * device will not switch to those rates when per-peer Fixed rate is set.
* TODO: Check RATEMASK_CMDID to support auto rates selection
* across HT/VHT and for multiple VHT MCS support.
*/
- if (sta->vht_cap.vht_supported && num_vht_rates == 1) {
+ if (sta->vht_cap.vht_supported && num_vht_single_rates >= 1) {
ath11k_mac_set_peer_vht_fixed_rate(arvif, sta, mask,
band);
- } else if (sta->he_cap.has_he && num_he_rates == 1) {
+ } else if (sta->he_cap.has_he && num_he_single_rates >= 1) {
ath11k_mac_set_peer_he_fixed_rate(arvif, sta, mask,
band);
} else {
@@ -7138,7 +7175,7 @@ ath11k_mac_op_set_bitrate_mask(struct ie
u8 he_gi = 0, he_ltf = 0;
int single_nss;
int ret;
- int num_rates;
+ int num_single_rates;
bool he_fixed_rate = false;
if (ath11k_mac_vif_chan(vif, &def))
@@ -7215,37 +7252,38 @@ ath11k_mac_op_set_bitrate_mask(struct ie
* the VHT rate as fixed rate for vht peers.
* - Multiple VHT Rates : When Multiple VHT rates are given,this
* can be set using RATEMASK CMD which uses FW rate-ctl alg.
+ * - Multiple VHT single Rates: like 1:9 2:9 3:9 4:9 provided in
+ * set_bitrates(), apply rate based on the best NSS supported by
+ * the peer through peer fixed rate command.
* TODO: Setting multiple VHT MCS and replacing peer_assoc with
* RATEMASK_CMDID can cover all use cases of setting rates
* across multiple preambles and rates within same type.
* But requires more validation of the command at this point.
*/
- num_rates = ath11k_mac_bitrate_mask_num_vht_rates(ar, band,
- mask);
+ num_single_rates = ath11k_mac_bitrate_num_vht_single_rates(ar, band,
+ mask, NULL);
if (!ath11k_mac_vht_mcs_range_present(ar, band, mask) &&
- num_rates > 1) {
- /* TODO: Handle multiple VHT MCS values setting using
- * RATEMASK CMD
- */
+ num_single_rates == 0) {
ath11k_warn(ar->ab,
"Setting VHT MCS range other than 0-7, 0-8 and 0-9 in bitrate mask not supported\n");
return -EINVAL;
}
- num_rates = ath11k_mac_bitrate_mask_num_he_rates(ar, band,
- mask);
- if (num_rates == 1)
- he_fixed_rate = true;
+ num_single_rates = ath11k_mac_bitrate_num_he_single_rates(ar, band,
+ mask, NULL);
if (!ath11k_mac_he_mcs_range_present(ar, band, mask) &&
- num_rates > 1) {
+ num_single_rates == 0) {
ath11k_warn(ar->ab,
"Setting HE MCS range other than 0-7, 0-9 and 0-11 in bitrate mask not supported\n");
return -EINVAL;
}
+ if (num_single_rates >= 1)
+ he_fixed_rate = true;
+
mutex_lock(&ar->conf_mutex);
ieee80211_iterate_stations_atomic(ar->hw,
ath11k_mac_disable_peer_fixed_rate,