From: Ching-Te Ku Date: Mon, 16 Jun 2025 09:02:44 +0000 (+0800) Subject: wifi: rtw89: coex: Query Bluetooth TX power when firmware support X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=10a39b9fd7a11591371bc352c16524f1a4d76396;p=thirdparty%2Flinux.git wifi: rtw89: coex: Query Bluetooth TX power when firmware support Add firmware report to monitor Bluetooth TX power/gain settings, so that we can check it works as expected or not. Signed-off-by: Ching-Te Ku Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20250616090252.51098-4-pkshih@realtek.com --- diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c index 3c607f5548b8d..d02725aad6c7a 100644 --- a/drivers/net/wireless/realtek/rtw89/coex.c +++ b/drivers/net/wireless/realtek/rtw89/coex.c @@ -153,8 +153,8 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = { .fcxbtcrpt = 8, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7, .fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7, .fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7, - .fwlrole = 8, .frptmap = 3, .fcxctrl = 7, .fcxinit = 7, - .fwevntrptl = 1, .fwc2hfunc = 2, .drvinfo_type = 2, .info_buf = 1800, + .fwlrole = 8, .frptmap = 4, .fcxctrl = 7, .fcxinit = 7, + .fwevntrptl = 1, .fwc2hfunc = 3, .drvinfo_type = 2, .info_buf = 1800, .max_role_num = 6, .fcxosi = 1, .fcxmlo = 1, }, {RTL8922A, RTW89_FW_VER_CODE(0, 35, 8, 0), @@ -333,6 +333,7 @@ enum btc_btf_set_report_en { RPT_EN_BT_DEVICE_INFO, RPT_EN_BT_AFH_MAP, RPT_EN_BT_AFH_MAP_LE, + RPT_EN_BT_TX_PWR_LVL, RPT_EN_FW_STEP_INFO, RPT_EN_TEST, RPT_EN_WL_ALL, @@ -896,6 +897,9 @@ static int _send_fw_cmd(struct rtw89_dev *rtwdev, u8 h2c_class, u8 h2c_func, return ret; } +#define BTC_BT_DEF_BR_TX_PWR 4 +#define BTC_BT_DEF_LE_TX_PWR 4 + static void _reset_btc_var(struct rtw89_dev *rtwdev, u8 type) { struct rtw89_btc *btc = &rtwdev->btc; @@ -964,6 +968,9 @@ static void _reset_btc_var(struct rtw89_dev *rtwdev, u8 type) if (type & BTC_RESET_MDINFO) memset(&btc->mdinfo, 0, sizeof(btc->mdinfo)); + + bt->link_info.bt_txpwr_desc.br_dbm = BTC_BT_DEF_BR_TX_PWR; + bt->link_info.bt_txpwr_desc.le_dbm = BTC_BT_DEF_LE_TX_PWR; } static u8 _search_reg_index(struct rtw89_dev *rtwdev, u8 mreg_num, u16 reg_type, u32 target) @@ -2381,6 +2388,7 @@ static u32 rtw89_btc_fw_rpt_ver(struct rtw89_dev *rtwdev, u32 rpt_map) bit_map = BIT(6); break; case 3: + case 4: bit_map = BIT(5); break; default: @@ -2395,6 +2403,7 @@ static u32 rtw89_btc_fw_rpt_ver(struct rtw89_dev *rtwdev, u32 rpt_map) bit_map = BIT(5); break; case 3: + case 4: bit_map = BIT(6); break; default: @@ -2407,12 +2416,27 @@ static u32 rtw89_btc_fw_rpt_ver(struct rtw89_dev *rtwdev, u32 rpt_map) bit_map = BIT(8); break; case 3: + case 4: bit_map = BIT(7); break; default: break; } break; + case RPT_EN_BT_TX_PWR_LVL: + switch (ver->frptmap) { + case 0: + case 1: + case 2: + case 3: + break; + case 4: + bit_map = BIT(8); + break; + default: + break; + } + break; case RPT_EN_FW_STEP_INFO: switch (ver->frptmap) { case 1: @@ -2422,6 +2446,9 @@ static u32 rtw89_btc_fw_rpt_ver(struct rtw89_dev *rtwdev, u32 rpt_map) case 3: bit_map = BIT(8); break; + case 4: + bit_map = BIT(9); + break; default: break; } @@ -2439,6 +2466,9 @@ static u32 rtw89_btc_fw_rpt_ver(struct rtw89_dev *rtwdev, u32 rpt_map) case 3: bit_map = GENMASK(2, 0) | BIT(8); break; + case 4: + bit_map = GENMASK(2, 0) | BIT(9); + break; default: break; } @@ -2455,6 +2485,9 @@ static u32 rtw89_btc_fw_rpt_ver(struct rtw89_dev *rtwdev, u32 rpt_map) case 3: bit_map = GENMASK(7, 3); break; + case 4: + bit_map = GENMASK(8, 3); + break; default: break; } @@ -2471,6 +2504,9 @@ static u32 rtw89_btc_fw_rpt_ver(struct rtw89_dev *rtwdev, u32 rpt_map) case 3: bit_map = GENMASK(8, 0); break; + case 4: + bit_map = GENMASK(9, 0); + break; default: break; } @@ -2487,6 +2523,9 @@ static u32 rtw89_btc_fw_rpt_ver(struct rtw89_dev *rtwdev, u32 rpt_map) case 3: bit_map = GENMASK(8, 2); break; + case 4: + bit_map = GENMASK(9, 2); + break; default: break; } @@ -7379,6 +7418,25 @@ static void _update_bt_scbd(struct rtw89_dev *rtwdev, bool only_update) _run_coex(rtwdev, BTC_RSN_UPDATE_BT_SCBD); } +#define BTC_BTINFO_PWR_LEN 5 +static void _update_bt_txpwr_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len) +{ + struct rtw89_btc_bt_info *bt = &rtwdev->btc.cx.bt; + struct rtw89_btc_bt_link_info *b = &bt->link_info; + + if (len != BTC_BTINFO_PWR_LEN) + return; + + if (!memcmp(bt->txpwr_info, buf, sizeof(bt->txpwr_info))) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s return by info duplicate!\n", __func__); + return; + } + + memcpy(bt->txpwr_info, buf, BTC_BTINFO_MAX); + memcpy(&b->bt_txpwr_desc, &buf[2], sizeof(b->bt_txpwr_desc)); +} + static bool _chk_wl_rfk_request(struct rtw89_dev *rtwdev) { struct rtw89_btc *btc = &rtwdev->btc; @@ -8617,6 +8675,8 @@ static u8 rtw89_btc_c2h_get_index_by_ver(struct rtw89_dev *rtwdev, u8 func) return BTF_EVNT_BUF_OVERFLOW; else if (ver->fwc2hfunc == 2) return func; + else if (ver->fwc2hfunc == 3) + return BTF_EVNT_BUF_OVERFLOW; else return BTF_EVNT_MAX; case BTF_EVNT_BUF_OVERFLOW: @@ -8626,11 +8686,20 @@ static u8 rtw89_btc_c2h_get_index_by_ver(struct rtw89_dev *rtwdev, u8 func) return BTF_EVNT_C2H_LOOPBACK; else if (ver->fwc2hfunc == 2) return func; + else if (ver->fwc2hfunc == 3) + return BTF_EVNT_C2H_LOOPBACK; else return BTF_EVNT_MAX; case BTF_EVNT_C2H_LOOPBACK: if (ver->fwc2hfunc == 2) return func; + else if (ver->fwc2hfunc == 3) + return BTF_EVNT_BT_LEAUDIO_INFO; + else + return BTF_EVNT_MAX; + case BTF_EVNT_BT_QUERY_TXPWR: + if (ver->fwc2hfunc == 3) + return func; else return BTF_EVNT_MAX; case BTF_EVNT_MAX: @@ -8693,6 +8762,9 @@ void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb, case BTF_EVNT_CX_RUNINFO: btc->dm.cnt_dm[BTC_DCNT_CX_RUNINFO]++; break; + case BTF_EVNT_BT_QUERY_TXPWR: + btc->cx.cnt_bt[BTC_BCNT_BTTXPWR_UPDATE]++; + _update_bt_txpwr_info(rtwdev, buf, len); } } @@ -8965,8 +9037,11 @@ static int _show_bt_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) struct rtw89_btc_cx *cx = &btc->cx; struct rtw89_btc_bt_info *bt = &cx->bt; struct rtw89_btc_wl_info *wl = &cx->wl; + u32 ver_main = FIELD_GET(GENMASK(31, 24), wl->ver_info.fw_coex); struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info; union rtw89_btc_module_info *md = &btc->mdinfo; + s8 br_dbm = bt->link_info.bt_txpwr_desc.br_dbm; + s8 le_dbm = bt->link_info.bt_txpwr_desc.le_dbm; char *p = buf, *end = buf + bufsz; u8 *afh = bt_linfo->afh_map; u8 *afh_le = bt_linfo->afh_map_le; @@ -9099,6 +9174,28 @@ static int _show_bt_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) p += scnprintf(p, end - p, "\n"); } + if (ver_main >= 9 && bt_linfo->profile_cnt.now) + rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_TX_PWR_LVL, true); + else + rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_TX_PWR_LVL, false); + + if (cx->cnt_bt[BTC_BCNT_BTTXPWR_UPDATE]) { + p += scnprintf(p, end - p, + " %-15s : br_index:0x%x, le_index:0x%x", + "[bt_txpwr_lvl]", + bt->link_info.bt_txpwr_desc.br_gain_index, + bt->link_info.bt_txpwr_desc.le_gain_index); + p += scnprintf(p, end - p, ", br_dbm:%d dBm", br_dbm); + p += scnprintf(p, end - p, ", le_dbm:%d dBm", le_dbm); + } else { + p += scnprintf(p, end - p, + " %-15s : br_index:NA, le_index:NA, br_dbm:%d dBm[def], le_dbm:%d dBm[def]", + "[bt_txpwr_lvl]", + bt->link_info.bt_txpwr_desc.br_dbm, + bt->link_info.bt_txpwr_desc.le_dbm); + } + p += scnprintf(p, end - p, "\n"); + if (bt_linfo->profile_cnt.now || bt_linfo->status.map.ble_connect) rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_AFH_MAP, true); else diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 328d4e9352fe0..3b046727e04a9 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -1322,6 +1322,7 @@ enum rtw89_btc_bt_state_cnt { BTC_BCNT_POLUT_NOW, BTC_BCNT_POLUT_DIFF, BTC_BCNT_RATECHG, + BTC_BCNT_BTTXPWR_UPDATE, BTC_BCNT_NUM, }; @@ -1810,6 +1811,13 @@ union rtw89_btc_bt_state_map { #define BTC_BT_AFH_GROUP 12 #define BTC_BT_AFH_LE_GROUP 5 +struct rtw89_btc_bt_txpwr_desc { + s8 br_dbm; + s8 le_dbm; + u8 br_gain_index; + u8 le_gain_index; +}; + struct rtw89_btc_bt_link_info { struct rtw89_btc_u8_sta_chg profile_cnt; struct rtw89_btc_bool_sta_chg multi_link; @@ -1819,6 +1827,7 @@ struct rtw89_btc_bt_link_info { struct rtw89_btc_bt_a2dp_desc a2dp_desc; struct rtw89_btc_bt_pan_desc pan_desc; union rtw89_btc_bt_state_map status; + struct rtw89_btc_bt_txpwr_desc bt_txpwr_desc; u8 sut_pwr_level[BTC_PROFILE_MAX]; u8 golden_rx_shift[BTC_PROFILE_MAX]; @@ -2089,6 +2098,7 @@ struct rtw89_btc_bt_info { union rtw89_btc_bt_rfk_info_map rfk_info; u8 raw_info[BTC_BTINFO_MAX]; /* raw bt info from mailbox */ + u8 txpwr_info[BTC_BTINFO_MAX]; u8 rssi_level; u32 scbd; @@ -3042,6 +3052,7 @@ enum rtw89_btc_btf_fw_event { BTF_EVNT_BT_LEAUDIO_INFO = 7, /* fwc2hfunc > 1 */ BTF_EVNT_BUF_OVERFLOW, BTF_EVNT_C2H_LOOPBACK, + BTF_EVNT_BT_QUERY_TXPWR, /* fwc2hfunc > 3 */ BTF_EVNT_MAX, };