iwlwifi: mvm: Fix rate scale NSS configuration
authorIlan Peer <ilan.peer@intel.com>
Fri, 6 Mar 2020 13:16:26 +0000 (15:16 +0200)
committerLuca Coelho <luciano.coelho@intel.com>
Fri, 6 Mar 2020 13:26:33 +0000 (15:26 +0200)
The TLC configuration did not take into consideration the station's
SMPS configuration, and thus configured rates for 2 NSS even if
static SMPS was reported by the station. Fix this.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Link: https://lore.kernel.org/r/iwlwifi.20200306151129.b4f940d13eca.Ieebfa889d08205a3a961ae0138fb5832e8a0f9c1@changeid
drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c

index 80ef238a84884ede56da9a818961b1decb0120b7..ca99a9c4f70ef4cbb58e850a31efe09e972f1c23 100644 (file)
@@ -6,7 +6,7 @@
  * GPL LICENSE SUMMARY
  *
  * Copyright(c) 2017        Intel Deutschland GmbH
- * Copyright(c) 2018 - 2019 Intel Corporation
+ * Copyright(c) 2018 - 2020 Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -27,7 +27,7 @@
  * BSD LICENSE
  *
  * Copyright(c) 2017        Intel Deutschland GmbH
- * Copyright(c) 2018 - 2019 Intel Corporation
+ * Copyright(c) 2018 - 2020 Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -195,11 +195,13 @@ rs_fw_vht_set_enabled_rates(const struct ieee80211_sta *sta,
 {
        u16 supp;
        int i, highest_mcs;
+       u8 nss = sta->rx_nss;
 
-       for (i = 0; i < sta->rx_nss; i++) {
-               if (i == IWL_TLC_NSS_MAX)
-                       break;
+       /* the station support only a single receive chain */
+       if (sta->smps_mode == IEEE80211_SMPS_STATIC)
+               nss = 1;
 
+       for (i = 0; i < nss && i < IWL_TLC_NSS_MAX; i++) {
                highest_mcs = rs_fw_vht_highest_rx_mcs_index(vht_cap, i + 1);
                if (!highest_mcs)
                        continue;
@@ -245,8 +247,13 @@ rs_fw_he_set_enabled_rates(const struct ieee80211_sta *sta,
        u16 tx_mcs_160 =
                le16_to_cpu(sband->iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_160);
        int i;
+       u8 nss = sta->rx_nss;
 
-       for (i = 0; i < sta->rx_nss && i < IWL_TLC_NSS_MAX; i++) {
+       /* the station support only a single receive chain */
+       if (sta->smps_mode == IEEE80211_SMPS_STATIC)
+               nss = 1;
+
+       for (i = 0; i < nss && i < IWL_TLC_NSS_MAX; i++) {
                u16 _mcs_160 = (mcs_160 >> (2 * i)) & 0x3;
                u16 _mcs_80 = (mcs_80 >> (2 * i)) & 0x3;
                u16 _tx_mcs_160 = (tx_mcs_160 >> (2 * i)) & 0x3;
@@ -307,8 +314,14 @@ static void rs_fw_set_supp_rates(struct ieee80211_sta *sta,
                cmd->mode = IWL_TLC_MNG_MODE_HT;
                cmd->ht_rates[IWL_TLC_NSS_1][IWL_TLC_HT_BW_NONE_160] =
                        cpu_to_le16(ht_cap->mcs.rx_mask[0]);
-               cmd->ht_rates[IWL_TLC_NSS_2][IWL_TLC_HT_BW_NONE_160] =
-                       cpu_to_le16(ht_cap->mcs.rx_mask[1]);
+
+               /* the station support only a single receive chain */
+               if (sta->smps_mode == IEEE80211_SMPS_STATIC)
+                       cmd->ht_rates[IWL_TLC_NSS_2][IWL_TLC_HT_BW_NONE_160] =
+                               0;
+               else
+                       cmd->ht_rates[IWL_TLC_NSS_2][IWL_TLC_HT_BW_NONE_160] =
+                               cpu_to_le16(ht_cap->mcs.rx_mask[1]);
        }
 }