Commit f53be9c4 authored by Gregory Greenman's avatar Gregory Greenman Committed by Johannes Berg

wifi: iwlwifi: mvm: adjust rs init to MLO

Rate scale initialization needs some parameters stored
separately for each link. Pass link_conf and link_sta
pointers and adjust the relevant code accordingly.
Signed-off-by: default avatarGregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230329100039.e2f458198844.I98bf3ea807dd8ae8d703915ce9c01e7b7d5ccb42@changeidSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 5ae9daf1
...@@ -3557,15 +3557,28 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, ...@@ -3557,15 +3557,28 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
* (2) if a link is valid in sta then it's valid in vif (can * (2) if a link is valid in sta then it's valid in vif (can
* use same index in the link array) * use same index in the link array)
*/ */
static void iwl_mvm_rs_rate_init_all_links(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
bool update)
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
unsigned int link_id;
for_each_mvm_vif_valid_link(mvmvif, link_id) {
struct ieee80211_bss_conf *conf =
rcu_dereference_protected(vif->link_conf[link_id], 1);
struct ieee80211_link_sta *link_sta =
rcu_dereference_protected(sta->link[link_id], 1);
if (!conf || !link_sta || !mvmvif->link[link_id]->phy_ctxt)
continue;
#define iwl_mvm_rs_rate_init_all_links(mvm, mvmvif, sta, update) do { \ iwl_mvm_rs_rate_init(mvm, sta, conf, link_sta,
typeof(mvmvif) _mvmvif = mvmvif; \ mvmvif->link[link_id]->phy_ctxt->channel->band,
unsigned int _i; \ update);
for_each_mvm_vif_valid_link(_mvmvif, _i) \ }
iwl_mvm_rs_rate_init((mvm), (sta), \ }
_mvmvif->link[_i]->phy_ctxt->channel->band,\
(update)); \
} while (0)
#define IWL_MVM_MIN_BEACON_INTERVAL_TU 16 #define IWL_MVM_MIN_BEACON_INTERVAL_TU 16
...@@ -3729,7 +3742,7 @@ iwl_mvm_sta_state_auth_to_assoc(struct ieee80211_hw *hw, ...@@ -3729,7 +3742,7 @@ iwl_mvm_sta_state_auth_to_assoc(struct ieee80211_hw *hw,
} }
out: out:
iwl_mvm_rs_rate_init_all_links(mvm, mvmvif, sta, false); iwl_mvm_rs_rate_init_all_links(mvm, vif, sta, false);
return callbacks->update_sta(mvm, vif, sta); return callbacks->update_sta(mvm, vif, sta);
} }
...@@ -3762,7 +3775,7 @@ iwl_mvm_sta_state_assoc_to_authorized(struct iwl_mvm *mvm, ...@@ -3762,7 +3775,7 @@ iwl_mvm_sta_state_assoc_to_authorized(struct iwl_mvm *mvm,
iwl_mvm_mei_host_associated(mvm, vif, mvm_sta); iwl_mvm_mei_host_associated(mvm, vif, mvm_sta);
} }
iwl_mvm_rs_rate_init_all_links(mvm, mvmvif, sta, true); iwl_mvm_rs_rate_init_all_links(mvm, vif, sta, true);
return 0; return 0;
} }
...@@ -3781,7 +3794,7 @@ iwl_mvm_sta_state_authorized_to_assoc(struct iwl_mvm *mvm, ...@@ -3781,7 +3794,7 @@ iwl_mvm_sta_state_authorized_to_assoc(struct iwl_mvm *mvm,
/* once we move into assoc state, need to update rate scale to /* once we move into assoc state, need to update rate scale to
* disable using wide bandwidth * disable using wide bandwidth
*/ */
iwl_mvm_rs_rate_init_all_links(mvm, mvmvif, sta, false); iwl_mvm_rs_rate_init_all_links(mvm, vif, sta, false);
if (!sta->tdls) { if (!sta->tdls) {
/* Set this but don't call iwl_mvm_mac_ctxt_changed() /* Set this but don't call iwl_mvm_mac_ctxt_changed()
...@@ -3950,6 +3963,7 @@ void iwl_mvm_sta_rc_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif, ...@@ -3950,6 +3963,7 @@ void iwl_mvm_sta_rc_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
IEEE80211_RC_SUPP_RATES_CHANGED | IEEE80211_RC_SUPP_RATES_CHANGED |
IEEE80211_RC_NSS_CHANGED)) IEEE80211_RC_NSS_CHANGED))
iwl_mvm_rs_rate_init(mvm, sta, iwl_mvm_rs_rate_init(mvm, sta,
&vif->bss_conf, &sta->deflink,
mvmvif->deflink.phy_ctxt->channel->band, mvmvif->deflink.phy_ctxt->channel->band,
true); true);
......
...@@ -500,16 +500,17 @@ void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm, ...@@ -500,16 +500,17 @@ void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm,
rcu_read_unlock(); rcu_read_unlock();
} }
u16 rs_fw_get_max_amsdu_len(struct ieee80211_sta *sta) u16 rs_fw_get_max_amsdu_len(struct ieee80211_sta *sta,
struct ieee80211_bss_conf *link_conf,
struct ieee80211_link_sta *link_sta)
{ {
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); const struct ieee80211_sta_vht_cap *vht_cap = &link_sta->vht_cap;
const struct ieee80211_sta_vht_cap *vht_cap = &sta->deflink.vht_cap; const struct ieee80211_sta_ht_cap *ht_cap = &link_sta->ht_cap;
const struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap;
if (WARN_ON_ONCE(!mvmsta->vif->bss_conf.chandef.chan)) if (WARN_ON_ONCE(!link_conf->chandef.chan))
return IEEE80211_MAX_MPDU_LEN_VHT_3895; return IEEE80211_MAX_MPDU_LEN_VHT_3895;
if (mvmsta->vif->bss_conf.chandef.chan->band == NL80211_BAND_6GHZ) { if (link_conf->chandef.chan->band == NL80211_BAND_6GHZ) {
switch (le16_get_bits(sta->deflink.he_6ghz_capa.capa, switch (le16_get_bits(sta->deflink.he_6ghz_capa.capa,
IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN)) { IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN)) {
case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454: case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454:
...@@ -546,16 +547,18 @@ u16 rs_fw_get_max_amsdu_len(struct ieee80211_sta *sta) ...@@ -546,16 +547,18 @@ u16 rs_fw_get_max_amsdu_len(struct ieee80211_sta *sta)
} }
void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
struct ieee80211_bss_conf *link_conf,
struct ieee80211_link_sta *link_sta,
enum nl80211_band band, bool update) enum nl80211_band band, bool update)
{ {
struct ieee80211_hw *hw = mvm->hw; struct ieee80211_hw *hw = mvm->hw;
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
struct iwl_lq_sta_rs_fw *lq_sta = &mvmsta->deflink.lq_sta.rs_fw;
u32 cmd_id = WIDE_ID(DATA_PATH_GROUP, TLC_MNG_CONFIG_CMD); u32 cmd_id = WIDE_ID(DATA_PATH_GROUP, TLC_MNG_CONFIG_CMD);
struct ieee80211_supported_band *sband = hw->wiphy->bands[band]; struct ieee80211_supported_band *sband = hw->wiphy->bands[band];
u16 max_amsdu_len = rs_fw_get_max_amsdu_len(sta); u16 max_amsdu_len = rs_fw_get_max_amsdu_len(sta, link_conf, link_sta);
struct iwl_mvm_link_sta *mvm_link_sta;
struct iwl_lq_sta_rs_fw *lq_sta;
struct iwl_tlc_config_cmd_v4 cfg_cmd = { struct iwl_tlc_config_cmd_v4 cfg_cmd = {
.sta_id = mvmsta->deflink.sta_id,
.max_ch_width = update ? .max_ch_width = update ?
rs_fw_bw_from_sta_bw(sta) : IWL_TLC_MNG_CH_WIDTH_20MHZ, 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)), .flags = cpu_to_le16(rs_fw_get_config_flags(mvm, sta, sband)),
...@@ -564,11 +567,24 @@ void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, ...@@ -564,11 +567,24 @@ void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
.max_mpdu_len = iwl_mvm_is_csum_supported(mvm) ? .max_mpdu_len = iwl_mvm_is_csum_supported(mvm) ?
cpu_to_le16(max_amsdu_len) : 0, cpu_to_le16(max_amsdu_len) : 0,
}; };
int ret; unsigned int link_id = link_conf->link_id;
int cmd_ver; int cmd_ver;
int ret;
rcu_read_lock();
mvm_link_sta = rcu_dereference(mvmsta->link[link_id]);
if (WARN_ON_ONCE(!mvm_link_sta)) {
rcu_read_unlock();
return;
}
cfg_cmd.sta_id = mvm_link_sta->sta_id;
lq_sta = &mvm_link_sta->lq_sta.rs_fw;
memset(lq_sta, 0, offsetof(typeof(*lq_sta), pers)); memset(lq_sta, 0, offsetof(typeof(*lq_sta), pers));
rcu_read_unlock();
#ifdef CONFIG_IWLWIFI_DEBUGFS #ifdef CONFIG_IWLWIFI_DEBUGFS
iwl_mvm_reset_frame_stats(mvm); iwl_mvm_reset_frame_stats(mvm);
#endif #endif
......
...@@ -1487,9 +1487,11 @@ static void rs_set_amsdu_len(struct iwl_mvm *mvm, struct ieee80211_sta *sta, ...@@ -1487,9 +1487,11 @@ static void rs_set_amsdu_len(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
enum rs_action scale_action) enum rs_action scale_action)
{ {
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
struct ieee80211_bss_conf *bss_conf = &mvmsta->vif->bss_conf;
int i; int i;
sta->deflink.agg.max_amsdu_len = rs_fw_get_max_amsdu_len(sta); sta->deflink.agg.max_amsdu_len =
rs_fw_get_max_amsdu_len(sta, bss_conf, &sta->deflink);
/* /*
* In case TLC offload is not active amsdu_enabled is either 0xFFFF * In case TLC offload is not active amsdu_enabled is either 0xFFFF
...@@ -1502,7 +1504,7 @@ static void rs_set_amsdu_len(struct iwl_mvm *mvm, struct ieee80211_sta *sta, ...@@ -1502,7 +1504,7 @@ static void rs_set_amsdu_len(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
else else
mvmsta->amsdu_enabled = 0xFFFF; mvmsta->amsdu_enabled = 0xFFFF;
if (mvmsta->vif->bss_conf.he_support && if (bss_conf->he_support &&
!iwlwifi_mod_params.disable_11ax) !iwlwifi_mod_params.disable_11ax)
mvmsta->max_amsdu_len = sta->deflink.agg.max_amsdu_len; mvmsta->max_amsdu_len = sta->deflink.agg.max_amsdu_len;
else else
...@@ -3002,17 +3004,20 @@ static void rs_drv_rate_update(void *mvm_r, ...@@ -3002,17 +3004,20 @@ static void rs_drv_rate_update(void *mvm_r,
void *priv_sta, u32 changed) void *priv_sta, u32 changed)
{ {
struct iwl_op_mode *op_mode = mvm_r; struct iwl_op_mode *op_mode = mvm_r;
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
struct iwl_mvm *mvm __maybe_unused = IWL_OP_MODE_GET_MVM(op_mode); struct iwl_mvm *mvm __maybe_unused = IWL_OP_MODE_GET_MVM(op_mode);
u8 tid; u8 tid;
if (!iwl_mvm_sta_from_mac80211(sta)->vif) if (!mvmsta->vif)
return; return;
/* Stop any ongoing aggregations as rs starts off assuming no agg */ /* Stop any ongoing aggregations as rs starts off assuming no agg */
for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++)
ieee80211_stop_tx_ba_session(sta, tid); ieee80211_stop_tx_ba_session(sta, tid);
iwl_mvm_rs_rate_init(mvm, sta, sband->band, true); iwl_mvm_rs_rate_init(mvm, sta,
&mvmsta->vif->bss_conf, &sta->deflink,
sband->band, true);
} }
static void __iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, static void __iwl_mvm_rs_tx_status(struct iwl_mvm *mvm,
...@@ -4097,10 +4102,12 @@ static const struct rate_control_ops rs_mvm_ops_drv = { ...@@ -4097,10 +4102,12 @@ static const struct rate_control_ops rs_mvm_ops_drv = {
}; };
void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
struct ieee80211_bss_conf *link_conf,
struct ieee80211_link_sta *link_sta,
enum nl80211_band band, bool update) enum nl80211_band band, bool update)
{ {
if (iwl_mvm_has_tlc_offload(mvm)) { if (iwl_mvm_has_tlc_offload(mvm)) {
rs_fw_rate_init(mvm, sta, band, update); rs_fw_rate_init(mvm, sta, link_conf, link_sta, band, update);
} else { } else {
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
......
...@@ -393,7 +393,9 @@ struct iwl_lq_sta { ...@@ -393,7 +393,9 @@ struct iwl_lq_sta {
/* Initialize station's rate scaling information after adding station */ /* Initialize station's rate scaling information after adding station */
void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
enum nl80211_band band, bool init); struct ieee80211_bss_conf *link_conf,
struct ieee80211_link_sta *link_sta,
enum nl80211_band band, bool update);
/* Notify RS about Tx status */ /* Notify RS about Tx status */
void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta, void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
...@@ -430,11 +432,15 @@ void iwl_mvm_reset_frame_stats(struct iwl_mvm *mvm); ...@@ -430,11 +432,15 @@ void iwl_mvm_reset_frame_stats(struct iwl_mvm *mvm);
void iwl_mvm_rs_add_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta); 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, void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
struct ieee80211_bss_conf *link_conf,
struct ieee80211_link_sta *link_sta,
enum nl80211_band band, bool update); enum nl80211_band band, bool update);
int rs_fw_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, int rs_fw_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
bool enable); bool enable);
void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm, void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm,
struct iwl_rx_cmd_buffer *rxb); struct iwl_rx_cmd_buffer *rxb);
u16 rs_fw_get_max_amsdu_len(struct ieee80211_sta *sta); u16 rs_fw_get_max_amsdu_len(struct ieee80211_sta *sta,
struct ieee80211_bss_conf *link_conf,
struct ieee80211_link_sta *link_sta);
#endif /* __rs__ */ #endif /* __rs__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment