wifi: mt76: connac: add beacon duplicate TX mode support for mt7996
For connac3 chipsets, setting of spe_idx is moved from TX descriptor to the fixed rate table. This patch implements the setting to support duplicate TX mode for beacon. Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com> Signed-off-by: Shayne Chen <shayne.chen@mediatek.com> Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
parent
6879b2e941
commit
254ab81f3b
@ -1242,6 +1242,7 @@ enum {
|
||||
MCU_UNI_CMD_CHANNEL_SWITCH = 0x34,
|
||||
MCU_UNI_CMD_THERMAL = 0x35,
|
||||
MCU_UNI_CMD_VOW = 0x37,
|
||||
MCU_UNI_CMD_FIXED_RATE_TABLE = 0x40,
|
||||
MCU_UNI_CMD_RRO = 0x57,
|
||||
MCU_UNI_CMD_OFFCH_SCAN_CTRL = 0x58,
|
||||
MCU_UNI_CMD_PER_STA_INFO = 0x6d,
|
||||
|
@ -354,6 +354,7 @@ mt7996_init_wiphy(struct ieee80211_hw *hw, struct mtk_wed_device *wed)
|
||||
IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US;
|
||||
|
||||
phy->slottime = 9;
|
||||
phy->beacon_rate = -1;
|
||||
|
||||
hw->sta_data_size = sizeof(struct mt7996_sta);
|
||||
hw->vif_data_size = sizeof(struct mt7996_vif);
|
||||
@ -468,11 +469,12 @@ static void mt7996_mac_init_basic_rates(struct mt7996_dev *dev)
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mt76_rates); i++) {
|
||||
u16 rate = mt76_rates[i].hw_value;
|
||||
u16 idx = MT7996_BASIC_RATES_TBL + i;
|
||||
/* odd index for driver, even index for firmware */
|
||||
u16 idx = MT7996_BASIC_RATES_TBL + 2 * 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);
|
||||
mt7996_mcu_set_fixed_rate_table(&dev->phy, idx, rate, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -248,17 +248,6 @@ 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);
|
||||
}
|
||||
|
||||
/* The HW does not translate the mac header to 802.3 for mesh point */
|
||||
static int mt7996_reverse_frag0_hdr_trans(struct sk_buff *skb, u16 hdr_gap)
|
||||
{
|
||||
|
@ -522,24 +522,25 @@ mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
|
||||
struct mt76_phy *mphy = hw->priv;
|
||||
u16 rate;
|
||||
u8 i, idx, ht;
|
||||
u8 i, idx;
|
||||
|
||||
rate = mt76_connac2_mac_tx_rate_val(mphy, vif, beacon, mcast);
|
||||
ht = FIELD_GET(MT_TX_RATE_MODE, rate) > MT_PHY_TYPE_OFDM;
|
||||
|
||||
if (beacon && ht) {
|
||||
struct mt7996_dev *dev = mt7996_hw_dev(hw);
|
||||
if (beacon) {
|
||||
struct mt7996_phy *phy = mphy->priv;
|
||||
|
||||
/* odd index for driver, even index for firmware */
|
||||
idx = MT7996_BEACON_RATES_TBL + 2 * phy->mt76->band_idx;
|
||||
if (phy->beacon_rate != rate)
|
||||
mt7996_mcu_set_fixed_rate_table(phy, idx, rate, beacon);
|
||||
|
||||
/* must odd index */
|
||||
idx = MT7996_BEACON_RATES_TBL + 2 * (mvif->idx % 20);
|
||||
mt7996_mac_set_fixed_rate_table(dev, idx, rate);
|
||||
return idx;
|
||||
}
|
||||
|
||||
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 MT7996_BASIC_RATES_TBL + 2 * i;
|
||||
|
||||
return mvif->basic_rates_idx;
|
||||
}
|
||||
@ -965,7 +966,6 @@ 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;
|
||||
|
@ -4179,6 +4179,35 @@ int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev,
|
||||
MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);
|
||||
}
|
||||
|
||||
int mt7996_mcu_set_fixed_rate_table(struct mt7996_phy *phy, u8 table_idx,
|
||||
u16 rate_idx, bool beacon)
|
||||
{
|
||||
#define UNI_FIXED_RATE_TABLE_SET 0
|
||||
#define SPE_IXD_SELECT_TXD 0
|
||||
#define SPE_IXD_SELECT_BMC_WTBL 1
|
||||
struct mt7996_dev *dev = phy->dev;
|
||||
struct fixed_rate_table_ctrl req = {
|
||||
.tag = cpu_to_le16(UNI_FIXED_RATE_TABLE_SET),
|
||||
.len = cpu_to_le16(sizeof(req) - 4),
|
||||
.table_idx = table_idx,
|
||||
.rate_idx = cpu_to_le16(rate_idx),
|
||||
.gi = 1,
|
||||
.he_ltf = 1,
|
||||
};
|
||||
u8 band_idx = phy->mt76->band_idx;
|
||||
|
||||
if (beacon) {
|
||||
req.spe_idx_sel = SPE_IXD_SELECT_TXD;
|
||||
req.spe_idx = 24 + band_idx;
|
||||
phy->beacon_rate = rate_idx;
|
||||
} else {
|
||||
req.spe_idx_sel = SPE_IXD_SELECT_BMC_WTBL;
|
||||
}
|
||||
|
||||
return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(FIXED_RATE_TABLE),
|
||||
&req, sizeof(req), false);
|
||||
}
|
||||
|
||||
int mt7996_mcu_rf_regval(struct mt7996_dev *dev, u32 regidx, u32 *val, bool set)
|
||||
{
|
||||
struct {
|
||||
|
@ -801,4 +801,24 @@ enum {
|
||||
#define MT7996_SEC_KEY_IDX GENMASK(2, 1)
|
||||
#define MT7996_SEC_IV BIT(3)
|
||||
|
||||
struct fixed_rate_table_ctrl {
|
||||
u8 _rsv[4];
|
||||
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
|
||||
u8 table_idx;
|
||||
u8 antenna_idx;
|
||||
__le16 rate_idx;
|
||||
u8 spe_idx_sel;
|
||||
u8 spe_idx;
|
||||
u8 gi;
|
||||
u8 he_ltf;
|
||||
bool ldpc;
|
||||
bool txbf;
|
||||
bool dynamic_bw;
|
||||
|
||||
u8 _rsv2;
|
||||
} __packed;
|
||||
|
||||
#endif
|
||||
|
@ -47,7 +47,7 @@
|
||||
#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
|
||||
#define MT7996_BASIC_RATES_TBL 31
|
||||
#define MT7996_BEACON_RATES_TBL 25
|
||||
|
||||
#define MT7996_THERMAL_THROTTLE_MAX 100
|
||||
@ -217,6 +217,8 @@ struct mt7996_phy {
|
||||
|
||||
u8 rdd_state;
|
||||
|
||||
u16 beacon_rate;
|
||||
|
||||
u32 rx_ampdu_ts;
|
||||
u32 ampdu_ref;
|
||||
|
||||
@ -472,6 +474,8 @@ int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 index,
|
||||
u8 rx_sel, u8 val);
|
||||
int mt7996_mcu_rdd_background_enable(struct mt7996_phy *phy,
|
||||
struct cfg80211_chan_def *chandef);
|
||||
int mt7996_mcu_set_fixed_rate_table(struct mt7996_phy *phy, u8 table_idx,
|
||||
u16 rate_idx, bool beacon);
|
||||
int mt7996_mcu_rf_regval(struct mt7996_dev *dev, u32 regidx, u32 *val, bool set);
|
||||
int mt7996_mcu_set_hdr_trans(struct mt7996_dev *dev, bool hdr_trans);
|
||||
int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u16 val);
|
||||
@ -538,8 +542,6 @@ 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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user