iwlwifi: mvm: rs: add basic implementation of the new RS API handlers
authorGregory Greenman <gregory.greenman@intel.com>
Wed, 1 Nov 2017 07:04:38 +0000 (09:04 +0200)
committerLuca Coelho <luciano.coelho@intel.com>
Tue, 5 Dec 2017 19:01:41 +0000 (21:01 +0200)
This patch adds rate scaling configuration command and
implements a few other handlers.

Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h
drivers/net/wireless/intel/iwlwifi/fw/api/rs.h
drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c
drivers/net/wireless/intel/iwlwifi/mvm/rs.c
drivers/net/wireless/intel/iwlwifi/mvm/rs.h
drivers/net/wireless/intel/iwlwifi/mvm/utils.c

index aa76dcc..8ec1a7f 100644 (file)
@@ -83,6 +83,11 @@ enum iwl_data_path_subcmd_ids {
        TRIGGER_RX_QUEUES_NOTIF_CMD = 0x2,
 
        /**
+        * @TLC_MNG_CONFIG_CMD: &struct iwl_tlc_config_cmd
+        */
+       TLC_MNG_CONFIG_CMD = 0xF,
+
+       /**
         * @STA_PM_NOTIF: &struct iwl_mvm_pm_state_notification
         */
        STA_PM_NOTIF = 0xFD,
index a13fd8a..ba88b0e 100644 (file)
 
 #include "mac.h"
 
+/**
+ * enum iwl_tlc_mng_cfg_flags_enum - options for TLC config flags
+ * @IWL_TLC_MNG_CFG_FLAGS_CCK_MSK: CCK support
+ * @IWL_TLC_MNG_CFG_FLAGS_DD_MSK: enable DD
+ * @IWL_TLC_MNG_CFG_FLAGS_STBC_MSK: enable STBC
+ * @IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK: enable LDPC
+ * @IWL_TLC_MNG_CFG_FLAGS_BF_MSK: enable BFER
+ * @IWL_TLC_MNG_CFG_FLAGS_DCM_MSK: enable DCM
+ */
+enum iwl_tlc_mng_cfg_flags_enum {
+       IWL_TLC_MNG_CFG_FLAGS_CCK_MSK   = BIT(0),
+       IWL_TLC_MNG_CFG_FLAGS_DD_MSK    = BIT(1),
+       IWL_TLC_MNG_CFG_FLAGS_STBC_MSK  = BIT(2),
+       IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK  = BIT(3),
+       IWL_TLC_MNG_CFG_FLAGS_BF_MSK    = BIT(4),
+       IWL_TLC_MNG_CFG_FLAGS_DCM_MSK   = BIT(5),
+};
+
+/**
+ * enum iwl_tlc_mng_cfg_cw_enum - channel width options
+ * @IWL_TLC_MNG_MAX_CH_WIDTH_20MHZ: 20MHZ channel
+ * @IWL_TLC_MNG_MAX_CH_WIDTH_40MHZ: 40MHZ channel
+ * @IWL_TLC_MNG_MAX_CH_WIDTH_80MHZ: 80MHZ channel
+ * @IWL_TLC_MNG_MAX_CH_WIDTH_160MHZ: 160MHZ channel
+ * @IWL_TLC_MNG_MAX_CH_WIDTH_LAST: maximum value
+ */
+enum iwl_tlc_mng_cfg_cw_enum {
+       IWL_TLC_MNG_MAX_CH_WIDTH_20MHZ,
+       IWL_TLC_MNG_MAX_CH_WIDTH_40MHZ,
+       IWL_TLC_MNG_MAX_CH_WIDTH_80MHZ,
+       IWL_TLC_MNG_MAX_CH_WIDTH_160MHZ,
+       IWL_TLC_MNG_MAX_CH_WIDTH_LAST = IWL_TLC_MNG_MAX_CH_WIDTH_160MHZ,
+};
+
+/**
+ * enum iwl_tlc_mng_cfg_chains_enum - possible chains
+ * @IWL_TLC_MNG_CHAIN_A_MSK: chain A
+ * @IWL_TLC_MNG_CHAIN_B_MSK: chain B
+ * @IWL_TLC_MNG_CHAIN_C_MSK: chain C
+ */
+enum iwl_tlc_mng_cfg_chains_enum {
+       IWL_TLC_MNG_CHAIN_A_MSK = BIT(0),
+       IWL_TLC_MNG_CHAIN_B_MSK = BIT(1),
+       IWL_TLC_MNG_CHAIN_C_MSK = BIT(2),
+};
+
+/**
+ * enum iwl_tlc_mng_cfg_gi_enum - guard interval options
+ * @IWL_TLC_MNG_SGI_20MHZ_MSK: enable short GI for 20MHZ
+ * @IWL_TLC_MNG_SGI_40MHZ_MSK: enable short GI for 40MHZ
+ * @IWL_TLC_MNG_SGI_80MHZ_MSK: enable short GI for 80MHZ
+ * @IWL_TLC_MNG_SGI_160MHZ_MSK: enable short GI for 160MHZ
+ */
+enum iwl_tlc_mng_cfg_gi_enum {
+       IWL_TLC_MNG_SGI_20MHZ_MSK  = BIT(0),
+       IWL_TLC_MNG_SGI_40MHZ_MSK  = BIT(1),
+       IWL_TLC_MNG_SGI_80MHZ_MSK  = BIT(2),
+       IWL_TLC_MNG_SGI_160MHZ_MSK = BIT(3),
+};
+
+/**
+ * enum iwl_tlc_mng_cfg_mode_enum - supported modes
+ * @IWL_TLC_MNG_MODE_CCK: enable CCK
+ * @IWL_TLC_MNG_MODE_OFDM_NON_HT: enable OFDM (non HT)
+ * @IWL_TLC_MNG_MODE_NON_HT: enable non HT
+ * @IWL_TLC_MNG_MODE_HT: enable HT
+ * @IWL_TLC_MNG_MODE_VHT: enable VHT
+ * @IWL_TLC_MNG_MODE_HE: enable HE
+ * @IWL_TLC_MNG_MODE_INVALID: invalid value
+ * @IWL_TLC_MNG_MODE_NUM: a count of possible modes
+ */
+enum iwl_tlc_mng_cfg_mode_enum {
+       IWL_TLC_MNG_MODE_CCK = 0,
+       IWL_TLC_MNG_MODE_OFDM_NON_HT = IWL_TLC_MNG_MODE_CCK,
+       IWL_TLC_MNG_MODE_NON_HT = IWL_TLC_MNG_MODE_CCK,
+       IWL_TLC_MNG_MODE_HT,
+       IWL_TLC_MNG_MODE_VHT,
+       IWL_TLC_MNG_MODE_HE,
+       IWL_TLC_MNG_MODE_INVALID,
+       IWL_TLC_MNG_MODE_NUM = IWL_TLC_MNG_MODE_INVALID,
+};
+
+/**
+ * enum iwl_tlc_mng_vht_he_types_enum - VHT HE types
+ * @IWL_TLC_MNG_VALID_VHT_HE_TYPES_SU: VHT HT single user
+ * @IWL_TLC_MNG_VALID_VHT_HE_TYPES_SU_EXT: VHT HT single user extended
+ * @IWL_TLC_MNG_VALID_VHT_HE_TYPES_MU: VHT HT multiple users
+ * @IWL_TLC_MNG_VALID_VHT_HE_TYPES_TRIG_BASED: trigger based
+ * @IWL_TLC_MNG_VALID_VHT_HE_TYPES_NUM: a count of possible types
+ */
+enum iwl_tlc_mng_vht_he_types_enum {
+       IWL_TLC_MNG_VALID_VHT_HE_TYPES_SU = 0,
+       IWL_TLC_MNG_VALID_VHT_HE_TYPES_SU_EXT,
+       IWL_TLC_MNG_VALID_VHT_HE_TYPES_MU,
+       IWL_TLC_MNG_VALID_VHT_HE_TYPES_TRIG_BASED,
+       IWL_TLC_MNG_VALID_VHT_HE_TYPES_NUM =
+               IWL_TLC_MNG_VALID_VHT_HE_TYPES_TRIG_BASED,
+
+};
+
+/**
+ * enum iwl_tlc_mng_ht_rates_enum - HT/VHT rates
+ * @IWL_TLC_MNG_HT_RATE_MCS0: index of MCS0
+ * @IWL_TLC_MNG_HT_RATE_MCS1: index of MCS1
+ * @IWL_TLC_MNG_HT_RATE_MCS2: index of MCS2
+ * @IWL_TLC_MNG_HT_RATE_MCS3: index of MCS3
+ * @IWL_TLC_MNG_HT_RATE_MCS4: index of MCS4
+ * @IWL_TLC_MNG_HT_RATE_MCS5: index of MCS5
+ * @IWL_TLC_MNG_HT_RATE_MCS6: index of MCS6
+ * @IWL_TLC_MNG_HT_RATE_MCS7: index of MCS7
+ * @IWL_TLC_MNG_HT_RATE_MCS8: index of MCS8
+ * @IWL_TLC_MNG_HT_RATE_MCS9: index of MCS9
+ * @IWL_TLC_MNG_HT_RATE_MAX: maximal rate for HT/VHT
+ */
+enum iwl_tlc_mng_ht_rates_enum {
+       IWL_TLC_MNG_HT_RATE_MCS0 = 0,
+       IWL_TLC_MNG_HT_RATE_MCS1,
+       IWL_TLC_MNG_HT_RATE_MCS2,
+       IWL_TLC_MNG_HT_RATE_MCS3,
+       IWL_TLC_MNG_HT_RATE_MCS4,
+       IWL_TLC_MNG_HT_RATE_MCS5,
+       IWL_TLC_MNG_HT_RATE_MCS6,
+       IWL_TLC_MNG_HT_RATE_MCS7,
+       IWL_TLC_MNG_HT_RATE_MCS8,
+       IWL_TLC_MNG_HT_RATE_MCS9,
+       IWL_TLC_MNG_HT_RATE_MAX = IWL_TLC_MNG_HT_RATE_MCS9,
+};
+
+/* Maximum supported tx antennas number */
+#define MAX_RS_ANT_NUM 3
+
+/**
+ * struct tlc_config_cmd - TLC configuration
+ * @sta_id: station id
+ * @reserved1: reserved
+ * @max_supp_ch_width: channel width
+ * @flags: bitmask of %IWL_TLC_MNG_CONFIG_FLAGS_ENABLE_\*
+ * @chains: bitmask of %IWL_TLC_MNG_CHAIN_\*
+ * @max_supp_ss: valid values are 0-3, 0 - spatial streams are not supported
+ * @valid_vht_he_types: bitmap of %IWL_TLC_MNG_VALID_VHT_HE_TYPES_\*
+ * @non_ht_supp_rates: bitmap of supported legacy rates
+ * @ht_supp_rates: bitmap of supported HT/VHT rates, valid bits are 0-9
+ * @mode: modulation type %IWL_TLC_MNG_MODE_\*
+ * @reserved2: reserved
+ * @he_supp_rates: bitmap of supported HE rates
+ * @sgi_ch_width_supp: bitmap of SGI support per channel width
+ * @he_gi_support: 11ax HE guard interval
+ * @max_ampdu_cnt: max AMPDU size (frames count)
+ */
+struct iwl_tlc_config_cmd {
+       u8 sta_id;
+       u8 reserved1[3];
+       u8 max_supp_ch_width;
+       u8 chains;
+       u8 max_supp_ss;
+       u8 valid_vht_he_types;
+       __le16 flags;
+       __le16 non_ht_supp_rates;
+       __le16 ht_supp_rates[MAX_RS_ANT_NUM];
+       u8 mode;
+       u8 reserved2;
+       __le16 he_supp_rates;
+       u8 sgi_ch_width_supp;
+       u8 he_gi_support;
+       __le32 max_ampdu_cnt;
+} __packed; /* TLC_MNG_CONFIG_CMD_API_S_VER_1 */
+
 /*
  * These serve as indexes into
  * struct iwl_rate_info fw_rate_idx_to_plcp[IWL_RATE_COUNT];
@@ -253,7 +420,6 @@ enum {
 #define RATE_MCS_ANT_ABC_MSK           (RATE_MCS_ANT_AB_MSK | \
                                         RATE_MCS_ANT_C_MSK)
 #define RATE_MCS_ANT_MSK               RATE_MCS_ANT_ABC_MSK
-#define RATE_MCS_ANT_NUM 3
 
 /* Bit 17: (0) SS, (1) SS*2 */
 #define RATE_MCS_STBC_POS              17
index aae55b2..8317b2f 100644 (file)
 #include "iwl-op-mode.h"
 #include "mvm.h"
 
+static u8 rs_fw_bw_from_sta_bw(struct ieee80211_sta *sta)
+{
+       switch (sta->bandwidth) {
+       case IEEE80211_STA_RX_BW_160:
+               return IWL_TLC_MNG_MAX_CH_WIDTH_160MHZ;
+       case IEEE80211_STA_RX_BW_80:
+               return IWL_TLC_MNG_MAX_CH_WIDTH_80MHZ;
+       case IEEE80211_STA_RX_BW_40:
+               return IWL_TLC_MNG_MAX_CH_WIDTH_40MHZ;
+       case IEEE80211_STA_RX_BW_20:
+       default:
+               return IWL_TLC_MNG_MAX_CH_WIDTH_20MHZ;
+       }
+}
+
+static u8 rs_fw_set_active_chains(u8 chains)
+{
+       u8 fw_chains = 0;
+
+       if (chains & ANT_A)
+               fw_chains |= IWL_TLC_MNG_CHAIN_A_MSK;
+       if (chains & ANT_B)
+               fw_chains |= IWL_TLC_MNG_CHAIN_B_MSK;
+       if (chains & ANT_C)
+               fw_chains |= IWL_TLC_MNG_CHAIN_C_MSK;
+
+       return fw_chains;
+}
+
+static u8 rs_fw_sgi_cw_support(struct ieee80211_sta *sta)
+{
+       struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
+       struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
+       u8 supp = 0;
+
+       if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20)
+               supp |= IWL_TLC_MNG_SGI_20MHZ_MSK;
+       if (ht_cap->cap & IEEE80211_HT_CAP_SGI_40)
+               supp |= IWL_TLC_MNG_SGI_40MHZ_MSK;
+       if (vht_cap->cap & IEEE80211_VHT_CAP_SHORT_GI_80)
+               supp |= IWL_TLC_MNG_SGI_80MHZ_MSK;
+       if (vht_cap->cap & IEEE80211_VHT_CAP_SHORT_GI_160)
+               supp |= IWL_TLC_MNG_SGI_160MHZ_MSK;
+
+       return supp;
+}
+
+static u16 rs_fw_set_config_flags(struct iwl_mvm *mvm,
+                                 struct ieee80211_sta *sta)
+{
+       struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
+       struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
+       bool vht_ena = vht_cap && vht_cap->vht_supported;
+       u16 flags = IWL_TLC_MNG_CFG_FLAGS_CCK_MSK |
+                   IWL_TLC_MNG_CFG_FLAGS_DCM_MSK |
+                   IWL_TLC_MNG_CFG_FLAGS_DD_MSK;
+
+       if (mvm->cfg->ht_params->stbc &&
+           (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) &&
+           ((ht_cap && (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC)) ||
+            (vht_ena && (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK))))
+               flags |= IWL_TLC_MNG_CFG_FLAGS_STBC_MSK;
+
+       if (mvm->cfg->ht_params->ldpc &&
+           ((ht_cap && (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)) ||
+            (vht_ena && (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC))))
+               flags |= IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK;
+
+       if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_BEAMFORMER) &&
+           (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) &&
+           (vht_cap->cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE))
+               flags |= IWL_TLC_MNG_CFG_FLAGS_BF_MSK;
+
+       return flags;
+}
+
+static
+int rs_fw_vht_highest_rx_mcs_index(struct ieee80211_sta_vht_cap *vht_cap,
+                                  int nss)
+{
+       u16 rx_mcs = le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map) &
+               (0x3 << (2 * (nss - 1)));
+       rx_mcs >>= (2 * (nss - 1));
+
+       switch (rx_mcs) {
+       case IEEE80211_VHT_MCS_SUPPORT_0_7:
+               return IWL_TLC_MNG_HT_RATE_MCS7;
+       case IEEE80211_VHT_MCS_SUPPORT_0_8:
+               return IWL_TLC_MNG_HT_RATE_MCS8;
+       case IEEE80211_VHT_MCS_SUPPORT_0_9:
+               return IWL_TLC_MNG_HT_RATE_MCS9;
+       default:
+               WARN_ON_ONCE(1);
+               break;
+       }
+
+       return 0;
+}
+
+static void rs_fw_vht_set_enabled_rates(struct ieee80211_sta *sta,
+                                       struct ieee80211_sta_vht_cap *vht_cap,
+                                       struct iwl_tlc_config_cmd *cmd)
+{
+       u16 supp;
+       int i, highest_mcs;
+
+       for (i = 0; i < sta->rx_nss; i++) {
+               if (i == MAX_RS_ANT_NUM)
+                       break;
+
+               highest_mcs = rs_fw_vht_highest_rx_mcs_index(vht_cap, i + 1);
+               if (!highest_mcs)
+                       continue;
+
+               supp = BIT(highest_mcs + 1) - 1;
+               if (sta->bandwidth == IEEE80211_STA_RX_BW_20)
+                       supp &= ~BIT(IWL_TLC_MNG_HT_RATE_MCS9);
+
+               cmd->ht_supp_rates[i] = cpu_to_le16(supp);
+       }
+}
+
+static void rs_fw_set_supp_rates(struct ieee80211_sta *sta,
+                                struct ieee80211_supported_band *sband,
+                                struct iwl_tlc_config_cmd *cmd)
+{
+       int i;
+       unsigned long tmp;
+       unsigned long supp; /* must be unsigned long for for_each_set_bit */
+       struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
+       struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
+
+       /* non HT rates */
+       supp = 0;
+       tmp = sta->supp_rates[sband->band];
+       for_each_set_bit(i, &tmp, BITS_PER_LONG)
+               supp |= BIT(sband->bitrates[i].hw_value);
+
+       cmd->non_ht_supp_rates = cpu_to_le16(supp);
+       cmd->mode = IWL_TLC_MNG_MODE_NON_HT;
+
+       /* HT/VHT rates */
+       if (vht_cap && vht_cap->vht_supported) {
+               cmd->mode = IWL_TLC_MNG_MODE_VHT;
+               rs_fw_vht_set_enabled_rates(sta, vht_cap, cmd);
+       } else if (ht_cap && ht_cap->ht_supported) {
+               cmd->mode = IWL_TLC_MNG_MODE_HT;
+               cmd->ht_supp_rates[0] = cpu_to_le16(ht_cap->mcs.rx_mask[0]);
+               cmd->ht_supp_rates[1] = cpu_to_le16(ht_cap->mcs.rx_mask[1]);
+       }
+}
+
 void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
                     enum nl80211_band band)
 {
+       struct ieee80211_hw *hw = mvm->hw;
+       struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
+       struct iwl_lq_sta_rs_fw *lq_sta = &mvmsta->lq_sta.rs_fw;
+       u32 cmd_id = iwl_cmd_id(TLC_MNG_CONFIG_CMD, DATA_PATH_GROUP, 0);
+       struct ieee80211_supported_band *sband;
+       struct iwl_tlc_config_cmd cfg_cmd = {
+               .sta_id = mvmsta->sta_id,
+               .max_supp_ch_width = rs_fw_bw_from_sta_bw(sta),
+               .flags = cpu_to_le16(rs_fw_set_config_flags(mvm, sta)),
+               .chains = rs_fw_set_active_chains(iwl_mvm_get_valid_tx_ant(mvm)),
+               .max_supp_ss = sta->rx_nss,
+               .max_ampdu_cnt = cpu_to_le32(mvmsta->max_agg_bufsize),
+               .sgi_ch_width_supp = rs_fw_sgi_cw_support(sta),
+       };
+       int ret;
+
+       memset(lq_sta, 0, offsetof(typeof(*lq_sta), pers));
+
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+       iwl_mvm_reset_frame_stats(mvm);
+#endif
+       sband = hw->wiphy->bands[band];
+       rs_fw_set_supp_rates(sta, sband, &cfg_cmd);
+
+       ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, sizeof(cfg_cmd), &cfg_cmd);
+       if (ret)
+               IWL_ERR(mvm, "Failed to send rate scale config (%d)\n", ret);
+}
+
+int rs_fw_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
+                       bool enable)
+{
+       /* TODO: need to introduce a new FW cmd since LQ cmd is not relevant */
+       IWL_DEBUG_RATE(mvm, "tx protection - not implemented yet.\n");
+       return 0;
 }
 
 void iwl_mvm_rs_add_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta)
index 3dd6535..428d34c 100644 (file)
@@ -4061,15 +4061,8 @@ void iwl_mvm_rate_control_unregister(void)
        ieee80211_rate_control_unregister(&rs_mvm_ops_drv);
 }
 
-/**
- * iwl_mvm_tx_protection - Gets LQ command, change it to enable/disable
- * Tx protection, according to this request and previous requests,
- * and send the LQ command.
- * @mvmsta: The station
- * @enable: Enable Tx protection?
- */
-int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
-                         bool enable)
+static int rs_drv_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
+                               bool enable)
 {
        struct iwl_lq_cmd *lq = &mvmsta->lq_sta.rs_drv.lq;
 
@@ -4087,3 +4080,17 @@ int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
 
        return iwl_mvm_send_lq_cmd(mvm, lq, false);
 }
+
+/**
+ * iwl_mvm_tx_protection - ask FW to enable RTS/CTS protection
+ * @mvmsta: The station
+ * @enable: Enable Tx protection?
+ */
+int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
+                         bool enable)
+{
+       if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TLC_OFFLOAD))
+               return rs_fw_tx_protection(mvm, mvmsta, enable);
+       else
+               return rs_drv_tx_protection(mvm, mvmsta, enable);
+}
index eb92ded..5b58e2d 100644 (file)
@@ -452,4 +452,6 @@ void rs_remove_sta_debugfs(void *mvm, void *mvm_sta);
 void iwl_mvm_rs_add_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta);
 void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
                     enum nl80211_band band);
+int rs_fw_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
+                       bool enable);
 #endif /* __rs__ */
index 79acb13..280edf8 100644 (file)
@@ -278,8 +278,8 @@ u8 iwl_mvm_next_antenna(struct iwl_mvm *mvm, u8 valid, u8 last_idx)
        u8 ind = last_idx;
        int i;
 
-       for (i = 0; i < RATE_MCS_ANT_NUM; i++) {
-               ind = (ind + 1) % RATE_MCS_ANT_NUM;
+       for (i = 0; i < MAX_RS_ANT_NUM; i++) {
+               ind = (ind + 1) % MAX_RS_ANT_NUM;
                if (valid & BIT(ind))
                        return ind;
        }