wifi: iwlwifi: mvm: use appropriate link for rate selection
We were still using the deflink in most cases, update the code to use the appropriate link. Signed-off-by: Benjamin Berg <benjamin.berg@intel.com> Signed-off-by: Gregory Greenman <gregory.greenman@intel.com> Link: https://lore.kernel.org/r/20230329100039.fa1025502fb4.Iaba0c64740fdcf04a521e2f213bd3f3e27862472@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
0d504ca1f1
commit
9213f809bb
@ -9,9 +9,9 @@
|
||||
#include "iwl-op-mode.h"
|
||||
#include "mvm.h"
|
||||
|
||||
static u8 rs_fw_bw_from_sta_bw(const struct ieee80211_sta *sta)
|
||||
static u8 rs_fw_bw_from_sta_bw(const struct ieee80211_link_sta *link_sta)
|
||||
{
|
||||
switch (sta->deflink.bandwidth) {
|
||||
switch (link_sta->bandwidth) {
|
||||
case IEEE80211_STA_RX_BW_320:
|
||||
return IWL_TLC_MNG_CH_WIDTH_320MHZ;
|
||||
case IEEE80211_STA_RX_BW_160:
|
||||
@ -38,11 +38,11 @@ static u8 rs_fw_set_active_chains(u8 chains)
|
||||
return fw_chains;
|
||||
}
|
||||
|
||||
static u8 rs_fw_sgi_cw_support(struct ieee80211_sta *sta)
|
||||
static u8 rs_fw_sgi_cw_support(struct ieee80211_link_sta *link_sta)
|
||||
{
|
||||
struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap;
|
||||
struct ieee80211_sta_vht_cap *vht_cap = &sta->deflink.vht_cap;
|
||||
struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap;
|
||||
struct ieee80211_sta_ht_cap *ht_cap = &link_sta->ht_cap;
|
||||
struct ieee80211_sta_vht_cap *vht_cap = &link_sta->vht_cap;
|
||||
struct ieee80211_sta_he_cap *he_cap = &link_sta->he_cap;
|
||||
u8 supp = 0;
|
||||
|
||||
if (he_cap->has_he)
|
||||
@ -61,12 +61,12 @@ static u8 rs_fw_sgi_cw_support(struct ieee80211_sta *sta)
|
||||
}
|
||||
|
||||
static u16 rs_fw_get_config_flags(struct iwl_mvm *mvm,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_link_sta *link_sta,
|
||||
struct ieee80211_supported_band *sband)
|
||||
{
|
||||
struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap;
|
||||
struct ieee80211_sta_vht_cap *vht_cap = &sta->deflink.vht_cap;
|
||||
struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap;
|
||||
struct ieee80211_sta_ht_cap *ht_cap = &link_sta->ht_cap;
|
||||
struct ieee80211_sta_vht_cap *vht_cap = &link_sta->vht_cap;
|
||||
struct ieee80211_sta_he_cap *he_cap = &link_sta->he_cap;
|
||||
bool vht_ena = vht_cap->vht_supported;
|
||||
u16 flags = 0;
|
||||
|
||||
@ -132,20 +132,20 @@ int rs_fw_vht_highest_rx_mcs_index(const struct ieee80211_sta_vht_cap *vht_cap,
|
||||
}
|
||||
|
||||
static void
|
||||
rs_fw_vht_set_enabled_rates(const struct ieee80211_sta *sta,
|
||||
rs_fw_vht_set_enabled_rates(const struct ieee80211_link_sta *link_sta,
|
||||
const struct ieee80211_sta_vht_cap *vht_cap,
|
||||
struct iwl_tlc_config_cmd_v4 *cmd)
|
||||
{
|
||||
u16 supp;
|
||||
int i, highest_mcs;
|
||||
u8 max_nss = sta->deflink.rx_nss;
|
||||
u8 max_nss = link_sta->rx_nss;
|
||||
struct ieee80211_vht_cap ieee_vht_cap = {
|
||||
.vht_cap_info = cpu_to_le32(vht_cap->cap),
|
||||
.supp_mcs = vht_cap->vht_mcs,
|
||||
};
|
||||
|
||||
/* the station support only a single receive chain */
|
||||
if (sta->deflink.smps_mode == IEEE80211_SMPS_STATIC)
|
||||
if (link_sta->smps_mode == IEEE80211_SMPS_STATIC)
|
||||
max_nss = 1;
|
||||
|
||||
for (i = 0; i < max_nss && i < IWL_TLC_NSS_MAX; i++) {
|
||||
@ -156,7 +156,7 @@ rs_fw_vht_set_enabled_rates(const struct ieee80211_sta *sta,
|
||||
continue;
|
||||
|
||||
supp = BIT(highest_mcs + 1) - 1;
|
||||
if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20)
|
||||
if (link_sta->bandwidth == IEEE80211_STA_RX_BW_20)
|
||||
supp &= ~BIT(IWL_TLC_MNG_HT_RATE_MCS9);
|
||||
|
||||
cmd->ht_rates[i][IWL_TLC_MCS_PER_BW_80] = cpu_to_le16(supp);
|
||||
@ -165,7 +165,7 @@ rs_fw_vht_set_enabled_rates(const struct ieee80211_sta *sta,
|
||||
* configuration is supported - only for MCS 0 since we already
|
||||
* decoded the MCS bits anyway ourselves.
|
||||
*/
|
||||
if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160 &&
|
||||
if (link_sta->bandwidth == IEEE80211_STA_RX_BW_160 &&
|
||||
ieee80211_get_vht_max_nss(&ieee_vht_cap,
|
||||
IEEE80211_VHT_CHANWIDTH_160MHZ,
|
||||
0, true, nss) >= nss)
|
||||
@ -192,11 +192,11 @@ static u16 rs_fw_he_ieee80211_mcs_to_rs_mcs(u16 mcs)
|
||||
}
|
||||
|
||||
static void
|
||||
rs_fw_he_set_enabled_rates(const struct ieee80211_sta *sta,
|
||||
rs_fw_he_set_enabled_rates(const struct ieee80211_link_sta *link_sta,
|
||||
struct ieee80211_supported_band *sband,
|
||||
struct iwl_tlc_config_cmd_v4 *cmd)
|
||||
{
|
||||
const struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap;
|
||||
const struct ieee80211_sta_he_cap *he_cap = &link_sta->he_cap;
|
||||
u16 mcs_160 = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160);
|
||||
u16 mcs_80 = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80);
|
||||
u16 tx_mcs_80 =
|
||||
@ -204,10 +204,10 @@ 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->deflink.rx_nss;
|
||||
u8 nss = link_sta->rx_nss;
|
||||
|
||||
/* the station support only a single receive chain */
|
||||
if (sta->deflink.smps_mode == IEEE80211_SMPS_STATIC)
|
||||
if (link_sta->smps_mode == IEEE80211_SMPS_STATIC)
|
||||
nss = 1;
|
||||
|
||||
for (i = 0; i < nss && i < IWL_TLC_NSS_MAX; i++) {
|
||||
@ -282,13 +282,14 @@ rs_fw_rs_mcs2eht_mcs(enum IWL_TLC_MCS_PER_BW bw,
|
||||
}
|
||||
}
|
||||
|
||||
static void rs_fw_eht_set_enabled_rates(const struct ieee80211_sta *sta,
|
||||
struct ieee80211_supported_band *sband,
|
||||
struct iwl_tlc_config_cmd_v4 *cmd)
|
||||
static void
|
||||
rs_fw_eht_set_enabled_rates(const struct ieee80211_link_sta *link_sta,
|
||||
struct ieee80211_supported_band *sband,
|
||||
struct iwl_tlc_config_cmd_v4 *cmd)
|
||||
{
|
||||
/* peer RX mcs capa */
|
||||
const struct ieee80211_eht_mcs_nss_supp *eht_rx_mcs =
|
||||
&sta->deflink.eht_cap.eht_mcs_nss_supp;
|
||||
&link_sta->eht_cap.eht_mcs_nss_supp;
|
||||
/* our TX mcs capa */
|
||||
const struct ieee80211_eht_mcs_nss_supp *eht_tx_mcs =
|
||||
&sband->iftype_data->eht_cap.eht_mcs_nss_supp;
|
||||
@ -298,7 +299,7 @@ static void rs_fw_eht_set_enabled_rates(const struct ieee80211_sta *sta,
|
||||
struct ieee80211_eht_mcs_nss_supp_20mhz_only mcs_tx_20;
|
||||
|
||||
/* peer is 20Mhz only */
|
||||
if (!(sta->deflink.he_cap.he_cap_elem.phy_cap_info[0] &
|
||||
if (!(link_sta->he_cap.he_cap_elem.phy_cap_info[0] &
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_MASK_ALL)) {
|
||||
mcs_rx_20 = eht_rx_mcs->only_20mhz;
|
||||
} else {
|
||||
@ -354,25 +355,25 @@ static void rs_fw_eht_set_enabled_rates(const struct ieee80211_sta *sta,
|
||||
}
|
||||
|
||||
/* the station support only a single receive chain */
|
||||
if (sta->deflink.smps_mode == IEEE80211_SMPS_STATIC ||
|
||||
sta->deflink.rx_nss < 2)
|
||||
if (link_sta->smps_mode == IEEE80211_SMPS_STATIC ||
|
||||
link_sta->rx_nss < 2)
|
||||
memset(cmd->ht_rates[IWL_TLC_NSS_2], 0,
|
||||
sizeof(cmd->ht_rates[IWL_TLC_NSS_2]));
|
||||
}
|
||||
|
||||
static void rs_fw_set_supp_rates(struct ieee80211_sta *sta,
|
||||
static void rs_fw_set_supp_rates(struct ieee80211_link_sta *link_sta,
|
||||
struct ieee80211_supported_band *sband,
|
||||
struct iwl_tlc_config_cmd_v4 *cmd)
|
||||
{
|
||||
int i;
|
||||
u16 supp = 0;
|
||||
unsigned long tmp; /* must be unsigned long for for_each_set_bit */
|
||||
const struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap;
|
||||
const struct ieee80211_sta_vht_cap *vht_cap = &sta->deflink.vht_cap;
|
||||
const struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap;
|
||||
const struct ieee80211_sta_ht_cap *ht_cap = &link_sta->ht_cap;
|
||||
const struct ieee80211_sta_vht_cap *vht_cap = &link_sta->vht_cap;
|
||||
const struct ieee80211_sta_he_cap *he_cap = &link_sta->he_cap;
|
||||
|
||||
/* non HT rates */
|
||||
tmp = sta->deflink.supp_rates[sband->band];
|
||||
tmp = link_sta->supp_rates[sband->band];
|
||||
for_each_set_bit(i, &tmp, BITS_PER_LONG)
|
||||
supp |= BIT(sband->bitrates[i].hw_value);
|
||||
|
||||
@ -380,22 +381,22 @@ static void rs_fw_set_supp_rates(struct ieee80211_sta *sta,
|
||||
cmd->mode = IWL_TLC_MNG_MODE_NON_HT;
|
||||
|
||||
/* HT/VHT rates */
|
||||
if (sta->deflink.eht_cap.has_eht) {
|
||||
if (link_sta->eht_cap.has_eht) {
|
||||
cmd->mode = IWL_TLC_MNG_MODE_EHT;
|
||||
rs_fw_eht_set_enabled_rates(sta, sband, cmd);
|
||||
rs_fw_eht_set_enabled_rates(link_sta, sband, cmd);
|
||||
} else if (he_cap->has_he) {
|
||||
cmd->mode = IWL_TLC_MNG_MODE_HE;
|
||||
rs_fw_he_set_enabled_rates(sta, sband, cmd);
|
||||
rs_fw_he_set_enabled_rates(link_sta, sband, cmd);
|
||||
} else if (vht_cap->vht_supported) {
|
||||
cmd->mode = IWL_TLC_MNG_MODE_VHT;
|
||||
rs_fw_vht_set_enabled_rates(sta, vht_cap, cmd);
|
||||
rs_fw_vht_set_enabled_rates(link_sta, vht_cap, cmd);
|
||||
} else if (ht_cap->ht_supported) {
|
||||
cmd->mode = IWL_TLC_MNG_MODE_HT;
|
||||
cmd->ht_rates[IWL_TLC_NSS_1][IWL_TLC_MCS_PER_BW_80] =
|
||||
cpu_to_le16(ht_cap->mcs.rx_mask[0]);
|
||||
|
||||
/* the station support only a single receive chain */
|
||||
if (sta->deflink.smps_mode == IEEE80211_SMPS_STATIC)
|
||||
if (link_sta->smps_mode == IEEE80211_SMPS_STATIC)
|
||||
cmd->ht_rates[IWL_TLC_NSS_2][IWL_TLC_MCS_PER_BW_80] =
|
||||
0;
|
||||
else
|
||||
@ -410,15 +411,18 @@ void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||
struct iwl_tlc_update_notif *notif;
|
||||
struct ieee80211_sta *sta;
|
||||
struct ieee80211_link_sta *link_sta;
|
||||
struct iwl_mvm_sta *mvmsta;
|
||||
struct iwl_mvm_link_sta *mvm_link_sta;
|
||||
struct iwl_lq_sta_rs_fw *lq_sta;
|
||||
u32 flags;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
notif = (void *)pkt->data;
|
||||
link_sta = rcu_dereference(mvm->fw_id_to_link_sta[notif->sta_id]);
|
||||
sta = rcu_dereference(mvm->fw_id_to_mac_id[notif->sta_id]);
|
||||
if (IS_ERR_OR_NULL(sta)) {
|
||||
if (IS_ERR_OR_NULL(sta) || !link_sta) {
|
||||
/* can happen in remove station flow where mvm removed internally
|
||||
* the station before removing from FW
|
||||
*/
|
||||
@ -438,7 +442,14 @@ void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm,
|
||||
|
||||
flags = le32_to_cpu(notif->flags);
|
||||
|
||||
lq_sta = &mvmsta->deflink.lq_sta.rs_fw;
|
||||
mvm_link_sta = rcu_dereference(mvmsta->link[link_sta->link_id]);
|
||||
if (!mvm_link_sta) {
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"Invalid mvmsta RCU pointer for link (%d) of sta id (%d) in TLC notification\n",
|
||||
link_sta->link_id, notif->sta_id);
|
||||
goto out;
|
||||
}
|
||||
lq_sta = &mvm_link_sta->lq_sta.rs_fw;
|
||||
|
||||
if (flags & IWL_TLC_NOTIF_FLAG_RATE) {
|
||||
char pretty_rate[100];
|
||||
@ -465,9 +476,9 @@ void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm,
|
||||
u16 size = le32_to_cpu(notif->amsdu_size);
|
||||
int i;
|
||||
|
||||
if (sta->deflink.agg.max_amsdu_len < size) {
|
||||
if (link_sta->agg.max_amsdu_len < size) {
|
||||
/*
|
||||
* In debug sta->deflink.agg.max_amsdu_len < size
|
||||
* In debug link_sta->agg.max_amsdu_len < size
|
||||
* so also check with orig_amsdu_len which holds the
|
||||
* original data before debugfs changed the value
|
||||
*/
|
||||
@ -477,18 +488,18 @@ void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm,
|
||||
|
||||
mvmsta->amsdu_enabled = le32_to_cpu(notif->amsdu_enabled);
|
||||
mvmsta->max_amsdu_len = size;
|
||||
sta->deflink.agg.max_rc_amsdu_len = mvmsta->max_amsdu_len;
|
||||
link_sta->agg.max_rc_amsdu_len = mvmsta->max_amsdu_len;
|
||||
|
||||
for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
|
||||
if (mvmsta->amsdu_enabled & BIT(i))
|
||||
sta->deflink.agg.max_tid_amsdu_len[i] =
|
||||
link_sta->agg.max_tid_amsdu_len[i] =
|
||||
iwl_mvm_max_amsdu_size(mvm, sta, i);
|
||||
else
|
||||
/*
|
||||
* Not so elegant, but this will effectively
|
||||
* prevent AMSDU on this TID
|
||||
*/
|
||||
sta->deflink.agg.max_tid_amsdu_len[i] = 1;
|
||||
link_sta->agg.max_tid_amsdu_len[i] = 1;
|
||||
}
|
||||
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
@ -511,7 +522,7 @@ u16 rs_fw_get_max_amsdu_len(struct ieee80211_sta *sta,
|
||||
return IEEE80211_MAX_MPDU_LEN_VHT_3895;
|
||||
|
||||
if (link_conf->chandef.chan->band == NL80211_BAND_6GHZ) {
|
||||
switch (le16_get_bits(sta->deflink.he_6ghz_capa.capa,
|
||||
switch (le16_get_bits(link_sta->he_6ghz_capa.capa,
|
||||
IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN)) {
|
||||
case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454:
|
||||
return IEEE80211_MAX_MPDU_LEN_VHT_11454;
|
||||
@ -560,10 +571,12 @@ void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
struct iwl_lq_sta_rs_fw *lq_sta;
|
||||
struct iwl_tlc_config_cmd_v4 cfg_cmd = {
|
||||
.max_ch_width = update ?
|
||||
rs_fw_bw_from_sta_bw(sta) : IWL_TLC_MNG_CH_WIDTH_20MHZ,
|
||||
.flags = cpu_to_le16(rs_fw_get_config_flags(mvm, sta, sband)),
|
||||
rs_fw_bw_from_sta_bw(link_sta) :
|
||||
IWL_TLC_MNG_CH_WIDTH_20MHZ,
|
||||
.flags = cpu_to_le16(rs_fw_get_config_flags(mvm, link_sta,
|
||||
sband)),
|
||||
.chains = rs_fw_set_active_chains(iwl_mvm_get_valid_tx_ant(mvm)),
|
||||
.sgi_ch_width_supp = rs_fw_sgi_cw_support(sta),
|
||||
.sgi_ch_width_supp = rs_fw_sgi_cw_support(link_sta),
|
||||
.max_mpdu_len = iwl_mvm_is_csum_supported(mvm) ?
|
||||
cpu_to_le16(max_amsdu_len) : 0,
|
||||
};
|
||||
@ -588,7 +601,7 @@ void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
iwl_mvm_reset_frame_stats(mvm);
|
||||
#endif
|
||||
rs_fw_set_supp_rates(sta, sband, &cfg_cmd);
|
||||
rs_fw_set_supp_rates(link_sta, sband, &cfg_cmd);
|
||||
|
||||
/*
|
||||
* since TLC offload works with one mode we can assume
|
||||
|
Loading…
x
Reference in New Issue
Block a user