[rdkb][common][bsp][Refactor and sync wifi from openwrt]
[Description]
ced8594f [MAC80211][WiFi6][Misc][Fix the MT76 WiFi6 Makefile]
7221999e [MAC80211][WiFi7][Misc][Correct the MAC80211 WiFi7 Makefile.]
9d87794a [MAC80211][WiFi7][Misc][Correct the MT76 WiFi7 Makefile.]
ff24e1b2 [openwrt-24][Mac80211][Fix patch conflict with upstream openwrt]
3a6c13e2 [mac80211][misc][fix patch fail due to openwrt update]
05763faa [MAC80211][WiFi7][misc][fix patch failed of wifi-scripts]
f34fd014 [mac80211][misc][fix patch fail due to openwrt update]
f6796660 [openwrt-24][Release][Fix build fail of Wi-Fi7 MT76]
7076d96c [MAC80211][WiFi7][Misc][Fix release build fail because of mt76 version upgradation]
1f748b17 [mac80211][misc][fix patch fail due to openwrt update]
95ba6722 [mac80211][misc][fix patch fail due to openwrt update]
17680d7f [MAC80211][WiFi7][misc][Rename eeprom of eFEM variants]
b97cefa1 [MAC80211][WiFi7][app][Add Griffin support for atenl/iwpriv]
6de718a4 [MAC80211][WiFi7][misc][fix wifi-scripts patch failed]
9f1ace86 [MAC80211][WiFi7][misc][fix hostapd Makefile patch]
e4d0d28e [MAC80211][Misc][Add MT7990 Firmware OpenWrt config]
f3a8a8f7 [MAC80211][Release][Fix build fail of Wi-Fi6 MT76]
dabe8eae [openwrt-24][common][bsp][Fix line ending]
6d438a9d [openwrt-24][common][bsp][Use zstd to compress rootfs debug symbols for unified autobuild]
c268e47e [openwrt][common][bsp][Change SMC ID of wdt nonrst reg of reset-boot-count to 0x570]
c6819fbc [openwrt-24][Release][Update release note for Filogic 880 alpha release]
6897b4de [openwrt-24][common][bsp][Adjust unified autobuild for internal build detection]
fb9b9762 [MAC80211][WiFi6/7][app][Add ext eeprom write back cmd support]
d42b42a3 [openwrt-24][common][bsp][Add kernel6.6 Filogic880 BE19000/BE14000]
3806f047 [MAC80211][misc][Add Bpi-R4 support]
ddbda753 [MAC80211][WiFi7][Misc][Fix build fail because of mt76 version upgradation]
90959b08 [MAC80211][WiFi6][mt76][Rebase mt76 pathes]
728a3362 [MAC80211][WiFi6][mt76][Refactor Qos Map]
b46277b5 [MAC80211][WiFi6][mt76][Fix add ba issue on tid not equal to zero]
c084ee8b [MAC80211][WiFi7][mt76][split mt76 Makefile patch]
bbaec094 [MAC80211][Release][Update Filogic 830/820/630 firmware]
5ce2eece [MAC80211][wifi6][MT76][Fix build fail]
5ac1121f [MAC80211][wifi6][MT76][Fix mt76 version to 2024-07-13]
485f92b1 [MAC80211][WiFi7][misc][synchronize PP bitmap when association]
84db8818 [MAC80211][WiFi6/7][app][Add ATETXNSS in iwpriv wrapper]
cc5a4605 [MAC80211][WiFi7][mt76][fix patch failed of Makefile]
[Release-log]
Change-Id: I06704c04c4b5571af4ffd189d636c1fc9f0567fd
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0019-mtk-mt76-mt7996-add-txpower-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0019-mtk-mt76-mt7996-add-txpower-support.patch
new file mode 100644
index 0000000..9c4eeda
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0019-mtk-mt76-mt7996-add-txpower-support.patch
@@ -0,0 +1,1048 @@
+From 5d3b2dafbf6b343983b999b19e94ad175c374bd3 Mon Sep 17 00:00:00 2001
+From: Allen Ye <allen.ye@mediatek.com>
+Date: Fri, 24 Mar 2023 23:35:30 +0800
+Subject: [PATCH 019/223] mtk: mt76: mt7996: add txpower support
+
+Add single sku and default enable sku.
+
+mtk: wifi: mt76: mt7996: Porting wifi6 txpower fix to eagle
+
+Refactor txpower flow.
+1. Fix wrong bbp CR address
+2. Ignore RegDB power limit when we have single sku table. And dump more informaiton in debugfs.
+3. Refactor get_txpower ops flow, we only consider CCK and OFDM power value as maximum.
+4. Remove sku_disable due to SQC is over and default enable both sku tables.
+
+Fix wrong power value when user set limit close to path table limit.
+
+Change-Id: I5738cd3730f041f1f42d582e2b62d39b70861376
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Signed-off-by: Allen Ye <allen.ye@mediatek.com>
+---
+ eeprom.c | 54 ++++++-
+ mt76.h | 9 ++
+ mt76_connac_mcu.c | 2 +-
+ mt7996/eeprom.c | 34 ++++
+ mt7996/eeprom.h | 42 +++++
+ mt7996/init.c | 16 +-
+ mt7996/main.c | 15 ++
+ mt7996/mcu.c | 69 +++++++-
+ mt7996/mcu.h | 2 +
+ mt7996/mt7996.h | 4 +
+ mt7996/mtk_debugfs.c | 363 +++++++++++++++++++++++++++++++++++++++++++
+ mt7996/mtk_mcu.c | 23 +++
+ mt7996/mtk_mcu.h | 92 +++++++++++
+ mt7996/regs.h | 27 ++--
+ 14 files changed, 725 insertions(+), 27 deletions(-)
+
+diff --git a/eeprom.c b/eeprom.c
+index 6bd2cc1a..85935dea 100644
+--- a/eeprom.c
++++ b/eeprom.c
+@@ -320,9 +320,10 @@ mt76_apply_array_limit(s8 *pwr, size_t pwr_len, const __be32 *data,
+ static void
+ mt76_apply_multi_array_limit(s8 *pwr, size_t pwr_len, s8 pwr_num,
+ const __be32 *data, size_t len, s8 target_power,
+- s8 nss_delta, s8 *max_power)
++ s8 nss_delta)
+ {
+ int i, cur;
++ s8 max_power = -128;
+
+ if (!data)
+ return;
+@@ -334,7 +335,7 @@ mt76_apply_multi_array_limit(s8 *pwr, size_t pwr_len, s8 pwr_num,
+ break;
+
+ mt76_apply_array_limit(pwr + pwr_len * i, pwr_len, data + 1,
+- target_power, nss_delta, max_power);
++ target_power, nss_delta, &max_power);
+ if (--cur > 0)
+ continue;
+
+@@ -350,6 +351,7 @@ mt76_apply_multi_array_limit(s8 *pwr, size_t pwr_len, s8 pwr_num,
+ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
+ struct ieee80211_channel *chan,
+ struct mt76_power_limits *dest,
++ struct mt76_power_path_limits *dest_path,
+ s8 target_power)
+ {
+ struct mt76_dev *dev = phy->dev;
+@@ -357,16 +359,20 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
+ const __be32 *val;
+ char name[16];
+ u32 mcs_rates = dev->drv->mcs_rates;
+- u32 ru_rates = ARRAY_SIZE(dest->ru[0]);
+ char band;
+ size_t len;
+- s8 max_power = 0;
++ s8 max_power = -127;
++ s8 max_power_backoff = -127;
+ s8 txs_delta;
++ int n_chains = hweight16(phy->chainmask);
++ s8 target_power_combine = target_power + mt76_tx_power_nss_delta(n_chains);
+
+ if (!mcs_rates)
+- mcs_rates = 10;
++ mcs_rates = 12;
+
+ memset(dest, target_power, sizeof(*dest));
++ if (dest_path != NULL)
++ memset(dest_path, 0, sizeof(*dest_path));
+
+ if (!IS_ENABLED(CONFIG_OF))
+ return target_power;
+@@ -412,12 +418,44 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
+ val = mt76_get_of_array(np, "rates-mcs", &len, mcs_rates + 1);
+ mt76_apply_multi_array_limit(dest->mcs[0], ARRAY_SIZE(dest->mcs[0]),
+ ARRAY_SIZE(dest->mcs), val, len,
+- target_power, txs_delta, &max_power);
++ target_power, txs_delta);
+
+- val = mt76_get_of_array(np, "rates-ru", &len, ru_rates + 1);
++ val = mt76_get_of_array(np, "rates-ru", &len, ARRAY_SIZE(dest->ru[0]) + 1);
+ mt76_apply_multi_array_limit(dest->ru[0], ARRAY_SIZE(dest->ru[0]),
+ ARRAY_SIZE(dest->ru), val, len,
+- target_power, txs_delta, &max_power);
++ target_power, txs_delta);
++
++ val = mt76_get_of_array(np, "rates-eht", &len, ARRAY_SIZE(dest->eht[0]) + 1);
++ mt76_apply_multi_array_limit(dest->eht[0], ARRAY_SIZE(dest->eht[0]),
++ ARRAY_SIZE(dest->eht), val, len,
++ target_power, txs_delta);
++
++ if (dest_path == NULL)
++ return max_power;
++
++ max_power_backoff = max_power;
++
++ val = mt76_get_of_array(np, "paths-cck", &len, ARRAY_SIZE(dest_path->cck));
++ mt76_apply_array_limit(dest_path->cck, ARRAY_SIZE(dest_path->cck), val,
++ target_power_combine, txs_delta, &max_power_backoff);
++
++ val = mt76_get_of_array(np, "paths-ofdm", &len, ARRAY_SIZE(dest_path->ofdm));
++ mt76_apply_array_limit(dest_path->ofdm, ARRAY_SIZE(dest_path->ofdm), val,
++ target_power_combine, txs_delta, &max_power_backoff);
++
++ val = mt76_get_of_array(np, "paths-ofdm-bf", &len, ARRAY_SIZE(dest_path->ofdm_bf));
++ mt76_apply_array_limit(dest_path->ofdm_bf, ARRAY_SIZE(dest_path->ofdm_bf), val,
++ target_power_combine, txs_delta, &max_power_backoff);
++
++ val = mt76_get_of_array(np, "paths-ru", &len, ARRAY_SIZE(dest_path->ru[0]) + 1);
++ mt76_apply_multi_array_limit(dest_path->ru[0], ARRAY_SIZE(dest_path->ru[0]),
++ ARRAY_SIZE(dest_path->ru), val, len,
++ target_power_combine, txs_delta);
++
++ val = mt76_get_of_array(np, "paths-ru-bf", &len, ARRAY_SIZE(dest_path->ru_bf[0]) + 1);
++ mt76_apply_multi_array_limit(dest_path->ru_bf[0], ARRAY_SIZE(dest_path->ru_bf[0]),
++ ARRAY_SIZE(dest_path->ru_bf), val, len,
++ target_power_combine, txs_delta);
+
+ return max_power;
+ }
+diff --git a/mt76.h b/mt76.h
+index 8666ec2f..ac2de858 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -1079,6 +1079,14 @@ struct mt76_power_limits {
+ s8 eht[16][16];
+ };
+
++struct mt76_power_path_limits {
++ s8 cck[5];
++ s8 ofdm[5];
++ s8 ofdm_bf[4];
++ s8 ru[16][15];
++ s8 ru_bf[16][15];
++};
++
+ struct mt76_ethtool_worker_info {
+ u64 *data;
+ int idx;
+@@ -1694,6 +1702,7 @@ mt76_find_channel_node(struct device_node *np, struct ieee80211_channel *chan);
+ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
+ struct ieee80211_channel *chan,
+ struct mt76_power_limits *dest,
++ struct mt76_power_path_limits *dest_path,
+ s8 target_power);
+
+ static inline bool mt76_queue_is_rx(struct mt76_dev *dev, struct mt76_queue *q)
+diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
+index 07f52dd6..c7145074 100644
+--- a/mt76_connac_mcu.c
++++ b/mt76_connac_mcu.c
+@@ -2160,7 +2160,7 @@ mt76_connac_mcu_rate_txpower_band(struct mt76_phy *phy,
+ sar_power = mt76_get_sar_power(phy, &chan, reg_power);
+
+ mt76_get_rate_power_limits(phy, &chan, limits,
+- sar_power);
++ NULL, sar_power);
+
+ tx_power_tlv.last_msg = ch_list[idx] == last_ch;
+ sku_tlbv.channel = ch_list[idx];
+diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
+index 5ff52577..b091e30c 100644
+--- a/mt7996/eeprom.c
++++ b/mt7996/eeprom.c
+@@ -541,3 +541,37 @@ s8 mt7996_eeprom_get_power_delta(struct mt7996_dev *dev, int band)
+
+ return val & MT_EE_RATE_DELTA_SIGN ? delta : -delta;
+ }
++
++const u8 mt7996_sku_group_len[] = {
++ [SKU_CCK] = 4,
++ [SKU_OFDM] = 8,
++ [SKU_HT20] = 8,
++ [SKU_HT40] = 9,
++ [SKU_VHT20] = 12,
++ [SKU_VHT40] = 12,
++ [SKU_VHT80] = 12,
++ [SKU_VHT160] = 12,
++ [SKU_HE26] = 12,
++ [SKU_HE52] = 12,
++ [SKU_HE106] = 12,
++ [SKU_HE242] = 12,
++ [SKU_HE484] = 12,
++ [SKU_HE996] = 12,
++ [SKU_HE2x996] = 12,
++ [SKU_EHT26] = 16,
++ [SKU_EHT52] = 16,
++ [SKU_EHT106] = 16,
++ [SKU_EHT242] = 16,
++ [SKU_EHT484] = 16,
++ [SKU_EHT996] = 16,
++ [SKU_EHT2x996] = 16,
++ [SKU_EHT4x996] = 16,
++ [SKU_EHT26_52] = 16,
++ [SKU_EHT26_106] = 16,
++ [SKU_EHT484_242] = 16,
++ [SKU_EHT996_484] = 16,
++ [SKU_EHT996_484_242] = 16,
++ [SKU_EHT2x996_484] = 16,
++ [SKU_EHT3x996] = 16,
++ [SKU_EHT3x996_484] = 16,
++};
+diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
+index b3b9b854..f3a9618b 100644
+--- a/mt7996/eeprom.h
++++ b/mt7996/eeprom.h
+@@ -127,4 +127,46 @@ mt7996_get_channel_group_6g(int channel)
+ return DIV_ROUND_UP(channel - 29, 32);
+ }
+
++enum mt7996_sku_rate_group {
++ SKU_CCK,
++ SKU_OFDM,
++
++ SKU_HT20,
++ SKU_HT40,
++
++ SKU_VHT20,
++ SKU_VHT40,
++ SKU_VHT80,
++ SKU_VHT160,
++
++ SKU_HE26,
++ SKU_HE52,
++ SKU_HE106,
++ SKU_HE242,
++ SKU_HE484,
++ SKU_HE996,
++ SKU_HE2x996,
++
++ SKU_EHT26,
++ SKU_EHT52,
++ SKU_EHT106,
++ SKU_EHT242,
++ SKU_EHT484,
++ SKU_EHT996,
++ SKU_EHT2x996,
++ SKU_EHT4x996,
++ SKU_EHT26_52,
++ SKU_EHT26_106,
++ SKU_EHT484_242,
++ SKU_EHT996_484,
++ SKU_EHT996_484_242,
++ SKU_EHT2x996_484,
++ SKU_EHT3x996,
++ SKU_EHT3x996_484,
++
++ MAX_SKU_RATE_GROUP_NUM,
++};
++
++extern const u8 mt7996_sku_group_len[MAX_SKU_RATE_GROUP_NUM];
++
+ #endif
+diff --git a/mt7996/init.c b/mt7996/init.c
+index 0a8e929a..994d74cc 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -297,7 +297,12 @@ static void __mt7996_init_txpower(struct mt7996_phy *phy,
+ 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;
++ struct mt76_power_path_limits limits_path;
++ struct device_node *np;
+
++ phy->sku_limit_en = true;
++ phy->sku_path_en = true;
++ np = mt76_find_power_limits_node(&dev->mt76);
+ for (i = 0; i < sband->n_channels; i++) {
+ struct ieee80211_channel *chan = &sband->channels[i];
+ int target_power = mt7996_eeprom_get_target_power(dev, chan);
+@@ -305,11 +310,18 @@ static void __mt7996_init_txpower(struct mt7996_phy *phy,
+ target_power += pwr_delta;
+ target_power = mt76_get_rate_power_limits(phy->mt76, chan,
+ &limits,
++ &limits_path,
+ target_power);
++ if (!limits_path.ofdm[0])
++ phy->sku_path_en = false;
++
+ target_power += nss_delta;
+ target_power = DIV_ROUND_UP(target_power, 2);
+- chan->max_power = min_t(int, chan->max_reg_power,
+- target_power);
++ if (!np)
++ chan->max_power = min_t(int, chan->max_reg_power,
++ target_power);
++ else
++ chan->max_power = target_power;
+ chan->orig_mpwr = target_power;
+ }
+ }
+diff --git a/mt7996/main.c b/mt7996/main.c
+index a1c3874c..e65b5bd7 100644
+--- a/mt7996/main.c
++++ b/mt7996/main.c
+@@ -85,6 +85,21 @@ int mt7996_run(struct ieee80211_hw *hw)
+ if (ret)
+ goto out;
+
++#ifdef CONFIG_MTK_DEBUG
++ ret = mt7996_mcu_set_tx_power_ctrl(phy, UNI_TXPOWER_SKU_POWER_LIMIT_CTRL,
++ dev->dbg.sku_disable ? 0 : phy->sku_limit_en);
++
++ ret = mt7996_mcu_set_tx_power_ctrl(phy, UNI_TXPOWER_BACKOFF_POWER_LIMIT_CTRL,
++ dev->dbg.sku_disable ? 0 : phy->sku_path_en);
++#else
++ ret = mt7996_mcu_set_tx_power_ctrl(phy, UNI_TXPOWER_SKU_POWER_LIMIT_CTRL,
++ phy->sku_limit_en);
++ ret = mt7996_mcu_set_tx_power_ctrl(phy, UNI_TXPOWER_BACKOFF_POWER_LIMIT_CTRL,
++ phy->sku_path_en);
++#endif
++ if (ret)
++ goto out;
++
+ set_bit(MT76_STATE_RUNNING, &phy->mt76->state);
+
+ ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work,
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 98edae2c..59a24478 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -4684,9 +4684,31 @@ int mt7996_mcu_wed_rro_reset_sessions(struct mt7996_dev *dev, u16 id)
+ sizeof(req), true);
+ }
+
++static void
++mt7996_update_max_txpower_cur(struct mt7996_phy *phy, int tx_power)
++{
++ struct mt76_phy *mphy = phy->mt76;
++ struct ieee80211_channel *chan = mphy->main_chan;
++ int e2p_power_limit = 0;
++
++ if (chan == NULL) {
++ mphy->txpower_cur = tx_power;
++ return;
++ }
++
++ e2p_power_limit = mt7996_eeprom_get_target_power(phy->dev, chan);
++ e2p_power_limit += mt7996_eeprom_get_power_delta(phy->dev, chan->band);
++
++ if (phy->sku_limit_en)
++ mphy->txpower_cur = min_t(int, e2p_power_limit, tx_power);
++ else
++ mphy->txpower_cur = e2p_power_limit;
++}
++
+ int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy)
+ {
+ #define TX_POWER_LIMIT_TABLE_RATE 0
++#define TX_POWER_LIMIT_TABLE_PATH 1
+ struct mt7996_dev *dev = phy->dev;
+ struct mt76_phy *mphy = phy->mt76;
+ struct ieee80211_hw *hw = mphy->hw;
+@@ -4706,13 +4728,22 @@ int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy)
+ .band_idx = phy->mt76->band_idx,
+ };
+ struct mt76_power_limits la = {};
++ struct mt76_power_path_limits la_path = {};
+ struct sk_buff *skb;
+- int i, tx_power;
++ int i, ret, txpower_limit;
++
++ if (hw->conf.power_level == INT_MIN)
++ hw->conf.power_level = 127;
++ txpower_limit = mt7996_get_power_bound(phy, hw->conf.power_level);
+
+- 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;
++ if (phy->sku_limit_en) {
++ txpower_limit = mt76_get_rate_power_limits(mphy, mphy->chandef.chan,
++ &la, &la_path, txpower_limit);
++ mt7996_update_max_txpower_cur(phy, txpower_limit);
++ } else {
++ mt7996_update_max_txpower_cur(phy, txpower_limit);
++ return 0;
++ }
+
+ skb = mt76_mcu_msg_alloc(&dev->mt76, NULL,
+ sizeof(req) + MT7996_SKU_PATH_NUM);
+@@ -4742,6 +4773,34 @@ int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy)
+ /* padding */
+ skb_put_zero(skb, MT7996_SKU_PATH_NUM - MT7996_SKU_RATE_NUM);
+
++ ret = mt76_mcu_skb_send_msg(&dev->mt76, skb,
++ MCU_WM_UNI_CMD(TXPOWER), true);
++ if (ret)
++ return ret;
++
++ /* only set per-path power table when it's configured */
++ if (!phy->sku_path_en)
++ return 0;
++
++ skb = mt76_mcu_msg_alloc(&dev->mt76, NULL,
++ sizeof(req) + MT7996_SKU_PATH_NUM);
++ if (!skb)
++ return -ENOMEM;
++ req.power_limit_type = TX_POWER_LIMIT_TABLE_PATH;
++
++ skb_put_data(skb, &req, sizeof(req));
++ skb_put_data(skb, &la_path.cck, sizeof(la_path.cck));
++ skb_put_data(skb, &la_path.ofdm, sizeof(la_path.ofdm));
++ skb_put_data(skb, &la_path.ofdm_bf, sizeof(la_path.ofdm_bf));
++
++ for (i = 0; i < 32; i++) {
++ bool bf = i % 2;
++ u8 idx = i / 2;
++ s8 *buf = bf ? la_path.ru_bf[idx] : la_path.ru[idx];
++
++ skb_put_data(skb, buf, sizeof(la_path.ru[0]));
++ }
++
+ return mt76_mcu_skb_send_msg(&dev->mt76, skb,
+ MCU_WM_UNI_CMD(TXPOWER), true);
+ }
+diff --git a/mt7996/mcu.h b/mt7996/mcu.h
+index f889cb8b..1ed05d7e 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -911,6 +911,7 @@ struct tx_power_ctrl {
+ bool ate_mode_enable;
+ bool percentage_ctrl_enable;
+ bool bf_backoff_enable;
++ u8 show_info_category;
+ u8 power_drop_level;
+ };
+ u8 band_idx;
+@@ -924,6 +925,7 @@ enum {
+ UNI_TXPOWER_BACKOFF_POWER_LIMIT_CTRL = 3,
+ UNI_TXPOWER_POWER_LIMIT_TABLE_CTRL = 4,
+ UNI_TXPOWER_ATE_MODE_CTRL = 6,
++ UNI_TXPOWER_SHOW_INFO = 7,
+ };
+
+ enum {
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 6cb6c724..a1a30b33 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -305,6 +305,9 @@ struct mt7996_phy {
+
+ struct mt7996_scs_ctrl scs_ctrl;
+
++ bool sku_limit_en;
++ bool sku_path_en;
++
+ #ifdef CONFIG_NL80211_TESTMODE
+ struct {
+ u32 *reg_backup;
+@@ -648,6 +651,7 @@ int mt7996_mcu_apply_tx_dpd(struct mt7996_phy *phy);
+ #ifdef CONFIG_NL80211_TESTMODE
+ void mt7996_tm_rf_test_event(struct mt7996_dev *dev, struct sk_buff *skb);
+ #endif
++int mt7996_mcu_get_tx_power_info(struct mt7996_phy *phy, u8 category, void *event);
+ int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable);
+ void mt7996_mcu_scs_sta_poll(struct work_struct *work);
+
+diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
+index 1807a744..ad89eccd 100644
+--- a/mt7996/mtk_debugfs.c
++++ b/mt7996/mtk_debugfs.c
+@@ -2439,6 +2439,364 @@ mt7996_scs_enable_set(void *data, u64 val)
+ DEFINE_DEBUGFS_ATTRIBUTE(fops_scs_enable, NULL,
+ mt7996_scs_enable_set, "%lld\n");
+
++static int
++mt7996_txpower_level_set(void *data, u64 val)
++{
++ struct mt7996_phy *phy = data;
++ int ret;
++
++ if (val > 100)
++ return -EINVAL;
++
++ ret = mt7996_mcu_set_tx_power_ctrl(phy, UNI_TXPOWER_PERCENTAGE_CTRL, !!val);
++ if (ret)
++ return ret;
++
++ return mt7996_mcu_set_tx_power_ctrl(phy, UNI_TXPOWER_PERCENTAGE_DROP_CTRL, val);
++}
++
++DEFINE_DEBUGFS_ATTRIBUTE(fops_txpower_level, NULL,
++ mt7996_txpower_level_set, "%lld\n");
++
++static ssize_t
++mt7996_get_txpower_info(struct file *file, char __user *user_buf,
++ size_t count, loff_t *ppos)
++{
++ struct mt7996_phy *phy = file->private_data;
++ struct mt7996_mcu_txpower_event *event;
++ struct txpower_basic_info *basic_info;
++ struct device_node *np;
++ static const size_t size = 2048;
++ int len = 0;
++ ssize_t ret;
++ char *buf;
++
++ buf = kzalloc(size, GFP_KERNEL);
++ event = kzalloc(sizeof(*event), GFP_KERNEL);
++ if (!buf || !event) {
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ ret = mt7996_mcu_get_tx_power_info(phy, BASIC_INFO, event);
++ if (ret ||
++ le32_to_cpu(event->basic_info.category) != UNI_TXPOWER_BASIC_INFO)
++ goto out;
++
++ basic_info = &event->basic_info;
++
++ len += scnprintf(buf + len, size - len,
++ "======================== BASIC INFO ========================\n");
++ len += scnprintf(buf + len, size - len, " Band Index: %d, Channel Band: %d\n",
++ basic_info->band_idx, basic_info->band);
++ len += scnprintf(buf + len, size - len, " PA Type: %s\n",
++ basic_info->is_epa ? "ePA" : "iPA");
++ len += scnprintf(buf + len, size - len, " LNA Type: %s\n",
++ basic_info->is_elna ? "eLNA" : "iLNA");
++
++ len += scnprintf(buf + len, size - len,
++ "------------------------------------------------------------\n");
++ len += scnprintf(buf + len, size - len, " SKU: %s\n",
++ basic_info->sku_enable ? "enable" : "disable");
++ len += scnprintf(buf + len, size - len, " Percentage Control: %s\n",
++ basic_info->percentage_ctrl_enable ? "enable" : "disable");
++ len += scnprintf(buf + len, size - len, " Power Drop: %d [dBm]\n",
++ basic_info->power_drop_level >> 1);
++ len += scnprintf(buf + len, size - len, " Backoff: %s\n",
++ basic_info->bf_backoff_enable ? "enable" : "disable");
++ len += scnprintf(buf + len, size - len, " TX Front-end Loss: %d, %d, %d, %d\n",
++ basic_info->front_end_loss_tx[0], basic_info->front_end_loss_tx[1],
++ basic_info->front_end_loss_tx[2], basic_info->front_end_loss_tx[3]);
++ len += scnprintf(buf + len, size - len, " RX Front-end Loss: %d, %d, %d, %d\n",
++ basic_info->front_end_loss_rx[0], basic_info->front_end_loss_rx[1],
++ basic_info->front_end_loss_rx[2], basic_info->front_end_loss_rx[3]);
++ len += scnprintf(buf + len, size - len,
++ " MU TX Power Mode: %s\n",
++ basic_info->mu_tx_power_manual_enable ? "manual" : "auto");
++ len += scnprintf(buf + len, size - len,
++ " MU TX Power (Auto / Manual): %d / %d [0.5 dBm]\n",
++ basic_info->mu_tx_power_auto, basic_info->mu_tx_power_manual);
++ len += scnprintf(buf + len, size - len,
++ " Thermal Compensation: %s\n",
++ basic_info->thermal_compensate_enable ? "enable" : "disable");
++ len += scnprintf(buf + len, size - len,
++ " Theraml Compensation Value: %d\n",
++ basic_info->thermal_compensate_value);
++ np = mt76_find_power_limits_node(phy->mt76->dev);
++ len += scnprintf(buf + len, size - len,
++ " RegDB: %s\n",
++ !np ? "enable" : "disable");
++ ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
++
++out:
++ kfree(buf);
++ kfree(event);
++ return ret;
++}
++
++static const struct file_operations mt7996_txpower_info_fops = {
++ .read = mt7996_get_txpower_info,
++ .open = simple_open,
++ .owner = THIS_MODULE,
++ .llseek = default_llseek,
++};
++
++#define mt7996_txpower_puts(rate, _len) \
++({ \
++ len += scnprintf(buf + len, size - len, "%-*s:", _len, #rate " (TMAC)"); \
++ for (i = 0; i < mt7996_sku_group_len[SKU_##rate]; i++, offs++) \
++ len += scnprintf(buf + len, size - len, " %6d", \
++ event->phy_rate_info.frame_power[offs][band_idx]); \
++ len += scnprintf(buf + len, size - len, "\n"); \
++})
++
++static ssize_t
++mt7996_get_txpower_sku(struct file *file, char __user *user_buf,
++ size_t count, loff_t *ppos)
++{
++ struct mt7996_phy *phy = file->private_data;
++ struct mt7996_dev *dev = phy->dev;
++ struct mt7996_mcu_txpower_event *event;
++ struct ieee80211_channel *chan = phy->mt76->chandef.chan;
++ struct ieee80211_supported_band sband;
++ u8 band_idx = phy->mt76->band_idx;
++ static const size_t size = 5120;
++ int i, offs = 0, len = 0;
++ u32 target_power = 0;
++ int n_chains = hweight16(phy->mt76->chainmask);
++ int nss_delta = mt76_tx_power_nss_delta(n_chains);
++ int pwr_delta;
++ ssize_t ret;
++ char *buf;
++ u32 reg;
++
++ buf = kzalloc(size, GFP_KERNEL);
++ event = kzalloc(sizeof(*event), GFP_KERNEL);
++ if (!buf || !event) {
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ ret = mt7996_mcu_get_tx_power_info(phy, PHY_RATE_INFO, event);
++ if (ret ||
++ le32_to_cpu(event->phy_rate_info.category) != UNI_TXPOWER_PHY_RATE_INFO)
++ goto out;
++
++ len += scnprintf(buf + len, size - len,
++ "\nPhy %d TX Power Table (Channel %d)\n",
++ band_idx, phy->mt76->chandef.chan->hw_value);
++ len += scnprintf(buf + len, size - len, "%-21s %6s %6s %6s %6s\n",
++ " ", "1m", "2m", "5m", "11m");
++ mt7996_txpower_puts(CCK, 21);
++
++ len += scnprintf(buf + len, size - len,
++ "%-21s %6s %6s %6s %6s %6s %6s %6s %6s\n",
++ " ", "6m", "9m", "12m", "18m", "24m", "36m", "48m",
++ "54m");
++ mt7996_txpower_puts(OFDM, 21);
++
++ len += scnprintf(buf + len, size - len,
++ "%-21s %6s %6s %6s %6s %6s %6s %6s %6s\n",
++ " ", "mcs0", "mcs1", "mcs2", "mcs3", "mcs4",
++ "mcs5", "mcs6", "mcs7");
++ mt7996_txpower_puts(HT20, 21);
++
++ len += scnprintf(buf + len, size - len,
++ "%-21s %6s %6s %6s %6s %6s %6s %6s %6s %6s\n",
++ " ", "mcs0", "mcs1", "mcs2", "mcs3", "mcs4", "mcs5",
++ "mcs6", "mcs7", "mcs32");
++ mt7996_txpower_puts(HT40, 21);
++
++ len += scnprintf(buf + len, size - len,
++ "%-21s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s\n",
++ " ", "mcs0", "mcs1", "mcs2", "mcs3", "mcs4", "mcs5",
++ "mcs6", "mcs7", "mcs8", "mcs9", "mcs10", "mcs11");
++ mt7996_txpower_puts(VHT20, 21);
++ mt7996_txpower_puts(VHT40, 21);
++ mt7996_txpower_puts(VHT80, 21);
++ mt7996_txpower_puts(VHT160, 21);
++ mt7996_txpower_puts(HE26, 21);
++ mt7996_txpower_puts(HE52, 21);
++ mt7996_txpower_puts(HE106, 21);
++ len += scnprintf(buf + len, size - len, "BW20/");
++ mt7996_txpower_puts(HE242, 16);
++ len += scnprintf(buf + len, size - len, "BW40/");
++ mt7996_txpower_puts(HE484, 16);
++ len += scnprintf(buf + len, size - len, "BW80/");
++ mt7996_txpower_puts(HE996, 16);
++ len += scnprintf(buf + len, size - len, "BW160/");
++ mt7996_txpower_puts(HE2x996, 15);
++
++ len += scnprintf(buf + len, size - len,
++ "%-21s %6s %6s %6s %6s %6s %6s %6s %6s ",
++ " ", "mcs0", "mcs1", "mcs2", "mcs3", "mcs4", "mcs5", "mcs6", "mcs7");
++ len += scnprintf(buf + len, size - len,
++ "%6s %6s %6s %6s %6s %6s %6s %6s\n",
++ "mcs8", "mcs9", "mcs10", "mcs11", "mcs12", "mcs13", "mcs14", "mcs15");
++ mt7996_txpower_puts(EHT26, 21);
++ mt7996_txpower_puts(EHT52, 21);
++ mt7996_txpower_puts(EHT106, 21);
++ len += scnprintf(buf + len, size - len, "BW20/");
++ mt7996_txpower_puts(EHT242, 16);
++ len += scnprintf(buf + len, size - len, "BW40/");
++ mt7996_txpower_puts(EHT484, 16);
++ len += scnprintf(buf + len, size - len, "BW80/");
++ mt7996_txpower_puts(EHT996, 16);
++ len += scnprintf(buf + len, size - len, "BW160/");
++ mt7996_txpower_puts(EHT2x996, 15);
++ len += scnprintf(buf + len, size - len, "BW320/");
++ mt7996_txpower_puts(EHT4x996, 15);
++ mt7996_txpower_puts(EHT26_52, 21);
++ mt7996_txpower_puts(EHT26_106, 21);
++ mt7996_txpower_puts(EHT484_242, 21);
++ mt7996_txpower_puts(EHT996_484, 21);
++ mt7996_txpower_puts(EHT996_484_242, 21);
++ mt7996_txpower_puts(EHT2x996_484, 21);
++ mt7996_txpower_puts(EHT3x996, 21);
++ mt7996_txpower_puts(EHT3x996_484, 21);
++
++ len += scnprintf(buf + len, size - len, "\nePA Gain: %d\n",
++ event->phy_rate_info.epa_gain);
++ len += scnprintf(buf + len, size - len, "Max Power Bound: %d\n",
++ event->phy_rate_info.max_power_bound);
++ len += scnprintf(buf + len, size - len, "Min Power Bound: %d\n",
++ event->phy_rate_info.min_power_bound);
++
++ reg = MT_WF_PHYDFE_TSSI_TXCTRL01(band_idx);
++ len += scnprintf(buf + len, size - len,
++ "\nBBP TX Power (target power from TMAC) : %6ld [0.5 dBm]\n",
++ mt76_get_field(dev, reg, MT_WF_PHYDFE_TSSI_TXCTRL_POWER_TMAC));
++ len += scnprintf(buf + len, size - len,
++ "RegDB maximum power:\t%d [dBm]\n",
++ chan->max_reg_power);
++
++ if (chan->band == NL80211_BAND_2GHZ)
++ sband = phy->mt76->sband_2g.sband;
++ else if (chan->band == NL80211_BAND_5GHZ)
++ sband = phy->mt76->sband_5g.sband;
++ else if (chan->band == NL80211_BAND_6GHZ)
++ sband = phy->mt76->sband_6g.sband;
++
++ pwr_delta = mt7996_eeprom_get_power_delta(dev, sband.band);
++
++ target_power = max_t(u32, target_power, mt7996_eeprom_get_target_power(dev, chan));
++ target_power += pwr_delta + nss_delta;
++ target_power = DIV_ROUND_UP(target_power, 2);
++ len += scnprintf(buf + len, size - len,
++ "eeprom maximum power:\t%d [dBm]\n",
++ target_power);
++
++ len += scnprintf(buf + len, size - len,
++ "nss_delta:\t%d [0.5 dBm]\n",
++ nss_delta);
++
++ ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
++
++out:
++ kfree(buf);
++ kfree(event);
++ return ret;
++}
++
++static const struct file_operations mt7996_txpower_sku_fops = {
++ .read = mt7996_get_txpower_sku,
++ .open = simple_open,
++ .owner = THIS_MODULE,
++ .llseek = default_llseek,
++};
++
++#define mt7996_txpower_path_puts(rate, arr_length) \
++({ \
++ len += scnprintf(buf + len, size - len, "%23s:", #rate " (TMAC)"); \
++ for (i = 0; i < arr_length; i++, offs++) \
++ len += scnprintf(buf + len, size - len, " %4d", \
++ event->backoff_table_info.frame_power[offs]); \
++ len += scnprintf(buf + len, size - len, "\n"); \
++})
++
++static ssize_t
++mt7996_get_txpower_path(struct file *file, char __user *user_buf,
++ size_t count, loff_t *ppos)
++{
++ struct mt7996_phy *phy = file->private_data;
++ struct mt7996_mcu_txpower_event *event;
++ static const size_t size = 5120;
++ int i, offs = 0, len = 0;
++ ssize_t ret;
++ char *buf;
++
++ buf = kzalloc(size, GFP_KERNEL);
++ event = kzalloc(sizeof(*event), GFP_KERNEL);
++ if (!buf || !event) {
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ ret = mt7996_mcu_get_tx_power_info(phy, BACKOFF_TABLE_INFO, event);
++ if (ret ||
++ le32_to_cpu(event->phy_rate_info.category) != UNI_TXPOWER_BACKOFF_TABLE_SHOW_INFO)
++ goto out;
++
++ len += scnprintf(buf + len, size - len, "\n%*c", 25, ' ');
++ len += scnprintf(buf + len, size - len, "1T1S/2T1S/3T1S/4T1S/5T1S/2T2S/3T2S/4T2S/5T2S/"
++ "3T3S/4T3S/5T3S/4T4S/5T4S/5T5S\n");
++
++ mt7996_txpower_path_puts(CCK, 5);
++ mt7996_txpower_path_puts(OFDM, 5);
++ mt7996_txpower_path_puts(BF-OFDM, 4);
++
++ mt7996_txpower_path_puts(RU26, 15);
++ mt7996_txpower_path_puts(BF-RU26, 15);
++ mt7996_txpower_path_puts(RU52, 15);
++ mt7996_txpower_path_puts(BF-RU52, 15);
++ mt7996_txpower_path_puts(RU26_52, 15);
++ mt7996_txpower_path_puts(BF-RU26_52, 15);
++ mt7996_txpower_path_puts(RU106, 15);
++ mt7996_txpower_path_puts(BF-RU106, 15);
++ mt7996_txpower_path_puts(RU106_52, 15);
++ mt7996_txpower_path_puts(BF-RU106_52, 15);
++
++ mt7996_txpower_path_puts(BW20/RU242, 15);
++ mt7996_txpower_path_puts(BF-BW20/RU242, 15);
++ mt7996_txpower_path_puts(BW40/RU484, 15);
++ mt7996_txpower_path_puts(BF-BW40/RU484, 15);
++ mt7996_txpower_path_puts(RU242_484, 15);
++ mt7996_txpower_path_puts(BF-RU242_484, 15);
++ mt7996_txpower_path_puts(BW80/RU996, 15);
++ mt7996_txpower_path_puts(BF-BW80/RU996, 15);
++ mt7996_txpower_path_puts(RU484_996, 15);
++ mt7996_txpower_path_puts(BF-RU484_996, 15);
++ mt7996_txpower_path_puts(RU242_484_996, 15);
++ mt7996_txpower_path_puts(BF-RU242_484_996, 15);
++ mt7996_txpower_path_puts(BW160/RU996x2, 15);
++ mt7996_txpower_path_puts(BF-BW160/RU996x2, 15);
++ mt7996_txpower_path_puts(RU484_996x2, 15);
++ mt7996_txpower_path_puts(BF-RU484_996x2, 15);
++ mt7996_txpower_path_puts(RU996x3, 15);
++ mt7996_txpower_path_puts(BF-RU996x3, 15);
++ mt7996_txpower_path_puts(RU484_996x3, 15);
++ mt7996_txpower_path_puts(BF-RU484_996x3, 15);
++ mt7996_txpower_path_puts(BW320/RU996x4, 15);
++ mt7996_txpower_path_puts(BF-BW320/RU996x4, 15);
++
++ len += scnprintf(buf + len, size - len, "\nBackoff table: %s\n",
++ event->backoff_table_info.backoff_en ? "enable" : "disable");
++
++ ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
++
++out:
++ kfree(buf);
++ kfree(event);
++ return ret;
++}
++
++static const struct file_operations mt7996_txpower_path_fops = {
++ .read = mt7996_get_txpower_path,
++ .open = simple_open,
++ .owner = THIS_MODULE,
++ .llseek = default_llseek,
++};
++
+ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
+ {
+ struct mt7996_dev *dev = phy->dev;
+@@ -2503,6 +2861,11 @@ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
+ debugfs_create_devm_seqfile(dev->mt76.dev, "tr_info", dir,
+ mt7996_trinfo_read);
+
++ debugfs_create_file("txpower_level", 0600, dir, phy, &fops_txpower_level);
++ debugfs_create_file("txpower_info", 0600, dir, phy, &mt7996_txpower_info_fops);
++ debugfs_create_file("txpower_sku", 0600, dir, phy, &mt7996_txpower_sku_fops);
++ debugfs_create_file("txpower_path", 0600, dir, phy, &mt7996_txpower_path_fops);
++
+ debugfs_create_devm_seqfile(dev->mt76.dev, "wtbl_info", dir,
+ mt7996_wtbl_read);
+
+diff --git a/mt7996/mtk_mcu.c b/mt7996/mtk_mcu.c
+index c16b25ab..e56ddd8f 100644
+--- a/mt7996/mtk_mcu.c
++++ b/mt7996/mtk_mcu.c
+@@ -12,8 +12,31 @@
+
+ #ifdef CONFIG_MTK_DEBUG
+
++int mt7996_mcu_get_tx_power_info(struct mt7996_phy *phy, u8 category, void *event)
++{
++ struct mt7996_dev *dev = phy->dev;
++ struct tx_power_ctrl req = {
++ .tag = cpu_to_le16(UNI_TXPOWER_SHOW_INFO),
++ .len = cpu_to_le16(sizeof(req) - 4),
++ .power_ctrl_id = UNI_TXPOWER_SHOW_INFO,
++ .show_info_category = category,
++ .band_idx = phy->mt76->band_idx,
++ };
++ struct sk_buff *skb;
++ int ret;
+
++ ret = mt76_mcu_send_and_get_msg(&dev->mt76,
++ MCU_WM_UNI_CMD_QUERY(TXPOWER),
++ &req, sizeof(req), true, &skb);
++ if (ret)
++ return ret;
+
++ memcpy(event, skb->data, sizeof(struct mt7996_mcu_txpower_event));
++
++ dev_kfree_skb(skb);
++
++ return 0;
++}
+
+ int mt7996_mcu_muru_dbg_info(struct mt7996_dev *dev, u16 item, u8 val)
+ {
+diff --git a/mt7996/mtk_mcu.h b/mt7996/mtk_mcu.h
+index 7f4d4e02..c30418ca 100644
+--- a/mt7996/mtk_mcu.h
++++ b/mt7996/mtk_mcu.h
+@@ -14,6 +14,98 @@ enum {
+ UNI_CMD_MURU_DBG_INFO = 0x18,
+ };
+
++struct txpower_basic_info {
++ u8 category;
++ u8 rsv1;
++
++ /* basic info */
++ u8 band_idx;
++ u8 band;
++
++ /* board type info */
++ bool is_epa;
++ bool is_elna;
++
++ /* power percentage info */
++ bool percentage_ctrl_enable;
++ s8 power_drop_level;
++
++ /* frond-end loss TX info */
++ s8 front_end_loss_tx[4];
++
++ /* frond-end loss RX info */
++ s8 front_end_loss_rx[4];
++
++ /* thermal info */
++ bool thermal_compensate_enable;
++ s8 thermal_compensate_value;
++ u8 rsv2;
++
++ /* TX power max/min limit info */
++ s8 max_power_bound;
++ s8 min_power_bound;
++
++ /* power limit info */
++ bool sku_enable;
++ bool bf_backoff_enable;
++
++ /* MU TX power info */
++ bool mu_tx_power_manual_enable;
++ s8 mu_tx_power_auto;
++ s8 mu_tx_power_manual;
++ u8 rsv3;
++};
++
++struct txpower_phy_rate_info {
++ u8 category;
++ u8 band_idx;
++ u8 band;
++ u8 epa_gain;
++
++ /* rate power info [dBm] */
++ s8 frame_power[MT7996_SKU_RATE_NUM][__MT_MAX_BAND];
++
++ /* TX power max/min limit info */
++ s8 max_power_bound;
++ s8 min_power_bound;
++ u8 rsv1;
++};
++
++struct txpower_backoff_table_info {
++ u8 category;
++ u8 band_idx;
++ u8 band;
++ u8 backoff_en;
++
++ s8 frame_power[MT7996_SKU_PATH_NUM];
++ u8 rsv[3];
++};
++
++struct mt7996_mcu_txpower_event {
++ u8 _rsv[4];
++
++ __le16 tag;
++ __le16 len;
++
++ union {
++ struct txpower_basic_info basic_info;
++ struct txpower_phy_rate_info phy_rate_info;
++ struct txpower_backoff_table_info backoff_table_info;
++ };
++};
++
++enum txpower_category {
++ BASIC_INFO,
++ BACKOFF_TABLE_INFO,
++ PHY_RATE_INFO,
++};
++
++enum txpower_event {
++ UNI_TXPOWER_BASIC_INFO = 0,
++ UNI_TXPOWER_BACKOFF_TABLE_SHOW_INFO = 3,
++ UNI_TXPOWER_PHY_RATE_INFO = 5,
++};
++
+ #endif
+
+ #endif
+diff --git a/mt7996/regs.h b/mt7996/regs.h
+index 3450a2fc..539e799c 100644
+--- a/mt7996/regs.h
++++ b/mt7996/regs.h
+@@ -695,24 +695,29 @@ enum offs_rev {
+ ((_wf) << 16) + (ofs))
+ #define MT_WF_PHYRX_CSD_IRPI(_band, _wf) MT_WF_PHYRX_CSD(_band, _wf, 0x1000)
+
+-/* PHYRX CTRL */
+-#define MT_WF_PHYRX_BAND_BASE 0x83080000
+-#define MT_WF_PHYRX_BAND(_band, ofs) (MT_WF_PHYRX_BAND_BASE + \
++/* PHYDFE CTRL */
++#define MT_WF_PHYDFE_TSSI_TXCTRL01(_band) MT_WF_PHYRX_CSD(_band, 0, 0xc718)
++#define MT_WF_PHYDFE_TSSI_TXCTRL_POWER_TMAC GENMASK(31, 24)
++
++/* PHY CTRL */
++#define MT_WF_PHY_BAND_BASE 0x83080000
++#define MT_WF_PHY_BAND(_band, ofs) (MT_WF_PHY_BAND_BASE + \
+ ((_band) << 20) + (ofs))
+
+-#define MT_WF_PHYRX_BAND_GID_TAB_VLD0(_band) MT_WF_PHYRX_BAND(_band, 0x1054)
+-#define MT_WF_PHYRX_BAND_GID_TAB_VLD1(_band) MT_WF_PHYRX_BAND(_band, 0x1058)
+-#define MT_WF_PHYRX_BAND_GID_TAB_POS0(_band) MT_WF_PHYRX_BAND(_band, 0x105c)
+-#define MT_WF_PHYRX_BAND_GID_TAB_POS1(_band) MT_WF_PHYRX_BAND(_band, 0x1060)
+-#define MT_WF_PHYRX_BAND_GID_TAB_POS2(_band) MT_WF_PHYRX_BAND(_band, 0x1064)
+-#define MT_WF_PHYRX_BAND_GID_TAB_POS3(_band) MT_WF_PHYRX_BAND(_band, 0x1068)
++#define MT_WF_PHYRX_BAND_GID_TAB_VLD0(_band) MT_WF_PHY_BAND(_band, 0x1054)
++#define MT_WF_PHYRX_BAND_GID_TAB_VLD1(_band) MT_WF_PHY_BAND(_band, 0x1058)
++#define MT_WF_PHYRX_BAND_GID_TAB_POS0(_band) MT_WF_PHY_BAND(_band, 0x105c)
++#define MT_WF_PHYRX_BAND_GID_TAB_POS1(_band) MT_WF_PHY_BAND(_band, 0x1060)
++#define MT_WF_PHYRX_BAND_GID_TAB_POS2(_band) MT_WF_PHY_BAND(_band, 0x1064)
++#define MT_WF_PHYRX_BAND_GID_TAB_POS3(_band) MT_WF_PHY_BAND(_band, 0x1068)
+
+-#define MT_WF_PHYRX_BAND_RX_CTRL1(_band) MT_WF_PHYRX_BAND(_band, 0x2004)
++/* PHYRX CTRL */
++#define MT_WF_PHYRX_BAND_RX_CTRL1(_band) MT_WF_PHY_BAND(_band, 0x2004)
+ #define MT_WF_PHYRX_BAND_RX_CTRL1_IPI_EN GENMASK(2, 0)
+ #define MT_WF_PHYRX_BAND_RX_CTRL1_STSCNT_EN GENMASK(11, 9)
+
+ /* PHYRX CSD BAND */
+-#define MT_WF_PHYRX_CSD_BAND_RXTD12(_band) MT_WF_PHYRX_BAND(_band, 0x8230)
++#define MT_WF_PHYRX_CSD_BAND_RXTD12(_band) MT_WF_PHY_BAND(_band, 0x8230)
+ #define MT_WF_PHYRX_CSD_BAND_RXTD12_IRPI_SW_CLR_ONLY BIT(18)
+ #define MT_WF_PHYRX_CSD_BAND_RXTD12_IRPI_SW_CLR BIT(29)
+
+--
+2.45.2
+