On Fri, 2023-12-01 at 15:40 -0800, Ben Greear wrote: > > External email : Please do not click links or open attachments until > you have verified the sender or the content. > On 11/2/23 03:02, Shayne Chen wrote: > > Add support for setting txpower from upper layer and configuring > per-rate > > txpower limit table. > > Hello Shayne, Hi Ben, > > From what I can tell, this patch causes STA vdevs to no longer send > probe > requests when trying to associate. I bisected to this in Felix's > tree that holds > this patch. > > Tested on x86-64, mtk7996 radio. Specifically > debugged on 2.4Ghz radio, but I think it affects 5Ghz too. > I have done some tests but didn't face this issue. Could you also use the newer firmware to test if it still happens? Thanks, Shayne > Thanks, > Ben > > > > > Co-developed-by: Allen Ye <allen.ye@xxxxxxxxxxxx> > > Signed-off-by: Allen Ye <allen.ye@xxxxxxxxxxxx> > > Co-developed-by: StanleyYP Wang <StanleyYP.Wang@xxxxxxxxxxxx> > > Signed-off-by: StanleyYP Wang <StanleyYP.Wang@xxxxxxxxxxxx> > > Signed-off-by: Shayne Chen <shayne.chen@xxxxxxxxxxxx> > > --- > > .../net/wireless/mediatek/mt76/mt7996/main.c | 8 +++ > > .../net/wireless/mediatek/mt76/mt7996/mcu.c | 58 > +++++++++++++++++++ > > .../net/wireless/mediatek/mt76/mt7996/mcu.h | 16 +++++ > > .../wireless/mediatek/mt76/mt7996/mt7996.h | 3 + > > 4 files changed, 85 insertions(+) > > > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c > b/drivers/net/wireless/mediatek/mt76/mt7996/main.c > > index 9f12b47eb2bf..7336eaa7b9ae 100644 > > --- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c > > +++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c > > @@ -396,6 +396,13 @@ static int mt7996_config(struct ieee80211_hw > *hw, u32 changed) > > ieee80211_wake_queues(hw); > > } > > > > +if (changed & (IEEE80211_CONF_CHANGE_POWER | > > + IEEE80211_CONF_CHANGE_CHANNEL)) { > > +ret = mt7996_mcu_set_txpower_sku(phy); > > +if (ret) > > +return ret; > > +} > > + > > mutex_lock(&dev->mt76.mutex); > > > > if (changed & IEEE80211_CONF_CHANGE_MONITOR) { > > @@ -965,6 +972,7 @@ mt7996_set_antenna(struct ieee80211_hw *hw, u32 > tx_ant, u32 rx_ant) > > mt76_set_stream_caps(phy->mt76, true); > > mt7996_set_stream_vht_txbf_caps(phy); > > mt7996_set_stream_he_eht_caps(phy); > > +mt7996_mcu_set_txpower_sku(phy); > > > > mutex_unlock(&dev->mt76.mutex); > > > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c > b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c > > index 8097924d460b..8141c24ade50 100644 > > --- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c > > +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c > > @@ -4353,3 +4353,61 @@ int mt7996_mcu_wed_rro_reset_sessions(struct > mt7996_dev *dev, u16 id) > > return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(RRO), &req, > > sizeof(req), true); > > } > > + > > +int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy) > > +{ > > +#define TX_POWER_LIMIT_TABLE_RATE0 > > +struct mt7996_dev *dev = phy->dev; > > +struct mt76_phy *mphy = phy->mt76; > > +struct ieee80211_hw *hw = mphy->hw; > > +struct tx_power_limit_table_ctrl { > > +u8 __rsv1[4]; > > + > > +__le16 tag; > > +__le16 len; > > +u8 power_ctrl_id; > > +u8 power_limit_type; > > +u8 band_idx; > > +} __packed req = { > > +.tag = cpu_to_le16(UNI_TXPOWER_POWER_LIMIT_TABLE_CTRL), > > +.len = cpu_to_le16(sizeof(req) + MT7996_SKU_RATE_NUM - 4), > > +.power_ctrl_id = UNI_TXPOWER_POWER_LIMIT_TABLE_CTRL, > > +.power_limit_type = TX_POWER_LIMIT_TABLE_RATE, > > +.band_idx = phy->mt76->band_idx, > > +}; > > +struct mt76_power_limits la = {}; > > +struct sk_buff *skb; > > +int i, tx_power; > > + > > +tx_power = mt7996_get_power_bound(phy, hw->conf.power_level); > > +tx_power = mt76_get_rate_power_limits(mphy, mphy->chandef.chan, > > + &la, tx_power); > > +mphy->txpower_cur = tx_power; > > + > > +skb = mt76_mcu_msg_alloc(&dev->mt76, NULL, > > + sizeof(req) + MT7996_SKU_RATE_NUM); > > +if (!skb) > > +return -ENOMEM; > > + > > +skb_put_data(skb, &req, sizeof(req)); > > +/* cck and ofdm */ > > +skb_put_data(skb, &la.cck, sizeof(la.cck) + sizeof(la.ofdm)); > > +/* ht20 */ > > +skb_put_data(skb, &la.mcs[0], 8); > > +/* ht40 */ > > +skb_put_data(skb, &la.mcs[1], 9); > > + > > +/* vht */ > > +for (i = 0; i < 4; i++) { > > +skb_put_data(skb, &la.mcs[i], sizeof(la.mcs[i])); > > +skb_put_zero(skb, 2); /* padding */ > > +} > > + > > +/* he */ > > +skb_put_data(skb, &la.ru[0], sizeof(la.ru)); > > +/* eht */ > > +skb_put_data(skb, &la.eht[0], sizeof(la.eht)); > > + > > +return mt76_mcu_skb_send_msg(&dev->mt76, skb, > > + MCU_WM_UNI_CMD(TXPOWER), true); > > +} > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h > b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h > > index a3eae32c8f10..1562c8a6a821 100644 > > --- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h > > +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h > > @@ -762,6 +762,18 @@ enum { > > #define MT7996_MAX_BSS_OFFLOAD_SIZE(MT7996_MAX_BEACON_SIZE +\ > > MT7996_BEACON_UPDATE_SIZE) > > > > +static inline s8 > > +mt7996_get_power_bound(struct mt7996_phy *phy, s8 txpower) > > +{ > > +struct mt76_phy *mphy = phy->mt76; > > +int n_chains = hweight16(mphy->chainmask); > > + > > +txpower = mt76_get_sar_power(mphy, mphy->chandef.chan, txpower * > 2); > > +txpower -= mt76_tx_power_nss_delta(n_chains); > > + > > +return txpower; > > +} > > + > > enum { > > UNI_BAND_CONFIG_RADIO_ENABLE, > > UNI_BAND_CONFIG_RTS_THRESHOLD = 0x08, > > @@ -830,6 +842,10 @@ enum { > > UNI_CMD_THERMAL_PROTECT_DUTY_CONFIG, > > }; > > > > +enum { > > +UNI_TXPOWER_POWER_LIMIT_TABLE_CTRL = 4, > > +}; > > + > > enum { > > UNI_CMD_ACCESS_REG_BASIC = 0x0, > > UNI_CMD_ACCESS_RF_REG_BASIC, > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h > b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h > > index d3eb564623ae..c62a42512bd6 100644 > > --- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h > > +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h > > @@ -42,6 +42,8 @@ > > #define MT7996_CFEND_RATE_DEFAULT0x49/* OFDM 24M */ > > #define MT7996_CFEND_RATE_11B0x03/* 11B LP, 11M */ > > > > +#define MT7996_SKU_RATE_NUM417 > > + > > #define MT7996_MAX_TWT_AGRT16 > > #define MT7996_MAX_STA_TWT_AGRT8 > > #define MT7996_MAX_QUEUE(__MT_RXQ_MAX +__MT_MCUQ_MAX + 3) > > @@ -471,6 +473,7 @@ int mt7996_mcu_get_chan_mib_info(struct > mt7996_phy *phy, bool chan_switch); > > int mt7996_mcu_get_temperature(struct mt7996_phy *phy); > > int mt7996_mcu_set_thermal_throttling(struct mt7996_phy *phy, u8 > state); > > int mt7996_mcu_set_thermal_protect(struct mt7996_phy *phy, bool > enable); > > +int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy); > > 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, >