[rdkb][common][bsp][Refactor and sync wifi from openwrt]
[Description]
d34487c3 [MAC80211][WiFi6][mt76][Add mt7981 mt7916 mt7915 fw_wm_info support]
327eaf76 [MAC80211][wifi7][Release][Update WiFi7 Filogic680/660 Firmware]
fa03d7ea [MAC80211][WiFi6][hostapd][Fix 2/6G channel switch fail issue]
c0bf67d9 [MAC80211][misc][Add Filogic 880 Non-MLO SDK Release]
e5d03217 [MAC80211][WiFi6][Rebase Patches][Refactor set_offchan_ctrl]
6cad79ae [MAC80211][WiFi6][hostapd][Add support for DFS channel switch with CSA sent]
cde50012 [MAC80211][WiFi6][core][Add DFS channel CSA flow]
0142fd16 [MAC80211][WiFi6][mt76][Add post channel switch callback for DFS channel switch support]
cb3f4c58 [MAC80211][WiFi6][mt76][Update Connac2 CSI Feature]
1b66ac4c [MAC80211][WiFi6][mt76][Refactor precal loading and binfile mode to align upstream]
0ece467b [MAC80211][WiFi6][mt76][Fix scs feature calltrace issue]
1dca03f1 [MAC80211][WiFi6/7][Misc][Change group mgmt cipher setting to align group cipher]
0aa52762 [MAC80211][WiFi6][mt76][Fix muru_onoff as all enabled by default]
c3e5f505 [MAC80211][WiFi6][hostapd][Fix mu_onoff was overwritten with unexpected values]
7090eabe [MAC80211][WiFi6/7][core][Add tx_burst option in wireless configuration file for Kite]
669d3071 [MAC80211][WiFi6][mt76][rebase patches]
c5d6b3e7 [mac80211][mt76][Fix patch fail]
55ef4059 [MAC80211][WiFi6][mt76][Fix TxS ACK is incorrectly reported]
e166eae1 [MAC80211][WiFi6][Misc][Add Filogic 820 Build]
118ffd7e [mac80211][wifi6][mt76][Fix crash caused by per-BSS counter updating]
68015098 [MAC80211][WiFi7][mt76][Add Eagle 2adie TBTC default bin]
eae6e8c0 [MAC80211][WiFi7][mt76][Add Eagle 2adie TBTC support in mt76 Makefile]
cccc8eb9 [MAC80211[WiFi6][hostapd][Fix wds AP interface adding issue]
173fe3b0 [MAC80211][WiFi6][mt76][Add scs feature for connac2 mt76]
1b8af8d9 [MAC80211][WiFi6][mt76][rebase patches]
6dc40325 [MAC80211][WiFi7][misc][fix hostapd udebug init fail]
aa4b39ae [[mt76][csi][mt7915][mt7986] update csi feature]
7d458da2 [MAC80211][WiFi6][hostapd][Auto Channel Selection channel time issue]
f0b5502f [MAC80211][WiFi7][misc][fix build error]
b63c9cf6 [MAC80211][WiFi6/7][misc][fix ucode and backport 6.5 patch fail]
ce056dc7 [mac80211][wifi6][mt76][Add variant support for Cheetah MT76]
c5ae3f9c [MAC80211][WiFi6/7][Misc][Add country setting consistent check before enable AP.]
d57d9c5a [mac80211][misc][wifi6/7][Update libubox to the latest version]
be7dbf21 [mac80211][misc][wifi7][Revert libubox to 20230523 to prevent build fail]
ae9b4428 [MAC80211][WiFi6][mt76][Add cal free data support]
52fd5d80 [MAC80211][WiFi7][Misc][Adjust MU EDCA timer in mac80211.sh]
66c649de [mac80211][hostapd][netifd][Revert udebug for build pass]
136c7f11 [MAC80211][hostapd][wifi7][Fix build fail]
8911e727 [MAC80211][WiFi6][hostapd][Auto Channel Selection issue and patch sync]
75161456 [MAC80211][WiFi7][mt76][Fix issue for testmode bit in eagle defaut bin]
4dc2d646 [MAC80211][WiFi6][mt76][Fix cheetah 5G ibf issue]
d4561158 [MAC80211][WiFi6][Misc][Add Filogic 820 Build]
2e5a1997 [MAC80211][WiFi6][hostapd][Backport hostapd ACS patches and some ACS fixes]
b0305b6e [MAC80211][WiFi6/7][Misc][Add 6g band default enable mbo IE]
[Release-log]
Change-Id: I872b422c1fc56ebd3a1cff3252cb403a2015eabe
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1037-mtk-wifi-mt76-testmode-add-kite-testmode-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1037-mtk-wifi-mt76-testmode-add-kite-testmode-support.patch
new file mode 100644
index 0000000..d3e9daf
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1037-mtk-wifi-mt76-testmode-add-kite-testmode-support.patch
@@ -0,0 +1,598 @@
+From 11a74db98d3f18b7d9ce7f2837079172a8b7d159 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Thu, 12 Oct 2023 16:17:33 +0800
+Subject: [PATCH 1037/1041] mtk: wifi: mt76: testmode: add kite testmode
+ support
+
+Add Kite testmode support
+1. avoid entering connac 2 testmode flow in kite
+2. refactor prek implementation for handling chip difference
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ mt7996/eeprom.c | 63 +++++++++++++-----------------
+ mt7996/eeprom.h | 81 +++++++++++++++++++++++++++------------
+ mt7996/mcu.c | 48 ++++++++++++++---------
+ mt7996/mt7996.h | 18 ++++++++-
+ mt7996/testmode.c | 97 ++++++++++++++++++++++++++++-------------------
+ testmode.c | 11 ++++--
+ 6 files changed, 198 insertions(+), 120 deletions(-)
+
+diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
+index cff1b875..9fef7035 100644
+--- a/mt7996/eeprom.c
++++ b/mt7996/eeprom.c
+@@ -29,12 +29,39 @@ const struct ieee80211_channel dpd_5g_skip_ch_list[] = {
+ CHAN5G(96, 5480)
+ };
+
++const struct ieee80211_channel dpd_5g_ch_list_bw80[] = {
++ CHAN5G(42, 5210),
++ CHAN5G(58, 5290),
++ CHAN5G(106, 5530),
++ CHAN5G(122, 5610),
++ CHAN5G(138, 5690),
++ CHAN5G(155, 5775),
++ CHAN5G(171, 5855)
++};
++
+ const struct ieee80211_channel dpd_5g_ch_list_bw160[] = {
+ CHAN5G(50, 5250),
+ CHAN5G(114, 5570),
+ CHAN5G(163, 5815)
+ };
+
++const struct ieee80211_channel dpd_6g_ch_list_bw80[] = {
++ CHAN6G(7, 5985),
++ CHAN6G(23, 6065),
++ CHAN6G(39, 6145),
++ CHAN6G(55, 6225),
++ CHAN6G(71, 6305),
++ CHAN6G(87, 6385),
++ CHAN6G(103, 6465),
++ CHAN6G(119, 6545),
++ CHAN6G(135, 6625),
++ CHAN6G(151, 6705),
++ CHAN6G(167, 6785),
++ CHAN6G(183, 6865),
++ CHAN6G(199, 6945),
++ CHAN6G(215, 7025)
++};
++
+ const struct ieee80211_channel dpd_6g_ch_list_bw160[] = {
+ CHAN6G(15, 6025),
+ CHAN6G(47, 6185),
+@@ -54,12 +81,6 @@ const struct ieee80211_channel dpd_6g_ch_list_bw320[] = {
+ CHAN6G(191, 6905)
+ };
+
+-const u32 dpd_2g_bw20_ch_num = ARRAY_SIZE(dpd_2g_ch_list_bw20);
+-const u32 dpd_5g_skip_ch_num = ARRAY_SIZE(dpd_5g_skip_ch_list);
+-const u32 dpd_5g_bw160_ch_num = ARRAY_SIZE(dpd_5g_ch_list_bw160);
+-const u32 dpd_6g_bw160_ch_num = ARRAY_SIZE(dpd_6g_ch_list_bw160);
+-const u32 dpd_6g_bw320_ch_num = ARRAY_SIZE(dpd_6g_ch_list_bw320);
+-
+ static int mt7996_check_eeprom(struct mt7996_dev *dev)
+ {
+ #define FEM_INT 0
+@@ -126,36 +147,6 @@ const char *mt7996_eeprom_name(struct mt7996_dev *dev)
+ }
+ }
+
+-int
+-mt7996_get_dpd_per_band_size(struct mt7996_dev *dev, enum nl80211_band band)
+-{
+- /* handle different sku */
+- static const u8 band_to_idx[] = {
+- [NL80211_BAND_2GHZ] = MT_BAND0,
+- [NL80211_BAND_5GHZ] = MT_BAND1,
+- [NL80211_BAND_6GHZ] = MT_BAND2,
+- };
+- struct mt7996_phy *phy = __mt7996_phy(dev, band_to_idx[band]);
+- struct mt76_phy *mphy;
+- int dpd_size;
+-
+- if (!phy)
+- return 0;
+-
+- mphy = phy->mt76;
+-
+- if (band == NL80211_BAND_2GHZ)
+- dpd_size = dpd_2g_bw20_ch_num * DPD_PER_CH_BW20_SIZE;
+- else if (band == NL80211_BAND_5GHZ)
+- dpd_size = (mphy->sband_5g.sband.n_channels - dpd_5g_skip_ch_num) *
+- DPD_PER_CH_BW20_SIZE + dpd_5g_bw160_ch_num * DPD_PER_CH_GT_BW20_SIZE;
+- else
+- dpd_size = mphy->sband_6g.sband.n_channels * DPD_PER_CH_BW20_SIZE +
+- (dpd_6g_bw160_ch_num + dpd_6g_bw320_ch_num) * DPD_PER_CH_GT_BW20_SIZE;
+-
+- return dpd_size;
+-}
+-
+ static int
+ mt7996_eeprom_load_default(struct mt7996_dev *dev)
+ {
+diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
+index 3e9992a3..0d05e75e 100644
+--- a/mt7996/eeprom.h
++++ b/mt7996/eeprom.h
+@@ -45,36 +45,69 @@ enum mt7996_eeprom_field {
+ #define MT_EE_WIFI_CAL_DPD GENMASK(5, 3)
+
+ #define MT_EE_CAL_UNIT 1024
+-#define MT_EE_CAL_GROUP_SIZE_2G (4 * MT_EE_CAL_UNIT)
+-#define MT_EE_CAL_GROUP_SIZE_5G (45 * MT_EE_CAL_UNIT)
+-#define MT_EE_CAL_GROUP_SIZE_6G (125 * MT_EE_CAL_UNIT)
+-#define MT_EE_CAL_ADCDCOC_SIZE_2G (4 * 4)
+-#define MT_EE_CAL_ADCDCOC_SIZE_5G (4 * 4)
+-#define MT_EE_CAL_ADCDCOC_SIZE_6G (4 * 5)
+-#define MT_EE_CAL_GROUP_SIZE (MT_EE_CAL_GROUP_SIZE_2G + \
+- MT_EE_CAL_GROUP_SIZE_5G + \
+- MT_EE_CAL_GROUP_SIZE_6G + \
+- MT_EE_CAL_ADCDCOC_SIZE_2G + \
+- MT_EE_CAL_ADCDCOC_SIZE_5G + \
+- MT_EE_CAL_ADCDCOC_SIZE_6G)
+-
+-#define DPD_PER_CH_LEGACY_SIZE (4 * MT_EE_CAL_UNIT)
+-#define DPD_PER_CH_MEM_SIZE (13 * MT_EE_CAL_UNIT)
+-#define DPD_PER_CH_OTFG0_SIZE (2 * MT_EE_CAL_UNIT)
+-#define DPD_PER_CH_BW20_SIZE (DPD_PER_CH_LEGACY_SIZE + DPD_PER_CH_OTFG0_SIZE)
+-#define DPD_PER_CH_GT_BW20_SIZE (DPD_PER_CH_MEM_SIZE + DPD_PER_CH_OTFG0_SIZE)
+-#define MT_EE_CAL_DPD_SIZE (780 * MT_EE_CAL_UNIT)
++
++enum mt7996_prek_rev {
++ GROUP_SIZE_2G,
++ GROUP_SIZE_5G,
++ GROUP_SIZE_6G,
++ ADCDCOC_SIZE_2G,
++ ADCDCOC_SIZE_5G,
++ ADCDCOC_SIZE_6G,
++ DPD_LEGACY_SIZE,
++ DPD_MEM_SIZE,
++ DPD_OTFG0_SIZE,
++};
++
++static const u32 mt7996_prek_rev[] = {
++ [GROUP_SIZE_2G] = 4 * MT_EE_CAL_UNIT,
++ [GROUP_SIZE_5G] = 45 * MT_EE_CAL_UNIT,
++ [GROUP_SIZE_6G] = 125 * MT_EE_CAL_UNIT,
++ [ADCDCOC_SIZE_2G] = 4 * 4,
++ [ADCDCOC_SIZE_5G] = 4 * 4,
++ [ADCDCOC_SIZE_6G] = 4 * 5,
++ [DPD_LEGACY_SIZE] = 4 * MT_EE_CAL_UNIT,
++ [DPD_MEM_SIZE] = 13 * MT_EE_CAL_UNIT,
++ [DPD_OTFG0_SIZE] = 2 * MT_EE_CAL_UNIT,
++};
++
++/* kite 2/5g config */
++static const u32 mt7992_prek_rev[] = {
++ [GROUP_SIZE_2G] = 4 * MT_EE_CAL_UNIT,
++ [GROUP_SIZE_5G] = 110 * MT_EE_CAL_UNIT,
++ [GROUP_SIZE_6G] = 0,
++ [ADCDCOC_SIZE_2G] = 4 * 4,
++ [ADCDCOC_SIZE_5G] = 4 * 5,
++ [ADCDCOC_SIZE_6G] = 0,
++ [DPD_LEGACY_SIZE] = 5 * MT_EE_CAL_UNIT,
++ [DPD_MEM_SIZE] = 16 * MT_EE_CAL_UNIT,
++ [DPD_OTFG0_SIZE] = 2 * MT_EE_CAL_UNIT,
++};
+
+ extern const struct ieee80211_channel dpd_2g_ch_list_bw20[];
+-extern const u32 dpd_2g_bw20_ch_num;
+ extern const struct ieee80211_channel dpd_5g_skip_ch_list[];
+-extern const u32 dpd_5g_skip_ch_num;
++extern const struct ieee80211_channel dpd_5g_ch_list_bw80[];
+ extern const struct ieee80211_channel dpd_5g_ch_list_bw160[];
+-extern const u32 dpd_5g_bw160_ch_num;
++extern const struct ieee80211_channel dpd_6g_ch_list_bw80[];
+ extern const struct ieee80211_channel dpd_6g_ch_list_bw160[];
+-extern const u32 dpd_6g_bw160_ch_num;
+ extern const struct ieee80211_channel dpd_6g_ch_list_bw320[];
+-extern const u32 dpd_6g_bw320_ch_num;
++
++#define PREK(id) (dev->prek.rev[(id)])
++#define DPD_CH_NUM(_type) (dev->prek.dpd_ch_num[DPD_CH_NUM_##_type])
++#define MT_EE_CAL_GROUP_SIZE (PREK(GROUP_SIZE_2G) + PREK(GROUP_SIZE_5G) + \
++ PREK(GROUP_SIZE_6G) + PREK(ADCDCOC_SIZE_2G) + \
++ PREK(ADCDCOC_SIZE_5G) + PREK(ADCDCOC_SIZE_6G))
++#define DPD_PER_CH_BW20_SIZE (PREK(DPD_LEGACY_SIZE) + PREK(DPD_OTFG0_SIZE))
++#define DPD_PER_CH_GT_BW20_SIZE (PREK(DPD_MEM_SIZE) + PREK(DPD_OTFG0_SIZE))
++#define MT_EE_CAL_DPD_SIZE_2G (DPD_CH_NUM(BW20_2G) * DPD_PER_CH_BW20_SIZE)
++#define MT_EE_CAL_DPD_SIZE_5G (DPD_CH_NUM(BW20_5G) * DPD_PER_CH_BW20_SIZE + \
++ DPD_CH_NUM(BW80_5G) * DPD_PER_CH_GT_BW20_SIZE + \
++ DPD_CH_NUM(BW160_5G) * DPD_PER_CH_GT_BW20_SIZE)
++#define MT_EE_CAL_DPD_SIZE_6G (DPD_CH_NUM(BW20_6G) * DPD_PER_CH_BW20_SIZE + \
++ DPD_CH_NUM(BW80_6G) * DPD_PER_CH_GT_BW20_SIZE + \
++ DPD_CH_NUM(BW160_6G) * DPD_PER_CH_GT_BW20_SIZE + \
++ DPD_CH_NUM(BW320_6G) * DPD_PER_CH_GT_BW20_SIZE)
++#define MT_EE_CAL_DPD_SIZE (MT_EE_CAL_DPD_SIZE_2G + MT_EE_CAL_DPD_SIZE_5G + \
++ MT_EE_CAL_DPD_SIZE_6G)
+
+ #define RF_DPD_FLAT_CAL BIT(28)
+ #define RF_PRE_CAL BIT(29)
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 4598d815..a049ab71 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -3744,13 +3744,11 @@ int mt7996_mcu_apply_tx_dpd(struct mt7996_phy *phy)
+ enum nl80211_chan_width bw = chandef->width;
+ const struct ieee80211_channel *chan_list;
+ u32 cal_id, chan_list_size, base_offset = 0, offs = MT_EE_DO_PRE_CAL;
+- u32 dpd_size_2g, dpd_size_5g, per_chan_size = DPD_PER_CH_BW20_SIZE;
++ u32 per_chan_size = DPD_PER_CH_BW20_SIZE;
+ u16 channel = ieee80211_frequency_to_channel(chandef->center_freq1);
+ u8 dpd_mask, *cal = dev->cal, *eeprom = dev->mt76.eeprom.data;
+ int idx, i, ret;
+-
+- dpd_size_2g = mt7996_get_dpd_per_band_size(dev, NL80211_BAND_2GHZ);
+- dpd_size_5g = mt7996_get_dpd_per_band_size(dev, NL80211_BAND_5GHZ);
++ bool has_skip_ch = (band == NL80211_BAND_5GHZ);
+
+ switch (band) {
+ case NL80211_BAND_2GHZ:
+@@ -3766,27 +3764,35 @@ int mt7996_mcu_apply_tx_dpd(struct mt7996_phy *phy)
+ return 0;
+ cal_id = RF_DPD_FLAT_CAL;
+ chan_list = dpd_2g_ch_list_bw20;
+- chan_list_size = dpd_2g_bw20_ch_num;
++ chan_list_size = DPD_CH_NUM(BW20_2G);
+ break;
+ case NL80211_BAND_5GHZ:
+ dpd_mask = MT_EE_WIFI_CAL_DPD_5G;
+ cal_id = RF_DPD_FLAT_5G_CAL;
+ chan_list = mphy->sband_5g.sband.channels;
+ chan_list_size = mphy->sband_5g.sband.n_channels;
+- base_offset += dpd_size_2g;
++ base_offset += MT_EE_CAL_DPD_SIZE_2G;
+ if (bw == NL80211_CHAN_WIDTH_160) {
+- base_offset += (mphy->sband_5g.sband.n_channels - dpd_5g_skip_ch_num) *
+- DPD_PER_CH_BW20_SIZE;
++ base_offset += DPD_CH_NUM(BW20_5G) * DPD_PER_CH_BW20_SIZE +
++ DPD_CH_NUM(BW80_5G) * DPD_PER_CH_GT_BW20_SIZE;
+ per_chan_size = DPD_PER_CH_GT_BW20_SIZE;
+ cal_id = RF_DPD_FLAT_5G_MEM_CAL;
+ chan_list = dpd_5g_ch_list_bw160;
+- chan_list_size = dpd_5g_bw160_ch_num;
++ chan_list_size = DPD_CH_NUM(BW160_5G);
++ has_skip_ch = false;
++ } else if (is_mt7992(&dev->mt76) && bw == NL80211_CHAN_WIDTH_80) {
++ base_offset += DPD_CH_NUM(BW20_5G) * DPD_PER_CH_BW20_SIZE;
++ per_chan_size = DPD_PER_CH_GT_BW20_SIZE;
++ cal_id = RF_DPD_FLAT_5G_MEM_CAL;
++ chan_list = dpd_5g_ch_list_bw80;
++ chan_list_size = DPD_CH_NUM(BW80_5G);
++ has_skip_ch = false;
+ } else if (bw > NL80211_CHAN_WIDTH_20) {
+ /* apply (center channel - 2)'s dpd cal data for bw 40/80 channels */
+ channel -= 2;
+ }
+ if (channel >= dpd_5g_skip_ch_list[0].hw_value &&
+- channel <= dpd_5g_skip_ch_list[dpd_5g_skip_ch_num - 1].hw_value)
++ channel <= dpd_5g_skip_ch_list[DPD_CH_NUM(BW20_5G_SKIP) - 1].hw_value)
+ return 0;
+ break;
+ case NL80211_BAND_6GHZ:
+@@ -3794,20 +3800,27 @@ int mt7996_mcu_apply_tx_dpd(struct mt7996_phy *phy)
+ cal_id = RF_DPD_FLAT_6G_CAL;
+ chan_list = mphy->sband_6g.sband.channels;
+ chan_list_size = mphy->sband_6g.sband.n_channels;
+- base_offset += dpd_size_2g + dpd_size_5g;
++ base_offset += MT_EE_CAL_DPD_SIZE_2G + MT_EE_CAL_DPD_SIZE_5G;
+ if (bw == NL80211_CHAN_WIDTH_160) {
+ base_offset += mphy->sband_6g.sband.n_channels * DPD_PER_CH_BW20_SIZE;
+ per_chan_size = DPD_PER_CH_GT_BW20_SIZE;
+ cal_id = RF_DPD_FLAT_6G_MEM_CAL;
+ chan_list = dpd_6g_ch_list_bw160;
+- chan_list_size = dpd_6g_bw160_ch_num;
+- } else if (bw == NL80211_CHAN_WIDTH_320) {
++ chan_list_size = DPD_CH_NUM(BW160_6G);
++ } else if (is_mt7996(&dev->mt76) && bw == NL80211_CHAN_WIDTH_320) {
+ base_offset += mphy->sband_6g.sband.n_channels * DPD_PER_CH_BW20_SIZE +
+- dpd_6g_bw160_ch_num * DPD_PER_CH_GT_BW20_SIZE;
++ DPD_CH_NUM(BW80_6G) * DPD_PER_CH_GT_BW20_SIZE +
++ DPD_CH_NUM(BW160_6G) * DPD_PER_CH_GT_BW20_SIZE;
+ per_chan_size = DPD_PER_CH_GT_BW20_SIZE;
+ cal_id = RF_DPD_FLAT_6G_MEM_CAL;
+ chan_list = dpd_6g_ch_list_bw320;
+- chan_list_size = dpd_6g_bw320_ch_num;
++ chan_list_size = DPD_CH_NUM(BW320_6G);
++ } else if (is_mt7992(&dev->mt76) && bw == NL80211_CHAN_WIDTH_80) {
++ base_offset += mphy->sband_6g.sband.n_channels * DPD_PER_CH_BW20_SIZE;
++ per_chan_size = DPD_PER_CH_GT_BW20_SIZE;
++ cal_id = RF_DPD_FLAT_6G_MEM_CAL;
++ chan_list = dpd_6g_ch_list_bw80;
++ chan_list_size = DPD_CH_NUM(BW80_6G);
+ } else if (bw > NL80211_CHAN_WIDTH_20) {
+ /* apply (center channel - 2)'s dpd cal data for bw 40/80 channels */
+ channel -= 2;
+@@ -3827,9 +3840,8 @@ int mt7996_mcu_apply_tx_dpd(struct mt7996_phy *phy)
+ if (idx == chan_list_size)
+ return -EINVAL;
+
+- if (band == NL80211_BAND_5GHZ && bw != NL80211_CHAN_WIDTH_160 &&
+- channel > dpd_5g_skip_ch_list[dpd_5g_skip_ch_num - 1].hw_value)
+- idx -= dpd_5g_skip_ch_num;
++ if (has_skip_ch && channel > dpd_5g_skip_ch_list[DPD_CH_NUM(BW20_5G_SKIP) - 1].hw_value)
++ idx -= DPD_CH_NUM(BW20_5G_SKIP);
+
+ cal += MT_EE_CAL_GROUP_SIZE + base_offset + idx * per_chan_size;
+
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 339d9890..17cae7f5 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -195,6 +195,19 @@ struct mt7996_twt_flow {
+
+ DECLARE_EWMA(avg_signal, 10, 8)
+
++enum mt7996_dpd_ch_num {
++ DPD_CH_NUM_BW20_2G,
++ DPD_CH_NUM_BW20_5G,
++ DPD_CH_NUM_BW20_5G_SKIP,
++ DPD_CH_NUM_BW80_5G,
++ DPD_CH_NUM_BW160_5G,
++ DPD_CH_NUM_BW20_6G,
++ DPD_CH_NUM_BW80_6G,
++ DPD_CH_NUM_BW160_6G,
++ DPD_CH_NUM_BW320_6G,
++ DPD_CH_NUM_TYPE_MAX,
++};
++
+ struct mt7996_sta {
+ struct mt76_wcid wcid; /* must be first */
+
+@@ -456,6 +469,10 @@ struct mt7996_dev {
+
+ void *cal;
+ u32 cur_prek_offset;
++ struct {
++ const u32 *rev;
++ u8 dpd_ch_num[DPD_CH_NUM_TYPE_MAX];
++ } prek;
+
+ struct {
+ u16 table_mask;
+@@ -592,7 +609,6 @@ int mt7996_eeprom_parse_hw_cap(struct mt7996_dev *dev, struct mt7996_phy *phy);
+ int mt7996_eeprom_get_target_power(struct mt7996_dev *dev,
+ struct ieee80211_channel *chan);
+ s8 mt7996_eeprom_get_power_delta(struct mt7996_dev *dev, int band);
+-int mt7996_get_dpd_per_band_size(struct mt7996_dev *dev, enum nl80211_band band);
+ int mt7996_dma_init(struct mt7996_dev *dev);
+ void mt7996_dma_reset(struct mt7996_dev *dev, bool force);
+ void mt7996_dma_prefetch(struct mt7996_dev *dev);
+diff --git a/mt7996/testmode.c b/mt7996/testmode.c
+index 0dc6629d..44ec84cc 100644
+--- a/mt7996/testmode.c
++++ b/mt7996/testmode.c
+@@ -434,7 +434,7 @@ mt7996_tm_set_tx_cont(struct mt7996_phy *phy, bool en)
+ static int
+ mt7996_tm_group_prek(struct mt7996_phy *phy, enum mt76_testmode_state state)
+ {
+- u8 *eeprom;
++ u8 *eeprom, do_precal;
+ u32 i, group_size, dpd_size, size, offs, *pre_cal;
+ int ret = 0;
+ struct mt7996_dev *dev = phy->dev;
+@@ -462,6 +462,9 @@ mt7996_tm_group_prek(struct mt7996_phy *phy, enum mt76_testmode_state state)
+ dpd_size = MT_EE_CAL_DPD_SIZE;
+ size = group_size + dpd_size;
+ offs = MT_EE_DO_PRE_CAL;
++ do_precal = (MT_EE_WIFI_CAL_GROUP_2G * !!PREK(GROUP_SIZE_2G)) |
++ (MT_EE_WIFI_CAL_GROUP_5G * !!PREK(GROUP_SIZE_5G)) |
++ (MT_EE_WIFI_CAL_GROUP_6G * !!PREK(GROUP_SIZE_6G));
+
+ switch (state) {
+ case MT76_TM_STATE_GROUP_PREK:
+@@ -476,13 +479,10 @@ mt7996_tm_group_prek(struct mt7996_phy *phy, enum mt76_testmode_state state)
+ wait_event_timeout(mdev->mcu.wait, dev->cur_prek_offset == group_size,
+ 30 * HZ);
+
+- if (ret) {
++ if (ret)
+ dev_err(dev->mt76.dev, "Group Pre-cal: mcu send msg failed!\n");
+- return ret;
+- }
+-
+- if (!ret)
+- eeprom[offs] |= MT_EE_WIFI_CAL_GROUP;
++ else
++ eeprom[offs] |= do_precal;
+ break;
+ case MT76_TM_STATE_GROUP_PREK_DUMP:
+ pre_cal = (u32 *)dev->cal;
+@@ -520,10 +520,12 @@ mt7996_tm_dpd_prek_send_req(struct mt7996_phy *phy, struct mt7996_tm_req *req,
+ struct mt76_phy *mphy = phy->mt76;
+ struct cfg80211_chan_def chandef_backup, *chandef = &mphy->chandef;
+ struct ieee80211_channel chan_backup;
+- int i, ret;
++ int i, ret, skip_ch_num = DPD_CH_NUM(BW20_5G_SKIP);
+
+ if (!chan_list)
+ return -EOPNOTSUPP;
++ if (!channel_size)
++ return 0;
+
+ req->rf_test.op.rf.param.cal_param.func_data = cpu_to_le32(func_data);
+
+@@ -533,7 +535,7 @@ mt7996_tm_dpd_prek_send_req(struct mt7996_phy *phy, struct mt7996_tm_req *req,
+ for (i = 0; i < channel_size; i++) {
+ if (chan_list[i].band == NL80211_BAND_5GHZ &&
+ chan_list[i].hw_value >= dpd_5g_skip_ch_list[0].hw_value &&
+- chan_list[i].hw_value <= dpd_5g_skip_ch_list[dpd_5g_skip_ch_num - 1].hw_value)
++ chan_list[i].hw_value <= dpd_5g_skip_ch_list[skip_ch_num - 1].hw_value)
+ continue;
+
+ memcpy(chandef->chan, &chan_list[i], sizeof(struct ieee80211_channel));
+@@ -602,11 +604,11 @@ mt7996_tm_dpd_prek(struct mt7996_phy *phy, enum mt76_testmode_state state)
+ switch (state) {
+ case MT76_TM_STATE_DPD_2G:
+ ret = mt7996_tm_dpd_prek_send_req(phy, &req, dpd_2g_ch_list_bw20,
+- dpd_2g_bw20_ch_num,
++ DPD_CH_NUM(BW20_2G),
+ NL80211_CHAN_WIDTH_20, RF_DPD_FLAT_CAL);
+- wait_on_prek_offset += dpd_2g_bw20_ch_num * DPD_PER_CH_BW20_SIZE;
+- wait_event_timeout(mdev->mcu.wait,
+- dev->cur_prek_offset == wait_on_prek_offset, 30 * HZ);
++ wait_on_prek_offset += DPD_CH_NUM(BW20_2G) * DPD_PER_CH_BW20_SIZE;
++ wait_event_timeout(mdev->mcu.wait, dev->cur_prek_offset == wait_on_prek_offset,
++ 30 * HZ);
+
+ do_precal = MT_EE_WIFI_CAL_DPD_2G;
+ break;
+@@ -617,18 +619,27 @@ mt7996_tm_dpd_prek(struct mt7996_phy *phy, enum mt76_testmode_state state)
+ NL80211_CHAN_WIDTH_20, RF_DPD_FLAT_5G_CAL);
+ if (ret)
+ return ret;
+- wait_on_prek_offset += (mphy->sband_5g.sband.n_channels - dpd_5g_skip_ch_num) *
+- DPD_PER_CH_BW20_SIZE;
+- wait_event_timeout(mdev->mcu.wait,
+- dev->cur_prek_offset == wait_on_prek_offset, 30 * HZ);
++ wait_on_prek_offset += DPD_CH_NUM(BW20_5G) * DPD_PER_CH_BW20_SIZE;
++ wait_event_timeout(mdev->mcu.wait, dev->cur_prek_offset == wait_on_prek_offset,
++ 30 * HZ);
++
++ /* 5g channel bw80 calibration */
++ ret = mt7996_tm_dpd_prek_send_req(phy, &req, dpd_5g_ch_list_bw80,
++ DPD_CH_NUM(BW80_5G),
++ NL80211_CHAN_WIDTH_80, RF_DPD_FLAT_5G_MEM_CAL);
++ if (ret)
++ return ret;
++ wait_on_prek_offset += DPD_CH_NUM(BW80_5G) * DPD_PER_CH_GT_BW20_SIZE;
++ wait_event_timeout(mdev->mcu.wait, dev->cur_prek_offset == wait_on_prek_offset,
++ 30 * HZ);
+
+ /* 5g channel bw160 calibration */
+ ret = mt7996_tm_dpd_prek_send_req(phy, &req, dpd_5g_ch_list_bw160,
+- dpd_5g_bw160_ch_num,
++ DPD_CH_NUM(BW160_5G),
+ NL80211_CHAN_WIDTH_160, RF_DPD_FLAT_5G_MEM_CAL);
+- wait_on_prek_offset += dpd_5g_bw160_ch_num * DPD_PER_CH_GT_BW20_SIZE;
+- wait_event_timeout(mdev->mcu.wait,
+- dev->cur_prek_offset == wait_on_prek_offset, 30 * HZ);
++ wait_on_prek_offset += DPD_CH_NUM(BW160_5G) * DPD_PER_CH_GT_BW20_SIZE;
++ wait_event_timeout(mdev->mcu.wait, dev->cur_prek_offset == wait_on_prek_offset,
++ 30 * HZ);
+
+ do_precal = MT_EE_WIFI_CAL_DPD_5G;
+ break;
+@@ -639,27 +650,37 @@ mt7996_tm_dpd_prek(struct mt7996_phy *phy, enum mt76_testmode_state state)
+ NL80211_CHAN_WIDTH_20, RF_DPD_FLAT_6G_CAL);
+ if (ret)
+ return ret;
+- wait_on_prek_offset += mphy->sband_6g.sband.n_channels * DPD_PER_CH_BW20_SIZE;
+- wait_event_timeout(mdev->mcu.wait,
+- dev->cur_prek_offset == wait_on_prek_offset, 30 * HZ);
++ wait_on_prek_offset += DPD_CH_NUM(BW20_6G) * DPD_PER_CH_BW20_SIZE;
++ wait_event_timeout(mdev->mcu.wait, dev->cur_prek_offset == wait_on_prek_offset,
++ 30 * HZ);
++
++ /* 6g channel bw80 calibration */
++ ret = mt7996_tm_dpd_prek_send_req(phy, &req, dpd_6g_ch_list_bw80,
++ DPD_CH_NUM(BW80_6G),
++ NL80211_CHAN_WIDTH_80, RF_DPD_FLAT_6G_MEM_CAL);
++ if (ret)
++ return ret;
++ wait_on_prek_offset += DPD_CH_NUM(BW80_6G) * DPD_PER_CH_GT_BW20_SIZE;
++ wait_event_timeout(mdev->mcu.wait, dev->cur_prek_offset == wait_on_prek_offset,
++ 30 * HZ);
+
+ /* 6g channel bw160 calibration */
+ ret = mt7996_tm_dpd_prek_send_req(phy, &req, dpd_6g_ch_list_bw160,
+- dpd_6g_bw160_ch_num,
++ DPD_CH_NUM(BW160_6G),
+ NL80211_CHAN_WIDTH_160, RF_DPD_FLAT_6G_MEM_CAL);
+ if (ret)
+ return ret;
+- wait_on_prek_offset += dpd_6g_bw160_ch_num * DPD_PER_CH_GT_BW20_SIZE;
+- wait_event_timeout(mdev->mcu.wait,
+- dev->cur_prek_offset == wait_on_prek_offset, 30 * HZ);
++ wait_on_prek_offset += DPD_CH_NUM(BW160_6G) * DPD_PER_CH_GT_BW20_SIZE;
++ wait_event_timeout(mdev->mcu.wait, dev->cur_prek_offset == wait_on_prek_offset,
++ 30 * HZ);
+
+ /* 6g channel bw320 calibration */
+ ret = mt7996_tm_dpd_prek_send_req(phy, &req, dpd_6g_ch_list_bw320,
+- dpd_6g_bw320_ch_num,
++ DPD_CH_NUM(BW320_6G),
+ NL80211_CHAN_WIDTH_320, RF_DPD_FLAT_6G_MEM_CAL);
+- wait_on_prek_offset += dpd_6g_bw320_ch_num * DPD_PER_CH_GT_BW20_SIZE;
+- wait_event_timeout(mdev->mcu.wait,
+- dev->cur_prek_offset == wait_on_prek_offset, 30 * HZ);
++ wait_on_prek_offset += DPD_CH_NUM(BW320_6G) * DPD_PER_CH_GT_BW20_SIZE;
++ wait_event_timeout(mdev->mcu.wait, dev->cur_prek_offset == wait_on_prek_offset,
++ 30 * HZ);
+
+ do_precal = MT_EE_WIFI_CAL_DPD_6G;
+ break;
+@@ -732,9 +753,9 @@ mt7996_tm_dump_precal(struct mt76_phy *mphy, struct sk_buff *msg, int flag, int
+ eeprom = dev->mt76.eeprom.data;
+ offs = MT_EE_DO_PRE_CAL;
+
+- dpd_size_2g = mt7996_get_dpd_per_band_size(dev, NL80211_BAND_2GHZ);
+- dpd_size_5g = mt7996_get_dpd_per_band_size(dev, NL80211_BAND_5GHZ);
+- dpd_size_6g = mt7996_get_dpd_per_band_size(dev, NL80211_BAND_6GHZ);
++ dpd_size_2g = MT_EE_CAL_DPD_SIZE_2G;
++ dpd_size_5g = MT_EE_CAL_DPD_SIZE_5G;
++ dpd_size_6g = MT_EE_CAL_DPD_SIZE_6G;
+
+ switch (type) {
+ case PREK_SYNC_ALL:
+@@ -810,9 +831,9 @@ mt7996_tm_re_cal_event(struct mt7996_dev *dev, struct mt7996_tm_rf_test_result *
+ u8 *pre_cal;
+
+ pre_cal = dev->cal;
+- dpd_size_2g = mt7996_get_dpd_per_band_size(dev, NL80211_BAND_2GHZ);
+- dpd_size_5g = mt7996_get_dpd_per_band_size(dev, NL80211_BAND_5GHZ);
+- dpd_size_6g = mt7996_get_dpd_per_band_size(dev, NL80211_BAND_6GHZ);
++ dpd_size_2g = MT_EE_CAL_DPD_SIZE_2G;
++ dpd_size_5g = MT_EE_CAL_DPD_SIZE_5G;
++ dpd_size_6g = MT_EE_CAL_DPD_SIZE_6G;
+
+ cal_idx = le32_to_cpu(data->cal_idx);
+ cal_type = le32_to_cpu(data->cal_type);
+diff --git a/testmode.c b/testmode.c
+index 7b8f9e66..81b492a5 100644
+--- a/testmode.c
++++ b/testmode.c
+@@ -37,6 +37,11 @@ const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS] = {
+ };
+ EXPORT_SYMBOL_GPL(mt76_tm_policy);
+
++static inline bool mt76_testmode_offload(struct mt76_dev *dev)
++{
++ return is_mt7996(dev) || is_mt7992(dev);
++}
++
+ void mt76_testmode_tx_pending(struct mt76_phy *phy)
+ {
+ struct mt76_testmode_data *td = &phy->test;
+@@ -197,7 +202,7 @@ mt76_testmode_tx_init(struct mt76_phy *phy)
+ u8 max_nss = hweight8(phy->antenna_mask);
+ int ret;
+
+- if (is_mt7996(phy->dev))
++ if (mt76_testmode_offload(phy->dev))
+ return 0;
+
+ ret = mt76_testmode_alloc_skb(phy, td->tx_mpdu_len);
+@@ -293,7 +298,7 @@ mt76_testmode_tx_start(struct mt76_phy *phy)
+ td->tx_done = 0;
+ td->tx_pending = td->tx_count;
+
+- if (!is_mt7996(dev))
++ if (!mt76_testmode_offload(dev))
+ mt76_worker_schedule(&dev->tx_worker);
+ }
+
+@@ -303,7 +308,7 @@ mt76_testmode_tx_stop(struct mt76_phy *phy)
+ struct mt76_testmode_data *td = &phy->test;
+ struct mt76_dev *dev = phy->dev;
+
+- if (is_mt7996(dev) && dev->test_ops->tx_stop) {
++ if (mt76_testmode_offload(dev) && dev->test_ops->tx_stop) {
+ dev->test_ops->tx_stop(phy);
+ return;
+ }
+--
+2.18.0
+