* [PATCH 1/2] mt76: mt7915: cleanup mt7915_mcu_sta_rate_ctrl_tlv() @ 2021-04-26 16:29 ` Ryder Lee 0 siblings, 0 replies; 8+ messages in thread From: Ryder Lee @ 2021-04-26 16:29 UTC (permalink / raw) To: Felix Fietkau, Lorenzo Bianconi Cc: Shayne Chen, linux-wireless, linux-mediatek, Ryder Lee Remove obsoleted codes. This is the preparation for .set_bitrate_mask(). Signed-off-by: Ryder Lee <ryder.lee@mediatek.com> --- .../net/wireless/mediatek/mt76/mt7915/mcu.c | 76 +++++-------------- .../net/wireless/mediatek/mt76/mt7915/mcu.h | 2 +- 2 files changed, 22 insertions(+), 56 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index e4f5f72fff29..ed36eaf047b4 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -147,10 +147,10 @@ mt7915_get_he_phy_cap(struct mt7915_phy *phy, struct ieee80211_vif *vif) } static u8 -mt7915_get_phy_mode(struct mt76_phy *mphy, struct ieee80211_vif *vif, - struct ieee80211_sta *sta) +mt7915_get_phy_mode(struct ieee80211_vif *vif, struct ieee80211_sta *sta) { - enum nl80211_band band = mphy->chandef.chan->band; + struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; + enum nl80211_band band = mvif->phy->mt76->chandef.chan->band; struct ieee80211_sta_ht_cap *ht_cap; struct ieee80211_sta_vht_cap *vht_cap; const struct ieee80211_sta_he_cap *he_cap; @@ -163,7 +163,7 @@ mt7915_get_phy_mode(struct mt76_phy *mphy, struct ieee80211_vif *vif, } else { struct ieee80211_supported_band *sband; - sband = mphy->hw->wiphy->bands[band]; + sband = mvif->phy->mt76->hw->wiphy->bands[band]; ht_cap = &sband->ht_cap; vht_cap = &sband->vht_cap; @@ -754,7 +754,7 @@ mt7915_mcu_bss_basic_tlv(struct sk_buff *skb, struct ieee80211_vif *vif, memcpy(bss->bssid, vif->bss_conf.bssid, ETH_ALEN); bss->bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int); bss->dtim_period = vif->bss_conf.dtim_period; - bss->phy_mode = mt7915_get_phy_mode(phy->mt76, vif, NULL); + bss->phy_mode = mt7915_get_phy_mode(vif, NULL); } else { memcpy(bss->bssid, phy->mt76->macaddr, ETH_ALEN); } @@ -2100,47 +2100,39 @@ static void mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { - struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv; - struct mt76_phy *mphy = &dev->mphy; - enum nl80211_band band; + struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; + struct cfg80211_chan_def *chandef = &mvif->phy->mt76->chandef; + enum nl80211_band band = chandef->chan->band; struct sta_rec_ra *ra; struct tlv *tlv; - u32 supp_rate, n_rates, cap = sta->wme ? STA_CAP_WMM : 0; - u8 i, nss = sta->rx_nss, mcs = 0; + u32 supp_rate = sta->supp_rates[band]; + u32 cap = sta->wme ? STA_CAP_WMM : 0; + u8 i, nss = sta->rx_nss; tlv = mt7915_mcu_add_tlv(skb, STA_REC_RA, sizeof(*ra)); ra = (struct sta_rec_ra *)tlv; - if (msta->wcid.ext_phy && dev->mt76.phy2) - mphy = dev->mt76.phy2; - - band = mphy->chandef.chan->band; - supp_rate = sta->supp_rates[band]; - n_rates = hweight32(supp_rate); - ra->valid = true; ra->auto_rate = true; - ra->phy_mode = mt7915_get_phy_mode(mphy, vif, sta); - ra->channel = mphy->chandef.chan->hw_value; + ra->phy_mode = mt7915_get_phy_mode(vif, sta); + ra->channel = chandef->chan->hw_value; ra->bw = sta->bandwidth; - ra->rate_len = n_rates; - ra->phy.bw = sta->bandwidth; + ra->phy.bw = mt7915_mcu_chan_bw(chandef); + + if (supp_rate) { + ra->rate_len = hweight32(supp_rate); - if (n_rates) { if (band == NL80211_BAND_2GHZ) { ra->supp_mode = MODE_CCK; ra->supp_cck_rate = supp_rate & GENMASK(3, 0); - ra->phy.type = MT_PHY_TYPE_CCK; - if (n_rates > 4) { + if (ra->rate_len > 4) { ra->supp_mode |= MODE_OFDM; ra->supp_ofdm_rate = supp_rate >> 4; - ra->phy.type = MT_PHY_TYPE_OFDM; } } else { ra->supp_mode = MODE_OFDM; ra->supp_ofdm_rate = supp_rate; - ra->phy.type = MT_PHY_TYPE_OFDM; } } @@ -2150,7 +2142,6 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, ra->supp_ht_mcs = *(__le32 *)ra->ht_mcs; ra->supp_mode |= MODE_HT; - mcs = hweight32(le32_to_cpu(ra->supp_ht_mcs)) - 1; ra->af = sta->ht_cap.ampdu_factor; ra->ht_gf = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD); @@ -2170,7 +2161,7 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, if (sta->vht_cap.vht_supported) { u16 mcs_map = le16_to_cpu(sta->vht_cap.vht_mcs.rx_mcs_map); u16 vht_mcs; - u8 af, mcs_prev; + u8 af; af = FIELD_GET(IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK, sta->vht_cap.cap); @@ -2189,7 +2180,7 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, cap |= STA_CAP_VHT_LDPC; ra->supp_mode |= MODE_VHT; - for (mcs = 0, i = 0; i < nss; i++, mcs_map >>= 2) { + for (i = 0; i < nss; i++, mcs_map >>= 2) { switch (mcs_map & 0x3) { case IEEE80211_VHT_MCS_SUPPORT_0_9: vht_mcs = GENMASK(9, 0); @@ -2206,10 +2197,6 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, ra->supp_vht_mcs[i] = cpu_to_le16(vht_mcs); - mcs_prev = hweight16(vht_mcs) - 1; - if (mcs_prev > mcs) - mcs = mcs_prev; - /* only support 2ss on 160MHz */ if (i > 1 && (ra->bw == CMD_CBW_160MHZ || ra->bw == CMD_CBW_8080MHZ)) @@ -2222,28 +2209,7 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, cap |= STA_CAP_HE; } - ra->sta_status = cpu_to_le32(cap); - - switch (BIT(fls(ra->supp_mode) - 1)) { - case MODE_VHT: - ra->phy.type = MT_PHY_TYPE_VHT; - ra->phy.mcs = mcs; - ra->phy.nss = nss; - ra->phy.stbc = !!(sta->vht_cap.cap & IEEE80211_VHT_CAP_TXSTBC); - ra->phy.ldpc = !!(sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC); - ra->phy.sgi = - !!(sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80); - break; - case MODE_HT: - ra->phy.type = MT_PHY_TYPE_HT; - ra->phy.mcs = mcs; - ra->phy.ldpc = sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING; - ra->phy.stbc = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_TX_STBC); - ra->phy.sgi = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20); - break; - default: - break; - } + ra->sta_cap = cpu_to_le32(cap); } int mt7915_mcu_add_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif, diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h index 453e34754c86..7e3432384633 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h @@ -943,7 +943,7 @@ struct sta_rec_ra { u8 op_vht_rx_nss; u8 op_vht_rx_nss_type; - __le32 sta_status; + __le32 sta_cap; struct ra_phy phy; } __packed; -- 2.18.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 1/2] mt76: mt7915: cleanup mt7915_mcu_sta_rate_ctrl_tlv() @ 2021-04-26 16:29 ` Ryder Lee 0 siblings, 0 replies; 8+ messages in thread From: Ryder Lee @ 2021-04-26 16:29 UTC (permalink / raw) To: Felix Fietkau, Lorenzo Bianconi Cc: Shayne Chen, linux-wireless, linux-mediatek, Ryder Lee Remove obsoleted codes. This is the preparation for .set_bitrate_mask(). Signed-off-by: Ryder Lee <ryder.lee@mediatek.com> --- .../net/wireless/mediatek/mt76/mt7915/mcu.c | 76 +++++-------------- .../net/wireless/mediatek/mt76/mt7915/mcu.h | 2 +- 2 files changed, 22 insertions(+), 56 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index e4f5f72fff29..ed36eaf047b4 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -147,10 +147,10 @@ mt7915_get_he_phy_cap(struct mt7915_phy *phy, struct ieee80211_vif *vif) } static u8 -mt7915_get_phy_mode(struct mt76_phy *mphy, struct ieee80211_vif *vif, - struct ieee80211_sta *sta) +mt7915_get_phy_mode(struct ieee80211_vif *vif, struct ieee80211_sta *sta) { - enum nl80211_band band = mphy->chandef.chan->band; + struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; + enum nl80211_band band = mvif->phy->mt76->chandef.chan->band; struct ieee80211_sta_ht_cap *ht_cap; struct ieee80211_sta_vht_cap *vht_cap; const struct ieee80211_sta_he_cap *he_cap; @@ -163,7 +163,7 @@ mt7915_get_phy_mode(struct mt76_phy *mphy, struct ieee80211_vif *vif, } else { struct ieee80211_supported_band *sband; - sband = mphy->hw->wiphy->bands[band]; + sband = mvif->phy->mt76->hw->wiphy->bands[band]; ht_cap = &sband->ht_cap; vht_cap = &sband->vht_cap; @@ -754,7 +754,7 @@ mt7915_mcu_bss_basic_tlv(struct sk_buff *skb, struct ieee80211_vif *vif, memcpy(bss->bssid, vif->bss_conf.bssid, ETH_ALEN); bss->bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int); bss->dtim_period = vif->bss_conf.dtim_period; - bss->phy_mode = mt7915_get_phy_mode(phy->mt76, vif, NULL); + bss->phy_mode = mt7915_get_phy_mode(vif, NULL); } else { memcpy(bss->bssid, phy->mt76->macaddr, ETH_ALEN); } @@ -2100,47 +2100,39 @@ static void mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { - struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv; - struct mt76_phy *mphy = &dev->mphy; - enum nl80211_band band; + struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; + struct cfg80211_chan_def *chandef = &mvif->phy->mt76->chandef; + enum nl80211_band band = chandef->chan->band; struct sta_rec_ra *ra; struct tlv *tlv; - u32 supp_rate, n_rates, cap = sta->wme ? STA_CAP_WMM : 0; - u8 i, nss = sta->rx_nss, mcs = 0; + u32 supp_rate = sta->supp_rates[band]; + u32 cap = sta->wme ? STA_CAP_WMM : 0; + u8 i, nss = sta->rx_nss; tlv = mt7915_mcu_add_tlv(skb, STA_REC_RA, sizeof(*ra)); ra = (struct sta_rec_ra *)tlv; - if (msta->wcid.ext_phy && dev->mt76.phy2) - mphy = dev->mt76.phy2; - - band = mphy->chandef.chan->band; - supp_rate = sta->supp_rates[band]; - n_rates = hweight32(supp_rate); - ra->valid = true; ra->auto_rate = true; - ra->phy_mode = mt7915_get_phy_mode(mphy, vif, sta); - ra->channel = mphy->chandef.chan->hw_value; + ra->phy_mode = mt7915_get_phy_mode(vif, sta); + ra->channel = chandef->chan->hw_value; ra->bw = sta->bandwidth; - ra->rate_len = n_rates; - ra->phy.bw = sta->bandwidth; + ra->phy.bw = mt7915_mcu_chan_bw(chandef); + + if (supp_rate) { + ra->rate_len = hweight32(supp_rate); - if (n_rates) { if (band == NL80211_BAND_2GHZ) { ra->supp_mode = MODE_CCK; ra->supp_cck_rate = supp_rate & GENMASK(3, 0); - ra->phy.type = MT_PHY_TYPE_CCK; - if (n_rates > 4) { + if (ra->rate_len > 4) { ra->supp_mode |= MODE_OFDM; ra->supp_ofdm_rate = supp_rate >> 4; - ra->phy.type = MT_PHY_TYPE_OFDM; } } else { ra->supp_mode = MODE_OFDM; ra->supp_ofdm_rate = supp_rate; - ra->phy.type = MT_PHY_TYPE_OFDM; } } @@ -2150,7 +2142,6 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, ra->supp_ht_mcs = *(__le32 *)ra->ht_mcs; ra->supp_mode |= MODE_HT; - mcs = hweight32(le32_to_cpu(ra->supp_ht_mcs)) - 1; ra->af = sta->ht_cap.ampdu_factor; ra->ht_gf = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD); @@ -2170,7 +2161,7 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, if (sta->vht_cap.vht_supported) { u16 mcs_map = le16_to_cpu(sta->vht_cap.vht_mcs.rx_mcs_map); u16 vht_mcs; - u8 af, mcs_prev; + u8 af; af = FIELD_GET(IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK, sta->vht_cap.cap); @@ -2189,7 +2180,7 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, cap |= STA_CAP_VHT_LDPC; ra->supp_mode |= MODE_VHT; - for (mcs = 0, i = 0; i < nss; i++, mcs_map >>= 2) { + for (i = 0; i < nss; i++, mcs_map >>= 2) { switch (mcs_map & 0x3) { case IEEE80211_VHT_MCS_SUPPORT_0_9: vht_mcs = GENMASK(9, 0); @@ -2206,10 +2197,6 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, ra->supp_vht_mcs[i] = cpu_to_le16(vht_mcs); - mcs_prev = hweight16(vht_mcs) - 1; - if (mcs_prev > mcs) - mcs = mcs_prev; - /* only support 2ss on 160MHz */ if (i > 1 && (ra->bw == CMD_CBW_160MHZ || ra->bw == CMD_CBW_8080MHZ)) @@ -2222,28 +2209,7 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, cap |= STA_CAP_HE; } - ra->sta_status = cpu_to_le32(cap); - - switch (BIT(fls(ra->supp_mode) - 1)) { - case MODE_VHT: - ra->phy.type = MT_PHY_TYPE_VHT; - ra->phy.mcs = mcs; - ra->phy.nss = nss; - ra->phy.stbc = !!(sta->vht_cap.cap & IEEE80211_VHT_CAP_TXSTBC); - ra->phy.ldpc = !!(sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC); - ra->phy.sgi = - !!(sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80); - break; - case MODE_HT: - ra->phy.type = MT_PHY_TYPE_HT; - ra->phy.mcs = mcs; - ra->phy.ldpc = sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING; - ra->phy.stbc = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_TX_STBC); - ra->phy.sgi = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20); - break; - default: - break; - } + ra->sta_cap = cpu_to_le32(cap); } int mt7915_mcu_add_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif, diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h index 453e34754c86..7e3432384633 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h @@ -943,7 +943,7 @@ struct sta_rec_ra { u8 op_vht_rx_nss; u8 op_vht_rx_nss_type; - __le32 sta_status; + __le32 sta_cap; struct ra_phy phy; } __packed; -- 2.18.0 _______________________________________________ Linux-mediatek mailing list Linux-mediatek@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-mediatek ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/2] mt76: mt7915: add .set_bitrate_mask() callback 2021-04-26 16:29 ` Ryder Lee @ 2021-04-26 16:29 ` Ryder Lee -1 siblings, 0 replies; 8+ messages in thread From: Ryder Lee @ 2021-04-26 16:29 UTC (permalink / raw) To: Felix Fietkau, Lorenzo Bianconi Cc: Shayne Chen, linux-wireless, linux-mediatek, Ryder Lee Add runtime configuration for bitrate mask. Note that GI cannot be setup. Example: iw dev wlan0 set bitrates vht-mcs-5 1:9 he-mcs-5 2:7 iw dev wlan0 set bitrates legacy-5 6 he-mcs-5 2:0-11 Signed-off-by: Ryder Lee <ryder.lee@mediatek.com> --- .../net/wireless/mediatek/mt76/mt7915/mac.c | 4 +- .../net/wireless/mediatek/mt76/mt7915/main.c | 57 +++++- .../net/wireless/mediatek/mt76/mt7915/mcu.c | 185 ++++++++++++++---- .../wireless/mediatek/mt76/mt7915/mt7915.h | 3 + 4 files changed, 206 insertions(+), 43 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c index 6a4b57509751..67ab268e1aad 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c @@ -1775,8 +1775,10 @@ void mt7915_mac_sta_rc_work(struct work_struct *work) if (changed & (IEEE80211_RC_SUPP_RATES_CHANGED | IEEE80211_RC_NSS_CHANGED | - IEEE80211_RC_BW_CHANGED)) + IEEE80211_RC_BW_CHANGED)) { + mt7915_mcu_add_he(dev, vif, sta); mt7915_mcu_add_rate_ctrl(dev, vif, sta); + } if (changed & IEEE80211_RC_SMPS_CHANGED) mt7915_mcu_add_smps(dev, vif, sta); diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c index e5bd687546b6..c22bd5eea381 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c @@ -172,6 +172,22 @@ static int get_omac_idx(enum nl80211_iftype type, u64 mask) return -1; } +static void mt7915_init_bitrate_mask(struct ieee80211_vif *vif) +{ + struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; + int i; + + for (i = 0; i < ARRAY_SIZE(mvif->bitrate_mask.control); i++) { + mvif->bitrate_mask.control[i].legacy = GENMASK(31, 0); + memset(mvif->bitrate_mask.control[i].ht_mcs, GENMASK(7, 0), + sizeof(mvif->bitrate_mask.control[i].ht_mcs)); + memset(mvif->bitrate_mask.control[i].vht_mcs, GENMASK(15, 0), + sizeof(mvif->bitrate_mask.control[i].vht_mcs)); + memset(mvif->bitrate_mask.control[i].he_mcs, GENMASK(15, 0), + sizeof(mvif->bitrate_mask.control[i].he_mcs)); + } +} + static int mt7915_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { @@ -241,6 +257,8 @@ static int mt7915_add_interface(struct ieee80211_hw *hw, vif->offload_flags = 0; vif->offload_flags |= IEEE80211_OFFLOAD_ENCAP_4ADDR; + mt7915_init_bitrate_mask(vif); + out: mutex_unlock(&dev->mt76.mutex); @@ -911,17 +929,15 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw, sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); } -static void -mt7915_sta_rc_update(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - u32 changed) +static void mt7915_sta_rc_work(void *data, struct ieee80211_sta *sta) { - struct mt7915_dev *dev = mt7915_hw_dev(hw); struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv; + struct mt7915_dev *dev = msta->vif->phy->dev; + struct ieee80211_hw *hw = msta->vif->phy->mt76->hw; + u32 *changed = data; spin_lock_bh(&dev->sta_poll_lock); - msta->stats.changed |= changed; + msta->stats.changed |= *changed; if (list_empty(&msta->rc_list)) list_add_tail(&msta->rc_list, &dev->sta_rc_list); spin_unlock_bh(&dev->sta_poll_lock); @@ -929,6 +945,32 @@ mt7915_sta_rc_update(struct ieee80211_hw *hw, ieee80211_queue_work(hw, &dev->rc_work); } +static void mt7915_sta_rc_update(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + u32 changed) +{ + mt7915_sta_rc_work(&changed, sta); +} + +static int +mt7915_set_bitrate_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + const struct cfg80211_bitrate_mask *mask) +{ + struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; + enum nl80211_band band = mvif->phy->mt76->chandef.chan->band; + u32 changed; + + if (mask->control[band].gi == NL80211_TXRATE_FORCE_LGI) + return -EINVAL; + + changed = IEEE80211_RC_SUPP_RATES_CHANGED; + mvif->bitrate_mask = *mask; + ieee80211_iterate_stations_atomic(hw, mt7915_sta_rc_work, &changed); + + return 0; +} + static void mt7915_sta_set_4addr(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta, @@ -990,6 +1032,7 @@ const struct ieee80211_ops mt7915_ops = { .get_survey = mt76_get_survey, .get_antenna = mt76_get_antenna, .set_antenna = mt7915_set_antenna, + .set_bitrate_mask = mt7915_set_bitrate_mask, .set_coverage_class = mt7915_set_coverage_class, .sta_statistics = mt7915_sta_statistics, .sta_set_4addr = mt7915_sta_set_4addr, diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index ed36eaf047b4..ec6fa5d39a22 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -209,6 +209,112 @@ mt7915_mcu_get_sta_nss(u16 mcs_map) return nss - 1; } +static void +mt7915_mcu_set_sta_he_mcs(struct ieee80211_sta *sta, __le16 *he_mcs, + const u16 *mask) +{ + struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv; + struct cfg80211_chan_def *chandef = &msta->vif->phy->mt76->chandef; + int nss, max_nss = sta->rx_nss > 3 ? 4 : sta->rx_nss; + u16 mcs_map; + + switch (chandef->width) { + case NL80211_CHAN_WIDTH_80P80: + mcs_map = le16_to_cpu(sta->he_cap.he_mcs_nss_supp.rx_mcs_80p80); + break; + case NL80211_CHAN_WIDTH_160: + mcs_map = le16_to_cpu(sta->he_cap.he_mcs_nss_supp.rx_mcs_160); + break; + default: + mcs_map = le16_to_cpu(sta->he_cap.he_mcs_nss_supp.rx_mcs_80); + break; + } + + for (nss = 0; nss < max_nss; nss++) { + int mcs; + + switch ((mcs_map >> (2 * nss)) & 0x3) { + case IEEE80211_HE_MCS_SUPPORT_0_11: + mcs = GENMASK(11, 0); + break; + case IEEE80211_HE_MCS_SUPPORT_0_9: + mcs = GENMASK(9, 0); + break; + case IEEE80211_HE_MCS_SUPPORT_0_7: + mcs = GENMASK(7, 0); + break; + default: + mcs = 0; + } + + mcs = mcs ? fls(mcs & mask[nss]) - 1 : -1; + + switch (mcs) { + case 0 ... 7: + mcs = IEEE80211_HE_MCS_SUPPORT_0_7; + break; + case 8 ... 9: + mcs = IEEE80211_HE_MCS_SUPPORT_0_9; + break; + case 10 ... 11: + mcs = IEEE80211_HE_MCS_SUPPORT_0_11; + break; + default: + mcs = IEEE80211_HE_MCS_NOT_SUPPORTED; + break; + } + mcs_map &= ~(0x3 << (nss * 2)); + mcs_map |= mcs << (nss * 2); + + /* only support 2ss on 160MHz */ + if (nss > 1 && (sta->bandwidth == IEEE80211_STA_RX_BW_160)) + break; + } + + *he_mcs = cpu_to_le16(mcs_map); +} + +static void +mt7915_mcu_set_sta_vht_mcs(struct ieee80211_sta *sta, __le16 *vht_mcs, + const u16 *mask) +{ + u16 mcs_map = le16_to_cpu(sta->vht_cap.vht_mcs.rx_mcs_map); + int nss, max_nss = sta->rx_nss > 3 ? 4 : sta->rx_nss; + u16 mcs; + + for (nss = 0; nss < max_nss; nss++, mcs_map >>= 2) { + switch (mcs_map & 0x3) { + case IEEE80211_VHT_MCS_SUPPORT_0_9: + mcs = GENMASK(9, 0); + break; + case IEEE80211_VHT_MCS_SUPPORT_0_8: + mcs = GENMASK(8, 0); + break; + case IEEE80211_VHT_MCS_SUPPORT_0_7: + mcs = GENMASK(7, 0); + break; + default: + mcs = 0; + } + + vht_mcs[nss] = cpu_to_le16(mcs & mask[nss]); + + /* only support 2ss on 160MHz */ + if (nss > 1 && (sta->bandwidth == IEEE80211_STA_RX_BW_160)) + break; + } +} + +static void +mt7915_mcu_set_sta_ht_mcs(struct ieee80211_sta *sta, u8 *ht_mcs, + const u8 *mask) +{ + int nss, max_nss = sta->rx_nss > 3 ? 4 : sta->rx_nss; + + for (nss = 0; nss < max_nss; nss++) + ht_mcs[nss] = sta->ht_cap.mcs.rx_mask[nss] & mask[nss]; +} + static int mt7915_mcu_parse_response(struct mt76_dev *mdev, int cmd, struct sk_buff *skb, int seq) @@ -1357,8 +1463,11 @@ mt7915_mcu_sta_basic_tlv(struct sk_buff *skb, struct ieee80211_vif *vif, static void mt7915_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta) { + struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv; struct ieee80211_sta_he_cap *he_cap = &sta->he_cap; struct ieee80211_he_cap_elem *elem = &he_cap->he_cap_elem; + enum nl80211_band band = msta->vif->phy->mt76->chandef.chan->band; + const u16 *mcs_mask = msta->vif->bitrate_mask.control[band].he_mcs; struct sta_rec_he *he; struct tlv *tlv; u32 cap = 0; @@ -1449,15 +1558,18 @@ mt7915_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta) case IEEE80211_STA_RX_BW_160: if (elem->phy_cap_info[0] & IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) - he->max_nss_mcs[CMD_HE_MCS_BW8080] = - he_cap->he_mcs_nss_supp.rx_mcs_80p80; + mt7915_mcu_set_sta_he_mcs(sta, + &he->max_nss_mcs[CMD_HE_MCS_BW8080], + mcs_mask); - he->max_nss_mcs[CMD_HE_MCS_BW160] = - he_cap->he_mcs_nss_supp.rx_mcs_160; + mt7915_mcu_set_sta_he_mcs(sta, + &he->max_nss_mcs[CMD_HE_MCS_BW160], + mcs_mask); fallthrough; default: - he->max_nss_mcs[CMD_HE_MCS_BW80] = - he_cap->he_mcs_nss_supp.rx_mcs_80; + mt7915_mcu_set_sta_he_mcs(sta, + &he->max_nss_mcs[CMD_HE_MCS_BW80], + mcs_mask); break; } @@ -2102,12 +2214,12 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, { struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; struct cfg80211_chan_def *chandef = &mvif->phy->mt76->chandef; + struct cfg80211_bitrate_mask *mask = &mvif->bitrate_mask; enum nl80211_band band = chandef->chan->band; struct sta_rec_ra *ra; struct tlv *tlv; u32 supp_rate = sta->supp_rates[band]; u32 cap = sta->wme ? STA_CAP_WMM : 0; - u8 i, nss = sta->rx_nss; tlv = mt7915_mcu_add_tlv(skb, STA_REC_RA, sizeof(*ra)); ra = (struct sta_rec_ra *)tlv; @@ -2120,6 +2232,7 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, ra->phy.bw = mt7915_mcu_chan_bw(chandef); if (supp_rate) { + supp_rate &= mask->control[band].legacy; ra->rate_len = hweight32(supp_rate); if (band == NL80211_BAND_2GHZ) { @@ -2137,10 +2250,8 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, } if (sta->ht_cap.ht_supported) { - for (i = 0; i < nss; i++) - ra->ht_mcs[i] = sta->ht_cap.mcs.rx_mask[i]; + const u8 *mcs_mask = mask->control[band].ht_mcs; - ra->supp_ht_mcs = *(__le32 *)ra->ht_mcs; ra->supp_mode |= MODE_HT; ra->af = sta->ht_cap.ampdu_factor; ra->ht_gf = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD); @@ -2156,13 +2267,16 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, cap |= STA_CAP_RX_STBC; if (sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING) cap |= STA_CAP_LDPC; + + mt7915_mcu_set_sta_ht_mcs(sta, ra->ht_mcs, mcs_mask); + ra->supp_ht_mcs = *(__le32 *)ra->ht_mcs; } if (sta->vht_cap.vht_supported) { - u16 mcs_map = le16_to_cpu(sta->vht_cap.vht_mcs.rx_mcs_map); - u16 vht_mcs; + const u16 *mcs_mask = mask->control[band].vht_mcs; u8 af; + ra->supp_mode |= MODE_VHT; af = FIELD_GET(IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK, sta->vht_cap.cap); ra->af = max_t(u8, ra->af, af); @@ -2179,29 +2293,7 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, if (sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC) cap |= STA_CAP_VHT_LDPC; - ra->supp_mode |= MODE_VHT; - for (i = 0; i < nss; i++, mcs_map >>= 2) { - switch (mcs_map & 0x3) { - case IEEE80211_VHT_MCS_SUPPORT_0_9: - vht_mcs = GENMASK(9, 0); - break; - case IEEE80211_VHT_MCS_SUPPORT_0_8: - vht_mcs = GENMASK(8, 0); - break; - case IEEE80211_VHT_MCS_SUPPORT_0_7: - vht_mcs = GENMASK(7, 0); - break; - default: - vht_mcs = 0; - } - - ra->supp_vht_mcs[i] = cpu_to_le16(vht_mcs); - - /* only support 2ss on 160MHz */ - if (i > 1 && (ra->bw == CMD_CBW_160MHZ || - ra->bw == CMD_CBW_8080MHZ)) - break; - } + mt7915_mcu_set_sta_vht_mcs(sta, ra->supp_vht_mcs, mcs_mask); } if (sta->he_cap.has_he) { @@ -2230,6 +2322,29 @@ int mt7915_mcu_add_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif, MCU_EXT_CMD(STA_REC_UPDATE), true); } +int mt7915_mcu_add_he(struct mt7915_dev *dev, struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; + struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv; + struct sk_buff *skb; + int len; + + if (!sta->he_cap.has_he) + return 0; + + len = sizeof(struct sta_req_hdr) + sizeof(struct sta_rec_he); + + skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta, len); + if (IS_ERR(skb)) + return PTR_ERR(skb); + + mt7915_mcu_sta_he_tlv(skb, sta); + + return mt76_mcu_skb_send_msg(&dev->mt76, skb, + MCU_EXT_CMD(STA_REC_UPDATE), true); +} + int mt7915_mcu_add_sta_adv(struct mt7915_dev *dev, struct ieee80211_vif *vif, struct ieee80211_sta *sta, bool enable) { diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h index 43e3d977cdb2..7eca123f657a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h @@ -103,6 +103,7 @@ struct mt7915_vif { struct mt7915_phy *phy; struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS]; + struct cfg80211_bitrate_mask bitrate_mask; }; struct mib_stats { @@ -332,6 +333,8 @@ int mt7915_mcu_add_obss_spr(struct mt7915_dev *dev, struct ieee80211_vif *vif, bool enable); int mt7915_mcu_add_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif, struct ieee80211_sta *sta); +int mt7915_mcu_add_he(struct mt7915_dev *dev, struct ieee80211_vif *vif, + struct ieee80211_sta *sta); int mt7915_mcu_add_smps(struct mt7915_dev *dev, struct ieee80211_vif *vif, struct ieee80211_sta *sta); int mt7915_set_channel(struct mt7915_phy *phy); -- 2.18.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/2] mt76: mt7915: add .set_bitrate_mask() callback @ 2021-04-26 16:29 ` Ryder Lee 0 siblings, 0 replies; 8+ messages in thread From: Ryder Lee @ 2021-04-26 16:29 UTC (permalink / raw) To: Felix Fietkau, Lorenzo Bianconi Cc: Shayne Chen, linux-wireless, linux-mediatek, Ryder Lee Add runtime configuration for bitrate mask. Note that GI cannot be setup. Example: iw dev wlan0 set bitrates vht-mcs-5 1:9 he-mcs-5 2:7 iw dev wlan0 set bitrates legacy-5 6 he-mcs-5 2:0-11 Signed-off-by: Ryder Lee <ryder.lee@mediatek.com> --- .../net/wireless/mediatek/mt76/mt7915/mac.c | 4 +- .../net/wireless/mediatek/mt76/mt7915/main.c | 57 +++++- .../net/wireless/mediatek/mt76/mt7915/mcu.c | 185 ++++++++++++++---- .../wireless/mediatek/mt76/mt7915/mt7915.h | 3 + 4 files changed, 206 insertions(+), 43 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c index 6a4b57509751..67ab268e1aad 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c @@ -1775,8 +1775,10 @@ void mt7915_mac_sta_rc_work(struct work_struct *work) if (changed & (IEEE80211_RC_SUPP_RATES_CHANGED | IEEE80211_RC_NSS_CHANGED | - IEEE80211_RC_BW_CHANGED)) + IEEE80211_RC_BW_CHANGED)) { + mt7915_mcu_add_he(dev, vif, sta); mt7915_mcu_add_rate_ctrl(dev, vif, sta); + } if (changed & IEEE80211_RC_SMPS_CHANGED) mt7915_mcu_add_smps(dev, vif, sta); diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c index e5bd687546b6..c22bd5eea381 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c @@ -172,6 +172,22 @@ static int get_omac_idx(enum nl80211_iftype type, u64 mask) return -1; } +static void mt7915_init_bitrate_mask(struct ieee80211_vif *vif) +{ + struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; + int i; + + for (i = 0; i < ARRAY_SIZE(mvif->bitrate_mask.control); i++) { + mvif->bitrate_mask.control[i].legacy = GENMASK(31, 0); + memset(mvif->bitrate_mask.control[i].ht_mcs, GENMASK(7, 0), + sizeof(mvif->bitrate_mask.control[i].ht_mcs)); + memset(mvif->bitrate_mask.control[i].vht_mcs, GENMASK(15, 0), + sizeof(mvif->bitrate_mask.control[i].vht_mcs)); + memset(mvif->bitrate_mask.control[i].he_mcs, GENMASK(15, 0), + sizeof(mvif->bitrate_mask.control[i].he_mcs)); + } +} + static int mt7915_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { @@ -241,6 +257,8 @@ static int mt7915_add_interface(struct ieee80211_hw *hw, vif->offload_flags = 0; vif->offload_flags |= IEEE80211_OFFLOAD_ENCAP_4ADDR; + mt7915_init_bitrate_mask(vif); + out: mutex_unlock(&dev->mt76.mutex); @@ -911,17 +929,15 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw, sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); } -static void -mt7915_sta_rc_update(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - u32 changed) +static void mt7915_sta_rc_work(void *data, struct ieee80211_sta *sta) { - struct mt7915_dev *dev = mt7915_hw_dev(hw); struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv; + struct mt7915_dev *dev = msta->vif->phy->dev; + struct ieee80211_hw *hw = msta->vif->phy->mt76->hw; + u32 *changed = data; spin_lock_bh(&dev->sta_poll_lock); - msta->stats.changed |= changed; + msta->stats.changed |= *changed; if (list_empty(&msta->rc_list)) list_add_tail(&msta->rc_list, &dev->sta_rc_list); spin_unlock_bh(&dev->sta_poll_lock); @@ -929,6 +945,32 @@ mt7915_sta_rc_update(struct ieee80211_hw *hw, ieee80211_queue_work(hw, &dev->rc_work); } +static void mt7915_sta_rc_update(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + u32 changed) +{ + mt7915_sta_rc_work(&changed, sta); +} + +static int +mt7915_set_bitrate_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + const struct cfg80211_bitrate_mask *mask) +{ + struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; + enum nl80211_band band = mvif->phy->mt76->chandef.chan->band; + u32 changed; + + if (mask->control[band].gi == NL80211_TXRATE_FORCE_LGI) + return -EINVAL; + + changed = IEEE80211_RC_SUPP_RATES_CHANGED; + mvif->bitrate_mask = *mask; + ieee80211_iterate_stations_atomic(hw, mt7915_sta_rc_work, &changed); + + return 0; +} + static void mt7915_sta_set_4addr(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta, @@ -990,6 +1032,7 @@ const struct ieee80211_ops mt7915_ops = { .get_survey = mt76_get_survey, .get_antenna = mt76_get_antenna, .set_antenna = mt7915_set_antenna, + .set_bitrate_mask = mt7915_set_bitrate_mask, .set_coverage_class = mt7915_set_coverage_class, .sta_statistics = mt7915_sta_statistics, .sta_set_4addr = mt7915_sta_set_4addr, diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index ed36eaf047b4..ec6fa5d39a22 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -209,6 +209,112 @@ mt7915_mcu_get_sta_nss(u16 mcs_map) return nss - 1; } +static void +mt7915_mcu_set_sta_he_mcs(struct ieee80211_sta *sta, __le16 *he_mcs, + const u16 *mask) +{ + struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv; + struct cfg80211_chan_def *chandef = &msta->vif->phy->mt76->chandef; + int nss, max_nss = sta->rx_nss > 3 ? 4 : sta->rx_nss; + u16 mcs_map; + + switch (chandef->width) { + case NL80211_CHAN_WIDTH_80P80: + mcs_map = le16_to_cpu(sta->he_cap.he_mcs_nss_supp.rx_mcs_80p80); + break; + case NL80211_CHAN_WIDTH_160: + mcs_map = le16_to_cpu(sta->he_cap.he_mcs_nss_supp.rx_mcs_160); + break; + default: + mcs_map = le16_to_cpu(sta->he_cap.he_mcs_nss_supp.rx_mcs_80); + break; + } + + for (nss = 0; nss < max_nss; nss++) { + int mcs; + + switch ((mcs_map >> (2 * nss)) & 0x3) { + case IEEE80211_HE_MCS_SUPPORT_0_11: + mcs = GENMASK(11, 0); + break; + case IEEE80211_HE_MCS_SUPPORT_0_9: + mcs = GENMASK(9, 0); + break; + case IEEE80211_HE_MCS_SUPPORT_0_7: + mcs = GENMASK(7, 0); + break; + default: + mcs = 0; + } + + mcs = mcs ? fls(mcs & mask[nss]) - 1 : -1; + + switch (mcs) { + case 0 ... 7: + mcs = IEEE80211_HE_MCS_SUPPORT_0_7; + break; + case 8 ... 9: + mcs = IEEE80211_HE_MCS_SUPPORT_0_9; + break; + case 10 ... 11: + mcs = IEEE80211_HE_MCS_SUPPORT_0_11; + break; + default: + mcs = IEEE80211_HE_MCS_NOT_SUPPORTED; + break; + } + mcs_map &= ~(0x3 << (nss * 2)); + mcs_map |= mcs << (nss * 2); + + /* only support 2ss on 160MHz */ + if (nss > 1 && (sta->bandwidth == IEEE80211_STA_RX_BW_160)) + break; + } + + *he_mcs = cpu_to_le16(mcs_map); +} + +static void +mt7915_mcu_set_sta_vht_mcs(struct ieee80211_sta *sta, __le16 *vht_mcs, + const u16 *mask) +{ + u16 mcs_map = le16_to_cpu(sta->vht_cap.vht_mcs.rx_mcs_map); + int nss, max_nss = sta->rx_nss > 3 ? 4 : sta->rx_nss; + u16 mcs; + + for (nss = 0; nss < max_nss; nss++, mcs_map >>= 2) { + switch (mcs_map & 0x3) { + case IEEE80211_VHT_MCS_SUPPORT_0_9: + mcs = GENMASK(9, 0); + break; + case IEEE80211_VHT_MCS_SUPPORT_0_8: + mcs = GENMASK(8, 0); + break; + case IEEE80211_VHT_MCS_SUPPORT_0_7: + mcs = GENMASK(7, 0); + break; + default: + mcs = 0; + } + + vht_mcs[nss] = cpu_to_le16(mcs & mask[nss]); + + /* only support 2ss on 160MHz */ + if (nss > 1 && (sta->bandwidth == IEEE80211_STA_RX_BW_160)) + break; + } +} + +static void +mt7915_mcu_set_sta_ht_mcs(struct ieee80211_sta *sta, u8 *ht_mcs, + const u8 *mask) +{ + int nss, max_nss = sta->rx_nss > 3 ? 4 : sta->rx_nss; + + for (nss = 0; nss < max_nss; nss++) + ht_mcs[nss] = sta->ht_cap.mcs.rx_mask[nss] & mask[nss]; +} + static int mt7915_mcu_parse_response(struct mt76_dev *mdev, int cmd, struct sk_buff *skb, int seq) @@ -1357,8 +1463,11 @@ mt7915_mcu_sta_basic_tlv(struct sk_buff *skb, struct ieee80211_vif *vif, static void mt7915_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta) { + struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv; struct ieee80211_sta_he_cap *he_cap = &sta->he_cap; struct ieee80211_he_cap_elem *elem = &he_cap->he_cap_elem; + enum nl80211_band band = msta->vif->phy->mt76->chandef.chan->band; + const u16 *mcs_mask = msta->vif->bitrate_mask.control[band].he_mcs; struct sta_rec_he *he; struct tlv *tlv; u32 cap = 0; @@ -1449,15 +1558,18 @@ mt7915_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta) case IEEE80211_STA_RX_BW_160: if (elem->phy_cap_info[0] & IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) - he->max_nss_mcs[CMD_HE_MCS_BW8080] = - he_cap->he_mcs_nss_supp.rx_mcs_80p80; + mt7915_mcu_set_sta_he_mcs(sta, + &he->max_nss_mcs[CMD_HE_MCS_BW8080], + mcs_mask); - he->max_nss_mcs[CMD_HE_MCS_BW160] = - he_cap->he_mcs_nss_supp.rx_mcs_160; + mt7915_mcu_set_sta_he_mcs(sta, + &he->max_nss_mcs[CMD_HE_MCS_BW160], + mcs_mask); fallthrough; default: - he->max_nss_mcs[CMD_HE_MCS_BW80] = - he_cap->he_mcs_nss_supp.rx_mcs_80; + mt7915_mcu_set_sta_he_mcs(sta, + &he->max_nss_mcs[CMD_HE_MCS_BW80], + mcs_mask); break; } @@ -2102,12 +2214,12 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, { struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; struct cfg80211_chan_def *chandef = &mvif->phy->mt76->chandef; + struct cfg80211_bitrate_mask *mask = &mvif->bitrate_mask; enum nl80211_band band = chandef->chan->band; struct sta_rec_ra *ra; struct tlv *tlv; u32 supp_rate = sta->supp_rates[band]; u32 cap = sta->wme ? STA_CAP_WMM : 0; - u8 i, nss = sta->rx_nss; tlv = mt7915_mcu_add_tlv(skb, STA_REC_RA, sizeof(*ra)); ra = (struct sta_rec_ra *)tlv; @@ -2120,6 +2232,7 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, ra->phy.bw = mt7915_mcu_chan_bw(chandef); if (supp_rate) { + supp_rate &= mask->control[band].legacy; ra->rate_len = hweight32(supp_rate); if (band == NL80211_BAND_2GHZ) { @@ -2137,10 +2250,8 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, } if (sta->ht_cap.ht_supported) { - for (i = 0; i < nss; i++) - ra->ht_mcs[i] = sta->ht_cap.mcs.rx_mask[i]; + const u8 *mcs_mask = mask->control[band].ht_mcs; - ra->supp_ht_mcs = *(__le32 *)ra->ht_mcs; ra->supp_mode |= MODE_HT; ra->af = sta->ht_cap.ampdu_factor; ra->ht_gf = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD); @@ -2156,13 +2267,16 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, cap |= STA_CAP_RX_STBC; if (sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING) cap |= STA_CAP_LDPC; + + mt7915_mcu_set_sta_ht_mcs(sta, ra->ht_mcs, mcs_mask); + ra->supp_ht_mcs = *(__le32 *)ra->ht_mcs; } if (sta->vht_cap.vht_supported) { - u16 mcs_map = le16_to_cpu(sta->vht_cap.vht_mcs.rx_mcs_map); - u16 vht_mcs; + const u16 *mcs_mask = mask->control[band].vht_mcs; u8 af; + ra->supp_mode |= MODE_VHT; af = FIELD_GET(IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK, sta->vht_cap.cap); ra->af = max_t(u8, ra->af, af); @@ -2179,29 +2293,7 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, if (sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC) cap |= STA_CAP_VHT_LDPC; - ra->supp_mode |= MODE_VHT; - for (i = 0; i < nss; i++, mcs_map >>= 2) { - switch (mcs_map & 0x3) { - case IEEE80211_VHT_MCS_SUPPORT_0_9: - vht_mcs = GENMASK(9, 0); - break; - case IEEE80211_VHT_MCS_SUPPORT_0_8: - vht_mcs = GENMASK(8, 0); - break; - case IEEE80211_VHT_MCS_SUPPORT_0_7: - vht_mcs = GENMASK(7, 0); - break; - default: - vht_mcs = 0; - } - - ra->supp_vht_mcs[i] = cpu_to_le16(vht_mcs); - - /* only support 2ss on 160MHz */ - if (i > 1 && (ra->bw == CMD_CBW_160MHZ || - ra->bw == CMD_CBW_8080MHZ)) - break; - } + mt7915_mcu_set_sta_vht_mcs(sta, ra->supp_vht_mcs, mcs_mask); } if (sta->he_cap.has_he) { @@ -2230,6 +2322,29 @@ int mt7915_mcu_add_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif, MCU_EXT_CMD(STA_REC_UPDATE), true); } +int mt7915_mcu_add_he(struct mt7915_dev *dev, struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; + struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv; + struct sk_buff *skb; + int len; + + if (!sta->he_cap.has_he) + return 0; + + len = sizeof(struct sta_req_hdr) + sizeof(struct sta_rec_he); + + skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta, len); + if (IS_ERR(skb)) + return PTR_ERR(skb); + + mt7915_mcu_sta_he_tlv(skb, sta); + + return mt76_mcu_skb_send_msg(&dev->mt76, skb, + MCU_EXT_CMD(STA_REC_UPDATE), true); +} + int mt7915_mcu_add_sta_adv(struct mt7915_dev *dev, struct ieee80211_vif *vif, struct ieee80211_sta *sta, bool enable) { diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h index 43e3d977cdb2..7eca123f657a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h @@ -103,6 +103,7 @@ struct mt7915_vif { struct mt7915_phy *phy; struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS]; + struct cfg80211_bitrate_mask bitrate_mask; }; struct mib_stats { @@ -332,6 +333,8 @@ int mt7915_mcu_add_obss_spr(struct mt7915_dev *dev, struct ieee80211_vif *vif, bool enable); int mt7915_mcu_add_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif, struct ieee80211_sta *sta); +int mt7915_mcu_add_he(struct mt7915_dev *dev, struct ieee80211_vif *vif, + struct ieee80211_sta *sta); int mt7915_mcu_add_smps(struct mt7915_dev *dev, struct ieee80211_vif *vif, struct ieee80211_sta *sta); int mt7915_set_channel(struct mt7915_phy *phy); -- 2.18.0 _______________________________________________ Linux-mediatek mailing list Linux-mediatek@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-mediatek ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] mt76: mt7915: add .set_bitrate_mask() callback 2021-04-26 16:29 ` Ryder Lee @ 2021-04-26 18:41 ` Ben Greear -1 siblings, 0 replies; 8+ messages in thread From: Ben Greear @ 2021-04-26 18:41 UTC (permalink / raw) To: Ryder Lee, Felix Fietkau, Lorenzo Bianconi Cc: Shayne Chen, linux-wireless, linux-mediatek On 4/26/21 9:29 AM, Ryder Lee wrote: > Add runtime configuration for bitrate mask. Note that GI cannot be setup. > > Example: > iw dev wlan0 set bitrates vht-mcs-5 1:9 he-mcs-5 2:7 > iw dev wlan0 set bitrates legacy-5 6 he-mcs-5 2:0-11 Is this only for data frames? In other words, is it OK to set exactly one HE/VHT MCS rate and let mgt, bcast, mcast, still work OK at legacy rates? Thanks, Ben -- Ben Greear <greearb@candelatech.com> Candela Technologies Inc http://www.candelatech.com ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] mt76: mt7915: add .set_bitrate_mask() callback @ 2021-04-26 18:41 ` Ben Greear 0 siblings, 0 replies; 8+ messages in thread From: Ben Greear @ 2021-04-26 18:41 UTC (permalink / raw) To: Ryder Lee, Felix Fietkau, Lorenzo Bianconi Cc: Shayne Chen, linux-wireless, linux-mediatek On 4/26/21 9:29 AM, Ryder Lee wrote: > Add runtime configuration for bitrate mask. Note that GI cannot be setup. > > Example: > iw dev wlan0 set bitrates vht-mcs-5 1:9 he-mcs-5 2:7 > iw dev wlan0 set bitrates legacy-5 6 he-mcs-5 2:0-11 Is this only for data frames? In other words, is it OK to set exactly one HE/VHT MCS rate and let mgt, bcast, mcast, still work OK at legacy rates? Thanks, Ben -- Ben Greear <greearb@candelatech.com> Candela Technologies Inc http://www.candelatech.com _______________________________________________ Linux-mediatek mailing list Linux-mediatek@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-mediatek ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] mt76: mt7915: add .set_bitrate_mask() callback 2021-04-26 18:41 ` Ben Greear @ 2021-04-26 19:11 ` Ryder Lee -1 siblings, 0 replies; 8+ messages in thread From: Ryder Lee @ 2021-04-26 19:11 UTC (permalink / raw) To: Ben Greear Cc: Felix Fietkau, Lorenzo Bianconi, Shayne Chen, linux-wireless, linux-mediatek On Mon, 2021-04-26 at 11:41 -0700, Ben Greear wrote: > On 4/26/21 9:29 AM, Ryder Lee wrote: > > Add runtime configuration for bitrate mask. Note that GI cannot be setup. > > > > Example: > > iw dev wlan0 set bitrates vht-mcs-5 1:9 he-mcs-5 2:7 > > iw dev wlan0 set bitrates legacy-5 6 he-mcs-5 2:0-11 > > Is this only for data frames? In other words, is it OK to > set exactly one HE/VHT MCS rate and let mgt, bcast, mcast, still > work OK at legacy rates? > > Thanks, > Ben > Yes. And this's more like a 'limit', and it actually re-initializes firmware rate control for each peer to add a boundry on top of rate table. When you specify something like 'iw dev wlan0 set bitrates vht-mcs-5 1:9', which means nss=1 mcs0-9 actually. If you would like stick to a fixed rate then there's a knob in mt7915 debugfs. As for other the mgmt, mcast, bcast should sill remain in low rate. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] mt76: mt7915: add .set_bitrate_mask() callback @ 2021-04-26 19:11 ` Ryder Lee 0 siblings, 0 replies; 8+ messages in thread From: Ryder Lee @ 2021-04-26 19:11 UTC (permalink / raw) To: Ben Greear Cc: Felix Fietkau, Lorenzo Bianconi, Shayne Chen, linux-wireless, linux-mediatek On Mon, 2021-04-26 at 11:41 -0700, Ben Greear wrote: > On 4/26/21 9:29 AM, Ryder Lee wrote: > > Add runtime configuration for bitrate mask. Note that GI cannot be setup. > > > > Example: > > iw dev wlan0 set bitrates vht-mcs-5 1:9 he-mcs-5 2:7 > > iw dev wlan0 set bitrates legacy-5 6 he-mcs-5 2:0-11 > > Is this only for data frames? In other words, is it OK to > set exactly one HE/VHT MCS rate and let mgt, bcast, mcast, still > work OK at legacy rates? > > Thanks, > Ben > Yes. And this's more like a 'limit', and it actually re-initializes firmware rate control for each peer to add a boundry on top of rate table. When you specify something like 'iw dev wlan0 set bitrates vht-mcs-5 1:9', which means nss=1 mcs0-9 actually. If you would like stick to a fixed rate then there's a knob in mt7915 debugfs. As for other the mgmt, mcast, bcast should sill remain in low rate. _______________________________________________ Linux-mediatek mailing list Linux-mediatek@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-mediatek ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2021-04-26 19:12 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-04-26 16:29 [PATCH 1/2] mt76: mt7915: cleanup mt7915_mcu_sta_rate_ctrl_tlv() Ryder Lee 2021-04-26 16:29 ` Ryder Lee 2021-04-26 16:29 ` [PATCH 2/2] mt76: mt7915: add .set_bitrate_mask() callback Ryder Lee 2021-04-26 16:29 ` Ryder Lee 2021-04-26 18:41 ` Ben Greear 2021-04-26 18:41 ` Ben Greear 2021-04-26 19:11 ` Ryder Lee 2021-04-26 19:11 ` Ryder Lee
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.