Commit 15ee62e7 authored by Ryder Lee's avatar Ryder Lee Committed by Felix Fietkau

wifi: mt76: mt7996: enable BSS_CHANGED_BASIC_RATES support

The connac3 removes fixed rate fields to reduce txd size and introduces
global rate tables (64 entries) for rate setting. Driver needs to fill
the corresponding idx in MT_TXD6_TX_RATE while tx, and push mt76_rate
into predifined table at bootup stage so that  mvif->basic_rates_idx
can immediately switch out once setting changes.

spe_idx is also needed for fixed rate frames, and will be updated by
future patches.

Note that all table entries are shared across driver and firmware
(i.e.TxBF), hence adding MT7996_BASIC_RATES_TBL to reflect mapping
status.
Signed-off-by: default avatarRyder Lee <ryder.lee@mediatek.com>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent 9c54548b
......@@ -255,6 +255,20 @@ mt7996_mac_init_band(struct mt7996_dev *dev, u8 band)
mt76_rmw(dev, MT_WTBLOFF_RSCR(band), mask, set);
}
static void mt7996_mac_init_basic_rates(struct mt7996_dev *dev)
{
int i;
for (i = 0; i < ARRAY_SIZE(mt76_rates); i++) {
u16 rate = mt76_rates[i].hw_value;
u16 idx = MT7996_BASIC_RATES_TBL + i;
rate = FIELD_PREP(MT_TX_RATE_MODE, rate >> 8) |
FIELD_PREP(MT_TX_RATE_IDX, rate & GENMASK(7, 0));
mt7996_mac_set_fixed_rate_table(dev, idx, rate);
}
}
void mt7996_mac_init(struct mt7996_dev *dev)
{
#define HIF_TXD_V2_1 4
......@@ -287,6 +301,8 @@ void mt7996_mac_init(struct mt7996_dev *dev)
for (i = MT_BAND0; i <= MT_BAND2; i++)
mt7996_mac_init_band(dev, i);
mt7996_mac_init_basic_rates(dev);
}
int mt7996_txbf_init(struct mt7996_dev *dev)
......
......@@ -252,6 +252,17 @@ void mt7996_mac_enable_rtscts(struct mt7996_dev *dev,
mt76_clear(dev, addr, BIT(5));
}
void mt7996_mac_set_fixed_rate_table(struct mt7996_dev *dev,
u8 tbl_idx, u16 rate_idx)
{
u32 ctrl = MT_WTBL_ITCR_WR | MT_WTBL_ITCR_EXEC | tbl_idx;
mt76_wr(dev, MT_WTBL_ITDR0, rate_idx);
/* use wtbl spe idx */
mt76_wr(dev, MT_WTBL_ITDR1, MT_WTBL_SPE_IDX_SEL);
mt76_wr(dev, MT_WTBL_ITCR, ctrl);
}
static void
mt7996_mac_decode_he_radiotap_ru(struct mt76_rx_status *status,
struct ieee80211_radiotap_he *he,
......@@ -985,7 +996,7 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
{
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_vif *vif = info->control.vif;
struct mt76_phy *mphy = &dev->mphy;
struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
u8 band_idx = (info->hw_queue & MT_TX_HW_QUEUE_PHY) >> 2;
u8 p_fmt, q_idx, omac_idx = 0, wmm_idx = 0;
bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP;
......@@ -997,15 +1008,11 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
BSS_CHANGED_FILS_DISCOVERY));
if (vif) {
struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
omac_idx = mvif->mt76.omac_idx;
wmm_idx = mvif->mt76.wmm_idx;
band_idx = mvif->mt76.band_idx;
}
mphy = mt76_dev_phy(&dev->mt76, band_idx);
if (inband_disc) {
p_fmt = MT_TX_TYPE_FW;
q_idx = MT_LMAC_ALTX0;
......@@ -1063,18 +1070,9 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
mt7996_mac_write_txwi_80211(dev, txwi, skb, key);
if (txwi[1] & cpu_to_le32(MT_TXD1_FIXED_RATE)) {
/* Fixed rata is available just for 802.11 txd */
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
bool multicast = is_multicast_ether_addr(hdr->addr1);
u16 rate = mt76_connac2_mac_tx_rate_val(mphy, vif, beacon,
multicast);
/* fix to bw 20 */
val = MT_TXD6_FIXED_BW |
FIELD_PREP(MT_TXD6_BW, 0) |
FIELD_PREP(MT_TXD6_TX_RATE, rate);
u8 idx = mvif->basic_rates_idx;
txwi[6] |= cpu_to_le32(val);
txwi[6] |= FIELD_PREP(MT_TXD6_TX_RATE, idx);
txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE);
}
}
......
......@@ -224,14 +224,11 @@ enum tx_mgnt_type {
#define MT_TXD6_TX_SRC GENMASK(31, 30)
#define MT_TXD6_VTA BIT(28)
#define MT_TXD6_FIXED_BW BIT(25)
#define MT_TXD6_BW GENMASK(24, 22)
#define MT_TXD6_BW GENMASK(25, 22)
#define MT_TXD6_TX_RATE GENMASK(21, 16)
#define MT_TXD6_TIMESTAMP_OFS_EN BIT(15)
#define MT_TXD6_TIMESTAMP_OFS_IDX GENMASK(14, 10)
#define MT_TXD6_MSDU_CNT GENMASK(9, 4)
#define MT_TXD6_SPE_ID_IDX BIT(10)
#define MT_TXD6_ANT_ID GENMASK(7, 4)
#define MT_TXD6_DIS_MAT BIT(3)
#define MT_TXD6_DAS BIT(2)
#define MT_TXD6_AMSDU_CAP BIT(1)
......@@ -245,7 +242,7 @@ enum tx_mgnt_type {
#define MT_TXD7_UDP_TCP_SUM BIT(15)
#define MT_TXD7_TX_TIME GENMASK(9, 0)
#define MT_TX_RATE_STBC BIT(13)
#define MT_TX_RATE_STBC BIT(14)
#define MT_TX_RATE_NSS GENMASK(13, 10)
#define MT_TX_RATE_MODE GENMASK(9, 6)
#define MT_TX_RATE_SU_EXT_TONE BIT(5)
......
......@@ -5,6 +5,7 @@
#include "mt7996.h"
#include "mcu.h"
#include "mac.h"
static bool mt7996_dev_running(struct mt7996_dev *dev)
{
......@@ -219,6 +220,11 @@ static int mt7996_add_interface(struct ieee80211_hw *hw,
vif->offload_flags = 0;
vif->offload_flags |= IEEE80211_OFFLOAD_ENCAP_4ADDR;
if (phy->mt76->chandef.chan->band != NL80211_BAND_2GHZ)
mvif->basic_rates_idx = MT7996_BASIC_RATES_TBL + 4;
else
mvif->basic_rates_idx = MT7996_BASIC_RATES_TBL;
mt7996_init_bitrate_mask(vif);
mt7996_mcu_add_bss_info(phy, vif, true);
......@@ -496,11 +502,30 @@ mt7996_update_bss_color(struct ieee80211_hw *hw,
}
}
static u8
mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
{
struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
struct mt76_phy *mphy = hw->priv;
u16 rate;
u8 i, idx;
rate = mt76_connac2_mac_tx_rate_val(mphy, vif, false, false);
idx = FIELD_GET(MT_TX_RATE_IDX, rate);
for (i = 0; i < ARRAY_SIZE(mt76_rates); i++)
if ((mt76_rates[i].hw_value & GENMASK(7, 0)) == idx)
return MT7996_BASIC_RATES_TBL + i;
return mvif->basic_rates_idx;
}
static void mt7996_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *info,
u64 changed)
{
struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
struct mt7996_phy *phy = mt7996_hw_phy(hw);
struct mt7996_dev *dev = mt7996_hw_dev(hw);
......@@ -532,6 +557,9 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw,
}
}
if (changed & BSS_CHANGED_BASIC_RATES)
mvif->basic_rates_idx = mt7996_get_rates_table(hw, vif);
if (changed & BSS_CHANGED_BEACON_ENABLED && info->enable_beacon) {
mt7996_mcu_add_bss_info(phy, vif, true);
mt7996_mcu_add_sta(dev, vif, NULL, true);
......@@ -891,6 +919,7 @@ mt7996_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
mt7996_set_stream_vht_txbf_caps(phy);
mt7996_set_stream_he_eht_caps(phy);
/* TODO: update bmc_wtbl spe_idx when antenna changes */
mutex_unlock(&dev->mt76.mutex);
return 0;
......
......@@ -597,25 +597,23 @@ mt7996_mcu_bss_he_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
}
static void
mt7996_mcu_bss_bmc_tlv(struct sk_buff *skb, struct mt7996_phy *phy)
mt7996_mcu_bss_bmc_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
struct mt7996_phy *phy)
{
struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
struct bss_rate_tlv *bmc;
struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
enum nl80211_band band = chandef->chan->band;
struct tlv *tlv;
u8 idx = mvif->basic_rates_idx;
tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_RATE, sizeof(*bmc));
bmc = (struct bss_rate_tlv *)tlv;
if (band == NL80211_BAND_2GHZ) {
bmc->short_preamble = true;
} else {
bmc->bc_trans = cpu_to_le16(0x8080);
bmc->mc_trans = cpu_to_le16(0x8080);
bmc->bc_fixed_rate = 1;
bmc->mc_fixed_rate = 1;
bmc->short_preamble = 1;
}
bmc->short_preamble = (band == NL80211_BAND_2GHZ);
bmc->bc_fixed_rate = idx;
bmc->mc_fixed_rate = idx;
}
static void
......@@ -823,7 +821,7 @@ int mt7996_mcu_add_bss_info(struct mt7996_phy *phy,
if (enable) {
mt7996_mcu_bss_rfch_tlv(skb, vif, phy);
mt7996_mcu_bss_bmc_tlv(skb, phy);
mt7996_mcu_bss_bmc_tlv(skb, vif, phy);
mt7996_mcu_bss_ra_tlv(skb, vif, phy);
mt7996_mcu_bss_txcmd_tlv(skb, true);
......
......@@ -43,6 +43,9 @@
#define MT7996_MAX_STA_TWT_AGRT 8
#define MT7996_MAX_QUEUE (__MT_RXQ_MAX + __MT_MCUQ_MAX + 3)
/* NOTE: used to map mt76_rates. idx may change if firmware expands table */
#define MT7996_BASIC_RATES_TBL 11
struct mt7996_vif;
struct mt7996_sta;
struct mt7996_dfs_pulse;
......@@ -120,6 +123,8 @@ struct mt7996_vif {
struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS];
struct cfg80211_bitrate_mask bitrate_mask;
u8 basic_rates_idx;
};
/* per-phy stats. */
......@@ -505,6 +510,8 @@ void mt7996_mac_cca_stats_reset(struct mt7996_phy *phy);
void mt7996_mac_enable_nf(struct mt7996_dev *dev, u8 band);
void mt7996_mac_enable_rtscts(struct mt7996_dev *dev,
struct ieee80211_vif *vif, bool enable);
void mt7996_mac_set_fixed_rate_table(struct mt7996_dev *dev,
u8 tbl_idx, u16 rate_idx);
void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
struct sk_buff *skb, struct mt76_wcid *wcid,
struct ieee80211_key_conf *key, int pid,
......
......@@ -228,6 +228,13 @@ enum base_rev {
#define MT_WTBL_UPDATE_ADM_COUNT_CLEAR BIT(14)
#define MT_WTBL_UPDATE_BUSY BIT(31)
#define MT_WTBL_ITCR MT_WTBLON_TOP(0x3b0)
#define MT_WTBL_ITCR_WR BIT(16)
#define MT_WTBL_ITCR_EXEC BIT(31)
#define MT_WTBL_ITDR0 MT_WTBLON_TOP(0x3b8)
#define MT_WTBL_ITDR1 MT_WTBLON_TOP(0x3bc)
#define MT_WTBL_SPE_IDX_SEL BIT(6)
/* WTBL */
#define MT_WTBL_BASE 0x820d8000
#define MT_WTBL_LMAC_ID GENMASK(14, 8)
......
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