wifi: rtw89: debug: txpwr table supports Wi-Fi 7 chips
authorZong-Zhe Yang <kevin_yang@realtek.com>
Tue, 3 Oct 2023 01:54:46 +0000 (09:54 +0800)
committerKalle Valo <kvalo@kernel.org>
Thu, 5 Oct 2023 06:54:17 +0000 (09:54 +0300)
We add TX power table format for Wi-Fi 7 chips. Since Wi-Fi 7 tables are
larger, in order to reuse some chunks, we extend code to process nested
entries. Now, dbgfs txpwr_table can work with Wi-Fi 7 chips.

An output example of dbgfs txpwr_table on Wi-Fi 7 chips is shown below.
...
[TX power byrate]
<< BW20 >>
CCK        -  1M      2M      5.5M   11M   |  20,  20,  20,  20, dBm
LEGACY     -  6M      9M      12M    18M   |  18,  18,  18,  18, dBm
LEGACY     -  24M     36M     48M    54M   |  18,  18,  17,  16, dBm
EHT        -  MCS14   MCS15  |   0,   0, dBm
DLRU_EHT   -  MCS14   MCS15  |   0,  18, dBm
MCS_1SS        -  MCS0    MCS1    MCS2   MCS3  |  18,  18,  18,  18, dBm
MCS_1SS        -  MCS4    MCS5    MCS6   MCS7  |  18,  17,  16,  15, dBm
MCS_1SS        -  MCS8    MCS9    MCS10  MCS11 |  14,  13,  12,  11, dBm
MCS_1SS        -  MCS12   MCS13  |  10,   9, dBm
HEDCM_1SS      -  MCS0    MCS1    MCS3   MCS4  |  18,  18,  18,  18, dBm
DLRU_MCS_1SS   -  MCS0    MCS1    MCS2   MCS3  |  18,  18,  18,  18, dBm
DLRU_MCS_1SS   -  MCS4    MCS5    MCS6   MCS7  |  18,  17,  16,  15, dBm
DLRU_MCS_1SS   -  MCS8    MCS9    MCS10  MCS11 |  14,  13,  12,  11, dBm
DLRU_MCS_1SS   -  MCS12   MCS13  |  10,   9, dBm
DLRU_HEDCM_1SS -  MCS0    MCS1    MCS3   MCS4  |  18,  18,  18,  18, dBm
MCS_2SS        -  MCS0    MCS1    MCS2   MCS3  |  18,  18,  18,  18, dBm
...
[TX power limit]
<< 1TX >>
CCK_20M     -  NON_BF  BF |   0,   0, dBm
CCK_40M     -  NON_BF  BF |   0,   0, dBm
OFDM        -  NON_BF  BF |  18,   0, dBm
MCS_20M_0   -  NON_BF  BF |  18,   0, dBm
MCS_20M_1   -  NON_BF  BF |   0,   0, dBm
...

Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20231003015446.14658-8-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/debug.c
drivers/net/wireless/realtek/rtw89/reg.h

index afdcc596c4a6fd6f456e14c7656e3f93dc614652..6990d3679bc04899a5c5abe49fee4a615740b15c 100644 (file)
@@ -367,7 +367,11 @@ static int rtw89_debug_priv_rf_reg_dump_get(struct seq_file *m, void *v)
 }
 
 struct txpwr_ent {
-       const char *txt;
+       bool nested;
+       union {
+               const char *txt;
+               const struct txpwr_ent *ptr;
+       };
        u8 len;
 };
 
@@ -379,6 +383,12 @@ struct txpwr_map {
        u32 addr_to_1ss;
 };
 
+#define __GEN_TXPWR_ENT_NESTED(_e) \
+       { .nested = true, .ptr = __txpwr_ent_##_e, \
+         .len = ARRAY_SIZE(__txpwr_ent_##_e) }
+
+#define __GEN_TXPWR_ENT0(_t) { .len = 0, .txt = _t }
+
 #define __GEN_TXPWR_ENT2(_t, _e0, _e1) \
        { .len = 2, .txt = _t "\t-  " _e0 "  " _e1 }
 
@@ -501,14 +511,196 @@ static const struct txpwr_map __txpwr_map_lmt_ru_ax = {
        .addr_to_1ss = R_AX_PWR_RU_LMT_1SS_MAX,
 };
 
-static u8 __print_txpwr_ent(struct seq_file *m, const struct txpwr_ent *ent,
-                           const s8 *buf, const u8 cur)
+static const struct txpwr_ent __txpwr_ent_byr_mcs_be[] = {
+       __GEN_TXPWR_ENT4("MCS_1SS       ", "MCS0  ", "MCS1  ", "MCS2 ", "MCS3 "),
+       __GEN_TXPWR_ENT4("MCS_1SS       ", "MCS4  ", "MCS5  ", "MCS6 ", "MCS7 "),
+       __GEN_TXPWR_ENT4("MCS_1SS       ", "MCS8  ", "MCS9  ", "MCS10", "MCS11"),
+       __GEN_TXPWR_ENT2("MCS_1SS       ", "MCS12 ", "MCS13 \t"),
+       __GEN_TXPWR_ENT4("HEDCM_1SS     ", "MCS0  ", "MCS1  ", "MCS3 ", "MCS4 "),
+       __GEN_TXPWR_ENT4("DLRU_MCS_1SS  ", "MCS0  ", "MCS1  ", "MCS2 ", "MCS3 "),
+       __GEN_TXPWR_ENT4("DLRU_MCS_1SS  ", "MCS4  ", "MCS5  ", "MCS6 ", "MCS7 "),
+       __GEN_TXPWR_ENT4("DLRU_MCS_1SS  ", "MCS8  ", "MCS9  ", "MCS10", "MCS11"),
+       __GEN_TXPWR_ENT2("DLRU_MCS_1SS  ", "MCS12 ", "MCS13 \t"),
+       __GEN_TXPWR_ENT4("DLRU_HEDCM_1SS", "MCS0  ", "MCS1  ", "MCS3 ", "MCS4 "),
+       __GEN_TXPWR_ENT4("MCS_2SS       ", "MCS0  ", "MCS1  ", "MCS2 ", "MCS3 "),
+       __GEN_TXPWR_ENT4("MCS_2SS       ", "MCS4  ", "MCS5  ", "MCS6 ", "MCS7 "),
+       __GEN_TXPWR_ENT4("MCS_2SS       ", "MCS8  ", "MCS9  ", "MCS10", "MCS11"),
+       __GEN_TXPWR_ENT2("MCS_2SS       ", "MCS12 ", "MCS13 \t"),
+       __GEN_TXPWR_ENT4("HEDCM_2SS     ", "MCS0  ", "MCS1  ", "MCS3 ", "MCS4 "),
+       __GEN_TXPWR_ENT4("DLRU_MCS_2SS  ", "MCS0  ", "MCS1  ", "MCS2 ", "MCS3 "),
+       __GEN_TXPWR_ENT4("DLRU_MCS_2SS  ", "MCS4  ", "MCS5  ", "MCS6 ", "MCS7 "),
+       __GEN_TXPWR_ENT4("DLRU_MCS_2SS  ", "MCS8  ", "MCS9  ", "MCS10", "MCS11"),
+       __GEN_TXPWR_ENT2("DLRU_MCS_2SS  ", "MCS12 ", "MCS13 \t"),
+       __GEN_TXPWR_ENT4("DLRU_HEDCM_2SS", "MCS0  ", "MCS1  ", "MCS3 ", "MCS4 "),
+};
+
+static const struct txpwr_ent __txpwr_ent_byr_be[] = {
+       __GEN_TXPWR_ENT0("BW20"),
+       __GEN_TXPWR_ENT4("CCK       ", "1M    ", "2M    ", "5.5M ", "11M  "),
+       __GEN_TXPWR_ENT4("LEGACY    ", "6M    ", "9M    ", "12M  ", "18M  "),
+       __GEN_TXPWR_ENT4("LEGACY    ", "24M   ", "36M   ", "48M  ", "54M  "),
+       __GEN_TXPWR_ENT2("EHT       ", "MCS14 ", "MCS15 \t"),
+       __GEN_TXPWR_ENT2("DLRU_EHT  ", "MCS14 ", "MCS15 \t"),
+       __GEN_TXPWR_ENT_NESTED(byr_mcs_be),
+
+       __GEN_TXPWR_ENT0("BW40"),
+       __GEN_TXPWR_ENT4("CCK       ", "1M    ", "2M    ", "5.5M ", "11M  "),
+       __GEN_TXPWR_ENT4("LEGACY    ", "6M    ", "9M    ", "12M  ", "18M  "),
+       __GEN_TXPWR_ENT4("LEGACY    ", "24M   ", "36M   ", "48M  ", "54M  "),
+       __GEN_TXPWR_ENT2("EHT       ", "MCS14 ", "MCS15 \t"),
+       __GEN_TXPWR_ENT2("DLRU_EHT  ", "MCS14 ", "MCS15 \t"),
+       __GEN_TXPWR_ENT_NESTED(byr_mcs_be),
+
+       /* there is no CCK section after BW80 */
+       __GEN_TXPWR_ENT0("BW80"),
+       __GEN_TXPWR_ENT4("LEGACY    ", "6M    ", "9M    ", "12M  ", "18M  "),
+       __GEN_TXPWR_ENT4("LEGACY    ", "24M   ", "36M   ", "48M  ", "54M  "),
+       __GEN_TXPWR_ENT2("EHT       ", "MCS14 ", "MCS15 \t"),
+       __GEN_TXPWR_ENT2("DLRU_EHT  ", "MCS14 ", "MCS15 \t"),
+       __GEN_TXPWR_ENT_NESTED(byr_mcs_be),
+
+       __GEN_TXPWR_ENT0("BW160"),
+       __GEN_TXPWR_ENT4("LEGACY    ", "6M    ", "9M    ", "12M  ", "18M  "),
+       __GEN_TXPWR_ENT4("LEGACY    ", "24M   ", "36M   ", "48M  ", "54M  "),
+       __GEN_TXPWR_ENT2("EHT       ", "MCS14 ", "MCS15 \t"),
+       __GEN_TXPWR_ENT2("DLRU_EHT  ", "MCS14 ", "MCS15 \t"),
+       __GEN_TXPWR_ENT_NESTED(byr_mcs_be),
+
+       __GEN_TXPWR_ENT0("BW320"),
+       __GEN_TXPWR_ENT4("LEGACY    ", "6M    ", "9M    ", "12M  ", "18M  "),
+       __GEN_TXPWR_ENT4("LEGACY    ", "24M   ", "36M   ", "48M  ", "54M  "),
+       __GEN_TXPWR_ENT2("EHT       ", "MCS14 ", "MCS15 \t"),
+       __GEN_TXPWR_ENT2("DLRU_EHT  ", "MCS14 ", "MCS15 \t"),
+       __GEN_TXPWR_ENT_NESTED(byr_mcs_be),
+};
+
+static const struct txpwr_map __txpwr_map_byr_be = {
+       .ent = __txpwr_ent_byr_be,
+       .size = ARRAY_SIZE(__txpwr_ent_byr_be),
+       .addr_from = R_BE_PWR_BY_RATE,
+       .addr_to = R_BE_PWR_BY_RATE_MAX,
+       .addr_to_1ss = 0, /* not support */
+};
+
+static const struct txpwr_ent __txpwr_ent_lmt_mcs_be[] = {
+       __GEN_TXPWR_ENT2("MCS_20M_0  ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_20M_1  ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_20M_2  ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_20M_3  ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_20M_4  ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_20M_5  ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_20M_6  ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_20M_7  ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_20M_8  ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_20M_9  ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_20M_10 ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_20M_11 ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_20M_12 ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_20M_13 ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_20M_14 ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_20M_15 ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_40M_0  ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_40M_1  ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_40M_2  ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_40M_3  ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_40M_4  ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_40M_5  ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_40M_6  ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_40M_7  ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_80M_0  ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_80M_1  ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_80M_2  ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_80M_3  ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_160M_0 ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_160M_1 ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_320M   ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_40M_0p5", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_40M_2p5", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_40M_4p5", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("MCS_40M_6p5", "NON_BF", "BF"),
+};
+
+static const struct txpwr_ent __txpwr_ent_lmt_be[] = {
+       __GEN_TXPWR_ENT0("1TX"),
+       __GEN_TXPWR_ENT2("CCK_20M    ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("CCK_40M    ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("OFDM       ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT_NESTED(lmt_mcs_be),
+
+       __GEN_TXPWR_ENT0("2TX"),
+       __GEN_TXPWR_ENT2("CCK_20M    ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("CCK_40M    ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT2("OFDM       ", "NON_BF", "BF"),
+       __GEN_TXPWR_ENT_NESTED(lmt_mcs_be),
+};
+
+static const struct txpwr_map __txpwr_map_lmt_be = {
+       .ent = __txpwr_ent_lmt_be,
+       .size = ARRAY_SIZE(__txpwr_ent_lmt_be),
+       .addr_from = R_BE_PWR_LMT,
+       .addr_to = R_BE_PWR_LMT_MAX,
+       .addr_to_1ss = 0, /* not support */
+};
+
+static const struct txpwr_ent __txpwr_ent_lmt_ru_indexes_be[] = {
+       __GEN_TXPWR_ENT8("RU26    ", "IDX_0 ", "IDX_1 ", "IDX_2 ", "IDX_3 ",
+                        "IDX_4 ", "IDX_5 ", "IDX_6 ", "IDX_7 "),
+       __GEN_TXPWR_ENT8("RU26    ", "IDX_8 ", "IDX_9 ", "IDX_10", "IDX_11",
+                        "IDX_12", "IDX_13", "IDX_14", "IDX_15"),
+       __GEN_TXPWR_ENT8("RU52    ", "IDX_0 ", "IDX_1 ", "IDX_2 ", "IDX_3 ",
+                        "IDX_4 ", "IDX_5 ", "IDX_6 ", "IDX_7 "),
+       __GEN_TXPWR_ENT8("RU52    ", "IDX_8 ", "IDX_9 ", "IDX_10", "IDX_11",
+                        "IDX_12", "IDX_13", "IDX_14", "IDX_15"),
+       __GEN_TXPWR_ENT8("RU106   ", "IDX_0 ", "IDX_1 ", "IDX_2 ", "IDX_3 ",
+                        "IDX_4 ", "IDX_5 ", "IDX_6 ", "IDX_7 "),
+       __GEN_TXPWR_ENT8("RU106   ", "IDX_8 ", "IDX_9 ", "IDX_10", "IDX_11",
+                        "IDX_12", "IDX_13", "IDX_14", "IDX_15"),
+       __GEN_TXPWR_ENT8("RU52_26 ", "IDX_0 ", "IDX_1 ", "IDX_2 ", "IDX_3 ",
+                        "IDX_4 ", "IDX_5 ", "IDX_6 ", "IDX_7 "),
+       __GEN_TXPWR_ENT8("RU52_26 ", "IDX_8 ", "IDX_9 ", "IDX_10", "IDX_11",
+                        "IDX_12", "IDX_13", "IDX_14", "IDX_15"),
+       __GEN_TXPWR_ENT8("RU106_26", "IDX_0 ", "IDX_1 ", "IDX_2 ", "IDX_3 ",
+                        "IDX_4 ", "IDX_5 ", "IDX_6 ", "IDX_7 "),
+       __GEN_TXPWR_ENT8("RU106_26", "IDX_8 ", "IDX_9 ", "IDX_10", "IDX_11",
+                        "IDX_12", "IDX_13", "IDX_14", "IDX_15"),
+};
+
+static const struct txpwr_ent __txpwr_ent_lmt_ru_be[] = {
+       __GEN_TXPWR_ENT0("1TX"),
+       __GEN_TXPWR_ENT_NESTED(lmt_ru_indexes_be),
+
+       __GEN_TXPWR_ENT0("2TX"),
+       __GEN_TXPWR_ENT_NESTED(lmt_ru_indexes_be),
+};
+
+static const struct txpwr_map __txpwr_map_lmt_ru_be = {
+       .ent = __txpwr_ent_lmt_ru_be,
+       .size = ARRAY_SIZE(__txpwr_ent_lmt_ru_be),
+       .addr_from = R_BE_PWR_RU_LMT,
+       .addr_to = R_BE_PWR_RU_LMT_MAX,
+       .addr_to_1ss = 0, /* not support */
+};
+
+static unsigned int
+__print_txpwr_ent(struct seq_file *m, const struct txpwr_ent *ent,
+                 const s8 *buf, const unsigned int cur)
 {
+       unsigned int cnt, i;
        char *fmt;
 
+       if (ent->nested) {
+               for (cnt = 0, i = 0; i < ent->len; i++)
+                       cnt += __print_txpwr_ent(m, ent->ptr + i, buf,
+                                                cur + cnt);
+               return cnt;
+       }
+
        switch (ent->len) {
+       case 0:
+               seq_printf(m, "\t<< %s >>\n", ent->txt);
+               return 0;
        case 2:
-               fmt = "%s\t| %3d, %3d,\tdBm\n";
+               fmt = "%s\t| %3d, %3d,\t\tdBm\n";
                seq_printf(m, fmt, ent->txt, buf[cur], buf[cur + 1]);
                return 2;
        case 4:
@@ -532,10 +724,10 @@ static int __print_txpwr_map(struct seq_file *m, struct rtw89_dev *rtwdev,
 {
        u8 fct = rtwdev->chip->txpwr_factor_mac;
        u8 path_num = rtwdev->chip->rf_path_num;
+       unsigned int cur, i;
        u32 max_valid_addr;
        u32 val, addr;
        s8 *buf, tmp;
-       u8 cur, i;
        int ret;
 
        buf = vzalloc(map->addr_to - map->addr_from + 4);
@@ -547,6 +739,9 @@ static int __print_txpwr_map(struct seq_file *m, struct rtw89_dev *rtwdev,
        else
                max_valid_addr = map->addr_to;
 
+       if (max_valid_addr == 0)
+               return -EOPNOTSUPP;
+
        for (addr = map->addr_from; addr <= max_valid_addr; addr += 4) {
                ret = rtw89_mac_txpwr_read32(rtwdev, RTW89_PHY_0, addr, &val);
                if (ret)
@@ -612,8 +807,15 @@ static const struct dbgfs_txpwr_table dbgfs_txpwr_table_ax = {
        .lmt_ru = &__txpwr_map_lmt_ru_ax,
 };
 
+static const struct dbgfs_txpwr_table dbgfs_txpwr_table_be = {
+       .byr = &__txpwr_map_byr_be,
+       .lmt = &__txpwr_map_lmt_be,
+       .lmt_ru = &__txpwr_map_lmt_ru_be,
+};
+
 static const struct dbgfs_txpwr_table *dbgfs_txpwr_tables[RTW89_CHIP_GEN_NUM] = {
        [RTW89_CHIP_AX] = &dbgfs_txpwr_table_ax,
+       [RTW89_CHIP_BE] = &dbgfs_txpwr_table_be,
 };
 
 static int rtw89_debug_priv_txpwr_table_get(struct seq_file *m, void *v)
index e7766d8ba2f2f917c14841b8e83bce48d44c3b28..95cdee52fdc8cc1e4aa321bfc91c281b2ddc8368 100644 (file)
 
 #define R_BE_PWR_RATE_OFST_CTRL 0x11A30
 #define R_BE_PWR_BY_RATE 0x11E00
+#define R_BE_PWR_BY_RATE_MAX 0x11FA8
 #define R_BE_PWR_LMT 0x11FAC
+#define R_BE_PWR_LMT_MAX 0x12040
 #define R_BE_PWR_RU_LMT 0x12048
+#define R_BE_PWR_RU_LMT_MAX 0x120E4
 
 #define CMAC1_START_ADDR_BE 0x14000
 #define CMAC1_END_ADDR_BE 0x17FFF