2023-12-13 00:52:28

by Ping-Ke Shih

[permalink] [raw]
Subject: [PATCH v2 0/6] wifi: rtw89: add/modify three fw elements and related RFK log

Patches 1/6 to 3/6 are to add/modify three firmware elements. First is to
add an new element to add TX power track tables that helps to adjust TX
power according to increasing/decreasing thermal value. Second is to modify
existing element of BB MCU firmware, because we need to add a field to
point out hardware version. Since we have not released firmware yet,
no need to process backward compatible thing.

The third patch is to add formatted string of firmware C2H events triggered
by firmware RFK (RF calibration) to help debugging. When RFK is running in
firmware, it sends logs with formatted string ID via C2H events, and then
patch 6/6 uses the ID to find corresponding formatted string as first
argument of printf() with fixed four arguments.

The remaining patches are to handle the C2H events and print out RFK status
or log in plain text.

v2:
- rebase to top of wireless-next to avoid conflict of patch 5/6, because
another patchset change fw.h nearby.

Ping-Ke Shih (6):
wifi: rtw89: fw: load TX power track tables from fw_element
wifi: rtw89: fw: add version field to BB MCU firmware element
wifi: rtw89: load RFK log format string from firmware file
wifi: rtw89: add C2H event handlers of RFK log and report
wifi: rtw89: parse and print out RFK log from C2H events
wifi: rtw89: phy: print out RFK log with formatted string

drivers/net/wireless/realtek/rtw89/core.h | 6 +
drivers/net/wireless/realtek/rtw89/fw.c | 110 +++++++-
drivers/net/wireless/realtek/rtw89/fw.h | 144 +++++++++++
drivers/net/wireless/realtek/rtw89/phy.c | 300 ++++++++++++++++++++++
drivers/net/wireless/realtek/rtw89/phy.h | 24 +-
5 files changed, 581 insertions(+), 3 deletions(-)

--
2.25.1



2023-12-13 00:52:30

by Ping-Ke Shih

[permalink] [raw]
Subject: [PATCH v2 1/6] wifi: rtw89: fw: load TX power track tables from fw_element

The TX power track tables are used to define compensation power reflected
to thermal value. Currently, we have 16 (2 * 4 * 2) tables made by
combinations of
{negative/positive thermal value, 2GHz/2GHz-CCK/5GHz/6GHz, path A/B}

Signed-off-by: Ping-Ke Shih <[email protected]>
---
drivers/net/wireless/realtek/rtw89/core.h | 4 ++
drivers/net/wireless/realtek/rtw89/fw.c | 71 +++++++++++++++++++++++
drivers/net/wireless/realtek/rtw89/fw.h | 60 +++++++++++++++++++
drivers/net/wireless/realtek/rtw89/phy.h | 2 -
4 files changed, 135 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index b1e498ad149e..e5dd51f79a6f 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -17,6 +17,7 @@ struct rtw89_pci_info;
struct rtw89_mac_gen_def;
struct rtw89_phy_gen_def;
struct rtw89_efuse_block_cfg;
+struct rtw89_fw_txpwr_track_cfg;

extern const struct ieee80211_ops rtw89_ops;

@@ -38,6 +39,8 @@ extern const struct ieee80211_ops rtw89_ops;
#define RSSI_FACTOR 1
#define RTW89_RSSI_RAW_TO_DBM(rssi) ((s8)((rssi) >> RSSI_FACTOR) - MAX_RSSI)
#define RTW89_TX_DIV_RSSI_RAW_TH (2 << RSSI_FACTOR)
+#define DELTA_SWINGIDX_SIZE 30
+
#define RTW89_RADIOTAP_ROOM_HE sizeof(struct ieee80211_radiotap_he)
#define RTW89_RADIOTAP_ROOM_EHT \
(sizeof(struct ieee80211_radiotap_tlv) + \
@@ -3948,6 +3951,7 @@ struct rtw89_fw_elm_info {
struct rtw89_phy_table *bb_gain;
struct rtw89_phy_table *rf_radio[RF_PATH_MAX];
struct rtw89_phy_table *rf_nctl;
+ struct rtw89_fw_txpwr_track_cfg *txpwr_trk;
};

struct rtw89_fw_info {
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 81034b6ce4b0..f9727c00d8b9 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -659,6 +659,72 @@ int rtw89_fw_recognize_txpwr_from_elm(struct rtw89_dev *rtwdev,
return 0;
}

+static
+int rtw89_build_txpwr_trk_tbl_from_elm(struct rtw89_dev *rtwdev,
+ const struct rtw89_fw_element_hdr *elm,
+ const union rtw89_fw_element_arg arg)
+{
+ struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ u32 needed_bitmap = 0;
+ u32 offset = 0;
+ int subband;
+ u32 bitmap;
+ int type;
+
+ if (chip->support_bands & BIT(NL80211_BAND_6GHZ))
+ needed_bitmap |= RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_6GHZ;
+ if (chip->support_bands & BIT(NL80211_BAND_5GHZ))
+ needed_bitmap |= RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_5GHZ;
+ if (chip->support_bands & BIT(NL80211_BAND_2GHZ))
+ needed_bitmap |= RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_2GHZ;
+
+ bitmap = le32_to_cpu(elm->u.txpwr_trk.bitmap);
+
+ if ((bitmap & needed_bitmap) != needed_bitmap) {
+ rtw89_warn(rtwdev, "needed txpwr trk bitmap %08x but %0x8x\n",
+ needed_bitmap, bitmap);
+ return -ENOENT;
+ }
+
+ elm_info->txpwr_trk = kzalloc(sizeof(*elm_info->txpwr_trk), GFP_KERNEL);
+ if (!elm_info->txpwr_trk)
+ return -ENOMEM;
+
+ for (type = 0; bitmap; type++, bitmap >>= 1) {
+ if (!(bitmap & BIT(0)))
+ continue;
+
+ if (type >= __RTW89_FW_TXPWR_TRK_TYPE_6GHZ_START &&
+ type <= __RTW89_FW_TXPWR_TRK_TYPE_6GHZ_MAX)
+ subband = 4;
+ else if (type >= __RTW89_FW_TXPWR_TRK_TYPE_5GHZ_START &&
+ type <= __RTW89_FW_TXPWR_TRK_TYPE_5GHZ_MAX)
+ subband = 3;
+ else if (type >= __RTW89_FW_TXPWR_TRK_TYPE_2GHZ_START &&
+ type <= __RTW89_FW_TXPWR_TRK_TYPE_2GHZ_MAX)
+ subband = 1;
+ else
+ break;
+
+ elm_info->txpwr_trk->delta[type] = &elm->u.txpwr_trk.contents[offset];
+
+ offset += subband;
+ if (offset * DELTA_SWINGIDX_SIZE > le32_to_cpu(elm->size))
+ goto err;
+ }
+
+ return 0;
+
+err:
+ rtw89_warn(rtwdev, "unexpected txpwr trk offset %d over size %d\n",
+ offset, le32_to_cpu(elm->size));
+ kfree(elm_info->txpwr_trk);
+ elm_info->txpwr_trk = NULL;
+
+ return -EFAULT;
+}
+
static const struct rtw89_fw_element_handler __fw_element_handlers[] = {
[RTW89_FW_ELEMENT_ID_BBMCU0] = {__rtw89_fw_recognize_from_elm,
{ .fw_type = RTW89_FW_BBMCU0 }, NULL},
@@ -711,6 +777,9 @@ static const struct rtw89_fw_element_handler __fw_element_handlers[] = {
rtw89_fw_recognize_txpwr_from_elm,
{ .offset = offsetof(struct rtw89_rfe_data, tx_shape_lmt_ru.conf) }, NULL,
},
+ [RTW89_FW_ELEMENT_ID_TXPWR_TRK] = {
+ rtw89_build_txpwr_trk_tbl_from_elm, {}, "PWR_TRK",
+ },
};

int rtw89_fw_recognize_elements(struct rtw89_dev *rtwdev)
@@ -1144,6 +1213,8 @@ static void rtw89_unload_firmware_elements(struct rtw89_dev *rtwdev)
for (i = 0; i < ARRAY_SIZE(elm_info->rf_radio); i++)
rtw89_free_phy_tbl_from_elm(elm_info->rf_radio[i]);
rtw89_free_phy_tbl_from_elm(elm_info->rf_nctl);
+
+ kfree(elm_info->txpwr_trk);
}

void rtw89_unload_firmware(struct rtw89_dev *rtwdev)
diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h
index 2b2d14284465..033ea4467876 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.h
+++ b/drivers/net/wireless/realtek/rtw89/fw.h
@@ -3426,6 +3426,7 @@ enum rtw89_fw_element_id {
RTW89_FW_ELEMENT_ID_TXPWR_LMT_RU_6GHZ = 15,
RTW89_FW_ELEMENT_ID_TX_SHAPE_LMT = 16,
RTW89_FW_ELEMENT_ID_TX_SHAPE_LMT_RU = 17,
+ RTW89_FW_ELEMENT_ID_TXPWR_TRK = 18,

RTW89_FW_ELEMENT_ID_NUM,
};
@@ -3446,6 +3447,7 @@ enum rtw89_fw_element_id {
BIT(RTW89_FW_ELEMENT_ID_RADIO_A) | \
BIT(RTW89_FW_ELEMENT_ID_RADIO_B) | \
BIT(RTW89_FW_ELEMENT_ID_RF_NCTL) | \
+ BIT(RTW89_FW_ELEMENT_ID_TXPWR_TRK) | \
BITS_OF_RTW89_TXPWR_FW_ELEMENTS)

struct __rtw89_fw_txpwr_element {
@@ -3457,6 +3459,59 @@ struct __rtw89_fw_txpwr_element {
u8 content[];
} __packed;

+enum rtw89_fw_txpwr_trk_type {
+ __RTW89_FW_TXPWR_TRK_TYPE_6GHZ_START = 0,
+ RTW89_FW_TXPWR_TRK_TYPE_6GB_N = 0,
+ RTW89_FW_TXPWR_TRK_TYPE_6GB_P = 1,
+ RTW89_FW_TXPWR_TRK_TYPE_6GA_N = 2,
+ RTW89_FW_TXPWR_TRK_TYPE_6GA_P = 3,
+ __RTW89_FW_TXPWR_TRK_TYPE_6GHZ_MAX = 3,
+
+ __RTW89_FW_TXPWR_TRK_TYPE_5GHZ_START = 4,
+ RTW89_FW_TXPWR_TRK_TYPE_5GB_N = 4,
+ RTW89_FW_TXPWR_TRK_TYPE_5GB_P = 5,
+ RTW89_FW_TXPWR_TRK_TYPE_5GA_N = 6,
+ RTW89_FW_TXPWR_TRK_TYPE_5GA_P = 7,
+ __RTW89_FW_TXPWR_TRK_TYPE_5GHZ_MAX = 7,
+
+ __RTW89_FW_TXPWR_TRK_TYPE_2GHZ_START = 8,
+ RTW89_FW_TXPWR_TRK_TYPE_2GB_N = 8,
+ RTW89_FW_TXPWR_TRK_TYPE_2GB_P = 9,
+ RTW89_FW_TXPWR_TRK_TYPE_2GA_N = 10,
+ RTW89_FW_TXPWR_TRK_TYPE_2GA_P = 11,
+ RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_B_N = 12,
+ RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_B_P = 13,
+ RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_A_N = 14,
+ RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_A_P = 15,
+ __RTW89_FW_TXPWR_TRK_TYPE_2GHZ_MAX = 15,
+
+ RTW89_FW_TXPWR_TRK_TYPE_NR,
+};
+
+struct rtw89_fw_txpwr_track_cfg {
+ const s8 (*delta[RTW89_FW_TXPWR_TRK_TYPE_NR])[DELTA_SWINGIDX_SIZE];
+};
+
+#define RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_6GHZ \
+ (BIT(RTW89_FW_TXPWR_TRK_TYPE_6GB_N) | \
+ BIT(RTW89_FW_TXPWR_TRK_TYPE_6GB_P) | \
+ BIT(RTW89_FW_TXPWR_TRK_TYPE_6GA_N) | \
+ BIT(RTW89_FW_TXPWR_TRK_TYPE_6GA_P))
+#define RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_5GHZ \
+ (BIT(RTW89_FW_TXPWR_TRK_TYPE_5GB_N) | \
+ BIT(RTW89_FW_TXPWR_TRK_TYPE_5GB_P) | \
+ BIT(RTW89_FW_TXPWR_TRK_TYPE_5GA_N) | \
+ BIT(RTW89_FW_TXPWR_TRK_TYPE_5GA_P))
+#define RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_2GHZ \
+ (BIT(RTW89_FW_TXPWR_TRK_TYPE_2GB_N) | \
+ BIT(RTW89_FW_TXPWR_TRK_TYPE_2GB_P) | \
+ BIT(RTW89_FW_TXPWR_TRK_TYPE_2GA_N) | \
+ BIT(RTW89_FW_TXPWR_TRK_TYPE_2GA_P) | \
+ BIT(RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_B_N) | \
+ BIT(RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_B_P) | \
+ BIT(RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_A_N) | \
+ BIT(RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_A_P))
+
struct rtw89_fw_element_hdr {
__le32 id; /* enum rtw89_fw_element_id */
__le32 size; /* exclude header size */
@@ -3477,6 +3532,11 @@ struct rtw89_fw_element_hdr {
__le32 data;
} __packed regs[];
} __packed reg2;
+ struct {
+ __le32 bitmap; /* bitmap of enum rtw89_fw_txpwr_trk_type */
+ __le32 rsvd;
+ s8 contents[][DELTA_SWINGIDX_SIZE];
+ } __packed txpwr_trk;
struct __rtw89_fw_txpwr_element txpwr;
} __packed u;
} __packed;
diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h
index d6363defcde6..6792b73e9ca3 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.h
+++ b/drivers/net/wireless/realtek/rtw89/phy.h
@@ -291,8 +291,6 @@ struct rtw89_txpwr_byrate_cfg {
u32 data;
};

-#define DELTA_SWINGIDX_SIZE 30
-
struct rtw89_txpwr_track_cfg {
const s8 (*delta_swingidx_6gb_n)[DELTA_SWINGIDX_SIZE];
const s8 (*delta_swingidx_6gb_p)[DELTA_SWINGIDX_SIZE];
--
2.25.1


2023-12-13 00:52:42

by Ping-Ke Shih

[permalink] [raw]
Subject: [PATCH v2 2/6] wifi: rtw89: fw: add version field to BB MCU firmware element

8922AE has more than one hardware version, and they use different BB MCU
firmware, so occupy a byte from element priv[] to annotate version. Since
there are more than one firmware and only matched version is adopted,
return 1 to ignore not matched firmware.

+===========================================+
| elm ID | elm size | version | |
+----------+----------+----------+----------+
| | element_priv[] |
+-------------------------------------------+

change to |
v

+===========================================+
| elm ID | elm size | version | |
+----------+----------+----------+----------+
| | cv | element_rsvd[] |
+-------------------------------------------+

Signed-off-by: Ping-Ke Shih <[email protected]>
---
drivers/net/wireless/realtek/rtw89/fw.c | 8 +++++++-
drivers/net/wireless/realtek/rtw89/fw.h | 5 +++++
2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index f9727c00d8b9..76c948da669e 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -401,10 +401,14 @@ int __rtw89_fw_recognize_from_elm(struct rtw89_dev *rtwdev,
const union rtw89_fw_element_arg arg)
{
enum rtw89_fw_type type = arg.fw_type;
+ struct rtw89_hal *hal = &rtwdev->hal;
struct rtw89_fw_suit *fw_suit;

+ if (hal->cv != elm->u.bbmcu.cv)
+ return 1; /* ignore this element */
+
fw_suit = rtw89_fw_suit_get(rtwdev, type);
- fw_suit->data = elm->u.common.contents;
+ fw_suit->data = elm->u.bbmcu.contents;
fw_suit->size = le32_to_cpu(elm->size);

return rtw89_fw_update_ver(rtwdev, type, fw_suit);
@@ -820,6 +824,8 @@ int rtw89_fw_recognize_elements(struct rtw89_dev *rtwdev)
goto next;

ret = handler->fn(rtwdev, hdr, handler->arg);
+ if (ret == 1) /* ignore this element */
+ goto next;
if (ret)
return ret;

diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h
index 033ea4467876..f2b61e9ad8a7 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.h
+++ b/drivers/net/wireless/realtek/rtw89/fw.h
@@ -3532,6 +3532,11 @@ struct rtw89_fw_element_hdr {
__le32 data;
} __packed regs[];
} __packed reg2;
+ struct {
+ u8 cv;
+ u8 priv[7];
+ u8 contents[];
+ } __packed bbmcu;
struct {
__le32 bitmap; /* bitmap of enum rtw89_fw_txpwr_trk_type */
__le32 rsvd;
--
2.25.1


2023-12-13 00:52:49

by Ping-Ke Shih

[permalink] [raw]
Subject: [PATCH v2 5/6] wifi: rtw89: parse and print out RFK log from C2H events

RFK log events contains two types. One called RUN log is to reflect state
during RFK is running, and it replies on formatted string loaded from
firmware file, but print this type as plain hexadecimal only in this patch.
The other is REPORT log that reflects the final result of a RFK, and
each calibration has its own struct to carry many specific information.

Signed-off-by: Ping-Ke Shih <[email protected]>
---
drivers/net/wireless/realtek/rtw89/fw.h | 66 +++++++++
drivers/net/wireless/realtek/rtw89/phy.c | 175 +++++++++++++++++++++++
2 files changed, 241 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h
index 55ccc07580df..aa749732a9e2 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.h
+++ b/drivers/net/wireless/realtek/rtw89/fw.h
@@ -3722,6 +3722,72 @@ struct rtw89_fw_h2c_rf_get_mccch {
__le32 current_band_type;
} __packed;

+enum rtw89_rf_log_type {
+ RTW89_RF_RUN_LOG = 0,
+ RTW89_RF_RPT_LOG = 1,
+};
+
+struct rtw89_c2h_rf_log_hdr {
+ u8 type; /* enum rtw89_rf_log_type */
+ __le16 len;
+ u8 content[];
+} __packed;
+
+struct rtw89_c2h_rf_dpk_rpt_log {
+ u8 ver;
+ u8 idx[2];
+ u8 band[2];
+ u8 bw[2];
+ u8 ch[2];
+ u8 path_ok[2];
+ u8 txagc[2];
+ u8 ther[2];
+ u8 gs[2];
+ u8 dc_i[4];
+ u8 dc_q[4];
+ u8 corr_val[2];
+ u8 corr_idx[2];
+ u8 is_timeout[2];
+ u8 rxbb_ov[2];
+ u8 rsvd;
+} __packed;
+
+struct rtw89_c2h_rf_dack_rpt_log {
+ u8 fwdack_ver;
+ u8 fwdack_rpt_ver;
+ u8 msbk_d[2][2][16];
+ u8 dadck_d[2][2];
+ u8 cdack_d[2][2][2];
+ __le16 addck2_d[2][2][2];
+ u8 adgaink_d[2][2];
+ __le16 biask_d[2][2];
+ u8 addck_timeout;
+ u8 cdack_timeout;
+ u8 dadck_timeout;
+ u8 msbk_timeout;
+ u8 adgaink_timeout;
+ u8 dack_fail;
+} __packed;
+
+struct rtw89_c2h_rf_rxdck_rpt_log {
+ u8 ver;
+ u8 band[2];
+ u8 bw[2];
+ u8 ch[2];
+ u8 timeout[2];
+} __packed;
+
+struct rtw89_c2h_rf_txgapk_rpt_log {
+ __le32 r0x8010[2];
+ __le32 chk_cnt;
+ u8 track_d[2][17];
+ u8 power_d[2][17];
+ u8 is_txgapk_ok;
+ u8 chk_id;
+ u8 ver;
+ u8 rsv1;
+} __packed;
+
#define RTW89_FW_RSVD_PLE_SIZE 0x800

#define RTW89_FW_BACKTRACE_INFO_SIZE 8
diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c
index 8a4a72b00340..496160f72755 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.c
+++ b/drivers/net/wireless/realtek/rtw89/phy.c
@@ -2445,34 +2445,209 @@ void (* const rtw89_phy_c2h_ra_handler[])(struct rtw89_dev *rtwdev,
[RTW89_PHY_C2H_FUNC_TXSTS] = NULL,
};

+static void rtw89_phy_c2h_rfk_rpt_log(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_c2h_rfk_log_func func,
+ void *content, u16 len)
+{
+ struct rtw89_c2h_rf_txgapk_rpt_log *txgapk;
+ struct rtw89_c2h_rf_rxdck_rpt_log *rxdck;
+ struct rtw89_c2h_rf_dack_rpt_log *dack;
+ struct rtw89_c2h_rf_dpk_rpt_log *dpk;
+
+ switch (func) {
+ case RTW89_PHY_C2H_RFK_LOG_FUNC_DPK:
+ if (len != sizeof(*dpk))
+ goto out;
+
+ dpk = content;
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "DPK ver:%d idx:%2ph band:%2ph bw:%2ph ch:%2ph path:%2ph\n",
+ dpk->ver, dpk->idx, dpk->band, dpk->bw, dpk->ch, dpk->path_ok);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "DPK txagc:%2ph ther:%2ph gs:%2ph dc_i:%4ph dc_q:%4ph\n",
+ dpk->txagc, dpk->ther, dpk->gs, dpk->dc_i, dpk->dc_q);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "DPK corr_v:%2ph corr_i:%2ph to:%2ph ov:%2ph\n",
+ dpk->corr_val, dpk->corr_idx, dpk->is_timeout, dpk->rxbb_ov);
+ return;
+ case RTW89_PHY_C2H_RFK_LOG_FUNC_DACK:
+ if (len != sizeof(*dack))
+ goto out;
+
+ dack = content;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]ver=0x%x 0x%x\n",
+ dack->fwdack_ver, dack->fwdack_rpt_ver);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 CDACK ic = [0x%x, 0x%x]\n",
+ dack->cdack_d[0][0][0], dack->cdack_d[0][0][1]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 CDACK qc = [0x%x, 0x%x]\n",
+ dack->cdack_d[0][1][0], dack->cdack_d[0][1][1]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 CDACK ic = [0x%x, 0x%x]\n",
+ dack->cdack_d[1][0][0], dack->cdack_d[1][0][1]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 CDACK qc = [0x%x, 0x%x]\n",
+ dack->cdack_d[1][1][0], dack->cdack_d[1][1][1]);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADC_DCK ic = [0x%x, 0x%x]\n",
+ dack->addck2_d[0][0][0], dack->addck2_d[0][0][1]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADC_DCK qc = [0x%x, 0x%x]\n",
+ dack->addck2_d[0][1][0], dack->addck2_d[0][1][1]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 ADC_DCK ic = [0x%x, 0x%x]\n",
+ dack->addck2_d[1][0][0], dack->addck2_d[1][0][1]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 ADC_DCK qc = [0x%x, 0x%x]\n",
+ dack->addck2_d[1][1][0], dack->addck2_d[1][1][1]);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADC_GAINK ic = 0x%x, qc = 0x%x\n",
+ dack->adgaink_d[0][0], dack->adgaink_d[0][1]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 ADC_GAINK ic = 0x%x, qc = 0x%x\n",
+ dack->adgaink_d[1][0], dack->adgaink_d[1][1]);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 DAC_DCK ic = 0x%x, qc = 0x%x\n",
+ dack->dadck_d[0][0], dack->dadck_d[0][1]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 DAC_DCK ic = 0x%x, qc = 0x%x\n",
+ dack->dadck_d[1][0], dack->dadck_d[1][1]);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 biask iqc = 0x%x\n",
+ dack->biask_d[0][0]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 biask iqc = 0x%x\n",
+ dack->biask_d[1][0]);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK ic: %*ph\n",
+ (int)sizeof(dack->msbk_d[0][0]), dack->msbk_d[0][0]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK qc: %*ph\n",
+ (int)sizeof(dack->msbk_d[0][1]), dack->msbk_d[0][1]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK ic: %*ph\n",
+ (int)sizeof(dack->msbk_d[1][0]), dack->msbk_d[1][0]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK qc: %*ph\n",
+ (int)sizeof(dack->msbk_d[1][1]), dack->msbk_d[1][1]);
+ return;
+ case RTW89_PHY_C2H_RFK_LOG_FUNC_RXDCK:
+ if (len != sizeof(*rxdck))
+ goto out;
+
+ rxdck = content;
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "RXDCK ver:%d band:%2ph bw:%2ph ch:%2ph to:%2ph\n",
+ rxdck->ver, rxdck->band, rxdck->bw, rxdck->ch,
+ rxdck->timeout);
+ return;
+ case RTW89_PHY_C2H_RFK_LOG_FUNC_TXGAPK:
+ if (len != sizeof(*txgapk))
+ goto out;
+
+ txgapk = content;
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[TXGAPK]rpt r0x8010[0]=0x%x, r0x8010[1]=0x%x\n",
+ le32_to_cpu(txgapk->r0x8010[0]),
+ le32_to_cpu(txgapk->r0x8010[1]));
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt chk_id = %d\n",
+ txgapk->chk_id);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt chk_cnt = %d\n",
+ le32_to_cpu(txgapk->chk_cnt));
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt ver = 0x%x\n",
+ txgapk->ver);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt rsv1 = %d\n",
+ txgapk->rsv1);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt track_d[0] = %*ph\n",
+ (int)sizeof(txgapk->track_d[0]), txgapk->track_d[0]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt power_d[0] = %*ph\n",
+ (int)sizeof(txgapk->power_d[0]), txgapk->power_d[0]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt track_d[1] = %*ph\n",
+ (int)sizeof(txgapk->track_d[1]), txgapk->track_d[1]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt power_d[1] = %*ph\n",
+ (int)sizeof(txgapk->power_d[1]), txgapk->power_d[1]);
+ return;
+ default:
+ break;
+ }
+
+out:
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "unexpected RFK func %d report log with length %d\n", func, len);
+}
+
+static void rtw89_phy_c2h_rfk_log(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
+ u32 len, enum rtw89_phy_c2h_rfk_log_func func,
+ const char *rfk_name)
+{
+ struct rtw89_c2h_hdr *c2h_hdr = (struct rtw89_c2h_hdr *)c2h->data;
+ struct rtw89_c2h_rf_log_hdr *log_hdr;
+ void *log_ptr = c2h_hdr;
+ u16 content_len;
+ u16 chunk_len;
+
+ if (!rtw89_debug_is_enabled(rtwdev, RTW89_DBG_RFK))
+ return;
+
+ log_ptr += sizeof(*c2h_hdr);
+ len -= sizeof(*c2h_hdr);
+
+ while (len > sizeof(*log_hdr)) {
+ log_hdr = log_ptr;
+ content_len = le16_to_cpu(log_hdr->len);
+ chunk_len = content_len + sizeof(*log_hdr);
+
+ if (chunk_len > len)
+ break;
+
+ switch (log_hdr->type) {
+ case RTW89_RF_RUN_LOG:
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "%s run: %*ph\n",
+ rfk_name, content_len, log_hdr->content);
+ break;
+ case RTW89_RF_RPT_LOG:
+ rtw89_phy_c2h_rfk_rpt_log(rtwdev, func,
+ log_hdr->content, content_len);
+ break;
+ default:
+ return;
+ }
+
+ log_ptr += chunk_len;
+ len -= chunk_len;
+ }
+}
+
static void
rtw89_phy_c2h_rfk_log_iqk(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
{
+ rtw89_phy_c2h_rfk_log(rtwdev, c2h, len,
+ RTW89_PHY_C2H_RFK_LOG_FUNC_IQK, "IQK");
}

static void
rtw89_phy_c2h_rfk_log_dpk(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
{
+ rtw89_phy_c2h_rfk_log(rtwdev, c2h, len,
+ RTW89_PHY_C2H_RFK_LOG_FUNC_DPK, "DPK");
}

static void
rtw89_phy_c2h_rfk_log_dack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
{
+ rtw89_phy_c2h_rfk_log(rtwdev, c2h, len,
+ RTW89_PHY_C2H_RFK_LOG_FUNC_DACK, "DACK");
}

static void
rtw89_phy_c2h_rfk_log_rxdck(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
{
+ rtw89_phy_c2h_rfk_log(rtwdev, c2h, len,
+ RTW89_PHY_C2H_RFK_LOG_FUNC_RXDCK, "RX_DCK");
}

static void
rtw89_phy_c2h_rfk_log_tssi(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
{
+ rtw89_phy_c2h_rfk_log(rtwdev, c2h, len,
+ RTW89_PHY_C2H_RFK_LOG_FUNC_TSSI, "TSSI");
}

static void
rtw89_phy_c2h_rfk_log_txgapk(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
{
+ rtw89_phy_c2h_rfk_log(rtwdev, c2h, len,
+ RTW89_PHY_C2H_RFK_LOG_FUNC_TXGAPK, "TXGAPK");
}

static
--
2.25.1


2023-12-13 00:52:52

by Ping-Ke Shih

[permalink] [raw]
Subject: [PATCH v2 3/6] wifi: rtw89: load RFK log format string from firmware file

To debug RFK (RF calibration) in firmware, it sends log via firmware C2H
events to driver with string format ID and four arguments. Load formatted
string from firmware file, and the string ID can get back its string. Then,
use regular print format to show the message.

This firmware element layout looks like

+============================================+
| elm ID | elm size | version | |
+----------+----------+----------+-----------+
| | nr |rsvd |rfk_id|rsvd|
+--------------------------------------------+
| offset[] (__le16 * nr) |
| ... |
+--------------------------------------------+
| formatted string with null termintor (*nr) |
| ... |
+============================================+

* a firmware file can contains more than one elements with this element ID
named RTW89_FW_ELEMENT_ID_RFKLOG_FMT (19), because many RFK needs its
own formatted strings, so add 'rfk_id' to know it belongs to which RFK.
* the 'formatted string' just follow 'offset[]' without padding to align
32bits.

Signed-off-by: Ping-Ke Shih <[email protected]>
---
drivers/net/wireless/realtek/rtw89/core.h | 2 ++
drivers/net/wireless/realtek/rtw89/fw.c | 29 +++++++++++++++++++++++
drivers/net/wireless/realtek/rtw89/fw.h | 8 +++++++
drivers/net/wireless/realtek/rtw89/phy.h | 15 ++++++++++++
4 files changed, 54 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index e5dd51f79a6f..5c266f349d37 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -18,6 +18,7 @@ struct rtw89_mac_gen_def;
struct rtw89_phy_gen_def;
struct rtw89_efuse_block_cfg;
struct rtw89_fw_txpwr_track_cfg;
+struct rtw89_phy_rfk_log_fmt;

extern const struct ieee80211_ops rtw89_ops;

@@ -3952,6 +3953,7 @@ struct rtw89_fw_elm_info {
struct rtw89_phy_table *rf_radio[RF_PATH_MAX];
struct rtw89_phy_table *rf_nctl;
struct rtw89_fw_txpwr_track_cfg *txpwr_trk;
+ struct rtw89_phy_rfk_log_fmt *rfk_log_fmt;
};

struct rtw89_fw_info {
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 76c948da669e..c1ebf1b13c0f 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -729,6 +729,31 @@ int rtw89_build_txpwr_trk_tbl_from_elm(struct rtw89_dev *rtwdev,
return -EFAULT;
}

+static
+int rtw89_build_rfk_log_fmt_from_elm(struct rtw89_dev *rtwdev,
+ const struct rtw89_fw_element_hdr *elm,
+ const union rtw89_fw_element_arg arg)
+{
+ struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
+ u8 rfk_id;
+
+ if (elm_info->rfk_log_fmt)
+ goto allocated;
+
+ elm_info->rfk_log_fmt = kzalloc(sizeof(*elm_info->rfk_log_fmt), GFP_KERNEL);
+ if (!elm_info->rfk_log_fmt)
+ return 1; /* this is an optional element, so just ignore this */
+
+allocated:
+ rfk_id = elm->u.rfk_log_fmt.rfk_id;
+ if (rfk_id >= RTW89_PHY_C2H_RFK_LOG_FUNC_NUM)
+ return 1;
+
+ elm_info->rfk_log_fmt->elm[rfk_id] = elm;
+
+ return 0;
+}
+
static const struct rtw89_fw_element_handler __fw_element_handlers[] = {
[RTW89_FW_ELEMENT_ID_BBMCU0] = {__rtw89_fw_recognize_from_elm,
{ .fw_type = RTW89_FW_BBMCU0 }, NULL},
@@ -784,6 +809,9 @@ static const struct rtw89_fw_element_handler __fw_element_handlers[] = {
[RTW89_FW_ELEMENT_ID_TXPWR_TRK] = {
rtw89_build_txpwr_trk_tbl_from_elm, {}, "PWR_TRK",
},
+ [RTW89_FW_ELEMENT_ID_RFKLOG_FMT] = {
+ rtw89_build_rfk_log_fmt_from_elm, {}, NULL,
+ },
};

int rtw89_fw_recognize_elements(struct rtw89_dev *rtwdev)
@@ -1221,6 +1249,7 @@ static void rtw89_unload_firmware_elements(struct rtw89_dev *rtwdev)
rtw89_free_phy_tbl_from_elm(elm_info->rf_nctl);

kfree(elm_info->txpwr_trk);
+ kfree(elm_info->rfk_log_fmt);
}

void rtw89_unload_firmware(struct rtw89_dev *rtwdev)
diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h
index f2b61e9ad8a7..55ccc07580df 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.h
+++ b/drivers/net/wireless/realtek/rtw89/fw.h
@@ -3427,6 +3427,7 @@ enum rtw89_fw_element_id {
RTW89_FW_ELEMENT_ID_TX_SHAPE_LMT = 16,
RTW89_FW_ELEMENT_ID_TX_SHAPE_LMT_RU = 17,
RTW89_FW_ELEMENT_ID_TXPWR_TRK = 18,
+ RTW89_FW_ELEMENT_ID_RFKLOG_FMT = 19,

RTW89_FW_ELEMENT_ID_NUM,
};
@@ -3542,6 +3543,13 @@ struct rtw89_fw_element_hdr {
__le32 rsvd;
s8 contents[][DELTA_SWINGIDX_SIZE];
} __packed txpwr_trk;
+ struct {
+ u8 nr;
+ u8 rsvd[3];
+ u8 rfk_id; /* enum rtw89_phy_c2h_rfk_log_func */
+ u8 rsvd1[3];
+ __le16 offset[];
+ } __packed rfk_log_fmt;
struct __rtw89_fw_txpwr_element txpwr;
} __packed u;
} __packed;
diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h
index 6792b73e9ca3..b60bc563d86f 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.h
+++ b/drivers/net/wireless/realtek/rtw89/phy.h
@@ -136,6 +136,17 @@ enum rtw89_phy_c2h_ra_func {
RTW89_PHY_C2H_FUNC_RA_MAX,
};

+enum rtw89_phy_c2h_rfk_log_func {
+ RTW89_PHY_C2H_RFK_LOG_FUNC_IQK = 0,
+ RTW89_PHY_C2H_RFK_LOG_FUNC_DPK = 1,
+ RTW89_PHY_C2H_RFK_LOG_FUNC_DACK = 2,
+ RTW89_PHY_C2H_RFK_LOG_FUNC_RXDCK = 3,
+ RTW89_PHY_C2H_RFK_LOG_FUNC_TSSI = 4,
+ RTW89_PHY_C2H_RFK_LOG_FUNC_TXGAPK = 5,
+
+ RTW89_PHY_C2H_RFK_LOG_FUNC_NUM,
+};
+
enum rtw89_phy_c2h_dm_func {
RTW89_PHY_C2H_DM_FUNC_FW_TEST,
RTW89_PHY_C2H_DM_FUNC_FW_TRIG_TX_RPT,
@@ -483,6 +494,10 @@ struct rtw89_txpwr_limit_ru_be {
s8 ru106_26[RTW89_RU_SEC_NUM_BE];
};

+struct rtw89_phy_rfk_log_fmt {
+ const struct rtw89_fw_element_hdr *elm[RTW89_PHY_C2H_RFK_LOG_FUNC_NUM];
+};
+
struct rtw89_phy_gen_def {
u32 cr_base;
const struct rtw89_ccx_regs *ccx;
--
2.25.1


2023-12-13 00:52:56

by Ping-Ke Shih

[permalink] [raw]
Subject: [PATCH v2 4/6] wifi: rtw89: add C2H event handlers of RFK log and report

Trigger a RFK (RF calibration) in firmware by a H2C command, and in
progress it reports log and a result finally by C2H events. Firstly, add
prototype of the C2H event handlers to have a simple picture of framework.

The callers who trigger H2C will wait until a C2H event is received,
so we must process these C2H events in receiving process. Thus, mark this
kind of C2H events as atomic. Also, timestamp is also useful for
debugging, mark C2H events carrying RFK log as atomic as well.

Signed-off-by: Ping-Ke Shih <[email protected]>
---
drivers/net/wireless/realtek/rtw89/fw.c | 2 +
drivers/net/wireless/realtek/rtw89/phy.c | 87 ++++++++++++++++++++++++
drivers/net/wireless/realtek/rtw89/phy.h | 7 ++
3 files changed, 96 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index c1ebf1b13c0f..8c1065278faf 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -3566,6 +3566,8 @@ static bool rtw89_fw_c2h_chk_atomic(struct rtw89_dev *rtwdev,
return false;
case RTW89_C2H_CAT_MAC:
return rtw89_mac_c2h_chk_atomic(rtwdev, class, func);
+ case RTW89_C2H_CAT_OUTSRC:
+ return rtw89_phy_c2h_chk_atomic(rtwdev, class, func);
}
}

diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c
index bfb1d8cfc531..8a4a72b00340 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.c
+++ b/drivers/net/wireless/realtek/rtw89/phy.c
@@ -2445,6 +2445,85 @@ void (* const rtw89_phy_c2h_ra_handler[])(struct rtw89_dev *rtwdev,
[RTW89_PHY_C2H_FUNC_TXSTS] = NULL,
};

+static void
+rtw89_phy_c2h_rfk_log_iqk(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
+{
+}
+
+static void
+rtw89_phy_c2h_rfk_log_dpk(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
+{
+}
+
+static void
+rtw89_phy_c2h_rfk_log_dack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
+{
+}
+
+static void
+rtw89_phy_c2h_rfk_log_rxdck(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
+{
+}
+
+static void
+rtw89_phy_c2h_rfk_log_tssi(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
+{
+}
+
+static void
+rtw89_phy_c2h_rfk_log_txgapk(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
+{
+}
+
+static
+void (* const rtw89_phy_c2h_rfk_log_handler[])(struct rtw89_dev *rtwdev,
+ struct sk_buff *c2h, u32 len) = {
+ [RTW89_PHY_C2H_RFK_LOG_FUNC_IQK] = rtw89_phy_c2h_rfk_log_iqk,
+ [RTW89_PHY_C2H_RFK_LOG_FUNC_DPK] = rtw89_phy_c2h_rfk_log_dpk,
+ [RTW89_PHY_C2H_RFK_LOG_FUNC_DACK] = rtw89_phy_c2h_rfk_log_dack,
+ [RTW89_PHY_C2H_RFK_LOG_FUNC_RXDCK] = rtw89_phy_c2h_rfk_log_rxdck,
+ [RTW89_PHY_C2H_RFK_LOG_FUNC_TSSI] = rtw89_phy_c2h_rfk_log_tssi,
+ [RTW89_PHY_C2H_RFK_LOG_FUNC_TXGAPK] = rtw89_phy_c2h_rfk_log_txgapk,
+};
+
+static void
+rtw89_phy_c2h_rfk_report_state(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
+{
+}
+
+static
+void (* const rtw89_phy_c2h_rfk_report_handler[])(struct rtw89_dev *rtwdev,
+ struct sk_buff *c2h, u32 len) = {
+ [RTW89_PHY_C2H_RFK_REPORT_FUNC_STATE] = rtw89_phy_c2h_rfk_report_state,
+};
+
+bool rtw89_phy_c2h_chk_atomic(struct rtw89_dev *rtwdev, u8 class, u8 func)
+{
+ switch (class) {
+ case RTW89_PHY_C2H_RFK_LOG:
+ switch (func) {
+ case RTW89_PHY_C2H_RFK_LOG_FUNC_IQK:
+ case RTW89_PHY_C2H_RFK_LOG_FUNC_DPK:
+ case RTW89_PHY_C2H_RFK_LOG_FUNC_DACK:
+ case RTW89_PHY_C2H_RFK_LOG_FUNC_RXDCK:
+ case RTW89_PHY_C2H_RFK_LOG_FUNC_TSSI:
+ case RTW89_PHY_C2H_RFK_LOG_FUNC_TXGAPK:
+ return true;
+ default:
+ return false;
+ }
+ case RTW89_PHY_C2H_RFK_REPORT:
+ switch (func) {
+ case RTW89_PHY_C2H_RFK_REPORT_FUNC_STATE:
+ return true;
+ default:
+ return false;
+ }
+ default:
+ return false;
+ }
+}
+
void rtw89_phy_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
u32 len, u8 class, u8 func)
{
@@ -2456,6 +2535,14 @@ void rtw89_phy_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
if (func < RTW89_PHY_C2H_FUNC_RA_MAX)
handler = rtw89_phy_c2h_ra_handler[func];
break;
+ case RTW89_PHY_C2H_RFK_LOG:
+ if (func < ARRAY_SIZE(rtw89_phy_c2h_rfk_log_handler))
+ handler = rtw89_phy_c2h_rfk_log_handler[func];
+ break;
+ case RTW89_PHY_C2H_RFK_REPORT:
+ if (func < ARRAY_SIZE(rtw89_phy_c2h_rfk_report_handler))
+ handler = rtw89_phy_c2h_rfk_report_handler[func];
+ break;
case RTW89_PHY_C2H_CLASS_DM:
if (func == RTW89_PHY_C2H_DM_FUNC_LOWRT_RTY)
return;
diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h
index b60bc563d86f..3e379077c6ca 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.h
+++ b/drivers/net/wireless/realtek/rtw89/phy.h
@@ -147,6 +147,10 @@ enum rtw89_phy_c2h_rfk_log_func {
RTW89_PHY_C2H_RFK_LOG_FUNC_NUM,
};

+enum rtw89_phy_c2h_rfk_report_func {
+ RTW89_PHY_C2H_RFK_REPORT_FUNC_STATE = 0,
+};
+
enum rtw89_phy_c2h_dm_func {
RTW89_PHY_C2H_DM_FUNC_FW_TEST,
RTW89_PHY_C2H_DM_FUNC_FW_TRIG_TX_RPT,
@@ -160,6 +164,8 @@ enum rtw89_phy_c2h_class {
RTW89_PHY_C2H_CLASS_RUA,
RTW89_PHY_C2H_CLASS_RA,
RTW89_PHY_C2H_CLASS_DM,
+ RTW89_PHY_C2H_RFK_LOG = 0x8,
+ RTW89_PHY_C2H_RFK_REPORT = 0x9,
RTW89_PHY_C2H_CLASS_BTC_MIN = 0x10,
RTW89_PHY_C2H_CLASS_BTC_MAX = 0x17,
RTW89_PHY_C2H_CLASS_MAX,
@@ -800,6 +806,7 @@ void rtw89_phy_ra_updata_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta
void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
const struct cfg80211_bitrate_mask *mask);
+bool rtw89_phy_c2h_chk_atomic(struct rtw89_dev *rtwdev, u8 class, u8 func);
void rtw89_phy_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
u32 len, u8 class, u8 func);
void rtw89_phy_cfo_track(struct rtw89_dev *rtwdev);
--
2.25.1


2023-12-13 00:53:04

by Ping-Ke Shih

[permalink] [raw]
Subject: [PATCH v2 6/6] wifi: rtw89: phy: print out RFK log with formatted string

With formatted string loaded from firmware file, we can use the formatted
string ID and get corresponding string, and then use regular rtw89_debug()
to show the message if debug mask of RFK is enabled.

If the string ID doesn't present, fallback to print plain hexadecimal.

Signed-off-by: Ping-Ke Shih <[email protected]>
---
drivers/net/wireless/realtek/rtw89/fw.h | 5 ++++
drivers/net/wireless/realtek/rtw89/phy.c | 38 ++++++++++++++++++++++++
2 files changed, 43 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h
index aa749732a9e2..bfe226fe3d07 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.h
+++ b/drivers/net/wireless/realtek/rtw89/fw.h
@@ -3733,6 +3733,11 @@ struct rtw89_c2h_rf_log_hdr {
u8 content[];
} __packed;

+struct rtw89_c2h_rf_run_log {
+ __le32 fmt_idx;
+ __le32 arg[4];
+} __packed;
+
struct rtw89_c2h_rf_dpk_rpt_log {
u8 ver;
u8 idx[2];
diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c
index 496160f72755..bafc7b1cc104 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.c
+++ b/drivers/net/wireless/realtek/rtw89/phy.c
@@ -2566,6 +2566,38 @@ static void rtw89_phy_c2h_rfk_rpt_log(struct rtw89_dev *rtwdev,
"unexpected RFK func %d report log with length %d\n", func, len);
}

+static bool rtw89_phy_c2h_rfk_run_log(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_c2h_rfk_log_func func,
+ void *content, u16 len)
+{
+ struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
+ const struct rtw89_c2h_rf_run_log *log = content;
+ const struct rtw89_fw_element_hdr *elm;
+ u32 fmt_idx;
+ u16 offset;
+
+ if (sizeof(*log) != len)
+ return false;
+
+ if (!elm_info->rfk_log_fmt)
+ return false;
+
+ elm = elm_info->rfk_log_fmt->elm[func];
+ fmt_idx = le32_to_cpu(log->fmt_idx);
+ if (!elm || fmt_idx >= elm->u.rfk_log_fmt.nr)
+ return false;
+
+ offset = le16_to_cpu(elm->u.rfk_log_fmt.offset[fmt_idx]);
+ if (offset == 0)
+ return false;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, &elm->u.common.contents[offset],
+ le32_to_cpu(log->arg[0]), le32_to_cpu(log->arg[1]),
+ le32_to_cpu(log->arg[2]), le32_to_cpu(log->arg[3]));
+
+ return true;
+}
+
static void rtw89_phy_c2h_rfk_log(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
u32 len, enum rtw89_phy_c2h_rfk_log_func func,
const char *rfk_name)
@@ -2575,6 +2607,7 @@ static void rtw89_phy_c2h_rfk_log(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
void *log_ptr = c2h_hdr;
u16 content_len;
u16 chunk_len;
+ bool handled;

if (!rtw89_debug_is_enabled(rtwdev, RTW89_DBG_RFK))
return;
@@ -2592,6 +2625,11 @@ static void rtw89_phy_c2h_rfk_log(struct rtw89_dev *rtwdev, struct sk_buff *c2h,

switch (log_hdr->type) {
case RTW89_RF_RUN_LOG:
+ handled = rtw89_phy_c2h_rfk_run_log(rtwdev, func,
+ log_hdr->content, content_len);
+ if (handled)
+ break;
+
rtw89_debug(rtwdev, RTW89_DBG_RFK, "%s run: %*ph\n",
rfk_name, content_len, log_hdr->content);
break;
--
2.25.1


2023-12-15 13:38:51

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH v2 1/6] wifi: rtw89: fw: load TX power track tables from fw_element

Ping-Ke Shih <[email protected]> wrote:

> The TX power track tables are used to define compensation power reflected
> to thermal value. Currently, we have 16 (2 * 4 * 2) tables made by
> combinations of
> {negative/positive thermal value, 2GHz/2GHz-CCK/5GHz/6GHz, path A/B}
>
> Signed-off-by: Ping-Ke Shih <[email protected]>

6 patches applied to wireless-next.git, thanks.

d60e73e5dd70 wifi: rtw89: fw: load TX power track tables from fw_element
344c066f2f5a wifi: rtw89: fw: add version field to BB MCU firmware element
7a9192eecf27 wifi: rtw89: load RFK log format string from firmware file
178b8e7d8a59 wifi: rtw89: add C2H event handlers of RFK log and report
edd77bb091d1 wifi: rtw89: parse and print out RFK log from C2H events
f0536b0d5fa8 wifi: rtw89: phy: print out RFK log with formatted string

--
https://patchwork.kernel.org/project/linux-wireless/patch/[email protected]/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches