diff options
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm')
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 15 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c | 3 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 5 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c | 24 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 164 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/rs.h | 3 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/rx.c | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/utils.c | 164 |
8 files changed, 180 insertions, 200 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 865f973f677d..edae13755ee6 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -115,7 +115,7 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, if (version >= 6) { - struct iwl_alive_ntf_v6 *palive; + struct iwl_alive_ntf_v7 *palive; if (pkt_len < sizeof(*palive)) return false; @@ -214,17 +214,8 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, ~FW_ADDR_CACHE_CONTROL; if (umac_error_table) { - if (umac_error_table >= - mvm->trans->mac_cfg->base->min_umac_error_event_table) { - iwl_fw_umac_set_alive_err_table(mvm->trans, - umac_error_table); - } else { - IWL_ERR(mvm, - "Not valid error log pointer 0x%08X for %s uCode\n", - umac_error_table, - (mvm->fwrt.cur_fw_img == IWL_UCODE_INIT) ? - "Init" : "RT"); - } + iwl_fw_umac_set_alive_err_table(mvm->trans, + umac_error_table); } alive_data->valid = status == IWL_ALIVE_STATUS_OK; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c index b1dca76b7141..380b6f8a53fd 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c @@ -102,9 +102,6 @@ static int iwl_mvm_mld_mac_add_interface(struct ieee80211_hw *hw, mvm->csme_vif = vif; } - if (vif->p2p || iwl_fw_lookup_cmd_ver(mvm->fw, PHY_CONTEXT_CMD, 1) < 5) - vif->driver_flags |= IEEE80211_VIF_IGNORE_OFDMA_WIDER_BW; - return 0; out_free_bf: diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index b515028adc8f..301d590fe0bd 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -2894,4 +2894,9 @@ iwl_mvm_send_ap_tx_power_constraint_cmd(struct iwl_mvm *mvm, void iwl_mvm_smps_workaround(struct iwl_mvm *mvm, struct ieee80211_vif *vif, bool update); + +/* rate_n_flags conversion */ +u32 iwl_mvm_v3_rate_from_fw(__le32 rate, u8 rate_ver); +__le32 iwl_mvm_v3_rate_to_fw(u32 rate, u8 rate_ver); + #endif /* __IWL_MVM_H__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c index 5e7e2926be0c..4f4111055ddd 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2012-2014, 2018-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2025 Intel Corporation * Copyright (C) 2013-2014 Intel Mobile Communications GmbH * Copyright (C) 2017 Intel Deutschland GmbH */ @@ -202,17 +202,13 @@ int iwl_mvm_phy_send_rlc(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt, static int iwl_mvm_phy_ctxt_apply(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt, const struct cfg80211_chan_def *chandef, - const struct cfg80211_chan_def *ap, u8 chains_static, u8 chains_dynamic, u32 action) { int ret; int ver = iwl_fw_lookup_cmd_ver(mvm->fw, PHY_CONTEXT_CMD, 1); - if (ver < 5 || !ap || !ap->chan) - ap = NULL; - - if (ver >= 3 && ver <= 6) { + if (ver >= 3 && ver <= 4) { struct iwl_phy_context_cmd cmd = {}; /* Set the command header fields */ @@ -223,14 +219,6 @@ static int iwl_mvm_phy_ctxt_apply(struct iwl_mvm *mvm, chains_static, chains_dynamic); - if (ap) { - cmd.sbb_bandwidth = iwl_mvm_get_channel_width(ap); - cmd.sbb_ctrl_channel_loc = iwl_mvm_get_ctrl_pos(ap); - } - - if (ver == 6) - cmd.puncture_mask = cpu_to_le16(chandef->punctured); - ret = iwl_mvm_send_cmd_pdu(mvm, PHY_CONTEXT_CMD, 0, sizeof(cmd), &cmd); } else if (ver < 3) { @@ -284,7 +272,7 @@ int iwl_mvm_phy_ctxt_add(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt, ctxt->width = chandef->width; ctxt->center_freq1 = chandef->center_freq1; - ret = iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, ap, + ret = iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, chains_static, chains_dynamic, FW_CTXT_ACTION_ADD); @@ -342,7 +330,7 @@ int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt, int ret; /* ... remove it here ...*/ - ret = iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, NULL, + ret = iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, chains_static, chains_dynamic, FW_CTXT_ACTION_REMOVE); if (ret) @@ -356,7 +344,7 @@ int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt, ctxt->width = chandef->width; ctxt->center_freq1 = chandef->center_freq1; - return iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, ap, + return iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, chains_static, chains_dynamic, action); } @@ -376,7 +364,7 @@ void iwl_mvm_phy_ctxt_unref(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt) cfg80211_chandef_create(&chandef, ctxt->channel, NL80211_CHAN_NO_HT); - iwl_mvm_phy_ctxt_apply(mvm, ctxt, &chandef, NULL, 1, 1, + iwl_mvm_phy_ctxt_apply(mvm, ctxt, &chandef, 1, 1, FW_CTXT_ACTION_REMOVE); } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c index 5802ed80a9ca..d1619a229d8f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c @@ -4178,167 +4178,3 @@ int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, else return rs_drv_tx_protection(mvm, mvmsta, enable); } - -static u32 iwl_legacy_rate_to_fw_idx(u32 rate_n_flags) -{ - int rate = rate_n_flags & RATE_LEGACY_RATE_MSK_V1; - int idx; - bool ofdm = !(rate_n_flags & RATE_MCS_CCK_MSK_V1); - int offset = ofdm ? IWL_FIRST_OFDM_RATE : 0; - int last = ofdm ? IWL_RATE_COUNT_LEGACY : IWL_FIRST_OFDM_RATE; - - for (idx = offset; idx < last; idx++) - if (iwl_fw_rate_idx_to_plcp(idx) == rate) - return idx - offset; - return IWL_RATE_INVALID; -} - -u32 iwl_mvm_v3_rate_from_fw(__le32 rate, u8 rate_ver) -{ - u32 rate_v3 = 0, rate_v1; - u32 dup = 0; - - if (rate_ver > 1) - return iwl_v3_rate_from_v2_v3(rate, rate_ver >= 3); - - rate_v1 = le32_to_cpu(rate); - if (rate_v1 == 0) - return rate_v1; - /* convert rate */ - if (rate_v1 & RATE_MCS_HT_MSK_V1) { - u32 nss; - - rate_v3 |= RATE_MCS_MOD_TYPE_HT; - rate_v3 |= - rate_v1 & RATE_HT_MCS_RATE_CODE_MSK_V1; - nss = u32_get_bits(rate_v1, RATE_HT_MCS_MIMO2_MSK); - rate_v3 |= u32_encode_bits(nss, RATE_MCS_NSS_MSK); - } else if (rate_v1 & RATE_MCS_VHT_MSK_V1 || - rate_v1 & RATE_MCS_HE_MSK_V1) { - u32 nss = u32_get_bits(rate_v1, RATE_VHT_MCS_NSS_MSK); - - rate_v3 |= rate_v1 & RATE_VHT_MCS_RATE_CODE_MSK; - - rate_v3 |= u32_encode_bits(nss, RATE_MCS_NSS_MSK); - - if (rate_v1 & RATE_MCS_HE_MSK_V1) { - u32 he_type_bits = rate_v1 & RATE_MCS_HE_TYPE_MSK_V1; - u32 he_type = he_type_bits >> RATE_MCS_HE_TYPE_POS_V1; - u32 he_106t = (rate_v1 & RATE_MCS_HE_106T_MSK_V1) >> - RATE_MCS_HE_106T_POS_V1; - u32 he_gi_ltf = (rate_v1 & RATE_MCS_HE_GI_LTF_MSK_V1) >> - RATE_MCS_HE_GI_LTF_POS; - - if ((he_type_bits == RATE_MCS_HE_TYPE_SU || - he_type_bits == RATE_MCS_HE_TYPE_EXT_SU) && - he_gi_ltf == RATE_MCS_HE_SU_4_LTF) - /* the new rate have an additional bit to - * represent the value 4 rather then using SGI - * bit for this purpose - as it was done in the - * old rate - */ - he_gi_ltf += (rate_v1 & RATE_MCS_SGI_MSK_V1) >> - RATE_MCS_SGI_POS_V1; - - rate_v3 |= he_gi_ltf << RATE_MCS_HE_GI_LTF_POS; - rate_v3 |= he_type << RATE_MCS_HE_TYPE_POS; - rate_v3 |= he_106t << RATE_MCS_HE_106T_POS; - rate_v3 |= rate_v1 & RATE_HE_DUAL_CARRIER_MODE_MSK; - rate_v3 |= RATE_MCS_MOD_TYPE_HE; - } else { - rate_v3 |= RATE_MCS_MOD_TYPE_VHT; - } - /* if legacy format */ - } else { - u32 legacy_rate = iwl_legacy_rate_to_fw_idx(rate_v1); - - if (WARN_ON_ONCE(legacy_rate == IWL_RATE_INVALID)) - legacy_rate = (rate_v1 & RATE_MCS_CCK_MSK_V1) ? - IWL_FIRST_CCK_RATE : IWL_FIRST_OFDM_RATE; - - rate_v3 |= legacy_rate; - if (!(rate_v1 & RATE_MCS_CCK_MSK_V1)) - rate_v3 |= RATE_MCS_MOD_TYPE_LEGACY_OFDM; - } - - /* convert flags */ - if (rate_v1 & RATE_MCS_LDPC_MSK_V1) - rate_v3 |= RATE_MCS_LDPC_MSK; - rate_v3 |= (rate_v1 & RATE_MCS_CHAN_WIDTH_MSK_V1) | - (rate_v1 & RATE_MCS_ANT_AB_MSK) | - (rate_v1 & RATE_MCS_STBC_MSK) | - (rate_v1 & RATE_MCS_BF_MSK); - - dup = (rate_v1 & RATE_MCS_DUP_MSK_V1) >> RATE_MCS_DUP_POS_V1; - if (dup) { - rate_v3 |= RATE_MCS_DUP_MSK; - rate_v3 |= dup << RATE_MCS_CHAN_WIDTH_POS; - } - - if ((!(rate_v1 & RATE_MCS_HE_MSK_V1)) && - (rate_v1 & RATE_MCS_SGI_MSK_V1)) - rate_v3 |= RATE_MCS_SGI_MSK; - - return rate_v3; -} - -__le32 iwl_mvm_v3_rate_to_fw(u32 rate, u8 rate_ver) -{ - u32 result = 0; - int rate_idx; - - if (rate_ver > 1) - return iwl_v3_rate_to_v2_v3(rate, rate_ver > 2); - - switch (rate & RATE_MCS_MOD_TYPE_MSK) { - case RATE_MCS_MOD_TYPE_CCK: - result = RATE_MCS_CCK_MSK_V1; - fallthrough; - case RATE_MCS_MOD_TYPE_LEGACY_OFDM: - rate_idx = u32_get_bits(rate, RATE_LEGACY_RATE_MSK); - if (!(result & RATE_MCS_CCK_MSK_V1)) - rate_idx += IWL_FIRST_OFDM_RATE; - result |= u32_encode_bits(iwl_fw_rate_idx_to_plcp(rate_idx), - RATE_LEGACY_RATE_MSK_V1); - break; - case RATE_MCS_MOD_TYPE_HT: - result = RATE_MCS_HT_MSK_V1; - result |= u32_encode_bits(u32_get_bits(rate, - RATE_HT_MCS_CODE_MSK), - RATE_HT_MCS_RATE_CODE_MSK_V1); - result |= u32_encode_bits(u32_get_bits(rate, - RATE_MCS_NSS_MSK), - RATE_HT_MCS_MIMO2_MSK); - break; - case RATE_MCS_MOD_TYPE_VHT: - result = RATE_MCS_VHT_MSK_V1; - result |= u32_encode_bits(u32_get_bits(rate, - RATE_VHT_MCS_NSS_MSK), - RATE_MCS_CODE_MSK); - result |= u32_encode_bits(u32_get_bits(rate, RATE_MCS_NSS_MSK), - RATE_VHT_MCS_NSS_MSK); - break; - case RATE_MCS_MOD_TYPE_HE: /* not generated */ - default: - WARN_ONCE(1, "bad modulation type %d\n", - u32_get_bits(rate, RATE_MCS_MOD_TYPE_MSK)); - return 0; - } - - if (rate & RATE_MCS_LDPC_MSK) - result |= RATE_MCS_LDPC_MSK_V1; - WARN_ON_ONCE(u32_get_bits(rate, RATE_MCS_CHAN_WIDTH_MSK) > - RATE_MCS_CHAN_WIDTH_160_VAL); - result |= (rate & RATE_MCS_CHAN_WIDTH_MSK_V1) | - (rate & RATE_MCS_ANT_AB_MSK) | - (rate & RATE_MCS_STBC_MSK) | - (rate & RATE_MCS_BF_MSK); - - /* not handling DUP since we don't use it */ - WARN_ON_ONCE(rate & RATE_MCS_DUP_MSK); - - if (rate & RATE_MCS_SGI_MSK) - result |= RATE_MCS_SGI_MSK_V1; - - return cpu_to_le32(result); -} diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h index dfb062b7c5c2..34c957bef6f8 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h @@ -425,9 +425,6 @@ void iwl_mvm_rate_control_unregister(void); struct iwl_mvm_sta; -u32 iwl_mvm_v3_rate_from_fw(__le32 rate, u8 rate_ver); -__le32 iwl_mvm_v3_rate_to_fw(u32 rate, u8 rate_ver); - int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, bool enable); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c index 8c1bb3a7ffca..d0c0faae0122 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c @@ -519,6 +519,8 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi, return; } rx_status->rate_idx = rate; + /* override BW - it could be DUP and indicate the wrong BW */ + rx_status->bw = RATE_INFO_BW_20; } #ifdef CONFIG_IWLWIFI_DEBUGFS diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c index fa995e235d9b..1a6c1f8706e1 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c @@ -1243,3 +1243,167 @@ bool iwl_mvm_vif_is_active(struct iwl_mvm_vif *mvmvif) return false; } + +static u32 iwl_legacy_rate_to_fw_idx(u32 rate_n_flags) +{ + int rate = rate_n_flags & RATE_LEGACY_RATE_MSK_V1; + int idx; + bool ofdm = !(rate_n_flags & RATE_MCS_CCK_MSK_V1); + int offset = ofdm ? IWL_FIRST_OFDM_RATE : 0; + int last = ofdm ? IWL_RATE_COUNT_LEGACY : IWL_FIRST_OFDM_RATE; + + for (idx = offset; idx < last; idx++) + if (iwl_fw_rate_idx_to_plcp(idx) == rate) + return idx - offset; + return IWL_RATE_INVALID; +} + +u32 iwl_mvm_v3_rate_from_fw(__le32 rate, u8 rate_ver) +{ + u32 rate_v3 = 0, rate_v1; + u32 dup = 0; + + if (rate_ver > 1) + return iwl_v3_rate_from_v2_v3(rate, rate_ver >= 3); + + rate_v1 = le32_to_cpu(rate); + if (rate_v1 == 0) + return rate_v1; + /* convert rate */ + if (rate_v1 & RATE_MCS_HT_MSK_V1) { + u32 nss; + + rate_v3 |= RATE_MCS_MOD_TYPE_HT; + rate_v3 |= + rate_v1 & RATE_HT_MCS_RATE_CODE_MSK_V1; + nss = u32_get_bits(rate_v1, RATE_HT_MCS_MIMO2_MSK); + rate_v3 |= u32_encode_bits(nss, RATE_MCS_NSS_MSK); + } else if (rate_v1 & RATE_MCS_VHT_MSK_V1 || + rate_v1 & RATE_MCS_HE_MSK_V1) { + u32 nss = u32_get_bits(rate_v1, RATE_VHT_MCS_NSS_MSK); + + rate_v3 |= rate_v1 & RATE_VHT_MCS_RATE_CODE_MSK; + + rate_v3 |= u32_encode_bits(nss, RATE_MCS_NSS_MSK); + + if (rate_v1 & RATE_MCS_HE_MSK_V1) { + u32 he_type_bits = rate_v1 & RATE_MCS_HE_TYPE_MSK_V1; + u32 he_type = he_type_bits >> RATE_MCS_HE_TYPE_POS_V1; + u32 he_106t = (rate_v1 & RATE_MCS_HE_106T_MSK_V1) >> + RATE_MCS_HE_106T_POS_V1; + u32 he_gi_ltf = (rate_v1 & RATE_MCS_HE_GI_LTF_MSK_V1) >> + RATE_MCS_HE_GI_LTF_POS; + + if ((he_type_bits == RATE_MCS_HE_TYPE_SU || + he_type_bits == RATE_MCS_HE_TYPE_EXT_SU) && + he_gi_ltf == RATE_MCS_HE_SU_4_LTF) + /* the new rate have an additional bit to + * represent the value 4 rather then using SGI + * bit for this purpose - as it was done in the + * old rate + */ + he_gi_ltf += (rate_v1 & RATE_MCS_SGI_MSK_V1) >> + RATE_MCS_SGI_POS_V1; + + rate_v3 |= he_gi_ltf << RATE_MCS_HE_GI_LTF_POS; + rate_v3 |= he_type << RATE_MCS_HE_TYPE_POS; + rate_v3 |= he_106t << RATE_MCS_HE_106T_POS; + rate_v3 |= rate_v1 & RATE_HE_DUAL_CARRIER_MODE_MSK; + rate_v3 |= RATE_MCS_MOD_TYPE_HE; + } else { + rate_v3 |= RATE_MCS_MOD_TYPE_VHT; + } + /* if legacy format */ + } else { + u32 legacy_rate = iwl_legacy_rate_to_fw_idx(rate_v1); + + if (WARN_ON_ONCE(legacy_rate == IWL_RATE_INVALID)) + legacy_rate = (rate_v1 & RATE_MCS_CCK_MSK_V1) ? + IWL_FIRST_CCK_RATE : IWL_FIRST_OFDM_RATE; + + rate_v3 |= legacy_rate; + if (!(rate_v1 & RATE_MCS_CCK_MSK_V1)) + rate_v3 |= RATE_MCS_MOD_TYPE_LEGACY_OFDM; + } + + /* convert flags */ + if (rate_v1 & RATE_MCS_LDPC_MSK_V1) + rate_v3 |= RATE_MCS_LDPC_MSK; + rate_v3 |= (rate_v1 & RATE_MCS_CHAN_WIDTH_MSK_V1) | + (rate_v1 & RATE_MCS_ANT_AB_MSK) | + (rate_v1 & RATE_MCS_STBC_MSK) | + (rate_v1 & RATE_MCS_BF_MSK); + + dup = (rate_v1 & RATE_MCS_DUP_MSK_V1) >> RATE_MCS_DUP_POS_V1; + if (dup) { + rate_v3 |= RATE_MCS_DUP_MSK; + rate_v3 |= dup << RATE_MCS_CHAN_WIDTH_POS; + } + + if ((!(rate_v1 & RATE_MCS_HE_MSK_V1)) && + (rate_v1 & RATE_MCS_SGI_MSK_V1)) + rate_v3 |= RATE_MCS_SGI_MSK; + + return rate_v3; +} + +__le32 iwl_mvm_v3_rate_to_fw(u32 rate, u8 rate_ver) +{ + u32 result = 0; + int rate_idx; + + if (rate_ver > 1) + return iwl_v3_rate_to_v2_v3(rate, rate_ver > 2); + + switch (rate & RATE_MCS_MOD_TYPE_MSK) { + case RATE_MCS_MOD_TYPE_CCK: + result = RATE_MCS_CCK_MSK_V1; + fallthrough; + case RATE_MCS_MOD_TYPE_LEGACY_OFDM: + rate_idx = u32_get_bits(rate, RATE_LEGACY_RATE_MSK); + if (!(result & RATE_MCS_CCK_MSK_V1)) + rate_idx += IWL_FIRST_OFDM_RATE; + result |= u32_encode_bits(iwl_fw_rate_idx_to_plcp(rate_idx), + RATE_LEGACY_RATE_MSK_V1); + break; + case RATE_MCS_MOD_TYPE_HT: + result = RATE_MCS_HT_MSK_V1; + result |= u32_encode_bits(u32_get_bits(rate, + RATE_HT_MCS_CODE_MSK), + RATE_HT_MCS_RATE_CODE_MSK_V1); + result |= u32_encode_bits(u32_get_bits(rate, + RATE_MCS_NSS_MSK), + RATE_HT_MCS_MIMO2_MSK); + break; + case RATE_MCS_MOD_TYPE_VHT: + result = RATE_MCS_VHT_MSK_V1; + result |= u32_encode_bits(u32_get_bits(rate, + RATE_VHT_MCS_NSS_MSK), + RATE_MCS_CODE_MSK); + result |= u32_encode_bits(u32_get_bits(rate, RATE_MCS_NSS_MSK), + RATE_VHT_MCS_NSS_MSK); + break; + case RATE_MCS_MOD_TYPE_HE: /* not generated */ + default: + WARN_ONCE(1, "bad modulation type %d\n", + u32_get_bits(rate, RATE_MCS_MOD_TYPE_MSK)); + return 0; + } + + if (rate & RATE_MCS_LDPC_MSK) + result |= RATE_MCS_LDPC_MSK_V1; + WARN_ON_ONCE(u32_get_bits(rate, RATE_MCS_CHAN_WIDTH_MSK) > + RATE_MCS_CHAN_WIDTH_160_VAL); + result |= (rate & RATE_MCS_CHAN_WIDTH_MSK_V1) | + (rate & RATE_MCS_ANT_AB_MSK) | + (rate & RATE_MCS_STBC_MSK) | + (rate & RATE_MCS_BF_MSK); + + /* not handling DUP since we don't use it */ + WARN_ON_ONCE(rate & RATE_MCS_DUP_MSK); + + if (rate & RATE_MCS_SGI_MSK) + result |= RATE_MCS_SGI_MSK_V1; + + return cpu_to_le32(result); +} |
