linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/8] wifi: mt76: change txpower init to per-phy
@ 2023-11-02 10:02 Shayne Chen
  2023-11-02 10:02 ` [PATCH 2/8] wifi: mt76: mt7996: add txpower setting support Shayne Chen
                   ` (6 more replies)
  0 siblings, 7 replies; 16+ messages in thread
From: Shayne Chen @ 2023-11-02 10:02 UTC (permalink / raw)
  To: Felix Fietkau
  Cc: linux-wireless, Lorenzo Bianconi, Ryder Lee, Evelyn Tsai,
	linux-mediatek, Shayne Chen, Allen Ye

Use per-phy structure for maximum txpower value initializing, since each
phy may have a different chainmask, which can impact the calculation of
power gain.

Co-developed-by: Allen Ye <allen.ye@mediatek.com>
Signed-off-by: Allen Ye <allen.ye@mediatek.com>
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
---
 .../net/wireless/mediatek/mt76/mt7915/init.c  | 30 ++++++++++++-------
 .../net/wireless/mediatek/mt76/mt7915/mac.c   |  4 +--
 .../wireless/mediatek/mt76/mt7915/mt7915.h    |  3 +-
 .../net/wireless/mediatek/mt76/mt7996/init.c  | 30 ++++++++++++-------
 .../net/wireless/mediatek/mt76/mt7996/mac.c   |  6 ++--
 .../wireless/mediatek/mt76/mt7996/mt7996.h    |  3 +-
 6 files changed, 47 insertions(+), 29 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
index 81478289f17e..cea2f6d9050a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
@@ -275,10 +275,11 @@ static void mt7915_led_set_brightness(struct led_classdev *led_cdev,
 		mt7915_led_set_config(led_cdev, 0xff, 0);
 }
 
-void mt7915_init_txpower(struct mt7915_dev *dev,
-			 struct ieee80211_supported_band *sband)
+static void __mt7915_init_txpower(struct mt7915_phy *phy,
+				  struct ieee80211_supported_band *sband)
 {
-	int i, n_chains = hweight8(dev->mphy.antenna_mask);
+	struct mt7915_dev *dev = phy->dev;
+	int i, n_chains = hweight16(phy->mt76->chainmask);
 	int nss_delta = mt76_tx_power_nss_delta(n_chains);
 	int pwr_delta = mt7915_eeprom_get_power_delta(dev, sband->band);
 	struct mt76_power_limits limits;
@@ -296,7 +297,7 @@ void mt7915_init_txpower(struct mt7915_dev *dev,
 		}
 
 		target_power += pwr_delta;
-		target_power = mt76_get_rate_power_limits(&dev->mphy, chan,
+		target_power = mt76_get_rate_power_limits(phy->mt76, chan,
 							  &limits,
 							  target_power);
 		target_power += nss_delta;
@@ -307,6 +308,19 @@ void mt7915_init_txpower(struct mt7915_dev *dev,
 	}
 }
 
+void mt7915_init_txpower(struct mt7915_phy *phy)
+{
+	if (!phy)
+		return;
+
+	if (phy->mt76->cap.has_2ghz)
+		__mt7915_init_txpower(phy, &phy->mt76->sband_2g.sband);
+	if (phy->mt76->cap.has_5ghz)
+		__mt7915_init_txpower(phy, &phy->mt76->sband_5g.sband);
+	if (phy->mt76->cap.has_6ghz)
+		__mt7915_init_txpower(phy, &phy->mt76->sband_6g.sband);
+}
+
 static void
 mt7915_regd_notifier(struct wiphy *wiphy,
 		     struct regulatory_request *request)
@@ -322,9 +336,7 @@ mt7915_regd_notifier(struct wiphy *wiphy,
 	if (dev->mt76.region == NL80211_DFS_UNSET)
 		mt7915_mcu_rdd_background_enable(phy, NULL);
 
-	mt7915_init_txpower(dev, &mphy->sband_2g.sband);
-	mt7915_init_txpower(dev, &mphy->sband_5g.sband);
-	mt7915_init_txpower(dev, &mphy->sband_6g.sband);
+	mt7915_init_txpower(phy);
 
 	mphy->dfs_state = MT_DFS_STATE_UNKNOWN;
 	mt7915_dfs_init_radar_detector(phy);
@@ -442,6 +454,7 @@ mt7915_init_wiphy(struct mt7915_phy *phy)
 	mt76_set_stream_caps(phy->mt76, true);
 	mt7915_set_stream_vht_txbf_caps(phy);
 	mt7915_set_stream_he_caps(phy);
+	mt7915_init_txpower(phy);
 
 	wiphy->available_antennas_rx = phy->mt76->antenna_mask;
 	wiphy->available_antennas_tx = phy->mt76->antenna_mask;
@@ -703,9 +716,6 @@ static void mt7915_init_work(struct work_struct *work)
 
 	mt7915_mcu_set_eeprom(dev);
 	mt7915_mac_init(dev);
-	mt7915_init_txpower(dev, &dev->mphy.sband_2g.sband);
-	mt7915_init_txpower(dev, &dev->mphy.sband_5g.sband);
-	mt7915_init_txpower(dev, &dev->mphy.sband_6g.sband);
 	mt7915_txbf_init(dev);
 }
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index 2222fb9aa103..ac6c086b1a9e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -1401,8 +1401,8 @@ mt7915_mac_restart(struct mt7915_dev *dev)
 		goto out;
 
 	mt7915_mac_init(dev);
-	mt7915_init_txpower(dev, &dev->mphy.sband_2g.sband);
-	mt7915_init_txpower(dev, &dev->mphy.sband_5g.sband);
+	mt7915_init_txpower(&dev->phy);
+	mt7915_init_txpower(phy2);
 	ret = mt7915_txbf_init(dev);
 
 	if (test_bit(MT76_STATE_RUNNING, &dev->mphy.state)) {
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
index d317c523b23f..4727d9c7b11d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
@@ -425,8 +425,7 @@ void mt7915_dma_cleanup(struct mt7915_dev *dev);
 int mt7915_dma_reset(struct mt7915_dev *dev, bool force);
 int mt7915_dma_start(struct mt7915_dev *dev, bool reset, bool wed_reset);
 int mt7915_txbf_init(struct mt7915_dev *dev);
-void mt7915_init_txpower(struct mt7915_dev *dev,
-			 struct ieee80211_supported_band *sband);
+void mt7915_init_txpower(struct mt7915_phy *phy);
 void mt7915_reset(struct mt7915_dev *dev);
 int mt7915_run(struct ieee80211_hw *hw);
 int mt7915_mcu_init(struct mt7915_dev *dev);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/init.c b/drivers/net/wireless/mediatek/mt76/mt7996/init.c
index 6a03cddaed04..1896571ad140 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/init.c
@@ -288,10 +288,11 @@ static void mt7996_led_set_brightness(struct led_classdev *led_cdev,
 		mt7996_led_set_config(led_cdev, 0xff, 0);
 }
 
-void mt7996_init_txpower(struct mt7996_dev *dev,
-			 struct ieee80211_supported_band *sband)
+static void __mt7996_init_txpower(struct mt7996_phy *phy,
+				  struct ieee80211_supported_band *sband)
 {
-	int i, nss = hweight8(dev->mphy.antenna_mask);
+	struct mt7996_dev *dev = phy->dev;
+	int i, nss = hweight16(phy->mt76->chainmask);
 	int nss_delta = mt76_tx_power_nss_delta(nss);
 	int pwr_delta = mt7996_eeprom_get_power_delta(dev, sband->band);
 	struct mt76_power_limits limits;
@@ -301,7 +302,7 @@ void mt7996_init_txpower(struct mt7996_dev *dev,
 		int target_power = mt7996_eeprom_get_target_power(dev, chan);
 
 		target_power += pwr_delta;
-		target_power = mt76_get_rate_power_limits(&dev->mphy, chan,
+		target_power = mt76_get_rate_power_limits(phy->mt76, chan,
 							  &limits,
 							  target_power);
 		target_power += nss_delta;
@@ -312,6 +313,19 @@ void mt7996_init_txpower(struct mt7996_dev *dev,
 	}
 }
 
+void mt7996_init_txpower(struct mt7996_phy *phy)
+{
+	if (!phy)
+		return;
+
+	if (phy->mt76->cap.has_2ghz)
+		__mt7996_init_txpower(phy, &phy->mt76->sband_2g.sband);
+	if (phy->mt76->cap.has_5ghz)
+		__mt7996_init_txpower(phy, &phy->mt76->sband_5g.sband);
+	if (phy->mt76->cap.has_6ghz)
+		__mt7996_init_txpower(phy, &phy->mt76->sband_6g.sband);
+}
+
 static void
 mt7996_regd_notifier(struct wiphy *wiphy,
 		     struct regulatory_request *request)
@@ -326,9 +340,7 @@ mt7996_regd_notifier(struct wiphy *wiphy,
 	if (dev->mt76.region == NL80211_DFS_UNSET)
 		mt7996_mcu_rdd_background_enable(phy, NULL);
 
-	mt7996_init_txpower(dev, &phy->mt76->sband_2g.sband);
-	mt7996_init_txpower(dev, &phy->mt76->sband_5g.sband);
-	mt7996_init_txpower(dev, &phy->mt76->sband_6g.sband);
+	mt7996_init_txpower(phy);
 
 	phy->mt76->dfs_state = MT_DFS_STATE_UNKNOWN;
 	mt7996_dfs_init_radar_detector(phy);
@@ -424,6 +436,7 @@ mt7996_init_wiphy(struct ieee80211_hw *hw, struct mtk_wed_device *wed)
 	mt76_set_stream_caps(phy->mt76, true);
 	mt7996_set_stream_vht_txbf_caps(phy);
 	mt7996_set_stream_he_eht_caps(phy);
+	mt7996_init_txpower(phy);
 
 	wiphy->available_antennas_rx = phy->mt76->antenna_mask;
 	wiphy->available_antennas_tx = phy->mt76->antenna_mask;
@@ -656,9 +669,6 @@ static void mt7996_init_work(struct work_struct *work)
 
 	mt7996_mcu_set_eeprom(dev);
 	mt7996_mac_init(dev);
-	mt7996_init_txpower(dev, &dev->mphy.sband_2g.sband);
-	mt7996_init_txpower(dev, &dev->mphy.sband_5g.sband);
-	mt7996_init_txpower(dev, &dev->mphy.sband_6g.sband);
 	mt7996_txbf_init(dev);
 }
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
index 71ae8e263221..56dfbeb51504 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
@@ -1755,9 +1755,9 @@ mt7996_mac_restart(struct mt7996_dev *dev)
 		goto out;
 
 	mt7996_mac_init(dev);
-	mt7996_init_txpower(dev, &dev->mphy.sband_2g.sband);
-	mt7996_init_txpower(dev, &dev->mphy.sband_5g.sband);
-	mt7996_init_txpower(dev, &dev->mphy.sband_6g.sband);
+	mt7996_init_txpower(&dev->phy);
+	mt7996_init_txpower(phy2);
+	mt7996_init_txpower(phy3);
 	ret = mt7996_txbf_init(dev);
 
 	if (test_bit(MT76_STATE_RUNNING, &dev->mphy.state)) {
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
index 0a150bcb2c19..d3eb564623ae 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
@@ -414,8 +414,7 @@ void mt7996_dma_cleanup(struct mt7996_dev *dev);
 void mt7996_dma_start(struct mt7996_dev *dev, bool reset, bool wed_reset);
 int mt7996_init_tx_queues(struct mt7996_phy *phy, int idx,
 			  int n_desc, int ring_base, struct mtk_wed_device *wed);
-void mt7996_init_txpower(struct mt7996_dev *dev,
-			 struct ieee80211_supported_band *sband);
+void mt7996_init_txpower(struct mt7996_phy *phy);
 int mt7996_txbf_init(struct mt7996_dev *dev);
 void mt7996_reset(struct mt7996_dev *dev);
 int mt7996_run(struct ieee80211_hw *hw);
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 2/8] wifi: mt76: mt7996: add txpower setting support
  2023-11-02 10:02 [PATCH 1/8] wifi: mt76: change txpower init to per-phy Shayne Chen
@ 2023-11-02 10:02 ` Shayne Chen
  2023-12-01 23:40   ` Ben Greear
  2023-11-02 10:02 ` [PATCH 3/8] wifi: mt76: use chainmask for power delta calculation Shayne Chen
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Shayne Chen @ 2023-11-02 10:02 UTC (permalink / raw)
  To: Felix Fietkau
  Cc: linux-wireless, Lorenzo Bianconi, Ryder Lee, Evelyn Tsai,
	linux-mediatek, Shayne Chen, Allen Ye, StanleyYP Wang

Add support for setting txpower from upper layer and configuring per-rate
txpower limit table.

Co-developed-by: Allen Ye <allen.ye@mediatek.com>
Signed-off-by: Allen Ye <allen.ye@mediatek.com>
Co-developed-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
---
 .../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_RATE	0
+	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_DEFAULT	0x49	/* OFDM 24M */
 #define MT7996_CFEND_RATE_11B		0x03	/* 11B LP, 11M */
 
+#define MT7996_SKU_RATE_NUM		417
+
 #define MT7996_MAX_TWT_AGRT		16
 #define MT7996_MAX_STA_TWT_AGRT		8
 #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,
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 3/8] wifi: mt76: use chainmask for power delta calculation
  2023-11-02 10:02 [PATCH 1/8] wifi: mt76: change txpower init to per-phy Shayne Chen
  2023-11-02 10:02 ` [PATCH 2/8] wifi: mt76: mt7996: add txpower setting support Shayne Chen
@ 2023-11-02 10:02 ` Shayne Chen
  2023-11-02 10:02 ` [PATCH 4/8] wifi: mt76: mt7996: switch to mcu command for TX GI report Shayne Chen
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 16+ messages in thread
From: Shayne Chen @ 2023-11-02 10:02 UTC (permalink / raw)
  To: Felix Fietkau
  Cc: linux-wireless, Lorenzo Bianconi, Ryder Lee, Evelyn Tsai,
	linux-mediatek, Allen Ye, Shayne Chen

From: Allen Ye <allen.ye@mediatek.com>

The power gain value is related to total TX path, so change the
calculation to use per-phy chainmask.

Signed-off-by: Allen Ye <allen.ye@mediatek.com>
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
---
 drivers/net/wireless/mediatek/mt76/eeprom.c     | 2 +-
 drivers/net/wireless/mediatek/mt76/mac80211.c   | 2 +-
 drivers/net/wireless/mediatek/mt76/mt7915/mcu.h | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c
index 7725dd6763ef..53f5ef4120ca 100644
--- a/drivers/net/wireless/mediatek/mt76/eeprom.c
+++ b/drivers/net/wireless/mediatek/mt76/eeprom.c
@@ -379,7 +379,7 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
 	if (!np)
 		return target_power;
 
-	txs_delta = mt76_get_txs_delta(np, hweight8(phy->antenna_mask));
+	txs_delta = mt76_get_txs_delta(np, hweight16(phy->chainmask));
 
 	val = mt76_get_of_array(np, "rates-cck", &len, ARRAY_SIZE(dest->cck));
 	mt76_apply_array_limit(dest->cck, ARRAY_SIZE(dest->cck), val,
diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c
index 6ee7be6eaab8..c15074bb24c1 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -1537,7 +1537,7 @@ int mt76_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		     int *dbm)
 {
 	struct mt76_phy *phy = hw->priv;
-	int n_chains = hweight8(phy->antenna_mask);
+	int n_chains = hweight16(phy->chainmask);
 	int delta = mt76_tx_power_nss_delta(n_chains);
 
 	*dbm = DIV_ROUND_UP(phy->txpower_cur + delta, 2);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
index 1592b5d6751a..b41ac4aaced7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
@@ -519,7 +519,7 @@ static inline s8
 mt7915_get_power_bound(struct mt7915_phy *phy, s8 txpower)
 {
 	struct mt76_phy *mphy = phy->mt76;
-	int n_chains = hweight8(mphy->antenna_mask);
+	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);
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 4/8] wifi: mt76: mt7996: switch to mcu command for TX GI report
  2023-11-02 10:02 [PATCH 1/8] wifi: mt76: change txpower init to per-phy Shayne Chen
  2023-11-02 10:02 ` [PATCH 2/8] wifi: mt76: mt7996: add txpower setting support Shayne Chen
  2023-11-02 10:02 ` [PATCH 3/8] wifi: mt76: use chainmask for power delta calculation Shayne Chen
@ 2023-11-02 10:02 ` Shayne Chen
  2023-12-04 21:57   ` Ben Greear
  2023-11-02 10:02 ` [PATCH 5/8] wifi: mt76: mt7996: fix alignment of sta info event Shayne Chen
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Shayne Chen @ 2023-11-02 10:02 UTC (permalink / raw)
  To: Felix Fietkau
  Cc: linux-wireless, Lorenzo Bianconi, Ryder Lee, Evelyn Tsai,
	linux-mediatek, Benjamin Lin, Shayne Chen

From: Benjamin Lin <benjamin-jw.lin@mediatek.com>

During runtime, the GI value in the WTBL is not updated in real-time. To
obtain the latest results for the TX GI, switch to use an MCU command.

Signed-off-by: Benjamin Lin <benjamin-jw.lin@mediatek.com>
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
---
 .../wireless/mediatek/mt76/mt76_connac_mcu.h  |  2 +-
 .../net/wireless/mediatek/mt76/mt7996/mac.c   | 48 ++-----------------
 .../net/wireless/mediatek/mt76/mt7996/main.c  |  1 +
 .../net/wireless/mediatek/mt76/mt7996/mcu.c   | 47 ++++++++++++++++++
 .../net/wireless/mediatek/mt76/mt7996/mcu.h   | 22 +++++++++
 5 files changed, 74 insertions(+), 46 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
index 65844de6dccd..0185804d8ce3 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
@@ -1328,7 +1328,7 @@ enum {
 };
 
 enum UNI_ALL_STA_INFO_TAG {
-	UNI_ALL_STA_TX_RATE,
+	UNI_ALL_STA_TXRX_RATE,
 	UNI_ALL_STA_TX_STAT,
 	UNI_ALL_STA_TXRX_ADM_STAT,
 	UNI_ALL_STA_TXRX_AIR_TIME,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
index 56dfbeb51504..9db610e2645f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
@@ -102,7 +102,6 @@ static void mt7996_mac_sta_poll(struct mt7996_dev *dev)
 	};
 	struct ieee80211_sta *sta;
 	struct mt7996_sta *msta;
-	struct rate_info *rate;
 	u32 tx_time[IEEE80211_NUM_ACS], rx_time[IEEE80211_NUM_ACS];
 	LIST_HEAD(sta_poll_list);
 	int i;
@@ -118,7 +117,6 @@ static void mt7996_mac_sta_poll(struct mt7996_dev *dev)
 		u32 addr, val;
 		u16 idx;
 		s8 rssi[4];
-		u8 bw;
 
 		spin_lock_bh(&dev->mt76.sta_poll_lock);
 		if (list_empty(&sta_poll_list)) {
@@ -174,49 +172,6 @@ static void mt7996_mac_sta_poll(struct mt7996_dev *dev)
 			ieee80211_sta_register_airtime(sta, tid, tx_cur, rx_cur);
 		}
 
-		/* We don't support reading GI info from txs packets.
-		 * For accurate tx status reporting and AQL improvement,
-		 * we need to make sure that flags match so polling GI
-		 * from per-sta counters directly.
-		 */
-		rate = &msta->wcid.rate;
-
-		switch (rate->bw) {
-		case RATE_INFO_BW_320:
-			bw = IEEE80211_STA_RX_BW_320;
-			break;
-		case RATE_INFO_BW_160:
-			bw = IEEE80211_STA_RX_BW_160;
-			break;
-		case RATE_INFO_BW_80:
-			bw = IEEE80211_STA_RX_BW_80;
-			break;
-		case RATE_INFO_BW_40:
-			bw = IEEE80211_STA_RX_BW_40;
-			break;
-		default:
-			bw = IEEE80211_STA_RX_BW_20;
-			break;
-		}
-
-		addr = mt7996_mac_wtbl_lmac_addr(dev, idx, 6);
-		val = mt76_rr(dev, addr);
-		if (rate->flags & RATE_INFO_FLAGS_EHT_MCS) {
-			addr = mt7996_mac_wtbl_lmac_addr(dev, idx, 5);
-			val = mt76_rr(dev, addr);
-			rate->eht_gi = FIELD_GET(GENMASK(25, 24), val);
-		} else if (rate->flags & RATE_INFO_FLAGS_HE_MCS) {
-			u8 offs = 24 + 2 * bw;
-
-			rate->he_gi = (val & (0x3 << offs)) >> offs;
-		} else if (rate->flags &
-			   (RATE_INFO_FLAGS_VHT_MCS | RATE_INFO_FLAGS_MCS)) {
-			if (val & BIT(12 + bw))
-				rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
-			else
-				rate->flags &= ~RATE_INFO_FLAGS_SHORT_GI;
-		}
-
 		/* get signal strength of resp frames (CTS/BA/ACK) */
 		addr = mt7996_mac_wtbl_lmac_addr(dev, idx, 34);
 		val = mt76_rr(dev, addr);
@@ -1298,6 +1253,8 @@ mt7996_mac_add_txs_skb(struct mt7996_dev *dev, struct mt76_wcid *wcid,
 			goto out;
 
 		rate.flags = RATE_INFO_FLAGS_VHT_MCS;
+		if (wcid->rate.flags & RATE_INFO_FLAGS_SHORT_GI)
+			rate.flags |= RATE_INFO_FLAGS_SHORT_GI;
 		break;
 	case MT_PHY_TYPE_HE_SU:
 	case MT_PHY_TYPE_HE_EXT_SU:
@@ -2312,6 +2269,7 @@ void mt7996_mac_work(struct work_struct *work)
 
 		mt7996_mac_update_stats(phy);
 
+		mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_RATE);
 		if (mtk_wed_device_active(&phy->dev->mt76.mmio.wed)) {
 			mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_ADM_STAT);
 			mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_MSDU_COUNT);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
index 7336eaa7b9ae..d9ba57ae9fdc 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
@@ -998,6 +998,7 @@ static void mt7996_sta_statistics(struct ieee80211_hw *hw,
 			sinfo->txrate.he_gi = txrate->he_gi;
 			sinfo->txrate.he_dcm = txrate->he_dcm;
 			sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc;
+			sinfo->txrate.eht_gi = txrate->eht_gi;
 		}
 		sinfo->txrate.flags = txrate->flags;
 		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
index 8141c24ade50..b8d0b52be1e7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
@@ -449,6 +449,43 @@ mt7996_mcu_ie_countdown(struct mt7996_dev *dev, struct sk_buff *skb)
 	}
 }
 
+static int
+mt7996_mcu_update_tx_gi(struct rate_info *rate, struct all_sta_trx_rate *mcu_rate)
+{
+	switch (mcu_rate->tx_mode) {
+	case MT_PHY_TYPE_CCK:
+	case MT_PHY_TYPE_OFDM:
+		break;
+	case MT_PHY_TYPE_HT:
+	case MT_PHY_TYPE_HT_GF:
+	case MT_PHY_TYPE_VHT:
+		if (mcu_rate->tx_gi)
+			rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
+		else
+			rate->flags &= ~RATE_INFO_FLAGS_SHORT_GI;
+		break;
+	case MT_PHY_TYPE_HE_SU:
+	case MT_PHY_TYPE_HE_EXT_SU:
+	case MT_PHY_TYPE_HE_TB:
+	case MT_PHY_TYPE_HE_MU:
+		if (mcu_rate->tx_gi > NL80211_RATE_INFO_HE_GI_3_2)
+			return -EINVAL;
+		rate->he_gi = mcu_rate->tx_gi;
+		break;
+	case MT_PHY_TYPE_EHT_SU:
+	case MT_PHY_TYPE_EHT_TRIG:
+	case MT_PHY_TYPE_EHT_MU:
+		if (mcu_rate->tx_gi > NL80211_RATE_INFO_EHT_GI_3_2)
+			return -EINVAL;
+		rate->eht_gi = mcu_rate->tx_gi;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static void
 mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
 {
@@ -465,6 +502,16 @@ mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
 		struct mt76_wcid *wcid;
 
 		switch (le16_to_cpu(res->tag)) {
+		case UNI_ALL_STA_TXRX_RATE:
+			wlan_idx = le16_to_cpu(res->rate[i].wlan_idx);
+			wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]);
+
+			if (!wcid)
+				break;
+
+			if (mt7996_mcu_update_tx_gi(&wcid->rate, &res->rate[i]))
+				dev_err(dev->mt76.dev, "Failed to update TX GI\n");
+			break;
 		case UNI_ALL_STA_TXRX_ADM_STAT:
 			wlan_idx = le16_to_cpu(res->adm_stat[i].wlan_idx);
 			wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h
index 1562c8a6a821..328edc354165 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h
@@ -175,6 +175,27 @@ struct mt7996_mcu_mib {
 	__le64 data;
 } __packed;
 
+struct all_sta_trx_rate {
+	__le16 wlan_idx;
+	u8 __rsv1[2];
+	u8 tx_mode;
+	u8 flags;
+	u8 tx_stbc;
+	u8 tx_gi;
+	u8 tx_bw;
+	u8 tx_ldpc;
+	u8 tx_mcs;
+	u8 tx_nss;
+	u8 rx_rate;
+	u8 rx_mode;
+	u8 rx_nsts;
+	u8 rx_gi;
+	u8 rx_coding;
+	u8 rx_stbc;
+	u8 rx_bw;
+	u8 __rsv2;
+} __packed;
+
 struct mt7996_mcu_all_sta_info_event {
 	u8 rsv[4];
 	__le16 tag;
@@ -185,6 +206,7 @@ struct mt7996_mcu_all_sta_info_event {
 	u8 rsv3[2];
 
 	union {
+		struct all_sta_trx_rate rate[0];
 		struct {
 			__le16 wlan_idx;
 			u8 rsv[2];
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 5/8] wifi: mt76: mt7996: fix alignment of sta info event
  2023-11-02 10:02 [PATCH 1/8] wifi: mt76: change txpower init to per-phy Shayne Chen
                   ` (2 preceding siblings ...)
  2023-11-02 10:02 ` [PATCH 4/8] wifi: mt76: mt7996: switch to mcu command for TX GI report Shayne Chen
@ 2023-11-02 10:02 ` Shayne Chen
  2023-11-02 10:03 ` [PATCH 6/8] wifi: mt76: mt7996: rework ampdu params setting Shayne Chen
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 16+ messages in thread
From: Shayne Chen @ 2023-11-02 10:02 UTC (permalink / raw)
  To: Felix Fietkau
  Cc: linux-wireless, Lorenzo Bianconi, Ryder Lee, Evelyn Tsai,
	linux-mediatek, StanleyYP Wang, Shayne Chen

From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>

Fix the alignment of struct mt7996_mcu_all_sta_info_event.

Fixes: adde3eed4a75 ("wifi: mt76: mt7996: Add mcu commands for getting sta tx statistic")
Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
---
 drivers/net/wireless/mediatek/mt76/mt7996/mcu.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h
index 328edc354165..e23cc96c4dbc 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h
@@ -203,7 +203,7 @@ struct mt7996_mcu_all_sta_info_event {
 	u8 more;
 	u8 rsv2;
 	__le16 sta_num;
-	u8 rsv3[2];
+	u8 rsv3[4];
 
 	union {
 		struct all_sta_trx_rate rate[0];
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 6/8] wifi: mt76: mt7996: rework ampdu params setting
  2023-11-02 10:02 [PATCH 1/8] wifi: mt76: change txpower init to per-phy Shayne Chen
                   ` (3 preceding siblings ...)
  2023-11-02 10:02 ` [PATCH 5/8] wifi: mt76: mt7996: fix alignment of sta info event Shayne Chen
@ 2023-11-02 10:03 ` Shayne Chen
  2023-11-02 10:03 ` [PATCH 7/8] wifi: mt76: connac: add beacon protection support for mt7996 Shayne Chen
  2023-11-02 10:03 ` [PATCH 8/8] wifi: mt76: connac: fix EHT phy mode check Shayne Chen
  6 siblings, 0 replies; 16+ messages in thread
From: Shayne Chen @ 2023-11-02 10:03 UTC (permalink / raw)
  To: Felix Fietkau
  Cc: linux-wireless, Lorenzo Bianconi, Ryder Lee, Evelyn Tsai,
	linux-mediatek, Peter Chiu, Shayne Chen

From: Peter Chiu <chui-hao.chiu@mediatek.com>

Add sta_rec_ht_uni struct to pass HT ampdu params to firmware. For VHT,
HE, and EHT mode, firmware will get the ampdu params by parsing the
corresponding capability.

Co-developed-by: Shayne Chen <shayne.chen@mediatek.com>
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
---
 .../net/wireless/mediatek/mt76/mt7996/mcu.c   | 48 +++----------------
 .../net/wireless/mediatek/mt76/mt7996/mcu.h   | 12 ++++-
 2 files changed, 16 insertions(+), 44 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
index b8d0b52be1e7..1afcc96a0a52 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
@@ -1255,7 +1255,7 @@ mt7996_mcu_sta_eht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
 static void
 mt7996_mcu_sta_ht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
 {
-	struct sta_rec_ht *ht;
+	struct sta_rec_ht_uni *ht;
 	struct tlv *tlv;
 
 	if (!sta->deflink.ht_cap.ht_supported)
@@ -1263,8 +1263,12 @@ mt7996_mcu_sta_ht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
 
 	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HT, sizeof(*ht));
 
-	ht = (struct sta_rec_ht *)tlv;
+	ht = (struct sta_rec_ht_uni *)tlv;
 	ht->ht_cap = cpu_to_le16(sta->deflink.ht_cap.cap);
+	ht->ampdu_param = u8_encode_bits(sta->deflink.ht_cap.ampdu_factor,
+					 IEEE80211_HT_AMPDU_PARM_FACTOR) |
+			  u8_encode_bits(sta->deflink.ht_cap.ampdu_density,
+					 IEEE80211_HT_AMPDU_PARM_DENSITY);
 }
 
 static void
@@ -1721,44 +1725,6 @@ mt7996_mcu_sta_bfee_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
 	bfee->fb_identity_matrix = (nrow == 1 && tx_ant == 2);
 }
 
-static void
-mt7996_mcu_sta_phy_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
-		       struct ieee80211_vif *vif, struct ieee80211_sta *sta)
-{
-	struct sta_rec_phy *phy;
-	struct tlv *tlv;
-	u8 af = 0, mm = 0;
-
-	if (!sta->deflink.ht_cap.ht_supported && !sta->deflink.he_6ghz_capa.capa)
-		return;
-
-	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_PHY, sizeof(*phy));
-
-	phy = (struct sta_rec_phy *)tlv;
-	if (sta->deflink.ht_cap.ht_supported) {
-		af = sta->deflink.ht_cap.ampdu_factor;
-		mm = sta->deflink.ht_cap.ampdu_density;
-	}
-
-	if (sta->deflink.vht_cap.vht_supported) {
-		u8 vht_af = FIELD_GET(IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK,
-				      sta->deflink.vht_cap.cap);
-
-		af = max_t(u8, af, vht_af);
-	}
-
-	if (sta->deflink.he_6ghz_capa.capa) {
-		af = le16_get_bits(sta->deflink.he_6ghz_capa.capa,
-				   IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP);
-		mm = le16_get_bits(sta->deflink.he_6ghz_capa.capa,
-				   IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START);
-	}
-
-	phy->ampdu = FIELD_PREP(IEEE80211_HT_AMPDU_PARM_FACTOR, af) |
-		     FIELD_PREP(IEEE80211_HT_AMPDU_PARM_DENSITY, mm);
-	phy->max_ampdu_len = af;
-}
-
 static void
 mt7996_mcu_sta_hdrt_tlv(struct mt7996_dev *dev, struct sk_buff *skb)
 {
@@ -2167,8 +2133,6 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
 
 	/* tag order is in accordance with firmware dependency. */
 	if (sta) {
-		/* starec phy */
-		mt7996_mcu_sta_phy_tlv(dev, skb, vif, sta);
 		/* starec hdrt mode */
 		mt7996_mcu_sta_hdrt_tlv(dev, skb);
 		/* starec bfer */
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h
index e23cc96c4dbc..1851528d10ca 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h
@@ -467,6 +467,15 @@ struct bss_mld_tlv {
 	u8 __rsv[3];
 } __packed;
 
+struct sta_rec_ht_uni {
+	__le16 tag;
+	__le16 len;
+	__le16 ht_cap;
+	__le16 ht_cap_ext;
+	u8 ampdu_param;
+	u8 _rsv[3];
+} __packed;
+
 struct sta_rec_ba_uni {
 	__le16 tag;
 	__le16 len;
@@ -758,14 +767,13 @@ enum {
 #define MT7996_STA_UPDATE_MAX_SIZE	(sizeof(struct sta_req_hdr) +		\
 					 sizeof(struct sta_rec_basic) +		\
 					 sizeof(struct sta_rec_bf) +		\
-					 sizeof(struct sta_rec_ht) +		\
+					 sizeof(struct sta_rec_ht_uni) +	\
 					 sizeof(struct sta_rec_he_v2) +		\
 					 sizeof(struct sta_rec_ba_uni) +	\
 					 sizeof(struct sta_rec_vht) +		\
 					 sizeof(struct sta_rec_uapsd) + 	\
 					 sizeof(struct sta_rec_amsdu) +		\
 					 sizeof(struct sta_rec_bfee) +		\
-					 sizeof(struct sta_rec_phy) +		\
 					 sizeof(struct sta_rec_ra_uni) +	\
 					 sizeof(struct sta_rec_sec) +		\
 					 sizeof(struct sta_rec_ra_fixed_uni) +	\
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 7/8] wifi: mt76: connac: add beacon protection support for mt7996
  2023-11-02 10:02 [PATCH 1/8] wifi: mt76: change txpower init to per-phy Shayne Chen
                   ` (4 preceding siblings ...)
  2023-11-02 10:03 ` [PATCH 6/8] wifi: mt76: mt7996: rework ampdu params setting Shayne Chen
@ 2023-11-02 10:03 ` Shayne Chen
  2023-11-02 10:03 ` [PATCH 8/8] wifi: mt76: connac: fix EHT phy mode check Shayne Chen
  6 siblings, 0 replies; 16+ messages in thread
From: Shayne Chen @ 2023-11-02 10:03 UTC (permalink / raw)
  To: Felix Fietkau
  Cc: linux-wireless, Lorenzo Bianconi, Ryder Lee, Evelyn Tsai,
	linux-mediatek, Allen Ye, Rudra Shahi, Shayne Chen

From: Allen Ye <allen.ye@mediatek.com>

Implement beacon protection feature for mt7996 chipsets, and also do
some cleanup on the set key routine.

Co-developed-by: Rudra Shahi <rudra.shahi@mediatek.com>
Signed-off-by: Rudra Shahi <rudra.shahi@mediatek.com>
Signed-off-by: Allen Ye <allen.ye@mediatek.com>
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
---
 .../wireless/mediatek/mt76/mt76_connac_mcu.h  |  24 +++
 .../net/wireless/mediatek/mt76/mt7996/main.c  |  12 +-
 .../net/wireless/mediatek/mt76/mt7996/mcu.c   | 139 +++++++++++++-----
 .../net/wireless/mediatek/mt76/mt7996/mcu.h   |  17 +++
 .../wireless/mediatek/mt76/mt7996/mt7996.h    |   3 +-
 5 files changed, 153 insertions(+), 42 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
index 0185804d8ce3..ae6d0179727d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
@@ -416,6 +416,14 @@ struct sta_rec_he_6g_capa {
 	u8 rsv[2];
 } __packed;
 
+struct sta_rec_pn_info {
+	__le16 tag;
+	__le16 len;
+	u8 pn[6];
+	u8 tsc_type;
+	u8 rsv;
+} __packed;
+
 struct sec_key {
 	u8 cipher_id;
 	u8 cipher_len;
@@ -768,6 +776,7 @@ struct wtbl_raw {
 					 sizeof(struct sta_rec_sec) +	\
 					 sizeof(struct sta_rec_ra_fixed) + \
 					 sizeof(struct sta_rec_he_6g_capa) + \
+					 sizeof(struct sta_rec_pn_info) + \
 					 sizeof(struct tlv) +		\
 					 MT76_CONNAC_WTBL_UPDATE_MAX_SIZE)
 
@@ -798,6 +807,7 @@ enum {
 	STA_REC_HE_V2 = 0x19,
 	STA_REC_MLD = 0x20,
 	STA_REC_EHT = 0x22,
+	STA_REC_PN_INFO = 0x26,
 	STA_REC_HDRT = 0x28,
 	STA_REC_HDR_TRANS = 0x2B,
 	STA_REC_MAX_NUM
@@ -1090,6 +1100,13 @@ enum mcu_cipher_type {
 	MCU_CIPHER_GCMP_256,
 	MCU_CIPHER_WAPI,
 	MCU_CIPHER_BIP_CMAC_128,
+	MCU_CIPHER_BIP_CMAC_256,
+	MCU_CIPHER_BCN_PROT_CMAC_128,
+	MCU_CIPHER_BCN_PROT_CMAC_256,
+	MCU_CIPHER_BCN_PROT_GMAC_128,
+	MCU_CIPHER_BCN_PROT_GMAC_256,
+	MCU_CIPHER_BIP_GMAC_128,
+	MCU_CIPHER_BIP_GMAC_256,
 };
 
 enum {
@@ -1310,6 +1327,7 @@ enum {
 	UNI_BSS_INFO_RATE = 11,
 	UNI_BSS_INFO_QBSS = 15,
 	UNI_BSS_INFO_SEC = 16,
+	UNI_BSS_INFO_BCN_PROT = 17,
 	UNI_BSS_INFO_TXCMD = 18,
 	UNI_BSS_INFO_UAPSD = 19,
 	UNI_BSS_INFO_PS = 21,
@@ -1771,6 +1789,12 @@ mt76_connac_mcu_get_cipher(int cipher)
 		return MCU_CIPHER_GCMP;
 	case WLAN_CIPHER_SUITE_GCMP_256:
 		return MCU_CIPHER_GCMP_256;
+	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+		return MCU_CIPHER_BIP_GMAC_128;
+	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+		return MCU_CIPHER_BIP_GMAC_256;
+	case WLAN_CIPHER_SUITE_BIP_CMAC_256:
+		return MCU_CIPHER_BIP_CMAC_256;
 	case WLAN_CIPHER_SUITE_SMS4:
 		return MCU_CIPHER_WAPI;
 	default:
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
index d9ba57ae9fdc..51deea84b642 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
@@ -350,6 +350,8 @@ static int mt7996_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 	case WLAN_CIPHER_SUITE_GCMP:
 	case WLAN_CIPHER_SUITE_GCMP_256:
 	case WLAN_CIPHER_SUITE_SMS4:
+	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
 		break;
 	case WLAN_CIPHER_SUITE_WEP40:
 	case WLAN_CIPHER_SUITE_WEP104:
@@ -373,9 +375,13 @@ static int mt7996_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 	}
 
 	mt76_wcid_key_setup(&dev->mt76, wcid, key);
-	err = mt7996_mcu_add_key(&dev->mt76, vif, &msta->bip,
-				 key, MCU_WMWA_UNI_CMD(STA_REC_UPDATE),
-				 &msta->wcid, cmd);
+
+	if (key->keyidx == 6 || key->keyidx == 7)
+		err = mt7996_mcu_bcn_prot_enable(dev, vif, key);
+	else
+		err = mt7996_mcu_add_key(&dev->mt76, vif, key,
+					 MCU_WMWA_UNI_CMD(STA_REC_UPDATE),
+					 &msta->wcid, cmd);
 out:
 	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 1afcc96a0a52..ea2f08614ba3 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
@@ -2171,7 +2171,6 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
 
 static int
 mt7996_mcu_sta_key_tlv(struct mt76_wcid *wcid,
-		       struct mt76_connac_sta_key_conf *sta_key_conf,
 		       struct sk_buff *skb,
 		       struct ieee80211_key_conf *key,
 		       enum set_key_cmd cmd)
@@ -2192,43 +2191,22 @@ mt7996_mcu_sta_key_tlv(struct mt76_wcid *wcid,
 			return -EOPNOTSUPP;
 
 		sec_key = &sec->key[0];
+		sec_key->wlan_idx = cpu_to_le16(wcid->idx);
+		sec_key->mgmt_prot = 0;
+		sec_key->cipher_id = cipher;
 		sec_key->cipher_len = sizeof(*sec_key);
-
-		if (cipher == MCU_CIPHER_BIP_CMAC_128) {
-			sec_key->wlan_idx = cpu_to_le16(wcid->idx);
-			sec_key->cipher_id = MCU_CIPHER_AES_CCMP;
-			sec_key->key_id = sta_key_conf->keyidx;
-			sec_key->key_len = 16;
-			memcpy(sec_key->key, sta_key_conf->key, 16);
-
-			sec_key = &sec->key[1];
-			sec_key->wlan_idx = cpu_to_le16(wcid->idx);
-			sec_key->cipher_id = MCU_CIPHER_BIP_CMAC_128;
-			sec_key->cipher_len = sizeof(*sec_key);
-			sec_key->key_len = 16;
-			memcpy(sec_key->key, key->key, 16);
-			sec->n_cipher = 2;
-		} else {
-			sec_key->wlan_idx = cpu_to_le16(wcid->idx);
-			sec_key->cipher_id = cipher;
-			sec_key->key_id = key->keyidx;
-			sec_key->key_len = key->keylen;
-			memcpy(sec_key->key, key->key, key->keylen);
-
-			if (cipher == MCU_CIPHER_TKIP) {
-				/* Rx/Tx MIC keys are swapped */
-				memcpy(sec_key->key + 16, key->key + 24, 8);
-				memcpy(sec_key->key + 24, key->key + 16, 8);
-			}
-
-			/* store key_conf for BIP batch update */
-			if (cipher == MCU_CIPHER_AES_CCMP) {
-				memcpy(sta_key_conf->key, key->key, key->keylen);
-				sta_key_conf->keyidx = key->keyidx;
-			}
-
-			sec->n_cipher = 1;
+		sec_key->key_id = key->keyidx;
+		sec_key->key_len = key->keylen;
+		sec_key->need_resp = 0;
+		memcpy(sec_key->key, key->key, key->keylen);
+
+		if (cipher == MCU_CIPHER_TKIP) {
+			/* Rx/Tx MIC keys are swapped */
+			memcpy(sec_key->key + 16, key->key + 24, 8);
+			memcpy(sec_key->key + 24, key->key + 16, 8);
 		}
+
+		sec->n_cipher = 1;
 	} else {
 		sec->n_cipher = 0;
 	}
@@ -2237,7 +2215,6 @@ mt7996_mcu_sta_key_tlv(struct mt76_wcid *wcid,
 }
 
 int mt7996_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif,
-		       struct mt76_connac_sta_key_conf *sta_key_conf,
 		       struct ieee80211_key_conf *key, int mcu_cmd,
 		       struct mt76_wcid *wcid, enum set_key_cmd cmd)
 {
@@ -2250,13 +2227,99 @@ int mt7996_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif,
 	if (IS_ERR(skb))
 		return PTR_ERR(skb);
 
-	ret = mt7996_mcu_sta_key_tlv(wcid, sta_key_conf, skb, key, cmd);
+	ret = mt7996_mcu_sta_key_tlv(wcid, skb, key, cmd);
 	if (ret)
 		return ret;
 
 	return mt76_mcu_skb_send_msg(dev, skb, mcu_cmd, true);
 }
 
+static int mt7996_mcu_get_pn(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+			     u8 *pn)
+{
+#define TSC_TYPE_BIGTK_PN 2
+	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
+	struct sta_rec_pn_info *pn_info;
+	struct sk_buff *skb, *rskb;
+	struct tlv *tlv;
+	int ret;
+
+	skb = mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76, &mvif->sta.wcid);
+	if (IS_ERR(skb))
+		return PTR_ERR(skb);
+
+	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_PN_INFO, sizeof(*pn_info));
+	pn_info = (struct sta_rec_pn_info *)tlv;
+
+	pn_info->tsc_type = TSC_TYPE_BIGTK_PN;
+	ret = mt76_mcu_skb_send_and_get_msg(&dev->mt76, skb,
+					    MCU_WM_UNI_CMD_QUERY(STA_REC_UPDATE),
+					    true, &rskb);
+	if (ret)
+		return ret;
+
+	skb_pull(rskb, 4);
+
+	pn_info = (struct sta_rec_pn_info *)rskb->data;
+	if (le16_to_cpu(pn_info->tag) == STA_REC_PN_INFO)
+		memcpy(pn, pn_info->pn, 6);
+
+	dev_kfree_skb(rskb);
+	return 0;
+}
+
+int mt7996_mcu_bcn_prot_enable(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+			       struct ieee80211_key_conf *key)
+{
+	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
+	struct mt7996_mcu_bcn_prot_tlv *bcn_prot;
+	struct sk_buff *skb;
+	struct tlv *tlv;
+	u8 pn[6] = {};
+	int len = sizeof(struct bss_req_hdr) +
+		  sizeof(struct mt7996_mcu_bcn_prot_tlv);
+	int ret;
+
+	skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76, len);
+	if (IS_ERR(skb))
+		return PTR_ERR(skb);
+
+	tlv = mt76_connac_mcu_add_tlv(skb, UNI_BSS_INFO_BCN_PROT, sizeof(*bcn_prot));
+
+	bcn_prot = (struct mt7996_mcu_bcn_prot_tlv *)tlv;
+
+	ret = mt7996_mcu_get_pn(dev, vif, pn);
+	if (ret) {
+		dev_kfree_skb(skb);
+		return ret;
+	}
+
+	switch (key->cipher) {
+	case WLAN_CIPHER_SUITE_AES_CMAC:
+		bcn_prot->cipher_id = MCU_CIPHER_BCN_PROT_CMAC_128;
+		break;
+	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+		bcn_prot->cipher_id = MCU_CIPHER_BCN_PROT_GMAC_128;
+		break;
+	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+		bcn_prot->cipher_id = MCU_CIPHER_BCN_PROT_GMAC_256;
+		break;
+	case WLAN_CIPHER_SUITE_BIP_CMAC_256:
+	default:
+		dev_err(dev->mt76.dev, "Not supported Bigtk Cipher\n");
+		dev_kfree_skb(skb);
+		return -EOPNOTSUPP;
+	}
+
+	pn[0]++;
+	memcpy(bcn_prot->pn, pn, 6);
+	bcn_prot->enable = BP_SW_MODE;
+	memcpy(bcn_prot->key, key->key, WLAN_MAX_KEY_LEN);
+	bcn_prot->key_id = key->keyidx;
+
+	return mt76_mcu_skb_send_msg(&dev->mt76, skb,
+				     MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);
+}
 int mt7996_mcu_add_dev_info(struct mt7996_phy *phy,
 			    struct ieee80211_vif *vif, bool enable)
 {
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h
index 1851528d10ca..10a1b09ff2fb 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h
@@ -345,6 +345,23 @@ struct bss_rate_tlv {
 	u8 __rsv2[9];
 } __packed;
 
+enum {
+	BP_DISABLE,
+	BP_SW_MODE,
+	BP_HW_MODE,
+};
+
+struct mt7996_mcu_bcn_prot_tlv {
+	__le16 tag;
+	__le16 len;
+	u8 pn[6];
+	u8 enable;
+	u8 cipher_id;
+	u8 key[WLAN_MAX_KEY_LEN];
+	u8 key_id;
+	u8 __rsv[3];
+} __packed;
+
 struct bss_ra_tlv {
 	__le16 tag;
 	__le16 len;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
index c62a42512bd6..0ba00e4166d9 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
@@ -584,9 +584,10 @@ int mt7996_init_debugfs(struct mt7996_phy *phy);
 void mt7996_debugfs_rx_fw_monitor(struct mt7996_dev *dev, const void *data, int len);
 bool mt7996_debugfs_rx_log(struct mt7996_dev *dev, const void *data, int len);
 int mt7996_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif,
-		       struct mt76_connac_sta_key_conf *sta_key_conf,
 		       struct ieee80211_key_conf *key, int mcu_cmd,
 		       struct mt76_wcid *wcid, enum set_key_cmd cmd);
+int mt7996_mcu_bcn_prot_enable(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+			       struct ieee80211_key_conf *key);
 int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev,
 				     struct ieee80211_vif *vif,
 				     struct ieee80211_sta *sta);
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 8/8] wifi: mt76: connac: fix EHT phy mode check
  2023-11-02 10:02 [PATCH 1/8] wifi: mt76: change txpower init to per-phy Shayne Chen
                   ` (5 preceding siblings ...)
  2023-11-02 10:03 ` [PATCH 7/8] wifi: mt76: connac: add beacon protection support for mt7996 Shayne Chen
@ 2023-11-02 10:03 ` Shayne Chen
  6 siblings, 0 replies; 16+ messages in thread
From: Shayne Chen @ 2023-11-02 10:03 UTC (permalink / raw)
  To: Felix Fietkau
  Cc: linux-wireless, Lorenzo Bianconi, Ryder Lee, Evelyn Tsai,
	linux-mediatek, MeiChia Chiu, Shayne Chen

From: MeiChia Chiu <meichia.chiu@mediatek.com>

Add a BSS eht_support check before returning EHT phy mode. Without this
patch, there might be an inconsistency where the softmac layer thinks
the BSS is in HE mode, while the FW thinks it is in EHT mode.

Signed-off-by: MeiChia Chiu <meichia.chiu@mediatek.com>
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
---
 drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
index ae6bf3c968df..b475555097ff 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
@@ -1359,7 +1359,7 @@ u8 mt76_connac_get_phy_mode_ext(struct mt76_phy *phy, struct ieee80211_vif *vif,
 	sband = phy->hw->wiphy->bands[band];
 	eht_cap = ieee80211_get_eht_iftype_cap(sband, vif->type);
 
-	if (!eht_cap || !eht_cap->has_eht)
+	if (!eht_cap || !eht_cap->has_eht || !vif->bss_conf.eht_support)
 		return mode;
 
 	switch (band) {
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH 2/8] wifi: mt76: mt7996: add txpower setting support
  2023-11-02 10:02 ` [PATCH 2/8] wifi: mt76: mt7996: add txpower setting support Shayne Chen
@ 2023-12-01 23:40   ` Ben Greear
  2023-12-07 17:15     ` shayne.chen
  0 siblings, 1 reply; 16+ messages in thread
From: Ben Greear @ 2023-12-01 23:40 UTC (permalink / raw)
  To: Shayne Chen, Felix Fietkau
  Cc: linux-wireless, Lorenzo Bianconi, Ryder Lee, Evelyn Tsai,
	linux-mediatek, Allen Ye, StanleyYP Wang

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,

 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.

Thanks,
Ben

> 
> Co-developed-by: Allen Ye <allen.ye@mediatek.com>
> Signed-off-by: Allen Ye <allen.ye@mediatek.com>
> Co-developed-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
> Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
> Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
> ---
>   .../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_RATE	0
> +	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_DEFAULT	0x49	/* OFDM 24M */
>   #define MT7996_CFEND_RATE_11B		0x03	/* 11B LP, 11M */
>   
> +#define MT7996_SKU_RATE_NUM		417
> +
>   #define MT7996_MAX_TWT_AGRT		16
>   #define MT7996_MAX_STA_TWT_AGRT		8
>   #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,

-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 4/8] wifi: mt76: mt7996: switch to mcu command for TX GI report
  2023-11-02 10:02 ` [PATCH 4/8] wifi: mt76: mt7996: switch to mcu command for TX GI report Shayne Chen
@ 2023-12-04 21:57   ` Ben Greear
  2023-12-07 17:07     ` shayne.chen
  0 siblings, 1 reply; 16+ messages in thread
From: Ben Greear @ 2023-12-04 21:57 UTC (permalink / raw)
  To: Shayne Chen, Felix Fietkau
  Cc: linux-wireless, Lorenzo Bianconi, Ryder Lee, Evelyn Tsai,
	linux-mediatek, Benjamin Lin

On 11/2/23 03:02, Shayne Chen wrote:
> From: Benjamin Lin <benjamin-jw.lin@mediatek.com>
> 
> During runtime, the GI value in the WTBL is not updated in real-time. To
> obtain the latest results for the TX GI, switch to use an MCU command.

Hello,

I do not see this callback happening on my system.  What firmware version
is needed for this to work?

And where to find it...

Thanks,
Ben

-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 4/8] wifi: mt76: mt7996: switch to mcu command for TX GI report
  2023-12-04 21:57   ` Ben Greear
@ 2023-12-07 17:07     ` shayne.chen
  2023-12-07 17:46       ` Ben Greear
  0 siblings, 1 reply; 16+ messages in thread
From: shayne.chen @ 2023-12-07 17:07 UTC (permalink / raw)
  To: greearb@candelatech.com, nbd@nbd.name
  Cc: linux-wireless@vger.kernel.org,
	Benjamin-jw Lin (林津緯),
	linux-mediatek@lists.infradead.org,
	Evelyn Tsai (蔡珊鈺), lorenzo@kernel.org,
	Ryder Lee

On Mon, 2023-12-04 at 13:57 -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:
> > From: Benjamin Lin <benjamin-jw.lin@mediatek.com>
> > 
> > During runtime, the GI value in the WTBL is not updated in real-
> time. To
> > obtain the latest results for the TX GI, switch to use an MCU
> command.
> 
> Hello,

Hi Ben,
> 
> I do not see this callback happening on my system.  What firmware
> version
> is needed for this to work?
> 
> And where to find it...
> 

Please get testing firmware files from the following link to see if it
works on your environment:
https://github.com/csyuanc/linux-firmware

Thanks,
Shayne 

> Thanks,
> Ben
> 

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 2/8] wifi: mt76: mt7996: add txpower setting support
  2023-12-01 23:40   ` Ben Greear
@ 2023-12-07 17:15     ` shayne.chen
  2023-12-07 21:01       ` Ben Greear
  0 siblings, 1 reply; 16+ messages in thread
From: shayne.chen @ 2023-12-07 17:15 UTC (permalink / raw)
  To: greearb@candelatech.com, nbd@nbd.name
  Cc: linux-wireless@vger.kernel.org,
	Allen Ye (葉芷勳),
	linux-mediatek@lists.infradead.org,
	Evelyn Tsai (蔡珊鈺), lorenzo@kernel.org,
	Ryder Lee, StanleyYP Wang (王侑邦)

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@mediatek.com>
> > Signed-off-by: Allen Ye <allen.ye@mediatek.com>
> > Co-developed-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
> > Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
> > Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
> > ---
> >   .../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,
> 

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 4/8] wifi: mt76: mt7996: switch to mcu command for TX GI report
  2023-12-07 17:07     ` shayne.chen
@ 2023-12-07 17:46       ` Ben Greear
  0 siblings, 0 replies; 16+ messages in thread
From: Ben Greear @ 2023-12-07 17:46 UTC (permalink / raw)
  To: shayne.chen, nbd@nbd.name
  Cc: linux-wireless@vger.kernel.org,
	Benjamin-jw Lin (林津緯),
	linux-mediatek@lists.infradead.org,
	Evelyn Tsai (蔡珊鈺), lorenzo@kernel.org,
	Ryder Lee

On 12/7/23 09:07, shayne.chen@mediatek.com wrote:
> On Mon, 2023-12-04 at 13:57 -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:
>>> From: Benjamin Lin <benjamin-jw.lin@mediatek.com>
>>>
>>> During runtime, the GI value in the WTBL is not updated in real-
>> time. To
>>> obtain the latest results for the TX GI, switch to use an MCU
>> command.
>>
>> Hello,
> 
> Hi Ben,
>>
>> I do not see this callback happening on my system.  What firmware
>> version
>> is needed for this to work?
>>
>> And where to find it...
>>
> 
> Please get testing firmware files from the following link to see if it
> works on your environment:
> https://github.com/csyuanc/linux-firmware

I do see the callback happening with that latest firmware, thanks for the link to that.

tx_gi is always reported at zero though, which seems unlikely to be correct.

[  625.875443] mt7996e 0000:0d:00.0: ERROR: MCU:  Sequence mismatch in response, seq: 13  rxd->seq: 12 cmd: 130022
[  625.988751] update-tx-gi, mode: 8  tx_gi: 0
[  625.988755] update-tx-gi, mode: 0  tx_gi: 0
[  626.091378] mt7996e 0000:0d:00.0: ERROR: MCU:  Sequence mismatch in response, seq: 1  rxd->seq: 15 cmd: 130022
[  626.204917] update-tx-gi, mode: 8  tx_gi: 0
[  626.204920] update-tx-gi, mode: 0  tx_gi: 0
[  626.307376] mt7996e 0000:0d:00.0: ERROR: MCU:  Sequence mismatch in response, seq: 4  rxd->seq: 3 cmd: 130022
[  626.421332] update-tx-gi, mode: 8  tx_gi: 0
[  626.421335] update-tx-gi, mode: 0  tx_gi: 0
[  626.523436] mt7996e 0000:0d:00.0: ERROR: MCU:  Sequence mismatch in response, seq: 7  rxd->seq: 6 cmd: 130022
[  626.636900] update-tx-gi, mode: 8  tx_gi: 0
[  626.636904] update-tx-gi, mode: 0  tx_gi: 0
[  626.739408] mt7996e 0000:0d:00.0: ERROR: MCU:  Sequence mismatch in response, seq: 10  rxd->seq: 9 cmd: 130022
[  626.852727] update-tx-gi, mode: 8  tx_gi: 0
[  626.852731] update-tx-gi, mode: 0  tx_gi: 0
[  626.955475] mt7996e 0000:0d:00.0: ERROR: MCU:  Sequence mismatch in response, seq: 13  rxd->seq: 12 cmd: 130022


diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
index 407894c13d91..8aad38a21cd4 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
@@ -534,6 +534,9 @@ mt7996_mcu_ie_countdown(struct mt7996_dev *dev, struct sk_buff *skb)
  static int
  mt7996_mcu_update_tx_gi(struct rate_info *rate, struct all_sta_trx_rate *mcu_rate)
  {
+       pr_info("update-tx-gi, mode: %d  tx_gi: %d\n",
+               mcu_rate->tx_mode, mcu_rate->tx_gi);
+
         switch (mcu_rate->tx_mode) {
         case MT_PHY_TYPE_CCK:
         case MT_PHY_TYPE_OFDM:
[greearb@ben-dt5 mediatek]$


And lots of seq mismatch warnings in this firmware...could that be because of the new guard-interval
callback perhaps?  Do the messages sent from FW increment the seq number?  The parse-response code appears
to assume that it's responses are the only thing that would increment the seq number...

Here's my code to debug the seq mismatch:

static int
mt7996_mcu_parse_response(struct mt76_dev *mdev, int cmd,
			  struct sk_buff *skb, int seq)
{
	struct mt7996_mcu_rxd *rxd;
	struct mt7996_mcu_uni_event *event;
	int mcu_cmd = FIELD_GET(__MCU_CMD_FIELD_ID, cmd);
	int ret = 0;

	if (!skb) {
		const char* first = "Secondary";

		mdev->mcu_timeouts++;
		if (!mdev->first_failed_mcu_cmd)
			first = "Initial";

		dev_err(mdev->dev, "MCU: %s Failure: Message %08x (cid %lx ext_cid: %lx seq %d) timeout (%d/%d).  Last successful cmd: 0x%x\n",
			first,
			cmd, FIELD_GET(__MCU_CMD_FIELD_ID, cmd),
			FIELD_GET(__MCU_CMD_FIELD_EXT_ID, cmd), seq,
			mdev->mcu_timeouts, MAX_MCU_TIMEOUTS,
			mdev->last_successful_mcu_cmd);

		if (!mdev->first_failed_mcu_cmd)
			mdev->first_failed_mcu_cmd = cmd;
		return -ETIMEDOUT;
	}

	mdev->mcu_timeouts = 0;
	mdev->last_successful_mcu_cmd = cmd;

	if (mdev->first_failed_mcu_cmd) {
		dev_err(mdev->dev, "MCU: First success after failure: Message %08x (cid %lx ext_cid: %lx seq %d)\n",
			cmd, FIELD_GET(__MCU_CMD_FIELD_ID, cmd),
			FIELD_GET(__MCU_CMD_FIELD_EXT_ID, cmd), seq);
		mdev->first_failed_mcu_cmd = 0;
	} else {
		/* verbose debugging
		   dev_err(mdev->dev, "MCU: OK response to message %08x (cid %lx ext_cid: %lx seq %d)\n",
		           cmd, FIELD_GET(__MCU_CMD_FIELD_ID, cmd),
		           FIELD_GET(__MCU_CMD_FIELD_EXT_ID, cmd), seq);
		*/
	}

	rxd = (struct mt7996_mcu_rxd *)skb->data;
	if (seq != rxd->seq) {
		dev_err(mdev->dev, "ERROR: MCU:  Sequence mismatch in response, seq: %d  rxd->seq: %d cmd: %0x\n",
			seq, rxd->seq, cmd);
		return -EAGAIN;
	}

	if (cmd == MCU_CMD(PATCH_SEM_CONTROL)) {
		skb_pull(skb, sizeof(*rxd) - 4);
		ret = *skb->data;
	} else if ((rxd->option & MCU_UNI_CMD_EVENT) &&
		    rxd->eid == MCU_UNI_EVENT_RESULT) {
		skb_pull(skb, sizeof(*rxd));
		event = (struct mt7996_mcu_uni_event *)skb->data;
		ret = le32_to_cpu(event->status);
		/* skip invalid event */
		if (mcu_cmd != event->cid)
			ret = -EAGAIN;
	} else {
		skb_pull(skb, sizeof(struct mt7996_mcu_rxd));
	}

	return ret;
}

Thanks,
Ben


-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH 2/8] wifi: mt76: mt7996: add txpower setting support
  2023-12-07 17:15     ` shayne.chen
@ 2023-12-07 21:01       ` Ben Greear
  2024-03-01 20:12         ` ***Spam*** " Ben Greear
  0 siblings, 1 reply; 16+ messages in thread
From: Ben Greear @ 2023-12-07 21:01 UTC (permalink / raw)
  To: shayne.chen, nbd@nbd.name
  Cc: linux-wireless@vger.kernel.org,
	Allen Ye (葉芷勳),
	linux-mediatek@lists.infradead.org,
	Evelyn Tsai (蔡珊鈺), lorenzo@kernel.org,
	Ryder Lee, StanleyYP Wang (王侑邦)

On 12/7/23 09:15, shayne.chen@mediatek.com wrote:
> 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?

The problem remains with this firmware:

[root@ct523c-a0af ~]# ethtool -i wlan2
driver: mt7996e
version: 6.7.0-rc3+
firmware-version: ____000000-20231012001354
expansion-rom-version:
bus-info: 0000:0d:00.0
supports-statistics: yes
supports-test: no
supports-eeprom-access: no
supports-register-dump: no
supports-priv-flags: no

Do you have a kernel tree that you are using successfully (not an owrt feed of patches)
that you can share?

Thanks,
Ben


-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: ***Spam*** [PATCH 2/8] wifi: mt76: mt7996: add txpower setting support
  2023-12-07 21:01       ` Ben Greear
@ 2024-03-01 20:12         ` Ben Greear
  2024-03-04 18:13           ` Ben Greear
  0 siblings, 1 reply; 16+ messages in thread
From: Ben Greear @ 2024-03-01 20:12 UTC (permalink / raw)
  To: shayne.chen, nbd@nbd.name
  Cc: linux-wireless@vger.kernel.org,
	Allen Ye (葉芷勳),
	linux-mediatek@lists.infradead.org,
	Evelyn Tsai (蔡珊鈺), lorenzo@kernel.org,
	Ryder Lee, StanleyYP Wang (王侑邦)

On 12/7/23 13:01, Ben Greear wrote:
> On 12/7/23 09:15, shayne.chen@mediatek.com wrote:
>> 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?

Hello Shayne,

I rebased on 6.8, and started adding some debugging around this issue.

I am using the MTK 7996 developer radio board on this system, in an x86-64 pc.  It is not able
to find the 'node', so the per mode power tables are not populated and left at
0x0.  Then, when this 0x0 data is sent to the firmware, the firmware gives
back a failure response 0xc00000bb

[ 8658.340984] mt7996e 0000:03:00.0: get-rate-power-limits:  Could not find node.
[ 8658.340988] mt7996e 0000:03:00.0: set-txpower-sku, tx_power: 36
[ 8658.341127] mt7996e 0000:03:00.0: mcu-parse-response, firmware returned failure code: 0xc00000bb.

Do we need to add code to not even send the mcu command if the per-mode txpower tables
cannot be found?

Or can we calculate the values to some useful default in that case?

For reference, here is my debug patch:


diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c
index 0c5c664de6b3..cf48073783b8 100644
--- a/drivers/net/wireless/mediatek/mt76/eeprom.c
+++ b/drivers/net/wireless/mediatek/mt76/eeprom.c
@@ -419,12 +422,16 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,

         memset(dest, target_power, sizeof(*dest));

-       if (!IS_ENABLED(CONFIG_OF))
+       if (!IS_ENABLED(CONFIG_OF)) {
+               mtk_dbg(dev, CFG, "get-rate-power-limits:  CONFIG_OF not enabled.\n");
                 return target_power;
+       }

         np = mt76_find_power_limits_node(dev);
-       if (!np)
+       if (!np) {
+               mtk_dbg(dev, CFG, "get-rate-power-limits:  Could not find node.\n");
                 return target_power;
+       }

         switch (chan->band) {
         case NL80211_BAND_2GHZ:
@@ -442,12 +449,17 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,

         snprintf(name, sizeof(name), "txpower-%cg", band);
         np = of_get_child_by_name(np, name);
-       if (!np)
+       if (!np) {
+               mtk_dbg(dev, CFG, "get-rate-power-limits:  Could not find band node: %s\n",
+                       name);
                 return target_power;
+       }

         np = mt76_find_channel_node(np, chan);
-       if (!np)
+       if (!np) {
+               mtk_dbg(dev, CFG, "get-rate-power-limits:  Could not find chan node\n");
                 return target_power;
+       }

         txs_delta = mt76_get_txs_delta(np, hweight16(phy->chainmask));

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 2c19b537feec..8f4774c4b1d5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -1114,6 +1114,7 @@ enum MTK_DEUBG {
         MTK_DEBUG_FATAL         = 0x00000004,
         MTK_DEBUG_WRN           = 0x00000008,
         MTK_DEBUG_MSG           = 0x00000010, /* messages to/from firmware */
+       MTK_DEBUG_CFG           = 0x00000020, /* Configuration related */
         MTK_DEBUG_ANY           = 0xffffffff
  };

diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
index e89a06464651..c7042c3a905b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
@@ -422,8 +422,11 @@ static int mt7996_config(struct ieee80211_hw *hw, u32 changed)
         if (changed & (IEEE80211_CONF_CHANGE_POWER |
                        IEEE80211_CONF_CHANGE_CHANNEL)) {
                 ret = mt7996_mcu_set_txpower_sku(phy);
-               if (ret)
-                       return ret;
+               if (ret) {
+                       dev_err(dev->mt76.dev,
+                               "config:  Failed to set txpower: %d\n", ret);
+                       //return ret;
+               }
         }

         mutex_lock(&dev->mt76.mutex);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
index d709d26eacd1..9dc896cd04e6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
@@ -281,6 +281,10 @@ mt7996_mcu_parse_response(struct mt76_dev *mdev, int cmd,
                 /* skip invalid event */
                 if (mcu_cmd != event->cid)
                         ret = -EAGAIN;
+               if (ret) {
+                       mtk_dbg(mdev, CFG, "mcu-parse-response, firmware returned failure code: 0x%x.\n",
+                               ret);
+               }
         } else {
                 skb_pull(skb, sizeof(struct mt7996_mcu_rxd));
         }
@@ -4571,6 +4575,7 @@ int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy)
         tx_power = mt76_get_rate_power_limits(mphy, mphy->chandef.chan,
                                               &la, tx_power);
         mphy->txpower_cur = tx_power;
+       mtk_dbg(&dev->mt76, CFG, "set-txpower-sku, tx_power: %d\n", tx_power);

         skb = mt76_mcu_msg_alloc(&dev->mt76, NULL,
                                  sizeof(req) + MT7996_SKU_RATE_NUM);

Thanks,
Ben



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: ***Spam*** [PATCH 2/8] wifi: mt76: mt7996: add txpower setting support
  2024-03-01 20:12         ` ***Spam*** " Ben Greear
@ 2024-03-04 18:13           ` Ben Greear
  0 siblings, 0 replies; 16+ messages in thread
From: Ben Greear @ 2024-03-04 18:13 UTC (permalink / raw)
  To: shayne.chen, nbd@nbd.name
  Cc: linux-wireless@vger.kernel.org,
	Allen Ye (葉芷勳),
	linux-mediatek@lists.infradead.org,
	Evelyn Tsai (蔡珊鈺), lorenzo@kernel.org,
	Ryder Lee, StanleyYP Wang (王侑邦)

On 3/1/24 12:12, Ben Greear wrote:
> On 12/7/23 13:01, Ben Greear wrote:
>> On 12/7/23 09:15, shayne.chen@mediatek.com wrote:
>>> 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?
> 
> Hello Shayne,
> 
> I rebased on 6.8, and started adding some debugging around this issue.

I received a patch from Chad that fixes this problem, the cmd size was wrong for one
reason or another.

Thanks,
Ben



^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2024-03-04 18:13 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-11-02 10:02 [PATCH 1/8] wifi: mt76: change txpower init to per-phy Shayne Chen
2023-11-02 10:02 ` [PATCH 2/8] wifi: mt76: mt7996: add txpower setting support Shayne Chen
2023-12-01 23:40   ` Ben Greear
2023-12-07 17:15     ` shayne.chen
2023-12-07 21:01       ` Ben Greear
2024-03-01 20:12         ` ***Spam*** " Ben Greear
2024-03-04 18:13           ` Ben Greear
2023-11-02 10:02 ` [PATCH 3/8] wifi: mt76: use chainmask for power delta calculation Shayne Chen
2023-11-02 10:02 ` [PATCH 4/8] wifi: mt76: mt7996: switch to mcu command for TX GI report Shayne Chen
2023-12-04 21:57   ` Ben Greear
2023-12-07 17:07     ` shayne.chen
2023-12-07 17:46       ` Ben Greear
2023-11-02 10:02 ` [PATCH 5/8] wifi: mt76: mt7996: fix alignment of sta info event Shayne Chen
2023-11-02 10:03 ` [PATCH 6/8] wifi: mt76: mt7996: rework ampdu params setting Shayne Chen
2023-11-02 10:03 ` [PATCH 7/8] wifi: mt76: connac: add beacon protection support for mt7996 Shayne Chen
2023-11-02 10:03 ` [PATCH 8/8] wifi: mt76: connac: fix EHT phy mode check Shayne Chen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).