max_bw_mhz is not populated with the stas maximum supported width during association. This means data frames are sent at the operating width, regardless of whether the sta can support the operating width. For example a STA that supports up to 4MHz receiving frames from an AP running on an 8MHz operating channel will be sent frames at 8MHz which it cannot receive. Make sure we initialise the stas maximum support bandwidth and while we are here rename it to max_rx_bw_mhz to indicate its the maximum bandwidth the sta can receive frames from. Note: This should be conveyed via ieee80211_link_sta::bandwidth, but the ieee80211_sta_rx_bandwidth enum does not support S1G widths as of now and will require some non-trivial work to support in the future. Signed-off-by: Lachlan Hodges --- drivers/net/wireless/morsemicro/mm81x/core.h | 7 ++++++- drivers/net/wireless/morsemicro/mm81x/mac.c | 11 +++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/morsemicro/mm81x/core.h b/drivers/net/wireless/morsemicro/mm81x/core.h index 2fd4b4786e77..75e998e8e324 100644 --- a/drivers/net/wireless/morsemicro/mm81x/core.h +++ b/drivers/net/wireless/morsemicro/mm81x/core.h @@ -192,7 +192,12 @@ struct mm81x_sta { bool tid_tx[IEEE80211_NUM_TIDS]; bool tid_start_tx[IEEE80211_NUM_TIDS]; u8 tid_params[IEEE80211_NUM_TIDS]; - int max_bw_mhz; + + /* + * We really should be using link_sta::bandwidth but + * that requires non-trivial work. + */ + int max_rx_bw_mhz; struct mm81x_rc_sta rc; struct mmrc_rate last_sta_tx_rate; s16 avg_rssi; diff --git a/drivers/net/wireless/morsemicro/mm81x/mac.c b/drivers/net/wireless/morsemicro/mm81x/mac.c index fa3b0cfccffe..d77df6e9af85 100644 --- a/drivers/net/wireless/morsemicro/mm81x/mac.c +++ b/drivers/net/wireless/morsemicro/mm81x/mac.c @@ -325,7 +325,7 @@ static int mm81x_mac_ops_start(struct ieee80211_hw *hw) return 0; } -static int mm81x_tx_h_get_max_bw(struct mm81x *mors) +static int mm81x_tx_h_get_max_tx_bw(struct mm81x *mors) { return MM81X_FW_SUPP(&mors->fw_caps, 8MHZ) ? 8 : MM81X_FW_SUPP(&mors->fw_caps, 4MHZ) ? 4 : @@ -1260,10 +1260,10 @@ static int mm81x_tx_h_get_bw(struct mm81x *mors, struct ieee80211_sta *sta, if (sta) mors_sta = (struct mm81x_sta *)sta->drv_priv; - tx_bw_mhz = min(mm81x_tx_h_get_max_bw(mors), + tx_bw_mhz = min(mm81x_tx_h_get_max_tx_bw(mors), cfg80211_chandef_get_width(&mors->chandef)); - if (mors_sta && mors_sta->max_bw_mhz) - tx_bw_mhz = min(tx_bw_mhz, mors_sta->max_bw_mhz); + if (mors_sta && mors_sta->max_rx_bw_mhz) + tx_bw_mhz = min(tx_bw_mhz, mors_sta->max_rx_bw_mhz); return tx_bw_mhz; } @@ -1718,6 +1718,9 @@ static int mm81x_mac_ops_sta_state(struct ieee80211_hw *hw, mors_vif->u.ap.num_stas++; else if (vif->type == NL80211_IFTYPE_STATION) mors_vif->u.sta.is_assoc = true; + + mors_sta->max_rx_bw_mhz = + S1G_SUPP_CH_WIDTH_MAX(sta->deflink.s1g_cap.cap); } if (new_state < old_state && new_state == IEEE80211_STA_NONE) { -- 2.43.0