diff options
Diffstat (limited to 'drivers/net/wireless/realtek/rtw89/coex.c')
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/coex.c | 1887 |
1 files changed, 1571 insertions, 316 deletions
diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c index 683854bba217..bbdfa9ac203c 100644 --- a/drivers/net/wireless/realtek/rtw89/coex.c +++ b/drivers/net/wireless/realtek/rtw89/coex.c @@ -9,6 +9,7 @@ #include "ps.h" #include "reg.h" +#define RTW89_COEX_VERSION 0x06030013 #define FCXDEF_STEP 50 /* MUST <= FCXMAX_STEP and match with wl fw*/ enum btc_fbtc_tdma_template { @@ -77,21 +78,21 @@ static const struct rtw89_btc_fbtc_tdma t_def[] = { static const struct rtw89_btc_fbtc_slot s_def[] = { [CXST_OFF] = __DEF_FBTC_SLOT(100, 0x55555555, SLOT_MIX), - [CXST_B2W] = __DEF_FBTC_SLOT(5, 0x5a5a5a5a, SLOT_ISO), - [CXST_W1] = __DEF_FBTC_SLOT(70, 0x5a5a5a5a, SLOT_ISO), - [CXST_W2] = __DEF_FBTC_SLOT(70, 0x5a5a5aaa, SLOT_ISO), - [CXST_W2B] = __DEF_FBTC_SLOT(15, 0x5a5a5a5a, SLOT_ISO), - [CXST_B1] = __DEF_FBTC_SLOT(100, 0x55555555, SLOT_MIX), - [CXST_B2] = __DEF_FBTC_SLOT(7, 0x6a5a5a5a, SLOT_MIX), - [CXST_B3] = __DEF_FBTC_SLOT(5, 0x55555555, SLOT_MIX), - [CXST_B4] = __DEF_FBTC_SLOT(50, 0x55555555, SLOT_MIX), - [CXST_LK] = __DEF_FBTC_SLOT(20, 0x5a5a5a5a, SLOT_ISO), + [CXST_B2W] = __DEF_FBTC_SLOT(5, 0xea5a5a5a, SLOT_ISO), + [CXST_W1] = __DEF_FBTC_SLOT(70, 0xea5a5a5a, SLOT_ISO), + [CXST_W2] = __DEF_FBTC_SLOT(70, 0xea5a5aaa, SLOT_ISO), + [CXST_W2B] = __DEF_FBTC_SLOT(15, 0xea5a5a5a, SLOT_ISO), + [CXST_B1] = __DEF_FBTC_SLOT(100, 0xe5555555, SLOT_MIX), + [CXST_B2] = __DEF_FBTC_SLOT(7, 0xea5a5a5a, SLOT_MIX), + [CXST_B3] = __DEF_FBTC_SLOT(5, 0xe5555555, SLOT_MIX), + [CXST_B4] = __DEF_FBTC_SLOT(50, 0xe5555555, SLOT_MIX), + [CXST_LK] = __DEF_FBTC_SLOT(20, 0xea5a5a5a, SLOT_ISO), [CXST_BLK] = __DEF_FBTC_SLOT(250, 0x55555555, SLOT_MIX), - [CXST_E2G] = __DEF_FBTC_SLOT(20, 0x6a5a5a5a, SLOT_MIX), + [CXST_E2G] = __DEF_FBTC_SLOT(20, 0xea5a5a5a, SLOT_MIX), [CXST_E5G] = __DEF_FBTC_SLOT(20, 0xffffffff, SLOT_MIX), - [CXST_EBT] = __DEF_FBTC_SLOT(20, 0x55555555, SLOT_MIX), + [CXST_EBT] = __DEF_FBTC_SLOT(20, 0xe5555555, SLOT_MIX), [CXST_ENULL] = __DEF_FBTC_SLOT(7, 0xaaaaaaaa, SLOT_ISO), - [CXST_WLK] = __DEF_FBTC_SLOT(250, 0x6a5a6a5a, SLOT_MIX), + [CXST_WLK] = __DEF_FBTC_SLOT(250, 0xea5a5a5a, SLOT_MIX), [CXST_W1FDD] = __DEF_FBTC_SLOT(35, 0xfafafafa, SLOT_ISO), [CXST_B1FDD] = __DEF_FBTC_SLOT(100, 0xffffffff, SLOT_MIX), }; @@ -99,13 +100,13 @@ static const struct rtw89_btc_fbtc_slot s_def[] = { static const u32 cxtbl[] = { 0xffffffff, /* 0 */ 0xaaaaaaaa, /* 1 */ - 0x55555555, /* 2 */ - 0x66555555, /* 3 */ - 0x66556655, /* 4 */ + 0xe5555555, /* 2 */ + 0xee555555, /* 3 */ + 0xd5555555, /* 4 */ 0x5a5a5a5a, /* 5 */ - 0x5a5a5aaa, /* 6 */ - 0xaa5a5a5a, /* 7 */ - 0x6a5a5a5a, /* 8 */ + 0xfa5a5a5a, /* 6 */ + 0xda5a5a5a, /* 7 */ + 0xea5a5a5a, /* 8 */ 0x6a5a5aaa, /* 9 */ 0x6a5a6a5a, /* 10 */ 0x6a5a6aaa, /* 11 */ @@ -261,6 +262,12 @@ enum btc_cx_poicy_type { /* TDMA off + pri: WL_Hi-Tx > BT_Hi_Rx, BT_Hi > WL > BT_Lo */ BTC_CXP_OFF_BWB1 = (BTC_CXP_OFF << 8) | 7, + /* TDMA off + pri: WL_Hi-Tx > BT, BT_Hi > other-WL > BT_Lo */ + BTC_CXP_OFF_BWB2 = (BTC_CXP_OFF << 8) | 8, + + /* TDMA off + pri: WL_Hi-Tx = BT */ + BTC_CXP_OFF_BWB3 = (BTC_CXP_OFF << 8) | 9, + /* TDMA off+Bcn-Protect + pri: WL_Hi-Tx > BT_Hi_Rx, BT_Hi > WL > BT_Lo*/ BTC_CXP_OFFB_BWB0 = (BTC_CXP_OFFB << 8) | 0, @@ -270,6 +277,21 @@ enum btc_cx_poicy_type { /* TDMA off + Ext-Ctrl + pri: E2G-slot block all BT */ BTC_CXP_OFFE_DEF2 = (BTC_CXP_OFFE << 8) | 1, + /* TDMA off + Ext-Ctrl + pri: default */ + BTC_CXP_OFFE_2GBWISOB = (BTC_CXP_OFFE << 8) | 2, + + /* TDMA off + Ext-Ctrl + pri: E2G-slot block all BT */ + BTC_CXP_OFFE_2GISOB = (BTC_CXP_OFFE << 8) | 3, + + /* TDMA off + Ext-Ctrl + pri: E2G-slot WL > BT */ + BTC_CXP_OFFE_2GBWMIXB = (BTC_CXP_OFFE << 8) | 4, + + /* TDMA off + Ext-Ctrl + pri: E2G/EBT-slot WL > BT */ + BTC_CXP_OFFE_WL = (BTC_CXP_OFFE << 8) | 5, + + /* TDMA off + Ext-Ctrl + pri: default */ + BTC_CXP_OFFE_2GBWMIXB2 = (BTC_CXP_OFFE << 8) | 6, + /* TDMA Fix slot-0: W1:B1 = 30:30 */ BTC_CXP_FIX_TD3030 = (BTC_CXP_FIX << 8) | 0, @@ -300,6 +322,9 @@ enum btc_cx_poicy_type { /* TDMA Fix slot-9: W1:B1 = 40:20 */ BTC_CXP_FIX_TD4020 = (BTC_CXP_FIX << 8) | 9, + /* TDMA Fix slot-9: W1:B1 = 40:10 */ + BTC_CXP_FIX_TD4010ISO = (BTC_CXP_FIX << 8) | 10, + /* PS-TDMA Fix slot-0: W1:B1 = 30:30 */ BTC_CXP_PFIX_TD3030 = (BTC_CXP_PFIX << 8) | 0, @@ -322,25 +347,25 @@ enum btc_cx_poicy_type { BTC_CXP_PFIX_TDW1B1 = (BTC_CXP_PFIX << 8) | 6, /* TDMA Auto slot-0: W1:B1 = 50:200 */ - BTC_CXP_AUTO_TD50200 = (BTC_CXP_AUTO << 8) | 0, + BTC_CXP_AUTO_TD50B1 = (BTC_CXP_AUTO << 8) | 0, /* TDMA Auto slot-1: W1:B1 = 60:200 */ - BTC_CXP_AUTO_TD60200 = (BTC_CXP_AUTO << 8) | 1, + BTC_CXP_AUTO_TD60B1 = (BTC_CXP_AUTO << 8) | 1, /* TDMA Auto slot-2: W1:B1 = 20:200 */ - BTC_CXP_AUTO_TD20200 = (BTC_CXP_AUTO << 8) | 2, + BTC_CXP_AUTO_TD20B1 = (BTC_CXP_AUTO << 8) | 2, /* TDMA Auto slot-3: W1:B1 = user-define */ BTC_CXP_AUTO_TDW1B1 = (BTC_CXP_AUTO << 8) | 3, /* PS-TDMA Auto slot-0: W1:B1 = 50:200 */ - BTC_CXP_PAUTO_TD50200 = (BTC_CXP_PAUTO << 8) | 0, + BTC_CXP_PAUTO_TD50B1 = (BTC_CXP_PAUTO << 8) | 0, /* PS-TDMA Auto slot-1: W1:B1 = 60:200 */ - BTC_CXP_PAUTO_TD60200 = (BTC_CXP_PAUTO << 8) | 1, + BTC_CXP_PAUTO_TD60B1 = (BTC_CXP_PAUTO << 8) | 1, /* PS-TDMA Auto slot-2: W1:B1 = 20:200 */ - BTC_CXP_PAUTO_TD20200 = (BTC_CXP_PAUTO << 8) | 2, + BTC_CXP_PAUTO_TD20B1 = (BTC_CXP_PAUTO << 8) | 2, /* PS-TDMA Auto slot-3: W1:B1 = user-define */ BTC_CXP_PAUTO_TDW1B1 = (BTC_CXP_PAUTO << 8) | 3, @@ -412,7 +437,7 @@ enum btc_w2b_scoreboard { BTC_WSCB_TDMA = BIT(9), BTC_WSCB_FIX2M = BIT(10), BTC_WSCB_WLRFK = BIT(11), - BTC_WSCB_BTRFK_GNT = BIT(12), /* not used, use mailbox to inform BT */ + BTC_WSCB_RXSCAN_PRI = BIT(12), BTC_WSCB_BT_HILNA = BIT(13), BTC_WSCB_BTLOG = BIT(14), BTC_WSCB_ALL = GENMASK(23, 0), @@ -434,6 +459,16 @@ enum btc_wl_link_mode { BTC_WLINK_MAX }; +enum btc_wl_mrole_type { + BTC_WLMROLE_NONE = 0x0, + BTC_WLMROLE_STA_GC, + BTC_WLMROLE_STA_GC_NOA, + BTC_WLMROLE_STA_GO, + BTC_WLMROLE_STA_GO_NOA, + BTC_WLMROLE_STA_STA, + BTC_WLMROLE_MAX +}; + enum btc_bt_hid_type { BTC_HID_218 = BIT(0), BTC_HID_418 = BIT(1), @@ -460,6 +495,11 @@ enum btc_gnt_state { BTC_GNT_MAX }; +enum btc_ctr_path { + BTC_CTRL_BY_BT = 0, + BTC_CTRL_BY_WL +}; + enum btc_wl_max_tx_time { BTC_MAX_TX_TIME_L1 = 500, BTC_MAX_TX_TIME_L2 = 1000, @@ -531,6 +571,7 @@ enum btc_reason_and_action { #define BTC_FREERUN_ANTISO_MIN 30 #define BTC_TDMA_BTHID_MAX 2 #define BTC_BLINK_NOCONNECT 0 +#define BTC_B1_MAX 250 /* unit ms */ static void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason); @@ -551,8 +592,10 @@ static void _send_fw_cmd(struct rtw89_dev *rtwdev, u8 h2c_class, u8 h2c_func, "[BTC], %s(): return by btc not init!!\n", __func__); pfwinfo->cnt_h2c_fail++; return; - } else if ((wl->status.map.rf_off_pre == 1 && wl->status.map.rf_off == 1) || - (wl->status.map.lps_pre == 1 && wl->status.map.lps == 1)) { + } else if ((wl->status.map.rf_off_pre == BTC_LPS_RF_OFF && + wl->status.map.rf_off == BTC_LPS_RF_OFF) || + (wl->status.map.lps_pre == BTC_LPS_RF_OFF && + wl->status.map.lps == BTC_LPS_RF_OFF)) { rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): return by wl off!!\n", __func__); pfwinfo->cnt_h2c_fail++; @@ -616,8 +659,6 @@ static void _reset_btc_var(struct rtw89_dev *rtwdev, u8 type) memset(&btc->mdinfo, 0, sizeof(btc->mdinfo)); } -#define BTC_FWINFO_BUF 1024 - #define BTC_RPT_HDR_SIZE 3 #define BTC_CHK_WLSLOT_DRIFT_MAX 15 #define BTC_CHK_HANG_MAX 3 @@ -869,18 +910,24 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, struct rtw89_btc_btf_fwinfo *pfwinfo, u8 *prptbuf, u32 index) { + const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_dm *dm = &btc->dm; struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; struct rtw89_btc_wl_info *wl = &btc->cx.wl; - struct rtw89_btc_fbtc_rpt_ctrl *prpt = NULL; + struct rtw89_btc_bt_info *bt = &btc->cx.bt; + struct rtw89_btc_fbtc_rpt_ctrl *prpt; + struct rtw89_btc_fbtc_rpt_ctrl_v1 *prpt_v1; struct rtw89_btc_fbtc_cysta *pcysta_le32 = NULL; + struct rtw89_btc_fbtc_cysta_v1 *pcysta_v1 = NULL; struct rtw89_btc_fbtc_cysta_cpu pcysta[1]; struct rtw89_btc_prpt *btc_prpt = NULL; struct rtw89_btc_fbtc_slot *rtp_slot = NULL; - u8 rpt_type = 0, *rpt_content = NULL, *pfinfo = NULL; - u16 wl_slot_set = 0; + void *rpt_content = NULL, *pfinfo = NULL; + u8 rpt_type = 0; + u16 wl_slot_set = 0, wl_slot_real = 0; u32 trace_step = btc->ctrl.trace_step, rpt_len = 0, diff_t; + u32 cnt_leak_slot = 0, bt_slot_real = 0, cnt_rx_imr = 0; u8 i; rtw89_debug(rtwdev, RTW89_DBG_BTC, @@ -904,100 +951,129 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, switch (rpt_type) { case BTC_RPT_TYPE_CTRL: pcinfo = &pfwinfo->rpt_ctrl.cinfo; - pfinfo = (u8 *)(&pfwinfo->rpt_ctrl.finfo); - pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo); - pcinfo->req_fver = BTCRPT_VER; + if (chip->chip_id == RTL8852A) { + pfinfo = &pfwinfo->rpt_ctrl.finfo; + pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo); + } else { + pfinfo = &pfwinfo->rpt_ctrl.finfo_v1; + pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo_v1); + } + pcinfo->req_fver = chip->fcxbtcrpt_ver; pcinfo->rx_len = rpt_len; pcinfo->rx_cnt++; break; case BTC_RPT_TYPE_TDMA: pcinfo = &pfwinfo->rpt_fbtc_tdma.cinfo; - pfinfo = (u8 *)(&pfwinfo->rpt_fbtc_tdma.finfo); - pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_tdma.finfo); - pcinfo->req_fver = FCXTDMA_VER; + if (chip->chip_id == RTL8852A) { + pfinfo = &pfwinfo->rpt_fbtc_tdma.finfo; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_tdma.finfo); + } else { + pfinfo = &pfwinfo->rpt_fbtc_tdma.finfo_v1; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_tdma.finfo_v1); + } + pcinfo->req_fver = chip->fcxtdma_ver; pcinfo->rx_len = rpt_len; pcinfo->rx_cnt++; break; case BTC_RPT_TYPE_SLOT: pcinfo = &pfwinfo->rpt_fbtc_slots.cinfo; - pfinfo = (u8 *)(&pfwinfo->rpt_fbtc_slots.finfo); + pfinfo = &pfwinfo->rpt_fbtc_slots.finfo; pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_slots.finfo); - pcinfo->req_fver = FCXSLOTS_VER; + pcinfo->req_fver = chip->fcxslots_ver; pcinfo->rx_len = rpt_len; pcinfo->rx_cnt++; break; case BTC_RPT_TYPE_CYSTA: pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; - pfinfo = (u8 *)(&pfwinfo->rpt_fbtc_cysta.finfo); - pcysta_le32 = &pfwinfo->rpt_fbtc_cysta.finfo; - rtw89_btc_fbtc_cysta_to_cpu(pcysta_le32, pcysta); - pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo); - pcinfo->req_fver = FCXCYSTA_VER; + if (chip->chip_id == RTL8852A) { + pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo; + pcysta_le32 = &pfwinfo->rpt_fbtc_cysta.finfo; + rtw89_btc_fbtc_cysta_to_cpu(pcysta_le32, pcysta); + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo); + } else { + pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo_v1; + pcysta_v1 = &pfwinfo->rpt_fbtc_cysta.finfo_v1; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo_v1); + } + pcinfo->req_fver = chip->fcxcysta_ver; pcinfo->rx_len = rpt_len; pcinfo->rx_cnt++; break; case BTC_RPT_TYPE_STEP: pcinfo = &pfwinfo->rpt_fbtc_step.cinfo; - pfinfo = (u8 *)(&pfwinfo->rpt_fbtc_step.finfo); - pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_step.finfo.step[0]) * - trace_step + 8; - pcinfo->req_fver = FCXSTEP_VER; + if (chip->chip_id == RTL8852A) { + pfinfo = &pfwinfo->rpt_fbtc_step.finfo; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_step.finfo.step[0]) * + trace_step + + offsetof(struct rtw89_btc_fbtc_steps, step); + } else { + pfinfo = &pfwinfo->rpt_fbtc_step.finfo_v1; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_step.finfo_v1.step[0]) * + trace_step + + offsetof(struct rtw89_btc_fbtc_steps_v1, step); + } + pcinfo->req_fver = chip->fcxstep_ver; pcinfo->rx_len = rpt_len; pcinfo->rx_cnt++; break; case BTC_RPT_TYPE_NULLSTA: pcinfo = &pfwinfo->rpt_fbtc_nullsta.cinfo; - pfinfo = (u8 *)(&pfwinfo->rpt_fbtc_nullsta.finfo); - pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_nullsta.finfo); - pcinfo->req_fver = FCXNULLSTA_VER; + if (chip->chip_id == RTL8852A) { + pfinfo = &pfwinfo->rpt_fbtc_nullsta.finfo; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_nullsta.finfo); + } else { + pfinfo = &pfwinfo->rpt_fbtc_nullsta.finfo_v1; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_nullsta.finfo_v1); + } + pcinfo->req_fver = chip->fcxnullsta_ver; pcinfo->rx_len = rpt_len; pcinfo->rx_cnt++; break; case BTC_RPT_TYPE_MREG: pcinfo = &pfwinfo->rpt_fbtc_mregval.cinfo; - pfinfo = (u8 *)(&pfwinfo->rpt_fbtc_mregval.finfo); + pfinfo = &pfwinfo->rpt_fbtc_mregval.finfo; pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_mregval.finfo); - pcinfo->req_fver = FCXMREG_VER; + pcinfo->req_fver = chip->fcxmreg_ver; pcinfo->rx_len = rpt_len; pcinfo->rx_cnt++; break; case BTC_RPT_TYPE_GPIO_DBG: pcinfo = &pfwinfo->rpt_fbtc_gpio_dbg.cinfo; - pfinfo = (u8 *)(&pfwinfo->rpt_fbtc_gpio_dbg.finfo); + pfinfo = &pfwinfo->rpt_fbtc_gpio_dbg.finfo; pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_gpio_dbg.finfo); - pcinfo->req_fver = FCXGPIODBG_VER; + pcinfo->req_fver = chip->fcxgpiodbg_ver; pcinfo->rx_len = rpt_len; pcinfo->rx_cnt++; break; case BTC_RPT_TYPE_BT_VER: pcinfo = &pfwinfo->rpt_fbtc_btver.cinfo; - pfinfo = (u8 *)(&pfwinfo->rpt_fbtc_btver.finfo); + pfinfo = &pfwinfo->rpt_fbtc_btver.finfo; pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btver.finfo); - pcinfo->req_fver = FCX_BTVER_VER; + pcinfo->req_fver = chip->fcxbtver_ver; pcinfo->rx_len = rpt_len; pcinfo->rx_cnt++; break; case BTC_RPT_TYPE_BT_SCAN: pcinfo = &pfwinfo->rpt_fbtc_btscan.cinfo; - pfinfo = (u8 *)(&pfwinfo->rpt_fbtc_btscan.finfo); + pfinfo = &pfwinfo->rpt_fbtc_btscan.finfo; pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btscan.finfo); - pcinfo->req_fver = FCX_BTSCAN_VER; + pcinfo->req_fver = chip->fcxbtscan_ver; pcinfo->rx_len = rpt_len; pcinfo->rx_cnt++; break; case BTC_RPT_TYPE_BT_AFH: pcinfo = &pfwinfo->rpt_fbtc_btafh.cinfo; - pfinfo = (u8 *)(&pfwinfo->rpt_fbtc_btafh.finfo); + pfinfo = &pfwinfo->rpt_fbtc_btafh.finfo; pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btafh.finfo); - pcinfo->req_fver = FCX_BTAFH_VER; + pcinfo->req_fver = chip->fcxbtafh_ver; pcinfo->rx_len = rpt_len; pcinfo->rx_cnt++; break; case BTC_RPT_TYPE_BT_DEVICE: pcinfo = &pfwinfo->rpt_fbtc_btdev.cinfo; - pfinfo = (u8 *)(&pfwinfo->rpt_fbtc_btdev.finfo); + pfinfo = &pfwinfo->rpt_fbtc_btdev.finfo; pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btdev.finfo); - pcinfo->req_fver = FCX_BTDEVINFO_VER; + pcinfo->req_fver = chip->fcxbtdevinfo_ver; pcinfo->rx_len = rpt_len; pcinfo->rx_cnt++; break; @@ -1026,7 +1102,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, memcpy(pfinfo, rpt_content, pcinfo->req_len); pcinfo->valid = 1; - if (rpt_type == BTC_RPT_TYPE_TDMA) { + if (rpt_type == BTC_RPT_TYPE_TDMA && chip->chip_id == RTL8852A) { rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): check %d %zu\n", __func__, BTC_DCNT_TDMA_NONSYNC, sizeof(dm->tdma_now)); @@ -1039,7 +1115,8 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, dm->tdma_now.type, dm->tdma_now.rxflctrl, dm->tdma_now.txpause, dm->tdma_now.wtgle_n, dm->tdma_now.leak_n, dm->tdma_now.ext_ctrl, - dm->tdma_now.rsvd0, dm->tdma_now.rsvd1); + dm->tdma_now.rxflctrl_role, + dm->tdma_now.option_ctrl); rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): %d rpt_fbtc_tdma %x %x %x %x %x %x %x %x\n", @@ -1050,14 +1127,46 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, pfwinfo->rpt_fbtc_tdma.finfo.wtgle_n, pfwinfo->rpt_fbtc_tdma.finfo.leak_n, pfwinfo->rpt_fbtc_tdma.finfo.ext_ctrl, - pfwinfo->rpt_fbtc_tdma.finfo.rsvd0, - pfwinfo->rpt_fbtc_tdma.finfo.rsvd1); + pfwinfo->rpt_fbtc_tdma.finfo.rxflctrl_role, + pfwinfo->rpt_fbtc_tdma.finfo.option_ctrl); } _chk_btc_err(rtwdev, BTC_DCNT_TDMA_NONSYNC, memcmp(&dm->tdma_now, &pfwinfo->rpt_fbtc_tdma.finfo, sizeof(dm->tdma_now))); + } else if (rpt_type == BTC_RPT_TYPE_TDMA) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): check %d %zu\n", __func__, + BTC_DCNT_TDMA_NONSYNC, sizeof(dm->tdma_now)); + + if (memcmp(&dm->tdma_now, &pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma, + sizeof(dm->tdma_now)) != 0) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): %d tdma_now %x %x %x %x %x %x %x %x\n", + __func__, BTC_DCNT_TDMA_NONSYNC, + dm->tdma_now.type, dm->tdma_now.rxflctrl, + dm->tdma_now.txpause, dm->tdma_now.wtgle_n, + dm->tdma_now.leak_n, dm->tdma_now.ext_ctrl, + dm->tdma_now.rxflctrl_role, + dm->tdma_now.option_ctrl); + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): %d rpt_fbtc_tdma %x %x %x %x %x %x %x %x\n", + __func__, BTC_DCNT_TDMA_NONSYNC, + pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma.type, + pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma.rxflctrl, + pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma.txpause, + pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma.wtgle_n, + pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma.leak_n, + pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma.ext_ctrl, + pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma.rxflctrl_role, + pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma.option_ctrl); + } + + _chk_btc_err(rtwdev, BTC_DCNT_TDMA_NONSYNC, + memcmp(&dm->tdma_now, + &pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma, + sizeof(dm->tdma_now))); } if (rpt_type == BTC_RPT_TYPE_SLOT) { @@ -1097,7 +1206,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, sizeof(dm->slot_now))); } - if (rpt_type == BTC_RPT_TYPE_CYSTA && + if (rpt_type == BTC_RPT_TYPE_CYSTA && chip->chip_id == RTL8852A && pcysta->cycles >= BTC_CYSTA_CHK_PERIOD) { /* Check Leak-AP */ if (pcysta->slot_cnt[CXST_LK] != 0 && @@ -1120,16 +1229,55 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, } _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE, pcysta->slot_cnt[CXST_W1]); - _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE, pcysta->slot_cnt[CXST_W1]); + _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE, pcysta->slot_cnt[CXST_B1]); _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_FREEZE, (u32)pcysta->cycles); + } else if (rpt_type == BTC_RPT_TYPE_CYSTA && pcysta_v1 && + le16_to_cpu(pcysta_v1->cycles) >= BTC_CYSTA_CHK_PERIOD) { + cnt_leak_slot = le32_to_cpu(pcysta_v1->slot_cnt[CXST_LK]); + cnt_rx_imr = le32_to_cpu(pcysta_v1->leak_slot.cnt_rximr); + /* Check Leak-AP */ + if (cnt_leak_slot != 0 && cnt_rx_imr != 0 && + dm->tdma_now.rxflctrl) { + if (cnt_leak_slot < BTC_LEAK_AP_TH * cnt_rx_imr) + dm->leak_ap = 1; + } + + /* Check diff time between real WL slot and W1 slot */ + if (dm->tdma_now.type == CXTDMA_OFF) { + wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur); + wl_slot_real = le16_to_cpu(pcysta_v1->cycle_time.tavg[CXT_WL]); + if (wl_slot_real > wl_slot_set) { + diff_t = wl_slot_real - wl_slot_set; + _chk_btc_err(rtwdev, BTC_DCNT_WL_SLOT_DRIFT, diff_t); + } + } + + /* Check diff time between real BT slot and EBT/E5G slot */ + if (dm->tdma_now.type == CXTDMA_OFF && + dm->tdma_now.ext_ctrl == CXECTL_EXT && + btc->bt_req_len != 0) { + bt_slot_real = le16_to_cpu(pcysta_v1->cycle_time.tavg[CXT_BT]); + + if (btc->bt_req_len > bt_slot_real) { + diff_t = btc->bt_req_len - bt_slot_real; + _chk_btc_err(rtwdev, BTC_DCNT_BT_SLOT_DRIFT, diff_t); + } + } + + _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE, + le32_to_cpu(pcysta_v1->slot_cnt[CXST_W1])); + _chk_btc_err(rtwdev, BTC_DCNT_B1_FREEZE, + le32_to_cpu(pcysta_v1->slot_cnt[CXST_B1])); + _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_FREEZE, + (u32)le16_to_cpu(pcysta_v1->cycles)); } - if (rpt_type == BTC_RPT_TYPE_CTRL) { + if (rpt_type == BTC_RPT_TYPE_CTRL && chip->chip_id == RTL8852A) { prpt = &pfwinfo->rpt_ctrl.finfo; btc->fwinfo.rpt_en_map = prpt->rpt_enable; wl->ver_info.fw_coex = prpt->wl_fw_coex_ver; wl->ver_info.fw = prpt->wl_fw_ver; - dm->wl_fw_cx_offload = !!(prpt->wl_fw_cx_offload); + dm->wl_fw_cx_offload = !!prpt->wl_fw_cx_offload; _chk_btc_err(rtwdev, BTC_DCNT_RPT_FREEZE, pfwinfo->event[BTF_EVNT_RPT]); @@ -1142,6 +1290,33 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, btc->cx.cnt_bt[BTC_BCNT_POLUT] = rtw89_mac_get_plt_cnt(rtwdev, RTW89_MAC_0); } + } else if (rpt_type == BTC_RPT_TYPE_CTRL) { + prpt_v1 = &pfwinfo->rpt_ctrl.finfo_v1; + btc->fwinfo.rpt_en_map = le32_to_cpu(prpt_v1->rpt_info.en); + wl->ver_info.fw_coex = le32_to_cpu(prpt_v1->wl_fw_info.cx_ver); + wl->ver_info.fw = le32_to_cpu(prpt_v1->wl_fw_info.fw_ver); + dm->wl_fw_cx_offload = !!le32_to_cpu(prpt_v1->wl_fw_info.cx_offload); + + for (i = RTW89_PHY_0; i < RTW89_PHY_MAX; i++) + memcpy(&dm->gnt.band[i], &prpt_v1->gnt_val[i], + sizeof(dm->gnt.band[i])); + + btc->cx.cnt_bt[BTC_BCNT_HIPRI_TX] = le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_HI_TX]); + btc->cx.cnt_bt[BTC_BCNT_HIPRI_RX] = le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_HI_RX]); + btc->cx.cnt_bt[BTC_BCNT_LOPRI_TX] = le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_LO_TX]); + btc->cx.cnt_bt[BTC_BCNT_LOPRI_RX] = le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_LO_RX]); + btc->cx.cnt_bt[BTC_BCNT_POLUT] = le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_POLLUTED]); + + _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_FREEZE, 0); + _chk_btc_err(rtwdev, BTC_DCNT_RPT_FREEZE, + pfwinfo->event[BTF_EVNT_RPT]); + + if (le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_RFK_TIMEOUT]) > 0) + bt->rfk_info.map.timeout = 1; + else + bt->rfk_info.map.timeout = 0; + + dm->error.map.bt_rfk_timeout = bt->rfk_info.map.timeout; } if (rpt_type >= BTC_RPT_TYPE_BT_VER && @@ -1155,6 +1330,7 @@ static void _parse_btc_report(struct rtw89_dev *rtwdev, struct rtw89_btc_btf_fwinfo *pfwinfo, u8 *pbuf, u32 buf_len) { + const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_btc_prpt *btc_prpt = NULL; u32 index = 0, rpt_len = 0; @@ -1164,7 +1340,7 @@ static void _parse_btc_report(struct rtw89_dev *rtwdev, while (pbuf) { btc_prpt = (struct rtw89_btc_prpt *)&pbuf[index]; - if (index + 2 >= BTC_FWINFO_BUF) + if (index + 2 >= chip->btc_fwinfo_buf) break; /* At least 3 bytes: type(1) & len(2) */ rpt_len = le16_to_cpu(btc_prpt->len); @@ -1182,10 +1358,12 @@ static void _parse_btc_report(struct rtw89_dev *rtwdev, static void _append_tdma(struct rtw89_dev *rtwdev) { + const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_dm *dm = &btc->dm; - struct rtw89_btc_btf_tlv *tlv = NULL; - struct rtw89_btc_fbtc_tdma *v = NULL; + struct rtw89_btc_btf_tlv *tlv; + struct rtw89_btc_fbtc_tdma *v; + struct rtw89_btc_fbtc_tdma_v1 *v1; u16 len = btc->policy_len; if (!btc->update_policy_force && @@ -1197,12 +1375,19 @@ static void _append_tdma(struct rtw89_dev *rtwdev) } tlv = (struct rtw89_btc_btf_tlv *)&btc->policy[len]; - v = (struct rtw89_btc_fbtc_tdma *)&tlv->val[0]; tlv->type = CXPOLICY_TDMA; - tlv->len = sizeof(*v); - - memcpy(v, &dm->tdma, sizeof(*v)); - btc->policy_len += BTC_TLV_HDR_LEN + sizeof(*v); + if (chip->chip_id == RTL8852A) { + v = (struct rtw89_btc_fbtc_tdma *)&tlv->val[0]; + tlv->len = sizeof(*v); + memcpy(v, &dm->tdma, sizeof(*v)); + btc->policy_len += BTC_TLV_HDR_LEN + sizeof(*v); + } else { + tlv->len = sizeof(*v1); + v1 = (struct rtw89_btc_fbtc_tdma_v1 *)&tlv->val[0]; + v1->fver = chip->fcxtdma_ver; + v1->tdma = dm->tdma; + btc->policy_len += BTC_TLV_HDR_LEN + sizeof(*v1); + } rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): type:%d, rxflctrl=%d, txpause=%d, wtgle_n=%d, leak_n=%d, ext_ctrl=%d\n", @@ -1408,12 +1593,17 @@ static void _fw_set_policy(struct rtw89_dev *rtwdev, u16 policy_type, static void _fw_set_drv_info(struct rtw89_dev *rtwdev, u8 type) { + const struct rtw89_chip_info *chip = rtwdev->chip; + switch (type) { case CXDRVINFO_INIT: rtw89_fw_h2c_cxdrv_init(rtwdev); break; case CXDRVINFO_ROLE: - rtw89_fw_h2c_cxdrv_role(rtwdev); + if (chip->chip_id == RTL8852A) + rtw89_fw_h2c_cxdrv_role(rtwdev); + else + rtw89_fw_h2c_cxdrv_role_v1(rtwdev); break; case CXDRVINFO_CTRL: rtw89_fw_h2c_cxdrv_ctrl(rtwdev); @@ -1448,7 +1638,7 @@ void btc_fw_event(struct rtw89_dev *rtwdev, u8 evt_id, void *data, u32 len) } } -static void _set_gnt_wl(struct rtw89_dev *rtwdev, u8 phy_map, u8 state) +static void _set_gnt(struct rtw89_dev *rtwdev, u8 phy_map, u8 wl_state, u8 bt_state) { struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_dm *dm = &btc->dm; @@ -1462,7 +1652,7 @@ static void _set_gnt_wl(struct rtw89_dev *rtwdev, u8 phy_map, u8 state) if (!(phy_map & BIT(i))) continue; - switch (state) { + switch (wl_state) { case BTC_GNT_HW: g[i].gnt_wl_sw_en = 0; g[i].gnt_wl = 0; @@ -1476,6 +1666,21 @@ static void _set_gnt_wl(struct rtw89_dev *rtwdev, u8 phy_map, u8 state) g[i].gnt_wl = 1; break; } + + switch (bt_state) { + case BTC_GNT_HW: + g[i].gnt_bt_sw_en = 0; + g[i].gnt_bt = 0; + break; + case BTC_GNT_SW_LO: + g[i].gnt_bt_sw_en = 1; + g[i].gnt_bt = 0; + break; + case BTC_GNT_SW_HI: + g[i].gnt_bt_sw_en = 1; + g[i].gnt_bt = 1; + break; + } } rtw89_chip_mac_cfg_gnt(rtwdev, &dm->gnt); @@ -1534,6 +1739,7 @@ static void _set_wl_tx_power(struct rtw89_dev *rtwdev, u32 level) static void _set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level) { + const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_wl_info *wl = &btc->cx.wl; @@ -1546,6 +1752,8 @@ static void _set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level) rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): level = %d\n", __func__, level); + + chip->ops->btc_set_wl_rx_gain(rtwdev, level); } static void _set_bt_tx_power(struct rtw89_dev *rtwdev, u8 level) @@ -1683,28 +1891,45 @@ static void _set_bt_afh_info(struct rtw89_dev *rtwdev) struct rtw89_btc_bt_info *bt = &btc->cx.bt; struct rtw89_btc_bt_link_info *b = &bt->link_info; struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; + struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1; + struct rtw89_btc_wl_active_role *r; + struct rtw89_btc_wl_active_role_v1 *r1; u8 en = 0, i, ch = 0, bw = 0; + u8 mode, connect_cnt; if (btc->ctrl.manual || wl->status.map.scan) return; - /* TODO if include module->ant.type == BTC_ANT_SHARED */ + if (chip->chip_id == RTL8852A) { + mode = wl_rinfo->link_mode; + connect_cnt = wl_rinfo->connect_cnt; + } else { + mode = wl_rinfo_v1->link_mode; + connect_cnt = wl_rinfo_v1->connect_cnt; + } + if (wl->status.map.rf_off || bt->whql_test || - wl_rinfo->link_mode == BTC_WLINK_NOLINK || - wl_rinfo->link_mode == BTC_WLINK_5G || - wl_rinfo->connect_cnt > BTC_TDMA_WLROLE_MAX) { + mode == BTC_WLINK_NOLINK || mode == BTC_WLINK_5G || + connect_cnt > BTC_TDMA_WLROLE_MAX) { en = false; - } else if (wl_rinfo->link_mode == BTC_WLINK_2G_MCC || - wl_rinfo->link_mode == BTC_WLINK_2G_SCC) { + } else if (mode == BTC_WLINK_2G_MCC || mode == BTC_WLINK_2G_SCC) { en = true; /* get p2p channel */ for (i = 0; i < RTW89_PORT_NUM; i++) { - if (wl_rinfo->active_role[i].role == - RTW89_WIFI_ROLE_P2P_GO || - wl_rinfo->active_role[i].role == - RTW89_WIFI_ROLE_P2P_CLIENT) { - ch = wl_rinfo->active_role[i].ch; - bw = wl_rinfo->active_role[i].bw; + r = &wl_rinfo->active_role[i]; + r1 = &wl_rinfo_v1->active_role_v1[i]; + + if (chip->chip_id == RTL8852A && + (r->role == RTW89_WIFI_ROLE_P2P_GO || + r->role == RTW89_WIFI_ROLE_P2P_CLIENT)) { + ch = r->ch; + bw = r->bw; + break; + } else if (chip->chip_id != RTL8852A && + (r1->role == RTW89_WIFI_ROLE_P2P_GO || + r1->role == RTW89_WIFI_ROLE_P2P_CLIENT)) { + ch = r1->ch; + bw = r1->bw; break; } } @@ -1712,10 +1937,18 @@ static void _set_bt_afh_info(struct rtw89_dev *rtwdev) en = true; /* get 2g channel */ for (i = 0; i < RTW89_PORT_NUM; i++) { - if (wl_rinfo->active_role[i].connected && - wl_rinfo->active_role[i].band == RTW89_BAND_2G) { - ch = wl_rinfo->active_role[i].ch; - bw = wl_rinfo->active_role[i].bw; + r = &wl_rinfo->active_role[i]; + r1 = &wl_rinfo_v1->active_role_v1[i]; + + if (chip->chip_id == RTL8852A && + r->connected && r->band == RTW89_BAND_2G) { + ch = r->ch; + bw = r->bw; + break; + } else if (chip->chip_id != RTL8852A && + r1->connected && r1->band == RTW89_BAND_2G) { + ch = r1->ch; + bw = r1->bw; break; } } @@ -1768,6 +2001,7 @@ static bool _check_freerun(struct rtw89_dev *rtwdev) struct rtw89_btc_wl_info *wl = &btc->cx.wl; struct rtw89_btc_bt_info *bt = &btc->cx.bt; struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; + struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1; struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info; struct rtw89_btc_bt_hid_desc *hid = &bt_linfo->hid_desc; @@ -1777,7 +2011,8 @@ static bool _check_freerun(struct rtw89_dev *rtwdev) } /* The below is dedicated antenna case */ - if (wl_rinfo->connect_cnt > BTC_TDMA_WLROLE_MAX) { + if (wl_rinfo->connect_cnt > BTC_TDMA_WLROLE_MAX || + wl_rinfo_v1->connect_cnt > BTC_TDMA_WLROLE_MAX) { btc->dm.trx_para_level = 5; return true; } @@ -1826,6 +2061,7 @@ static bool _check_freerun(struct rtw89_dev *rtwdev) } #define _tdma_set_flctrl(btc, flc) ({(btc)->dm.tdma.rxflctrl = flc; }) +#define _tdma_set_flctrl_role(btc, role) ({(btc)->dm.tdma.rxflctrl_role = role; }) #define _tdma_set_tog(btc, wtg) ({(btc)->dm.tdma.wtgle_n = wtg; }) #define _tdma_set_lek(btc, lek) ({(btc)->dm.tdma.leak_n = lek; }) @@ -1904,6 +2140,15 @@ union btc_btinfo { static void _set_policy(struct rtw89_dev *rtwdev, u16 policy_type, enum btc_reason_and_action action) { + const struct rtw89_chip_info *chip = rtwdev->chip; + + chip->ops->btc_set_policy(rtwdev, policy_type); + _fw_set_policy(rtwdev, policy_type, action); +} + +#define BTC_B1_MAX 250 /* unit ms */ +void rtw89_btc_set_policy(struct rtw89_dev *rtwdev, u16 policy_type) +{ struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_dm *dm = &btc->dm; struct rtw89_btc_fbtc_tdma *t = &dm->tdma; @@ -1964,6 +2209,9 @@ static void _set_policy(struct rtw89_dev *rtwdev, u16 policy_type, case BTC_CXP_OFF_BWB1: _slot_set_tbl(btc, CXST_OFF, cxtbl[8]); break; + case BTC_CXP_OFF_BWB3: + _slot_set_tbl(btc, CXST_OFF, cxtbl[6]); + break; } break; case BTC_CXP_OFFB: /* TDMA off + beacon protect */ @@ -2080,17 +2328,361 @@ static void _set_policy(struct rtw89_dev *rtwdev, u16 policy_type, _write_scbd(rtwdev, BTC_WSCB_TDMA, true); *t = t_def[CXTD_AUTO]; switch (policy_type) { - case BTC_CXP_AUTO_TD50200: + case BTC_CXP_AUTO_TD50B1: + _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_AUTO_TD60B1: + _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_AUTO_TD20B1: + _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_AUTO_TDW1B1: /* W1:B1 = user-define */ + _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], + tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1], + tbl_b1, SLOT_MIX); + break; + } + break; + case BTC_CXP_PAUTO: /* PS-TDMA Auto-Slot */ + _write_scbd(rtwdev, BTC_WSCB_TDMA, true); + *t = t_def[CXTD_PAUTO]; + switch (policy_type) { + case BTC_CXP_PAUTO_TD50B1: + _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PAUTO_TD60B1: + _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PAUTO_TD20B1: + _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PAUTO_TDW1B1: + _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], + tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1], + tbl_b1, SLOT_MIX); + break; + } + break; + case BTC_CXP_AUTO2: /* TDMA Auto-Slot2 */ + _write_scbd(rtwdev, BTC_WSCB_TDMA, true); + *t = t_def[CXTD_AUTO2]; + switch (policy_type) { + case BTC_CXP_AUTO2_TD3050: + _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_AUTO2_TD3070: + _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B4, 70, tbl_b4, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_AUTO2_TD5050: + _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_AUTO2_TD6060: + _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B4, 60, tbl_b4, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_AUTO2_TD2080: + _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B4, 80, tbl_b4, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_AUTO2_TDW1B4: /* W1:B1 = user-define */ + _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], + tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B4, dm->slot_dur[CXST_B4], + tbl_b4, SLOT_MIX); + break; + } + break; + case BTC_CXP_PAUTO2: /* PS-TDMA Auto-Slot2 */ + _write_scbd(rtwdev, BTC_WSCB_TDMA, true); + *t = t_def[CXTD_PAUTO2]; + switch (policy_type) { + case BTC_CXP_PAUTO2_TD3050: + _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PAUTO2_TD3070: + _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B4, 70, tbl_b4, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PAUTO2_TD5050: + _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PAUTO2_TD6060: + _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B4, 60, tbl_b4, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PAUTO2_TD2080: + _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B4, 80, tbl_b4, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PAUTO2_TDW1B4: /* W1:B1 = user-define */ + _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], + tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B4, dm->slot_dur[CXST_B4], + tbl_b4, SLOT_MIX); + break; + } + break; + } +} +EXPORT_SYMBOL(rtw89_btc_set_policy); + +void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_fbtc_tdma *t = &dm->tdma; + struct rtw89_btc_fbtc_slot *s = dm->slot; + struct rtw89_btc_wl_role_info_v1 *wl_rinfo = &btc->cx.wl.role_info_v1; + struct rtw89_btc_bt_hid_desc *hid = &btc->cx.bt.link_info.hid_desc; + struct rtw89_btc_bt_hfp_desc *hfp = &btc->cx.bt.link_info.hfp_desc; + u8 type, null_role; + u32 tbl_w1, tbl_b1, tbl_b4; + + type = FIELD_GET(BTC_CXP_MASK, policy_type); + + if (btc->mdinfo.ant.type == BTC_ANT_SHARED) { + if (btc->cx.wl.status.map._4way) + tbl_w1 = cxtbl[1]; + else if (hid->exist && hid->type == BTC_HID_218) + tbl_w1 = cxtbl[7]; /* Ack/BA no break bt Hi-Pri-rx */ + else + tbl_w1 = cxtbl[8]; + + if (dm->leak_ap && + (type == BTC_CXP_PFIX || type == BTC_CXP_PAUTO2)) { + tbl_b1 = cxtbl[3]; + tbl_b4 = cxtbl[3]; + } else if (hid->exist && hid->type == BTC_HID_218) { + tbl_b1 = cxtbl[4]; /* Ack/BA no break bt Hi-Pri-rx */ + tbl_b4 = cxtbl[4]; + } else { + tbl_b1 = cxtbl[2]; + tbl_b4 = cxtbl[2]; + } + } else { + tbl_w1 = cxtbl[16]; + tbl_b1 = cxtbl[17]; + tbl_b4 = cxtbl[17]; + } + + btc->bt_req_en = false; + + switch (type) { + case BTC_CXP_USERDEF0: + btc->update_policy_force = true; + *t = t_def[CXTD_OFF]; + s[CXST_OFF] = s_def[CXST_OFF]; + _slot_set_tbl(btc, CXST_OFF, cxtbl[2]); + break; + case BTC_CXP_OFF: /* TDMA off */ + _write_scbd(rtwdev, BTC_WSCB_TDMA, false); + *t = t_def[CXTD_OFF]; + s[CXST_OFF] = s_def[CXST_OFF]; + + switch (policy_type) { + case BTC_CXP_OFF_BT: + _slot_set_tbl(btc, CXST_OFF, cxtbl[2]); + break; + case BTC_CXP_OFF_WL: + _slot_set_tbl(btc, CXST_OFF, cxtbl[1]); + break; + case BTC_CXP_OFF_EQ0: + _slot_set_tbl(btc, CXST_OFF, cxtbl[0]); + break; + case BTC_CXP_OFF_EQ1: + _slot_set_tbl(btc, CXST_OFF, cxtbl[16]); + break; + case BTC_CXP_OFF_EQ2: + _slot_set_tbl(btc, CXST_OFF, cxtbl[17]); + break; + case BTC_CXP_OFF_EQ3: + _slot_set_tbl(btc, CXST_OFF, cxtbl[18]); + break; + case BTC_CXP_OFF_BWB0: + _slot_set_tbl(btc, CXST_OFF, cxtbl[5]); + break; + case BTC_CXP_OFF_BWB1: + _slot_set_tbl(btc, CXST_OFF, cxtbl[8]); + break; + case BTC_CXP_OFF_BWB2: + _slot_set_tbl(btc, CXST_OFF, cxtbl[7]); + break; + case BTC_CXP_OFF_BWB3: + _slot_set_tbl(btc, CXST_OFF, cxtbl[6]); + break; + default: + break; + } + break; + case BTC_CXP_OFFB: /* TDMA off + beacon protect */ + _write_scbd(rtwdev, BTC_WSCB_TDMA, false); + *t = t_def[CXTD_OFF_B2]; + s[CXST_OFF] = s_def[CXST_OFF]; + + switch (policy_type) { + case BTC_CXP_OFFB_BWB0: + _slot_set_tbl(btc, CXST_OFF, cxtbl[8]); + break; + default: + break; + } + break; + case BTC_CXP_OFFE: /* TDMA off + beacon protect + Ext_control */ + btc->bt_req_en = true; + _write_scbd(rtwdev, BTC_WSCB_TDMA, true); + *t = t_def[CXTD_OFF_EXT]; + + /* To avoid wl-s0 tx break by hid/hfp tx */ + if (hid->exist || hfp->exist) + tbl_w1 = cxtbl[16]; + + switch (policy_type) { + case BTC_CXP_OFFE_DEF: + s[CXST_E2G] = s_def[CXST_E2G]; + s[CXST_E5G] = s_def[CXST_E5G]; + s[CXST_EBT] = s_def[CXST_EBT]; + s[CXST_ENULL] = s_def[CXST_ENULL]; + break; + case BTC_CXP_OFFE_DEF2: + _slot_set(btc, CXST_E2G, 20, cxtbl[1], SLOT_ISO); + s[CXST_E5G] = s_def[CXST_E5G]; + s[CXST_EBT] = s_def[CXST_EBT]; + s[CXST_ENULL] = s_def[CXST_ENULL]; + break; + default: + break; + } + break; + case BTC_CXP_FIX: /* TDMA Fix-Slot */ + _write_scbd(rtwdev, BTC_WSCB_TDMA, true); + *t = t_def[CXTD_FIX]; + + switch (policy_type) { + case BTC_CXP_FIX_TD3030: + _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_FIX_TD5050: + _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 50, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_FIX_TD2030: + _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_FIX_TD4010: + _slot_set(btc, CXST_W1, 40, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 10, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_FIX_TD4010ISO: + _slot_set(btc, CXST_W1, 40, cxtbl[1], SLOT_ISO); + _slot_set(btc, CXST_B1, 10, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_FIX_TD7010: + _slot_set(btc, CXST_W1, 70, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 10, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_FIX_TD2060: + _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_FIX_TD3060: + _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_FIX_TD2080: + _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 80, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_FIX_TDW1B1: /* W1:B1 = user-define */ + _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], + tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1], + tbl_b1, SLOT_MIX); + break; + default: + break; + } + break; + case BTC_CXP_PFIX: /* PS-TDMA Fix-Slot */ + _write_scbd(rtwdev, BTC_WSCB_TDMA, true); + *t = t_def[CXTD_PFIX]; + + switch (policy_type) { + case BTC_CXP_PFIX_TD3030: + _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PFIX_TD5050: + _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 50, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PFIX_TD2030: + _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PFIX_TD2060: + _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PFIX_TD3070: + _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PFIX_TD2080: + _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, 80, tbl_b1, SLOT_MIX); + break; + case BTC_CXP_PFIX_TDW1B1: /* W1:B1 = user-define */ + _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], + tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1], + tbl_b1, SLOT_MIX); + break; + default: + break; + } + break; + case BTC_CXP_AUTO: /* TDMA Auto-Slot */ + _write_scbd(rtwdev, BTC_WSCB_TDMA, true); + *t = t_def[CXTD_AUTO]; + + switch (policy_type) { + case BTC_CXP_AUTO_TD50B1: _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); - _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); break; - case BTC_CXP_AUTO_TD60200: + case BTC_CXP_AUTO_TD60B1: _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO); - _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); break; - case BTC_CXP_AUTO_TD20200: + case BTC_CXP_AUTO_TD20B1: _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); - _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); break; case BTC_CXP_AUTO_TDW1B1: /* W1:B1 = user-define */ _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], @@ -2098,23 +2690,26 @@ static void _set_policy(struct rtw89_dev *rtwdev, u16 policy_type, _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1], tbl_b1, SLOT_MIX); break; + default: + break; } break; case BTC_CXP_PAUTO: /* PS-TDMA Auto-Slot */ _write_scbd(rtwdev, BTC_WSCB_TDMA, true); *t = t_def[CXTD_PAUTO]; + switch (policy_type) { - case BTC_CXP_PAUTO_TD50200: + case BTC_CXP_PAUTO_TD50B1: _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); - _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); break; - case BTC_CXP_PAUTO_TD60200: + case BTC_CXP_PAUTO_TD60B1: _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO); - _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); break; - case BTC_CXP_PAUTO_TD20200: + case BTC_CXP_PAUTO_TD20B1: _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); - _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); break; case BTC_CXP_PAUTO_TDW1B1: _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], @@ -2122,119 +2717,112 @@ static void _set_policy(struct rtw89_dev *rtwdev, u16 policy_type, _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1], tbl_b1, SLOT_MIX); break; + default: + break; } break; case BTC_CXP_AUTO2: /* TDMA Auto-Slot2 */ _write_scbd(rtwdev, BTC_WSCB_TDMA, true); *t = t_def[CXTD_AUTO2]; + switch (policy_type) { case BTC_CXP_AUTO2_TD3050: _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); - _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX); break; case BTC_CXP_AUTO2_TD3070: _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); - _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); _slot_set(btc, CXST_B4, 70, tbl_b4, SLOT_MIX); break; case BTC_CXP_AUTO2_TD5050: _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); - _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX); break; case BTC_CXP_AUTO2_TD6060: _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO); - _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); _slot_set(btc, CXST_B4, 60, tbl_b4, SLOT_MIX); break; case BTC_CXP_AUTO2_TD2080: _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); - _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); _slot_set(btc, CXST_B4, 80, tbl_b4, SLOT_MIX); break; case BTC_CXP_AUTO2_TDW1B4: /* W1:B1 = user-define */ _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1], + tbl_b1, SLOT_MIX); _slot_set(btc, CXST_B4, dm->slot_dur[CXST_B4], tbl_b4, SLOT_MIX); break; + default: + break; } break; case BTC_CXP_PAUTO2: /* PS-TDMA Auto-Slot2 */ _write_scbd(rtwdev, BTC_WSCB_TDMA, true); *t = t_def[CXTD_PAUTO2]; + switch (policy_type) { case BTC_CXP_PAUTO2_TD3050: _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); - _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX); break; case BTC_CXP_PAUTO2_TD3070: _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); - _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); _slot_set(btc, CXST_B4, 70, tbl_b4, SLOT_MIX); break; case BTC_CXP_PAUTO2_TD5050: _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); - _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX); break; case BTC_CXP_PAUTO2_TD6060: _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO); - _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); _slot_set(btc, CXST_B4, 60, tbl_b4, SLOT_MIX); break; case BTC_CXP_PAUTO2_TD2080: _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); - _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); + _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); _slot_set(btc, CXST_B4, 80, tbl_b4, SLOT_MIX); break; case BTC_CXP_PAUTO2_TDW1B4: /* W1:B1 = user-define */ _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], tbl_w1, SLOT_ISO); + _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1], + tbl_b1, SLOT_MIX); _slot_set(btc, CXST_B4, dm->slot_dur[CXST_B4], tbl_b4, SLOT_MIX); break; + default: + break; } break; } - _fw_set_policy(rtwdev, policy_type, action); -} - -static void _set_gnt_bt(struct rtw89_dev *rtwdev, u8 phy_map, u8 state) -{ - struct rtw89_btc *btc = &rtwdev->btc; - struct rtw89_btc_dm *dm = &btc->dm; - struct rtw89_mac_ax_gnt *g = dm->gnt.band; - u8 i; - - if (phy_map > BTC_PHY_ALL) - return; + if (wl_rinfo->link_mode == BTC_WLINK_2G_SCC && dm->tdma.rxflctrl) { + null_role = FIELD_PREP(0x0f, dm->wl_scc.null_role1) | + FIELD_PREP(0xf0, dm->wl_scc.null_role2); + _tdma_set_flctrl_role(btc, null_role); + } - for (i = 0; i < RTW89_PHY_MAX; i++) { - if (!(phy_map & BIT(i))) - continue; + /* enter leak_slot after each null-1 */ + if (dm->leak_ap && dm->tdma.leak_n > 1) + _tdma_set_lek(btc, 1); - switch (state) { - case BTC_GNT_HW: - g[i].gnt_bt_sw_en = 0; - g[i].gnt_bt = 0; - break; - case BTC_GNT_SW_LO: - g[i].gnt_bt_sw_en = 1; - g[i].gnt_bt = 0; - break; - case BTC_GNT_SW_HI: - g[i].gnt_bt_sw_en = 1; - g[i].gnt_bt = 1; - break; - } + if (dm->tdma_instant_excute) { + btc->dm.tdma.option_ctrl |= BIT(0); + btc->update_policy_force = true; } - - rtw89_chip_mac_cfg_gnt(rtwdev, &dm->gnt); } +EXPORT_SYMBOL(rtw89_btc_set_policy_v1); static void _set_bt_plut(struct rtw89_dev *rtwdev, u8 phy_map, u8 tx_val, u8 rx_val) @@ -2300,86 +2888,74 @@ static void _set_ant(struct rtw89_dev *rtwdev, bool force_exec, switch (type) { case BTC_ANT_WPOWERON: - rtw89_chip_cfg_ctrl_path(rtwdev, false); + rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_BT); break; case BTC_ANT_WINIT: - if (bt->enable.now) { - _set_gnt_wl(rtwdev, phy_map, BTC_GNT_SW_LO); - _set_gnt_bt(rtwdev, phy_map, BTC_GNT_SW_HI); - } else { - _set_gnt_wl(rtwdev, phy_map, BTC_GNT_SW_HI); - _set_gnt_bt(rtwdev, phy_map, BTC_GNT_SW_LO); - } - rtw89_chip_cfg_ctrl_path(rtwdev, true); + if (bt->enable.now) + _set_gnt(rtwdev, phy_map, BTC_GNT_SW_LO, BTC_GNT_SW_HI); + else + _set_gnt(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO); + + rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL); _set_bt_plut(rtwdev, BTC_PHY_ALL, BTC_PLT_BT, BTC_PLT_BT); break; case BTC_ANT_WONLY: - _set_gnt_wl(rtwdev, phy_map, BTC_GNT_SW_HI); - _set_gnt_bt(rtwdev, phy_map, BTC_GNT_SW_LO); - rtw89_chip_cfg_ctrl_path(rtwdev, true); + _set_gnt(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO); + rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL); _set_bt_plut(rtwdev, BTC_PHY_ALL, BTC_PLT_NONE, BTC_PLT_NONE); break; case BTC_ANT_WOFF: - rtw89_chip_cfg_ctrl_path(rtwdev, false); + rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_BT); _set_bt_plut(rtwdev, BTC_PHY_ALL, BTC_PLT_NONE, BTC_PLT_NONE); break; case BTC_ANT_W2G: - rtw89_chip_cfg_ctrl_path(rtwdev, true); + rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL); if (rtwdev->dbcc_en) { for (i = 0; i < RTW89_PHY_MAX; i++) { b2g = (wl_dinfo->real_band[i] == RTW89_BAND_2G); gnt_wl_ctrl = b2g ? BTC_GNT_HW : BTC_GNT_SW_HI; - _set_gnt_wl(rtwdev, BIT(i), gnt_wl_ctrl); - gnt_bt_ctrl = b2g ? BTC_GNT_HW : BTC_GNT_SW_HI; /* BT should control by GNT_BT if WL_2G at S0 */ if (i == 1 && wl_dinfo->real_band[0] == RTW89_BAND_2G && wl_dinfo->real_band[1] == RTW89_BAND_5G) gnt_bt_ctrl = BTC_GNT_HW; - _set_gnt_bt(rtwdev, BIT(i), gnt_bt_ctrl); - + _set_gnt(rtwdev, BIT(i), gnt_wl_ctrl, gnt_bt_ctrl); plt_ctrl = b2g ? BTC_PLT_BT : BTC_PLT_NONE; _set_bt_plut(rtwdev, BIT(i), plt_ctrl, plt_ctrl); } } else { - _set_gnt_wl(rtwdev, phy_map, BTC_GNT_HW); - _set_gnt_bt(rtwdev, phy_map, BTC_GNT_HW); + _set_gnt(rtwdev, phy_map, BTC_GNT_HW, BTC_GNT_HW); _set_bt_plut(rtwdev, BTC_PHY_ALL, BTC_PLT_BT, BTC_PLT_BT); } break; case BTC_ANT_W5G: - rtw89_chip_cfg_ctrl_path(rtwdev, true); - _set_gnt_wl(rtwdev, phy_map, BTC_GNT_SW_HI); - _set_gnt_bt(rtwdev, phy_map, BTC_GNT_HW); + rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL); + _set_gnt(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_HW); _set_bt_plut(rtwdev, BTC_PHY_ALL, BTC_PLT_NONE, BTC_PLT_NONE); break; case BTC_ANT_W25G: - rtw89_chip_cfg_ctrl_path(rtwdev, true); - _set_gnt_wl(rtwdev, phy_map, BTC_GNT_HW); - _set_gnt_bt(rtwdev, phy_map, BTC_GNT_HW); + rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL); + _set_gnt(rtwdev, phy_map, BTC_GNT_HW, BTC_GNT_HW); _set_bt_plut(rtwdev, BTC_PHY_ALL, BTC_PLT_GNT_WL, BTC_PLT_GNT_WL); break; case BTC_ANT_FREERUN: - rtw89_chip_cfg_ctrl_path(rtwdev, true); - _set_gnt_wl(rtwdev, phy_map, BTC_GNT_SW_HI); - _set_gnt_bt(rtwdev, phy_map, BTC_GNT_SW_HI); + rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL); + _set_gnt(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_HI); _set_bt_plut(rtwdev, BTC_PHY_ALL, BTC_PLT_NONE, BTC_PLT_NONE); break; case BTC_ANT_WRFK: - rtw89_chip_cfg_ctrl_path(rtwdev, true); - _set_gnt_wl(rtwdev, phy_map, BTC_GNT_SW_HI); - _set_gnt_bt(rtwdev, phy_map, BTC_GNT_SW_LO); + rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL); + _set_gnt(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO); _set_bt_plut(rtwdev, phy_map, BTC_PLT_NONE, BTC_PLT_NONE); break; case BTC_ANT_BRFK: - rtw89_chip_cfg_ctrl_path(rtwdev, false); - _set_gnt_wl(rtwdev, phy_map, BTC_GNT_SW_LO); - _set_gnt_bt(rtwdev, phy_map, BTC_GNT_SW_HI); + rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_BT); + _set_gnt(rtwdev, phy_map, BTC_GNT_SW_LO, BTC_GNT_SW_HI); _set_bt_plut(rtwdev, phy_map, BTC_PLT_NONE, BTC_PLT_NONE); break; default: @@ -2491,14 +3067,19 @@ static void _action_bt_idle(struct rtw89_dev *rtwdev) static void _action_bt_hfp(struct rtw89_dev *rtwdev) { struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); if (btc->mdinfo.ant.type == BTC_ANT_SHARED) { - if (btc->cx.wl.status.map._4way) + if (btc->cx.wl.status.map._4way) { _set_policy(rtwdev, BTC_CXP_OFF_WL, BTC_ACT_BT_HFP); - else - _set_policy(rtwdev, BTC_CXP_OFF_BWB0, BTC_ACT_BT_HFP); + } else if (wl->status.map.traffic_dir & BIT(RTW89_TFC_UL)) { + btc->cx.bt.scan_rx_low_pri = true; + _set_policy(rtwdev, BTC_CXP_OFF_BWB2, BTC_ACT_BT_HFP); + } else { + _set_policy(rtwdev, BTC_CXP_OFF_BWB1, BTC_ACT_BT_HFP); + } } else { _set_policy(rtwdev, BTC_CXP_OFF_EQ2, BTC_ACT_BT_HFP); } @@ -2506,17 +3087,37 @@ static void _action_bt_hfp(struct rtw89_dev *rtwdev) static void _action_bt_hid(struct rtw89_dev *rtwdev) { + const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_bt_info *bt = &btc->cx.bt; + struct rtw89_btc_bt_hid_desc *hid = &bt->link_info.hid_desc; + u16 policy_type = BTC_CXP_OFF_BT; _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); - if (btc->mdinfo.ant.type == BTC_ANT_SHARED) /* shared-antenna */ - if (btc->cx.wl.status.map._4way) - _set_policy(rtwdev, BTC_CXP_OFF_WL, BTC_ACT_BT_HID); - else - _set_policy(rtwdev, BTC_CXP_OFF_BWB0, BTC_ACT_BT_HID); - else /* dedicated-antenna */ - _set_policy(rtwdev, BTC_CXP_OFF_EQ3, BTC_ACT_BT_HID); + if (btc->mdinfo.ant.type == BTC_ANT_SHARED) { /* shared-antenna */ + if (wl->status.map._4way) { + policy_type = BTC_CXP_OFF_WL; + } else if (wl->status.map.traffic_dir & BIT(RTW89_TFC_UL)) { + btc->cx.bt.scan_rx_low_pri = true; + if (hid->type & BTC_HID_BLE) + policy_type = BTC_CXP_OFF_BWB0; + else + policy_type = BTC_CXP_OFF_BWB2; + } else if (hid->type == BTC_HID_218) { + bt->scan_rx_low_pri = true; + policy_type = BTC_CXP_OFF_BWB2; + } else if (chip->para_ver == 0x1) { + policy_type = BTC_CXP_OFF_BWB3; + } else { + policy_type = BTC_CXP_OFF_BWB1; + } + } else { /* dedicated-antenna */ + policy_type = BTC_CXP_OFF_EQ3; + } + + _set_policy(rtwdev, policy_type, BTC_ACT_BT_HID); } static void _action_bt_a2dp(struct rtw89_dev *rtwdev) @@ -2537,7 +3138,7 @@ static void _action_bt_a2dp(struct rtw89_dev *rtwdev) BTC_CXP_PAUTO_TDW1B1, BTC_ACT_BT_A2DP); } else { _set_policy(rtwdev, - BTC_CXP_PAUTO_TD50200, BTC_ACT_BT_A2DP); + BTC_CXP_PAUTO_TD50B1, BTC_ACT_BT_A2DP); } break; case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-A2DP */ @@ -2554,12 +3155,12 @@ static void _action_bt_a2dp(struct rtw89_dev *rtwdev) _set_policy(rtwdev, BTC_CXP_AUTO_TDW1B1, BTC_ACT_BT_A2DP); } else { - _set_policy(rtwdev, BTC_CXP_AUTO_TD50200, + _set_policy(rtwdev, BTC_CXP_AUTO_TD50B1, BTC_ACT_BT_A2DP); } break; case BTC_WIDLE: /* wl-idle + bt-A2DP */ - _set_policy(rtwdev, BTC_CXP_AUTO_TD20200, BTC_ACT_BT_A2DP); + _set_policy(rtwdev, BTC_CXP_AUTO_TD20B1, BTC_ACT_BT_A2DP); break; } } @@ -2639,7 +3240,7 @@ static void _action_bt_a2dp_hid(struct rtw89_dev *rtwdev) BTC_CXP_PAUTO_TDW1B1, BTC_ACT_BT_A2DP_HID); } else { _set_policy(rtwdev, - BTC_CXP_PAUTO_TD50200, BTC_ACT_BT_A2DP_HID); + BTC_CXP_PAUTO_TD50B1, BTC_ACT_BT_A2DP_HID); } break; case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-A2DP+HID */ @@ -2657,7 +3258,7 @@ static void _action_bt_a2dp_hid(struct rtw89_dev *rtwdev) _set_policy(rtwdev, BTC_CXP_AUTO_TDW1B1, BTC_ACT_BT_A2DP_HID); } else { - _set_policy(rtwdev, BTC_CXP_AUTO_TD50200, + _set_policy(rtwdev, BTC_CXP_AUTO_TD50B1, BTC_ACT_BT_A2DP_HID); } break; @@ -2792,19 +3393,27 @@ static void _action_wl_rfk(struct rtw89_dev *rtwdev) static void _set_btg_ctrl(struct rtw89_dev *rtwdev) { + const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_wl_info *wl = &btc->cx.wl; struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; + struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1; struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info; - bool is_btg = false; + bool is_btg; + u8 mode; if (btc->ctrl.manual) return; + if (chip->chip_id == RTL8852A) + mode = wl_rinfo->link_mode; + else + mode = wl_rinfo_v1->link_mode; + /* notify halbb ignore GNT_BT or not for WL BB Rx-AGC control */ - if (wl_rinfo->link_mode == BTC_WLINK_5G) /* always 0 if 5G */ + if (mode == BTC_WLINK_5G) /* always 0 if 5G */ is_btg = false; - else if (wl_rinfo->link_mode == BTC_WLINK_25G_DBCC && + else if (mode == BTC_WLINK_25G_DBCC && wl_dinfo->real_band[RTW89_PHY_1] != RTW89_BAND_2G) is_btg = false; else @@ -2816,7 +3425,7 @@ static void _set_btg_ctrl(struct rtw89_dev *rtwdev) btc->dm.wl_btg_rx = is_btg; - if (wl_rinfo->link_mode == BTC_WLINK_25G_MCC) + if (mode == BTC_WLINK_25G_MCC) return; rtw89_ctrl_btg(rtwdev, is_btg); @@ -2889,6 +3498,7 @@ static void rtw89_tx_time_iter(void *data, struct ieee80211_sta *sta) static void _set_wl_tx_limit(struct rtw89_dev *rtwdev) { + const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_cx *cx = &btc->cx; struct rtw89_btc_dm *dm = &btc->dm; @@ -2898,16 +3508,22 @@ static void _set_wl_tx_limit(struct rtw89_dev *rtwdev) struct rtw89_btc_bt_hfp_desc *hfp = &b->hfp_desc; struct rtw89_btc_bt_hid_desc *hid = &b->hid_desc; struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; + struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1; struct rtw89_txtime_data data = {.rtwdev = rtwdev}; - u8 mode = wl_rinfo->link_mode; - u8 tx_retry = 0; - u32 tx_time = 0; - u16 enable = 0; + u8 mode; + u8 tx_retry; + u32 tx_time; + u16 enable; bool reenable = false; if (btc->ctrl.manual) return; + if (chip->chip_id == RTL8852A) + mode = wl_rinfo->link_mode; + else + mode = wl_rinfo_v1->link_mode; + if (btc->dm.freerun || btc->ctrl.igno_bt || b->profile_cnt.now == 0 || mode == BTC_WLINK_5G || mode == BTC_WLINK_NOLINK) { enable = 0; @@ -2951,13 +3567,21 @@ static void _set_wl_tx_limit(struct rtw89_dev *rtwdev) static void _set_bt_rx_agc(struct rtw89_dev *rtwdev) { + const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_wl_info *wl = &btc->cx.wl; struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; + struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1; struct rtw89_btc_bt_info *bt = &btc->cx.bt; bool bt_hi_lna_rx = false; + u8 mode; + + if (chip->chip_id == RTL8852A) + mode = wl_rinfo->link_mode; + else + mode = wl_rinfo_v1->link_mode; - if (wl_rinfo->link_mode != BTC_WLINK_NOLINK && btc->dm.wl_btg_rx) + if (mode != BTC_WLINK_NOLINK && btc->dm.wl_btg_rx) bt_hi_lna_rx = true; if (bt_hi_lna_rx == bt->hi_lna_rx) @@ -2966,14 +3590,34 @@ static void _set_bt_rx_agc(struct rtw89_dev *rtwdev) _write_scbd(rtwdev, BTC_WSCB_BT_HILNA, bt_hi_lna_rx); } +static void _set_bt_rx_scan_pri(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_bt_info *bt = &btc->cx.bt; + + _write_scbd(rtwdev, BTC_WSCB_RXSCAN_PRI, (bool)(!!bt->scan_rx_low_pri)); +} + /* TODO add these functions */ static void _action_common(struct rtw89_dev *rtwdev) { + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + _set_btg_ctrl(rtwdev); _set_wl_tx_limit(rtwdev); _set_bt_afh_info(rtwdev); _set_bt_rx_agc(rtwdev); _set_rf_trx_para(rtwdev); + _set_bt_rx_scan_pri(rtwdev); + + if (wl->scbd_change) { + rtw89_mac_cfg_sb(rtwdev, wl->scbd); + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], write scbd: 0x%08x\n", + wl->scbd); + wl->scbd_change = false; + btc->cx.cnt_wl[BTC_WCNT_SCBDUPDATE]++; + } } static void _action_by_bt(struct rtw89_dev *rtwdev) @@ -3145,6 +3789,68 @@ static void _action_wl_2g_scc(struct rtw89_dev *rtwdev) } } +static void _action_wl_2g_scc_v1(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_bt_info *bt = &btc->cx.bt; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_wl_role_info_v1 *wl_rinfo = &wl->role_info_v1; + u16 policy_type = BTC_CXP_OFF_BT; + u32 dur; + + if (btc->mdinfo.ant.type == BTC_ANT_DEDICATED) { + policy_type = BTC_CXP_OFF_EQ0; + } else { + /* shared-antenna */ + switch (wl_rinfo->mrole_type) { + case BTC_WLMROLE_STA_GC: + dm->wl_scc.null_role1 = RTW89_WIFI_ROLE_STATION; + dm->wl_scc.null_role2 = RTW89_WIFI_ROLE_P2P_CLIENT; + dm->wl_scc.ebt_null = 0; /* no ext-slot-control */ + _action_by_bt(rtwdev); + return; + case BTC_WLMROLE_STA_STA: + dm->wl_scc.null_role1 = RTW89_WIFI_ROLE_STATION; + dm->wl_scc.null_role2 = RTW89_WIFI_ROLE_STATION; + dm->wl_scc.ebt_null = 0; /* no ext-slot-control */ + _action_by_bt(rtwdev); + return; + case BTC_WLMROLE_STA_GC_NOA: + case BTC_WLMROLE_STA_GO: + case BTC_WLMROLE_STA_GO_NOA: + dm->wl_scc.null_role1 = RTW89_WIFI_ROLE_STATION; + dm->wl_scc.null_role2 = RTW89_WIFI_ROLE_NONE; + dur = wl_rinfo->mrole_noa_duration; + + if (wl->status.map._4way) { + dm->wl_scc.ebt_null = 0; + policy_type = BTC_CXP_OFFE_WL; + } else if (bt->link_info.status.map.connect == 0) { + dm->wl_scc.ebt_null = 0; + policy_type = BTC_CXP_OFFE_2GISOB; + } else if (bt->link_info.a2dp_desc.exist && + dur < btc->bt_req_len) { + dm->wl_scc.ebt_null = 1; /* tx null at EBT */ + policy_type = BTC_CXP_OFFE_2GBWMIXB2; + } else if (bt->link_info.a2dp_desc.exist || + bt->link_info.pan_desc.exist) { + dm->wl_scc.ebt_null = 1; /* tx null at EBT */ + policy_type = BTC_CXP_OFFE_2GBWISOB; + } else { + dm->wl_scc.ebt_null = 0; + policy_type = BTC_CXP_OFFE_2GBWISOB; + } + break; + default: + break; + } + } + + _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); + _set_policy(rtwdev, policy_type, BTC_ACT_WL_2G_SCC); +} + static void _action_wl_2g_ap(struct rtw89_dev *rtwdev) { struct rtw89_btc *btc = &rtwdev->btc; @@ -3234,20 +3940,20 @@ static void _write_scbd(struct rtw89_dev *rtwdev, u32 val, bool state) struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_wl_info *wl = &btc->cx.wl; u32 scbd_val = 0; + u8 force_exec = false; if (!chip->scbd) return; scbd_val = state ? wl->scbd | val : wl->scbd & ~val; - if (scbd_val == wl->scbd) - return; - rtw89_mac_cfg_sb(rtwdev, scbd_val); - rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], write scbd: 0x%08x\n", - scbd_val); - wl->scbd = scbd_val; + if (val & BTC_WSCB_ACTIVE || val & BTC_WSCB_ON) + force_exec = true; - btc->cx.cnt_wl[BTC_WCNT_SCBDUPDATE]++; + if (scbd_val != wl->scbd || force_exec) { + wl->scbd = scbd_val; + wl->scbd_change = true; + } } static u8 @@ -3428,8 +4134,158 @@ static void _update_wl_info(struct rtw89_dev *rtwdev) } rtw89_debug(rtwdev, RTW89_DBG_BTC, - "[BTC], cnt_connect = %d, link_mode = %d\n", - cnt_connect, wl_rinfo->link_mode); + "[BTC], cnt_connect = %d, connecting = %d, link_mode = %d\n", + cnt_connect, cnt_connecting, wl_rinfo->link_mode); + + _fw_set_drv_info(rtwdev, CXDRVINFO_ROLE); +} + +static void _update_wl_info_v1(struct rtw89_dev *rtwdev) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_wl_link_info *wl_linfo = wl->link_info; + struct rtw89_btc_wl_role_info_v1 *wl_rinfo = &wl->role_info_v1; + struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info; + u8 cnt_connect = 0, cnt_connecting = 0, cnt_active = 0; + u8 cnt_2g = 0, cnt_5g = 0, phy; + u32 wl_2g_ch[2] = {}, wl_5g_ch[2] = {}; + bool b2g = false, b5g = false, client_joined = false; + u8 i; + + memset(wl_rinfo, 0, sizeof(*wl_rinfo)); + + for (i = 0; i < RTW89_PORT_NUM; i++) { + if (!wl_linfo[i].active) + continue; + + cnt_active++; + wl_rinfo->active_role_v1[cnt_active - 1].role = wl_linfo[i].role; + wl_rinfo->active_role_v1[cnt_active - 1].pid = wl_linfo[i].pid; + wl_rinfo->active_role_v1[cnt_active - 1].phy = wl_linfo[i].phy; + wl_rinfo->active_role_v1[cnt_active - 1].band = wl_linfo[i].band; + wl_rinfo->active_role_v1[cnt_active - 1].noa = (u8)wl_linfo[i].noa; + wl_rinfo->active_role_v1[cnt_active - 1].connected = 0; + + wl->port_id[wl_linfo[i].role] = wl_linfo[i].pid; + + phy = wl_linfo[i].phy; + + if (rtwdev->dbcc_en && phy < RTW89_PHY_MAX) { + wl_dinfo->role[phy] = wl_linfo[i].role; + wl_dinfo->op_band[phy] = wl_linfo[i].band; + _update_dbcc_band(rtwdev, phy); + _fw_set_drv_info(rtwdev, CXDRVINFO_DBCC); + } + + if (wl_linfo[i].connected == MLME_NO_LINK) { + continue; + } else if (wl_linfo[i].connected == MLME_LINKING) { + cnt_connecting++; + } else { + cnt_connect++; + if ((wl_linfo[i].role == RTW89_WIFI_ROLE_P2P_GO || + wl_linfo[i].role == RTW89_WIFI_ROLE_AP) && + wl_linfo[i].client_cnt > 1) + client_joined = true; + } + + wl_rinfo->role_map.val |= BIT(wl_linfo[i].role); + wl_rinfo->active_role_v1[cnt_active - 1].ch = wl_linfo[i].ch; + wl_rinfo->active_role_v1[cnt_active - 1].bw = wl_linfo[i].bw; + wl_rinfo->active_role_v1[cnt_active - 1].connected = 1; + + /* only care 2 roles + BT coex */ + if (wl_linfo[i].band != RTW89_BAND_2G) { + if (cnt_5g <= ARRAY_SIZE(wl_5g_ch) - 1) + wl_5g_ch[cnt_5g] = wl_linfo[i].ch; + cnt_5g++; + b5g = true; + } else { + if (cnt_2g <= ARRAY_SIZE(wl_2g_ch) - 1) + wl_2g_ch[cnt_2g] = wl_linfo[i].ch; + cnt_2g++; + b2g = true; + } + } + + wl_rinfo->connect_cnt = cnt_connect; + + /* Be careful to change the following sequence!! */ + if (cnt_connect == 0) { + wl_rinfo->link_mode = BTC_WLINK_NOLINK; + wl_rinfo->role_map.role.none = 1; + } else if (!b2g && b5g) { + wl_rinfo->link_mode = BTC_WLINK_5G; + } else if (wl_rinfo->role_map.role.nan) { + wl_rinfo->link_mode = BTC_WLINK_2G_NAN; + } else if (cnt_connect > BTC_TDMA_WLROLE_MAX) { + wl_rinfo->link_mode = BTC_WLINK_OTHER; + } else if (b2g && b5g && cnt_connect == 2) { + if (rtwdev->dbcc_en) { + switch (wl_dinfo->role[RTW89_PHY_0]) { + case RTW89_WIFI_ROLE_STATION: + wl_rinfo->link_mode = BTC_WLINK_2G_STA; + break; + case RTW89_WIFI_ROLE_P2P_GO: + wl_rinfo->link_mode = BTC_WLINK_2G_GO; + break; + case RTW89_WIFI_ROLE_P2P_CLIENT: + wl_rinfo->link_mode = BTC_WLINK_2G_GC; + break; + case RTW89_WIFI_ROLE_AP: + wl_rinfo->link_mode = BTC_WLINK_2G_AP; + break; + default: + wl_rinfo->link_mode = BTC_WLINK_OTHER; + break; + } + } else { + wl_rinfo->link_mode = BTC_WLINK_25G_MCC; + } + } else if (!b5g && cnt_connect == 2) { + if (wl_rinfo->role_map.role.station && + (wl_rinfo->role_map.role.p2p_go || + wl_rinfo->role_map.role.p2p_gc || + wl_rinfo->role_map.role.ap)) { + if (wl_2g_ch[0] == wl_2g_ch[1]) + wl_rinfo->link_mode = BTC_WLINK_2G_SCC; + else + wl_rinfo->link_mode = BTC_WLINK_2G_MCC; + } else { + wl_rinfo->link_mode = BTC_WLINK_2G_MCC; + } + } else if (!b5g && cnt_connect == 1) { + if (wl_rinfo->role_map.role.station) + wl_rinfo->link_mode = BTC_WLINK_2G_STA; + else if (wl_rinfo->role_map.role.ap) + wl_rinfo->link_mode = BTC_WLINK_2G_AP; + else if (wl_rinfo->role_map.role.p2p_go) + wl_rinfo->link_mode = BTC_WLINK_2G_GO; + else if (wl_rinfo->role_map.role.p2p_gc) + wl_rinfo->link_mode = BTC_WLINK_2G_GC; + else + wl_rinfo->link_mode = BTC_WLINK_OTHER; + } + + /* if no client_joined, don't care P2P-GO/AP role */ + if (wl_rinfo->role_map.role.p2p_go || wl_rinfo->role_map.role.ap) { + if (!client_joined) { + if (wl_rinfo->link_mode == BTC_WLINK_2G_SCC || + wl_rinfo->link_mode == BTC_WLINK_2G_MCC) { + wl_rinfo->link_mode = BTC_WLINK_2G_STA; + wl_rinfo->connect_cnt = 1; + } else if (wl_rinfo->link_mode == BTC_WLINK_2G_GO || + wl_rinfo->link_mode == BTC_WLINK_2G_AP) { + wl_rinfo->link_mode = BTC_WLINK_NOLINK; + wl_rinfo->connect_cnt = 0; + } + } + } + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], cnt_connect = %d, connecting = %d, link_mode = %d\n", + cnt_connect, cnt_connecting, wl_rinfo->link_mode); _fw_set_drv_info(rtwdev, CXDRVINFO_ROLE); } @@ -3584,23 +4440,32 @@ static bool _chk_wl_rfk_request(struct rtw89_dev *rtwdev) static void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason) { + const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_dm *dm = &rtwdev->btc.dm; struct rtw89_btc_cx *cx = &btc->cx; struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_bt_info *bt = &btc->cx.bt; struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; - u8 mode = wl_rinfo->link_mode; + struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1; + u8 mode; lockdep_assert_held(&rtwdev->mutex); - rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): reason=%d, mode=%d\n", - __func__, reason, mode); - rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): wl_only=%d, bt_only=%d\n", - __func__, dm->wl_only, dm->bt_only); dm->run_reason = reason; _update_dm_step(rtwdev, reason); _update_btc_state_map(rtwdev); + if (chip->chip_id == RTL8852A) + mode = wl_rinfo->link_mode; + else + mode = wl_rinfo_v1->link_mode; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): reason=%d, mode=%d\n", + __func__, reason, mode); + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): wl_only=%d, bt_only=%d\n", + __func__, dm->wl_only, dm->bt_only); + /* Be careful to change the following function sequence!! */ if (btc->ctrl.manual) { rtw89_debug(rtwdev, RTW89_DBG_BTC, @@ -3657,6 +4522,7 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason) btc->ctrl.igno_bt = false; dm->freerun = false; + bt->scan_rx_low_pri = false; if (reason == BTC_RSN_NTFY_INIT) { _action_wl_init(rtwdev); @@ -3699,21 +4565,30 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason) _action_wl_2g_sta(rtwdev); break; case BTC_WLINK_2G_AP: + bt->scan_rx_low_pri = true; _action_wl_2g_ap(rtwdev); break; case BTC_WLINK_2G_GO: + bt->scan_rx_low_pri = true; _action_wl_2g_go(rtwdev); break; case BTC_WLINK_2G_GC: + bt->scan_rx_low_pri = true; _action_wl_2g_gc(rtwdev); break; case BTC_WLINK_2G_SCC: - _action_wl_2g_scc(rtwdev); + bt->scan_rx_low_pri = true; + if (chip->chip_id == RTL8852A) + _action_wl_2g_scc(rtwdev); + else if (chip->chip_id == RTL8852C) + _action_wl_2g_scc_v1(rtwdev); break; case BTC_WLINK_2G_MCC: + bt->scan_rx_low_pri = true; _action_wl_2g_mcc(rtwdev); break; case BTC_WLINK_25G_MCC: + bt->scan_rx_low_pri = true; _action_wl_25g_mcc(rtwdev); break; case BTC_WLINK_5G: @@ -3743,11 +4618,14 @@ void rtw89_btc_ntfy_poweron(struct rtw89_dev *rtwdev) void rtw89_btc_ntfy_poweroff(struct rtw89_dev *rtwdev) { struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): !!\n", __func__); btc->dm.cnt_notify[BTC_NCNT_POWER_OFF]++; btc->cx.wl.status.map.rf_off = 1; + btc->cx.wl.status.map.busy = 0; + wl->status.map.lps = BTC_LPS_OFF; _write_scbd(rtwdev, BTC_WSCB_ALL, false); _run_coex(rtwdev, BTC_RSN_NTFY_POWEROFF); @@ -3807,7 +4685,7 @@ void rtw89_btc_ntfy_init(struct rtw89_dev *rtwdev, u8 mode) _write_scbd(rtwdev, BTC_WSCB_ACTIVE | BTC_WSCB_ON | BTC_WSCB_BTLOG, true); _update_bt_scbd(rtwdev, true); - if (rtw89_mac_get_ctrl_path(rtwdev)) { + if (rtw89_mac_get_ctrl_path(rtwdev) && chip->chip_id == RTL8852A) { rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): PTA owner warning!!\n", __func__); @@ -4150,7 +5028,8 @@ enum btc_wl_mode { void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, struct rtw89_sta *rtwsta, enum btc_role_state state) { - struct rtw89_hal *hal = &rtwdev->hal; + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); + const struct rtw89_chip_info *chip = rtwdev->chip; struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta); struct rtw89_btc *btc = &rtwdev->btc; @@ -4165,8 +5044,7 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif vif->type == NL80211_IFTYPE_STATION); rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], port=%d\n", rtwvif->port); rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], band=%d ch=%d bw=%d\n", - hal->current_band_type, hal->current_channel, - hal->current_band_width); + chan->band_type, chan->channel, chan->band_width); rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], associated=%d\n", state == BTC_ROLE_MSTS_STA_CONN_END); rtw89_debug(rtwdev, RTW89_DBG_BTC, @@ -4205,9 +5083,9 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif r.connected = MLME_LINKED; r.bcn_period = vif->bss_conf.beacon_int; r.dtim_period = vif->bss_conf.dtim_period; - r.band = hal->current_band_type; - r.ch = hal->current_channel; - r.bw = hal->current_band_width; + r.band = chan->band_type; + r.ch = chan->channel; + r.bw = chan->band_width; ether_addr_copy(r.mac_addr, rtwvif->mac_addr); if (rtwsta && vif->type == NL80211_IFTYPE_STATION) @@ -4218,7 +5096,10 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif wlinfo = &wl->link_info[r.pid]; memcpy(wlinfo, &r, sizeof(*wlinfo)); - _update_wl_info(rtwdev); + if (chip->chip_id == RTL8852A) + _update_wl_info(rtwdev); + else + _update_wl_info_v1(rtwdev); if (wlinfo->role == RTW89_WIFI_ROLE_STATION && wlinfo->connected == MLME_NO_LINK) @@ -4240,6 +5121,7 @@ void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_sta const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_wl_info *wl = &btc->cx.wl; + u32 val; rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): rf_state = %d\n", __func__, rf_state); @@ -4249,10 +5131,12 @@ void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_sta case BTC_RFCTRL_WL_OFF: wl->status.map.rf_off = 1; wl->status.map.lps = BTC_LPS_OFF; + wl->status.map.busy = 0; break; case BTC_RFCTRL_FW_CTRL: wl->status.map.rf_off = 0; wl->status.map.lps = BTC_LPS_RF_OFF; + wl->status.map.busy = 0; break; case BTC_RFCTRL_WL_ON: default: @@ -4262,14 +5146,17 @@ void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_sta } if (rf_state == BTC_RFCTRL_WL_ON) { + btc->dm.cnt_dm[BTC_DCNT_BTCNT_FREEZE] = 0; rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_MREG | RPT_EN_BT_VER_INFO, true); - _write_scbd(rtwdev, BTC_WSCB_ACTIVE, true); + val = BTC_WSCB_ACTIVE | BTC_WSCB_ON | BTC_WSCB_BTLOG; + _write_scbd(rtwdev, val, true); _update_bt_scbd(rtwdev, true); chip->ops->btc_init_cfg(rtwdev); } else { rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_ALL, false); - _write_scbd(rtwdev, BTC_WSCB_ACTIVE | BTC_WSCB_WLBUSY, false); + if (rf_state == BTC_RFCTRL_WL_OFF) + _write_scbd(rtwdev, BTC_WSCB_ALL, false); } _run_coex(rtwdev, BTC_RSN_NTFY_RADIO_STATE); @@ -4609,10 +5496,10 @@ static void _show_cx_info(struct rtw89_dev *rtwdev, struct seq_file *m) seq_printf(m, "========== [BTC COEX INFO (%d)] ==========\n", chip->chip_id); - ver_main = FIELD_GET(GENMASK(31, 24), chip->para_ver); - ver_sub = FIELD_GET(GENMASK(23, 16), chip->para_ver); - ver_hotfix = FIELD_GET(GENMASK(15, 8), chip->para_ver); - id_branch = FIELD_GET(GENMASK(7, 0), chip->para_ver); + ver_main = FIELD_GET(GENMASK(31, 24), RTW89_COEX_VERSION); + ver_sub = FIELD_GET(GENMASK(23, 16), RTW89_COEX_VERSION); + ver_hotfix = FIELD_GET(GENMASK(15, 8), RTW89_COEX_VERSION); + id_branch = FIELD_GET(GENMASK(7, 0), RTW89_COEX_VERSION); seq_printf(m, " %-15s : Coex:%d.%d.%d(branch:%d), ", "[coex_version]", ver_main, ver_sub, ver_hotfix, id_branch); @@ -4726,23 +5613,29 @@ static void _show_wl_role_info(struct rtw89_dev *rtwdev, struct seq_file *m) static void _show_wl_info(struct rtw89_dev *rtwdev, struct seq_file *m) { + const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_cx *cx = &btc->cx; struct rtw89_btc_wl_info *wl = &cx->wl; struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; + struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1; + u8 mode; if (!(btc->dm.coex_info_map & BTC_COEX_INFO_WL)) return; seq_puts(m, "========== [WL Status] ==========\n"); - seq_printf(m, " %-15s : link_mode:%d, ", - "[status]", (u32)wl_rinfo->link_mode); + if (chip->chip_id == RTL8852A) + mode = wl_rinfo->link_mode; + else + mode = wl_rinfo_v1->link_mode; + + seq_printf(m, " %-15s : link_mode:%d, ", "[status]", mode); seq_printf(m, - "rf_off:%s, power_save:%s, scan:%s(band:%d/phy_map:0x%x), ", - wl->status.map.rf_off ? "Y" : "N", - wl->status.map.lps ? "Y" : "N", + "rf_off:%d, power_save:%d, scan:%s(band:%d/phy_map:0x%x), ", + wl->status.map.rf_off, wl->status.map.lps, wl->status.map.scan ? "Y" : "N", wl->scan_info.band[RTW89_PHY_0], wl->scan_info.phy_map); @@ -4908,6 +5801,7 @@ static void _show_bt_info(struct rtw89_dev *rtwdev, struct seq_file *m) #define CASE_BTC_ACT_STR(e) case BTC_ACT_ ## e | BTC_ACT_EXT_BIT: return #e #define CASE_BTC_POLICY_STR(e) \ case BTC_CXP_ ## e | BTC_POLICY_EXT_BIT: return #e +#define CASE_BTC_SLOT_STR(e) case CXST_ ## e: return #e static const char *steps_to_str(u16 step) { @@ -4969,9 +5863,16 @@ static const char *steps_to_str(u16 step) CASE_BTC_POLICY_STR(OFF_EQ3); CASE_BTC_POLICY_STR(OFF_BWB0); CASE_BTC_POLICY_STR(OFF_BWB1); + CASE_BTC_POLICY_STR(OFF_BWB2); + CASE_BTC_POLICY_STR(OFF_BWB3); CASE_BTC_POLICY_STR(OFFB_BWB0); CASE_BTC_POLICY_STR(OFFE_DEF); CASE_BTC_POLICY_STR(OFFE_DEF2); + CASE_BTC_POLICY_STR(OFFE_2GBWISOB); + CASE_BTC_POLICY_STR(OFFE_2GISOB); + CASE_BTC_POLICY_STR(OFFE_2GBWMIXB); + CASE_BTC_POLICY_STR(OFFE_WL); + CASE_BTC_POLICY_STR(OFFE_2GBWMIXB2); CASE_BTC_POLICY_STR(FIX_TD3030); CASE_BTC_POLICY_STR(FIX_TD5050); CASE_BTC_POLICY_STR(FIX_TD2030); @@ -4982,6 +5883,7 @@ static const char *steps_to_str(u16 step) CASE_BTC_POLICY_STR(FIX_TD2080); CASE_BTC_POLICY_STR(FIX_TDW1B1); CASE_BTC_POLICY_STR(FIX_TD4020); + CASE_BTC_POLICY_STR(FIX_TD4010ISO); CASE_BTC_POLICY_STR(PFIX_TD3030); CASE_BTC_POLICY_STR(PFIX_TD5050); CASE_BTC_POLICY_STR(PFIX_TD2030); @@ -4989,13 +5891,13 @@ static const char *steps_to_str(u16 step) CASE_BTC_POLICY_STR(PFIX_TD3070); CASE_BTC_POLICY_STR(PFIX_TD2080); CASE_BTC_POLICY_STR(PFIX_TDW1B1); - CASE_BTC_POLICY_STR(AUTO_TD50200); - CASE_BTC_POLICY_STR(AUTO_TD60200); - CASE_BTC_POLICY_STR(AUTO_TD20200); + CASE_BTC_POLICY_STR(AUTO_TD50B1); + CASE_BTC_POLICY_STR(AUTO_TD60B1); + CASE_BTC_POLICY_STR(AUTO_TD20B1); CASE_BTC_POLICY_STR(AUTO_TDW1B1); - CASE_BTC_POLICY_STR(PAUTO_TD50200); - CASE_BTC_POLICY_STR(PAUTO_TD60200); - CASE_BTC_POLICY_STR(PAUTO_TD20200); + CASE_BTC_POLICY_STR(PAUTO_TD50B1); + CASE_BTC_POLICY_STR(PAUTO_TD60B1); + CASE_BTC_POLICY_STR(PAUTO_TD20B1); CASE_BTC_POLICY_STR(PAUTO_TDW1B1); CASE_BTC_POLICY_STR(AUTO2_TD3050); CASE_BTC_POLICY_STR(AUTO2_TD3070); @@ -5014,6 +5916,32 @@ static const char *steps_to_str(u16 step) } } +static const char *id_to_slot(u32 id) +{ + switch (id) { + CASE_BTC_SLOT_STR(OFF); + CASE_BTC_SLOT_STR(B2W); + CASE_BTC_SLOT_STR(W1); + CASE_BTC_SLOT_STR(W2); + CASE_BTC_SLOT_STR(W2B); + CASE_BTC_SLOT_STR(B1); + CASE_BTC_SLOT_STR(B2); + CASE_BTC_SLOT_STR(B3); + CASE_BTC_SLOT_STR(B4); + CASE_BTC_SLOT_STR(LK); + CASE_BTC_SLOT_STR(BLK); + CASE_BTC_SLOT_STR(E2G); + CASE_BTC_SLOT_STR(E5G); + CASE_BTC_SLOT_STR(EBT); + CASE_BTC_SLOT_STR(ENULL); + CASE_BTC_SLOT_STR(WLK); + CASE_BTC_SLOT_STR(W1FDD); + CASE_BTC_SLOT_STR(B1FDD); + default: + return "unknown"; + } +} + static void seq_print_segment(struct seq_file *m, const char *prefix, u16 *data, u8 len, u8 seg_len, u8 start_idx, u8 ring_len) @@ -5105,21 +6033,31 @@ static void _show_dm_info(struct rtw89_dev *rtwdev, struct seq_file *m) (bt->hi_lna_rx ? "Hi" : "Ori"), dm->wl_btg_rx); seq_printf(m, - " %-15s : wl_tx_limit[en:%d/max_t:%dus/max_retry:%d], bt_slot_reg:%d-TU\n", + " %-15s : wl_tx_limit[en:%d/max_t:%dus/max_retry:%d], bt_slot_reg:%d-TU, bt_scan_rx_low_pri:%d\n", "[dm_ctrl]", dm->wl_tx_limit.enable, dm->wl_tx_limit.tx_time, - dm->wl_tx_limit.tx_retry, btc->bt_req_len); + dm->wl_tx_limit.tx_retry, btc->bt_req_len, bt->scan_rx_low_pri); } static void _show_error(struct rtw89_dev *rtwdev, struct seq_file *m) { + const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; - struct rtw89_btc_fbtc_cysta *pcysta = NULL; - - pcysta = &pfwinfo->rpt_fbtc_cysta.finfo; + struct rtw89_btc_fbtc_cysta *pcysta; + struct rtw89_btc_fbtc_cysta_v1 *pcysta_v1; + u32 except_cnt, exception_map; + + if (chip->chip_id == RTL8852A) { + pcysta = &pfwinfo->rpt_fbtc_cysta.finfo; + except_cnt = le32_to_cpu(pcysta->except_cnt); + exception_map = le32_to_cpu(pcysta->exception); + } else { + pcysta_v1 = &pfwinfo->rpt_fbtc_cysta.finfo_v1; + except_cnt = le32_to_cpu(pcysta_v1->except_cnt); + exception_map = le32_to_cpu(pcysta_v1->except_map); + } - if (pfwinfo->event[BTF_EVNT_BUF_OVERFLOW] == 0 && - pcysta->except_cnt == 0 && + if (pfwinfo->event[BTF_EVNT_BUF_OVERFLOW] == 0 && except_cnt == 0 && !pfwinfo->len_mismch && !pfwinfo->fver_mismch) return; @@ -5144,16 +6082,17 @@ static void _show_error(struct rtw89_dev *rtwdev, struct seq_file *m) } /* cycle statistics exceptions */ - if (pcysta->exception || pcysta->except_cnt) { + if (exception_map || except_cnt) { seq_printf(m, "exception-type: 0x%x, exception-cnt = %d", - pcysta->exception, pcysta->except_cnt); + exception_map, except_cnt); } seq_puts(m, "\n"); } static void _show_fbtc_tdma(struct rtw89_dev *rtwdev, struct seq_file *m) { + const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; @@ -5166,7 +6105,10 @@ static void _show_fbtc_tdma(struct rtw89_dev *rtwdev, struct seq_file *m) if (!pcinfo->valid) return; - t = &pfwinfo->rpt_fbtc_tdma.finfo; + if (chip->chip_id == RTL8852A) + t = &pfwinfo->rpt_fbtc_tdma.finfo; + else + t = &pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma; seq_printf(m, " %-15s : ", "[tdma_policy]"); @@ -5369,12 +6311,145 @@ static void _show_fbtc_cysta(struct rtw89_dev *rtwdev, struct seq_file *m) } } +static void _show_fbtc_cysta_v1(struct rtw89_dev *rtwdev, struct seq_file *m) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc; + struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_fbtc_a2dp_trx_stat *a2dp_trx; + struct rtw89_btc_fbtc_cysta_v1 *pcysta; + struct rtw89_btc_rpt_cmn_info *pcinfo; + u8 i, cnt = 0, slot_pair, divide_cnt; + u16 cycle, c_begin, c_end, store_index; + + pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; + if (!pcinfo->valid) + return; + + pcysta = &pfwinfo->rpt_fbtc_cysta.finfo_v1; + seq_printf(m, + " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]", + "[cycle_cnt]", + le16_to_cpu(pcysta->cycles), + le32_to_cpu(pcysta->bcn_cnt[CXBCN_ALL]), + le32_to_cpu(pcysta->bcn_cnt[CXBCN_ALL_OK]), + le32_to_cpu(pcysta->bcn_cnt[CXBCN_BT_SLOT]), + le32_to_cpu(pcysta->bcn_cnt[CXBCN_BT_OK])); + + for (i = 0; i < CXST_MAX; i++) { + if (!le32_to_cpu(pcysta->slot_cnt[i])) + continue; + + seq_printf(m, ", %s:%d", id_to_slot(i), + le32_to_cpu(pcysta->slot_cnt[i])); + } + + if (dm->tdma_now.rxflctrl) + seq_printf(m, ", leak_rx:%d", le32_to_cpu(pcysta->leak_slot.cnt_rximr)); + + if (le32_to_cpu(pcysta->collision_cnt)) + seq_printf(m, ", collision:%d", le32_to_cpu(pcysta->collision_cnt)); + + if (le32_to_cpu(pcysta->skip_cnt)) + seq_printf(m, ", skip:%d", le32_to_cpu(pcysta->skip_cnt)); + + seq_puts(m, "\n"); + + seq_printf(m, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]", + "[cycle_time]", + le16_to_cpu(pcysta->cycle_time.tavg[CXT_WL]), + le16_to_cpu(pcysta->cycle_time.tavg[CXT_BT]), + le16_to_cpu(pcysta->leak_slot.tavg) / 1000, + le16_to_cpu(pcysta->leak_slot.tavg) % 1000); + seq_printf(m, + ", max_t[wl:%d/bt:%d/lk:%d.%03d]", + le16_to_cpu(pcysta->cycle_time.tmax[CXT_WL]), + le16_to_cpu(pcysta->cycle_time.tmax[CXT_BT]), + le16_to_cpu(pcysta->leak_slot.tmax) / 1000, + le16_to_cpu(pcysta->leak_slot.tmax) % 1000); + seq_printf(m, + ", maxdiff_t[wl:%d/bt:%d]\n", + le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_WL]), + le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_BT])); + + cycle = le16_to_cpu(pcysta->cycles); + if (cycle == 0) + return; + + /* 1 cycle record 1 wl-slot and 1 bt-slot */ + slot_pair = BTC_CYCLE_SLOT_MAX / 2; + + if (cycle <= slot_pair) + c_begin = 1; + else + c_begin = cycle - slot_pair + 1; + + c_end = cycle; + + if (a2dp->exist) + divide_cnt = 3; + else + divide_cnt = BTC_CYCLE_SLOT_MAX / 4; + + for (cycle = c_begin; cycle <= c_end; cycle++) { + cnt++; + store_index = ((cycle - 1) % slot_pair) * 2; + + if (cnt % divide_cnt == 1) { + seq_printf(m, "\n\r %-15s : ", "[cycle_step]"); + } else { + seq_printf(m, "->b%02d", + le16_to_cpu(pcysta->slot_step_time[store_index])); + if (a2dp->exist) { + a2dp_trx = &pcysta->a2dp_trx[store_index]; + seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", + a2dp_trx->empty_cnt, + a2dp_trx->retry_cnt, + a2dp_trx->tx_rate ? 3 : 2, + a2dp_trx->tx_cnt, + a2dp_trx->ack_cnt, + a2dp_trx->nack_cnt); + } + seq_printf(m, "->w%02d", + le16_to_cpu(pcysta->slot_step_time[store_index + 1])); + if (a2dp->exist) { + a2dp_trx = &pcysta->a2dp_trx[store_index + 1]; + seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", + a2dp_trx->empty_cnt, + a2dp_trx->retry_cnt, + a2dp_trx->tx_rate ? 3 : 2, + a2dp_trx->tx_cnt, + a2dp_trx->ack_cnt, + a2dp_trx->nack_cnt); + } + } + if (cnt % (BTC_CYCLE_SLOT_MAX / 4) == 0 || cnt == c_end) + seq_puts(m, "\n"); + } + + if (a2dp->exist) { + seq_printf(m, "%-15s : a2dp_ept:%d, a2dp_late:%d", + "[a2dp_t_sta]", + le16_to_cpu(pcysta->a2dp_ept.cnt), + le16_to_cpu(pcysta->a2dp_ept.cnt_timeout)); + + seq_printf(m, ", avg_t:%d, max_t:%d", + le16_to_cpu(pcysta->a2dp_ept.tavg), + le16_to_cpu(pcysta->a2dp_ept.tmax)); + + seq_puts(m, "\n"); + } +} + static void _show_fbtc_nullsta(struct rtw89_dev *rtwdev, struct seq_file *m) { + const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; - struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; - struct rtw89_btc_fbtc_cynullsta *ns = NULL; + struct rtw89_btc_rpt_cmn_info *pcinfo; + struct rtw89_btc_fbtc_cynullsta *ns; + struct rtw89_btc_fbtc_cynullsta_v1 *ns_v1; u8 i = 0; if (!btc->dm.tdma_now.rxflctrl) @@ -5384,25 +6459,58 @@ static void _show_fbtc_nullsta(struct rtw89_dev *rtwdev, struct seq_file *m) if (!pcinfo->valid) return; - ns = &pfwinfo->rpt_fbtc_nullsta.finfo; + if (chip->chip_id == RTL8852A) { + ns = &pfwinfo->rpt_fbtc_nullsta.finfo; - seq_printf(m, " %-15s : ", "[null_sta]"); + seq_printf(m, " %-15s : ", "[null_sta]"); - for (i = 0; i < 2; i++) { - if (i != 0) - seq_printf(m, ", null-%d", i); - else - seq_printf(m, "null-%d", i); - seq_printf(m, "[ok:%d/", le32_to_cpu(ns->result[i][1])); - seq_printf(m, "fail:%d/", le32_to_cpu(ns->result[i][0])); - seq_printf(m, "on_time:%d/", le32_to_cpu(ns->result[i][2])); - seq_printf(m, "retry:%d/", le32_to_cpu(ns->result[i][3])); - seq_printf(m, "avg_t:%d.%03d/", - le32_to_cpu(ns->avg_t[i]) / 1000, - le32_to_cpu(ns->avg_t[i]) % 1000); - seq_printf(m, "max_t:%d.%03d]", - le32_to_cpu(ns->max_t[i]) / 1000, - le32_to_cpu(ns->max_t[i]) % 1000); + for (i = 0; i < 2; i++) { + if (i != 0) + seq_printf(m, ", null-%d", i); + else + seq_printf(m, "null-%d", i); + seq_printf(m, "[ok:%d/", + le32_to_cpu(ns->result[i][1])); + seq_printf(m, "fail:%d/", + le32_to_cpu(ns->result[i][0])); + seq_printf(m, "on_time:%d/", + le32_to_cpu(ns->result[i][2])); + seq_printf(m, "retry:%d/", + le32_to_cpu(ns->result[i][3])); + seq_printf(m, "avg_t:%d.%03d/", + le32_to_cpu(ns->avg_t[i]) / 1000, + le32_to_cpu(ns->avg_t[i]) % 1000); + seq_printf(m, "max_t:%d.%03d]", + le32_to_cpu(ns->max_t[i]) / 1000, + le32_to_cpu(ns->max_t[i]) % 1000); + } + } else { + ns_v1 = &pfwinfo->rpt_fbtc_nullsta.finfo_v1; + + seq_printf(m, " %-15s : ", "[null_sta]"); + + for (i = 0; i < 2; i++) { + if (i != 0) + seq_printf(m, ", null-%d", i); + else + seq_printf(m, "null-%d", i); + seq_printf(m, "[Tx:%d/", + le32_to_cpu(ns_v1->result[i][4])); + seq_printf(m, "[ok:%d/", + le32_to_cpu(ns_v1->result[i][1])); + seq_printf(m, "fail:%d/", + le32_to_cpu(ns_v1->result[i][0])); + seq_printf(m, "on_time:%d/", + le32_to_cpu(ns_v1->result[i][2])); + seq_printf(m, "retry:%d/", + le32_to_cpu(ns_v1->result[i][3])); + seq_printf(m, "avg_t:%d.%03d/", + le32_to_cpu(ns_v1->avg_t[i]) / 1000, + le32_to_cpu(ns_v1->avg_t[i]) % 1000); + seq_printf(m, "max_t:%d.%03d]", + le32_to_cpu(ns_v1->max_t[i]) / 1000, + le32_to_cpu(ns_v1->max_t[i]) % 1000); + } } seq_puts(m, "\n"); } @@ -5478,6 +6586,7 @@ static void _show_fbtc_step(struct rtw89_dev *rtwdev, struct seq_file *m) static void _show_fw_dm_msg(struct rtw89_dev *rtwdev, struct seq_file *m) { + const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_btc *btc = &rtwdev->btc; if (!(btc->dm.coex_info_map & BTC_COEX_INFO_DM)) @@ -5486,11 +6595,57 @@ static void _show_fw_dm_msg(struct rtw89_dev *rtwdev, struct seq_file *m) _show_error(rtwdev, m); _show_fbtc_tdma(rtwdev, m); _show_fbtc_slots(rtwdev, m); - _show_fbtc_cysta(rtwdev, m); + + if (chip->chip_id == RTL8852A) + _show_fbtc_cysta(rtwdev, m); + else + _show_fbtc_cysta_v1(rtwdev, m); + _show_fbtc_nullsta(rtwdev, m); _show_fbtc_step(rtwdev, m); } +static void _get_gnt(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_coex_gnt *gnt_cfg) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_mac_ax_gnt *gnt; + u32 val, status; + + if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B) { + rtw89_mac_read_lte(rtwdev, R_AX_LTE_SW_CFG_1, &val); + rtw89_mac_read_lte(rtwdev, R_AX_GNT_VAL, &status); + + gnt = &gnt_cfg->band[0]; + gnt->gnt_bt_sw_en = !!(val & B_AX_GNT_BT_RFC_S0_SW_CTRL); + gnt->gnt_bt = !!(status & B_AX_GNT_BT_RFC_S0_STA); + gnt->gnt_wl_sw_en = !!(val & B_AX_GNT_WL_RFC_S0_SW_CTRL); + gnt->gnt_wl = !!(status & B_AX_GNT_WL_RFC_S0_STA); + + gnt = &gnt_cfg->band[1]; + gnt->gnt_bt_sw_en = !!(val & B_AX_GNT_BT_RFC_S1_SW_CTRL); + gnt->gnt_bt = !!(status & B_AX_GNT_BT_RFC_S1_STA); + gnt->gnt_wl_sw_en = !!(val & B_AX_GNT_WL_RFC_S1_SW_CTRL); + gnt->gnt_wl = !!(status & B_AX_GNT_WL_RFC_S1_STA); + } else if (chip->chip_id == RTL8852C) { + val = rtw89_read32(rtwdev, R_AX_GNT_SW_CTRL); + status = rtw89_read32(rtwdev, R_AX_GNT_VAL_V1); + + gnt = &gnt_cfg->band[0]; + gnt->gnt_bt_sw_en = !!(val & B_AX_GNT_BT_RFC_S0_SWCTRL); + gnt->gnt_bt = !!(status & B_AX_GNT_BT_RFC_S0); + gnt->gnt_wl_sw_en = !!(val & B_AX_GNT_WL_RFC_S0_SWCTRL); + gnt->gnt_wl = !!(status & B_AX_GNT_WL_RFC_S0); + + gnt = &gnt_cfg->band[1]; + gnt->gnt_bt_sw_en = !!(val & B_AX_GNT_BT_RFC_S1_SWCTRL); + gnt->gnt_bt = !!(status & B_AX_GNT_BT_RFC_S1); + gnt->gnt_wl_sw_en = !!(val & B_AX_GNT_WL_RFC_S1_SWCTRL); + gnt->gnt_wl = !!(status & B_AX_GNT_WL_RFC_S1); + } else { + return; + } +} + static void _show_mreg(struct rtw89_dev *rtwdev, struct seq_file *m) { const struct rtw89_chip_info *chip = rtwdev->chip; @@ -5502,7 +6657,8 @@ static void _show_mreg(struct rtw89_dev *rtwdev, struct seq_file *m) struct rtw89_btc_cx *cx = &btc->cx; struct rtw89_btc_wl_info *wl = &btc->cx.wl; struct rtw89_btc_bt_info *bt = &btc->cx.bt; - struct rtw89_mac_ax_gnt gnt[2] = {0}; + struct rtw89_mac_ax_coex_gnt gnt_cfg = {}; + struct rtw89_mac_ax_gnt gnt; u8 i = 0, type = 0, cnt = 0; u32 val, offset; @@ -5519,45 +6675,28 @@ static void _show_mreg(struct rtw89_dev *rtwdev, struct seq_file *m) /* To avoid I/O if WL LPS or power-off */ if (!wl->status.map.lps && !wl->status.map.rf_off) { - rtw89_mac_read_lte(rtwdev, R_AX_LTE_SW_CFG_1, &val); - if (val & (B_AX_GNT_BT_RFC_S0_SW_VAL | - B_AX_GNT_BT_BB_S0_SW_VAL)) - gnt[0].gnt_bt = true; - if (val & (B_AX_GNT_BT_RFC_S0_SW_CTRL | - B_AX_GNT_BT_BB_S0_SW_CTRL)) - gnt[0].gnt_bt_sw_en = true; - if (val & (B_AX_GNT_WL_RFC_S0_SW_VAL | - B_AX_GNT_WL_BB_S0_SW_VAL)) - gnt[0].gnt_wl = true; - if (val & (B_AX_GNT_WL_RFC_S0_SW_CTRL | - B_AX_GNT_WL_BB_S0_SW_CTRL)) - gnt[0].gnt_wl_sw_en = true; - - if (val & (B_AX_GNT_BT_RFC_S1_SW_VAL | - B_AX_GNT_BT_BB_S1_SW_VAL)) - gnt[1].gnt_bt = true; - if (val & (B_AX_GNT_BT_RFC_S1_SW_CTRL | - B_AX_GNT_BT_BB_S1_SW_CTRL)) - gnt[1].gnt_bt_sw_en = true; - if (val & (B_AX_GNT_WL_RFC_S1_SW_VAL | - B_AX_GNT_WL_BB_S1_SW_VAL)) - gnt[1].gnt_wl = true; - if (val & (B_AX_GNT_WL_RFC_S1_SW_CTRL | - B_AX_GNT_WL_BB_S1_SW_CTRL)) - gnt[1].gnt_wl_sw_en = true; + if (chip->chip_id == RTL8852A) + btc->dm.pta_owner = rtw89_mac_get_ctrl_path(rtwdev); + else if (chip->chip_id == RTL8852C) + btc->dm.pta_owner = 0; + _get_gnt(rtwdev, &gnt_cfg); + gnt = gnt_cfg.band[0]; seq_printf(m, " %-15s : pta_owner:%s, phy-0[gnt_wl:%s-%d/gnt_bt:%s-%d], ", "[gnt_status]", - (rtw89_mac_get_ctrl_path(rtwdev) ? "WL" : "BT"), - (gnt[0].gnt_wl_sw_en ? "SW" : "HW"), gnt[0].gnt_wl, - (gnt[0].gnt_bt_sw_en ? "SW" : "HW"), gnt[0].gnt_bt); + chip->chip_id == RTL8852C ? "HW" : + btc->dm.pta_owner == BTC_CTRL_BY_WL ? "WL" : "BT", + gnt.gnt_wl_sw_en ? "SW" : "HW", gnt.gnt_wl, + gnt.gnt_bt_sw_en ? "SW" : "HW", gnt.gnt_bt); + gnt = gnt_cfg.band[1]; seq_printf(m, "phy-1[gnt_wl:%s-%d/gnt_bt:%s-%d]\n", - (gnt[1].gnt_wl_sw_en ? "SW" : "HW"), gnt[1].gnt_wl, - (gnt[1].gnt_bt_sw_en ? "SW" : "HW"), gnt[1].gnt_bt); + gnt.gnt_wl_sw_en ? "SW" : "HW", + gnt.gnt_wl, + gnt.gnt_bt_sw_en ? "SW" : "HW", + gnt.gnt_bt); } - pcinfo = &pfwinfo->rpt_fbtc_mregval.cinfo; if (!pcinfo->valid) { rtw89_debug(rtwdev, RTW89_DBG_BTC, @@ -5714,8 +6853,121 @@ static void _show_summary(struct rtw89_dev *rtwdev, struct seq_file *m) cnt[BTC_NCNT_CUSTOMERIZE]); } +static void _show_summary_v1(struct rtw89_dev *rtwdev, struct seq_file *m) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; + struct rtw89_btc_fbtc_rpt_ctrl_v1 *prptctrl; + struct rtw89_btc_rpt_cmn_info *pcinfo; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_wl_info *wl = &cx->wl; + struct rtw89_btc_bt_info *bt = &cx->bt; + u32 cnt_sum = 0, *cnt = btc->dm.cnt_notify; + u8 i; + + if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY)) + return; + + seq_puts(m, "========== [Statistics] ==========\n"); + + pcinfo = &pfwinfo->rpt_ctrl.cinfo; + if (pcinfo->valid && !wl->status.map.lps && !wl->status.map.rf_off) { + prptctrl = &pfwinfo->rpt_ctrl.finfo_v1; + + seq_printf(m, + " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d), ", + "[summary]", pfwinfo->cnt_h2c, + pfwinfo->cnt_h2c_fail, + le32_to_cpu(prptctrl->rpt_info.cnt_h2c), + pfwinfo->cnt_c2h, + le32_to_cpu(prptctrl->rpt_info.cnt_c2h)); + + seq_printf(m, + "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x, dm_error_map:0x%x", + pfwinfo->event[BTF_EVNT_RPT], + le32_to_cpu(prptctrl->rpt_info.cnt), + le32_to_cpu(prptctrl->rpt_info.en), + dm->error.val); + + if (dm->error.map.wl_fw_hang) + seq_puts(m, " (WL FW Hang!!)"); + seq_puts(m, "\n"); + seq_printf(m, + " %-15s : send_ok:%d, send_fail:%d, recv:%d, ", + "[mailbox]", + le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok), + le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail), + le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv)); + + seq_printf(m, + "A2DP_empty:%d(stop:%d, tx:%d, ack:%d, nack:%d)\n", + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack)); + + seq_printf(m, + " %-15s : wl_rfk[req:%d/go:%d/reject:%d/timeout:%d]", + "[RFK]", cx->cnt_wl[BTC_WCNT_RFK_REQ], + cx->cnt_wl[BTC_WCNT_RFK_GO], + cx->cnt_wl[BTC_WCNT_RFK_REJECT], + cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]); + + seq_printf(m, + ", bt_rfk[req:%d/go:%d/reject:%d/timeout:%d/fail:%d]\n", + le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ]), + le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_GO]), + le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REJECT]), + le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_TIMEOUT]), + le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_FAIL])); + + if (le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_TIMEOUT]) > 0) + bt->rfk_info.map.timeout = 1; + else + bt->rfk_info.map.timeout = 0; + + dm->error.map.wl_rfk_timeout = bt->rfk_info.map.timeout; + } else { + seq_printf(m, + " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d, rpt_cnt=%d, rpt_map=0x%x", + "[summary]", pfwinfo->cnt_h2c, + pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h, + pfwinfo->event[BTF_EVNT_RPT], + btc->fwinfo.rpt_en_map); + seq_puts(m, " (WL FW report invalid!!)\n"); + } + + for (i = 0; i < BTC_NCNT_NUM; i++) + cnt_sum += dm->cnt_notify[i]; + + seq_printf(m, + " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", + "[notify_cnt]", cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], + cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); + + seq_printf(m, + "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d\n", + cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], + cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], + cnt[BTC_NCNT_WL_STA]); + + seq_printf(m, + " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ", + "[notify_cnt]", cnt[BTC_NCNT_SCAN_START], + cnt[BTC_NCNT_SCAN_FINISH], cnt[BTC_NCNT_SWITCH_BAND], + cnt[BTC_NCNT_SPECIAL_PACKET]); + + seq_printf(m, + "timer=%d, control=%d, customerize=%d\n", + cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL], + cnt[BTC_NCNT_CUSTOMERIZE]); +} + void rtw89_btc_dump_info(struct rtw89_dev *rtwdev, struct seq_file *m) { + const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_fw_suit *fw_suit = &rtwdev->fw.normal; struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_cx *cx = &btc->cx; @@ -5746,5 +6998,8 @@ void rtw89_btc_dump_info(struct rtw89_dev *rtwdev, struct seq_file *m) _show_dm_info(rtwdev, m); _show_fw_dm_msg(rtwdev, m); _show_mreg(rtwdev, m); - _show_summary(rtwdev, m); + if (chip->chip_id == RTL8852A) + _show_summary(rtwdev, m); + else + _show_summary_v1(rtwdev, m); } |