18e93258fSBjoern A. Zeeb // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 28e93258fSBjoern A. Zeeb /* Copyright(c) 2019-2020 Realtek Corporation 38e93258fSBjoern A. Zeeb */ 48e93258fSBjoern A. Zeeb 58e93258fSBjoern A. Zeeb #include "coex.h" 68e93258fSBjoern A. Zeeb #include "debug.h" 78e93258fSBjoern A. Zeeb #include "fw.h" 88e93258fSBjoern A. Zeeb #include "mac.h" 9*6d67aabdSBjoern A. Zeeb #include "phy.h" 108e93258fSBjoern A. Zeeb #include "ps.h" 118e93258fSBjoern A. Zeeb #include "reg.h" 128e93258fSBjoern A. Zeeb 13e2340276SBjoern A. Zeeb #define RTW89_COEX_VERSION 0x07000113 148e93258fSBjoern A. Zeeb #define FCXDEF_STEP 50 /* MUST <= FCXMAX_STEP and match with wl fw*/ 15*6d67aabdSBjoern A. Zeeb #define BTC_E2G_LIMIT_DEF 80 168e93258fSBjoern A. Zeeb 178e93258fSBjoern A. Zeeb enum btc_fbtc_tdma_template { 188e93258fSBjoern A. Zeeb CXTD_OFF = 0x0, 198e93258fSBjoern A. Zeeb CXTD_OFF_B2, 208e93258fSBjoern A. Zeeb CXTD_OFF_EXT, 218e93258fSBjoern A. Zeeb CXTD_FIX, 228e93258fSBjoern A. Zeeb CXTD_PFIX, 238e93258fSBjoern A. Zeeb CXTD_AUTO, 248e93258fSBjoern A. Zeeb CXTD_PAUTO, 258e93258fSBjoern A. Zeeb CXTD_AUTO2, 268e93258fSBjoern A. Zeeb CXTD_PAUTO2, 278e93258fSBjoern A. Zeeb CXTD_MAX, 288e93258fSBjoern A. Zeeb }; 298e93258fSBjoern A. Zeeb 308e93258fSBjoern A. Zeeb enum btc_fbtc_tdma_type { 318e93258fSBjoern A. Zeeb CXTDMA_OFF = 0x0, 328e93258fSBjoern A. Zeeb CXTDMA_FIX = 0x1, 338e93258fSBjoern A. Zeeb CXTDMA_AUTO = 0x2, 348e93258fSBjoern A. Zeeb CXTDMA_AUTO2 = 0x3, 358e93258fSBjoern A. Zeeb CXTDMA_MAX 368e93258fSBjoern A. Zeeb }; 378e93258fSBjoern A. Zeeb 388e93258fSBjoern A. Zeeb enum btc_fbtc_tdma_rx_flow_ctrl { 398e93258fSBjoern A. Zeeb CXFLC_OFF = 0x0, 408e93258fSBjoern A. Zeeb CXFLC_NULLP = 0x1, 418e93258fSBjoern A. Zeeb CXFLC_QOSNULL = 0x2, 428e93258fSBjoern A. Zeeb CXFLC_CTS = 0x3, 438e93258fSBjoern A. Zeeb CXFLC_MAX 448e93258fSBjoern A. Zeeb }; 458e93258fSBjoern A. Zeeb 468e93258fSBjoern A. Zeeb enum btc_fbtc_tdma_wlan_tx_pause { 478e93258fSBjoern A. Zeeb CXTPS_OFF = 0x0, /* no wl tx pause*/ 488e93258fSBjoern A. Zeeb CXTPS_ON = 0x1, 498e93258fSBjoern A. Zeeb CXTPS_MAX 508e93258fSBjoern A. Zeeb }; 518e93258fSBjoern A. Zeeb 528e93258fSBjoern A. Zeeb enum btc_mlme_state { 538e93258fSBjoern A. Zeeb MLME_NO_LINK, 548e93258fSBjoern A. Zeeb MLME_LINKING, 558e93258fSBjoern A. Zeeb MLME_LINKED, 568e93258fSBjoern A. Zeeb }; 578e93258fSBjoern A. Zeeb 588e93258fSBjoern A. Zeeb struct btc_fbtc_1slot { 598e93258fSBjoern A. Zeeb u8 fver; 608e93258fSBjoern A. Zeeb u8 sid; /* slot id */ 618e93258fSBjoern A. Zeeb struct rtw89_btc_fbtc_slot slot; 628e93258fSBjoern A. Zeeb } __packed; 638e93258fSBjoern A. Zeeb 648e93258fSBjoern A. Zeeb static const struct rtw89_btc_fbtc_tdma t_def[] = { 658e93258fSBjoern A. Zeeb [CXTD_OFF] = { CXTDMA_OFF, CXFLC_OFF, CXTPS_OFF, 0, 0, 0, 0, 0}, 668e93258fSBjoern A. Zeeb [CXTD_OFF_B2] = { CXTDMA_OFF, CXFLC_OFF, CXTPS_OFF, 0, 0, 1, 0, 0}, 67e2340276SBjoern A. Zeeb [CXTD_OFF_EXT] = { CXTDMA_OFF, CXFLC_OFF, CXTPS_OFF, 0, 0, 2, 0, 0}, 688e93258fSBjoern A. Zeeb [CXTD_FIX] = { CXTDMA_FIX, CXFLC_OFF, CXTPS_OFF, 0, 0, 0, 0, 0}, 698e93258fSBjoern A. Zeeb [CXTD_PFIX] = { CXTDMA_FIX, CXFLC_NULLP, CXTPS_ON, 0, 5, 0, 0, 0}, 708e93258fSBjoern A. Zeeb [CXTD_AUTO] = { CXTDMA_AUTO, CXFLC_OFF, CXTPS_OFF, 0, 0, 0, 0, 0}, 718e93258fSBjoern A. Zeeb [CXTD_PAUTO] = { CXTDMA_AUTO, CXFLC_NULLP, CXTPS_ON, 0, 5, 0, 0, 0}, 728e93258fSBjoern A. Zeeb [CXTD_AUTO2] = {CXTDMA_AUTO2, CXFLC_OFF, CXTPS_OFF, 0, 0, 0, 0, 0}, 738e93258fSBjoern A. Zeeb [CXTD_PAUTO2] = {CXTDMA_AUTO2, CXFLC_NULLP, CXTPS_ON, 0, 5, 0, 0, 0} 748e93258fSBjoern A. Zeeb }; 758e93258fSBjoern A. Zeeb 768e93258fSBjoern A. Zeeb #define __DEF_FBTC_SLOT(__dur, __cxtbl, __cxtype) \ 778e93258fSBjoern A. Zeeb { .dur = cpu_to_le16(__dur), .cxtbl = cpu_to_le32(__cxtbl), \ 788e93258fSBjoern A. Zeeb .cxtype = cpu_to_le16(__cxtype),} 798e93258fSBjoern A. Zeeb 808e93258fSBjoern A. Zeeb static const struct rtw89_btc_fbtc_slot s_def[] = { 818e93258fSBjoern A. Zeeb [CXST_OFF] = __DEF_FBTC_SLOT(100, 0x55555555, SLOT_MIX), 82e2340276SBjoern A. Zeeb [CXST_B2W] = __DEF_FBTC_SLOT(5, 0xea5a5a5a, SLOT_ISO), 83e2340276SBjoern A. Zeeb [CXST_W1] = __DEF_FBTC_SLOT(70, 0xea5a5a5a, SLOT_ISO), 84e2340276SBjoern A. Zeeb [CXST_W2] = __DEF_FBTC_SLOT(15, 0xea5a5a5a, SLOT_ISO), 85e2340276SBjoern A. Zeeb [CXST_W2B] = __DEF_FBTC_SLOT(15, 0xea5a5a5a, SLOT_ISO), 86e2340276SBjoern A. Zeeb [CXST_B1] = __DEF_FBTC_SLOT(250, 0xe5555555, SLOT_MIX), 87e2340276SBjoern A. Zeeb [CXST_B2] = __DEF_FBTC_SLOT(7, 0xea5a5a5a, SLOT_MIX), 88e2340276SBjoern A. Zeeb [CXST_B3] = __DEF_FBTC_SLOT(5, 0xe5555555, SLOT_MIX), 89e2340276SBjoern A. Zeeb [CXST_B4] = __DEF_FBTC_SLOT(50, 0xe5555555, SLOT_MIX), 90e2340276SBjoern A. Zeeb [CXST_LK] = __DEF_FBTC_SLOT(20, 0xea5a5a5a, SLOT_ISO), 91e2340276SBjoern A. Zeeb [CXST_BLK] = __DEF_FBTC_SLOT(500, 0x55555555, SLOT_MIX), 92e2340276SBjoern A. Zeeb [CXST_E2G] = __DEF_FBTC_SLOT(0, 0xea5a5a5a, SLOT_MIX), 93e2340276SBjoern A. Zeeb [CXST_E5G] = __DEF_FBTC_SLOT(0, 0xffffffff, SLOT_ISO), 94*6d67aabdSBjoern A. Zeeb [CXST_EBT] = __DEF_FBTC_SLOT(5, 0xe5555555, SLOT_MIX), 95e2340276SBjoern A. Zeeb [CXST_ENULL] = __DEF_FBTC_SLOT(0, 0xaaaaaaaa, SLOT_ISO), 96e2340276SBjoern A. Zeeb [CXST_WLK] = __DEF_FBTC_SLOT(250, 0xea5a5a5a, SLOT_MIX), 97e2340276SBjoern A. Zeeb [CXST_W1FDD] = __DEF_FBTC_SLOT(50, 0xffffffff, SLOT_ISO), 98e2340276SBjoern A. Zeeb [CXST_B1FDD] = __DEF_FBTC_SLOT(50, 0xffffdfff, SLOT_ISO), 998e93258fSBjoern A. Zeeb }; 1008e93258fSBjoern A. Zeeb 1018e93258fSBjoern A. Zeeb static const u32 cxtbl[] = { 1028e93258fSBjoern A. Zeeb 0xffffffff, /* 0 */ 1038e93258fSBjoern A. Zeeb 0xaaaaaaaa, /* 1 */ 104e2340276SBjoern A. Zeeb 0xe5555555, /* 2 */ 105e2340276SBjoern A. Zeeb 0xee555555, /* 3 */ 106e2340276SBjoern A. Zeeb 0xd5555555, /* 4 */ 1078e93258fSBjoern A. Zeeb 0x5a5a5a5a, /* 5 */ 108e2340276SBjoern A. Zeeb 0xfa5a5a5a, /* 6 */ 109e2340276SBjoern A. Zeeb 0xda5a5a5a, /* 7 */ 110e2340276SBjoern A. Zeeb 0xea5a5a5a, /* 8 */ 1118e93258fSBjoern A. Zeeb 0x6a5a5aaa, /* 9 */ 1128e93258fSBjoern A. Zeeb 0x6a5a6a5a, /* 10 */ 1138e93258fSBjoern A. Zeeb 0x6a5a6aaa, /* 11 */ 1148e93258fSBjoern A. Zeeb 0x6afa5afa, /* 12 */ 1158e93258fSBjoern A. Zeeb 0xaaaa5aaa, /* 13 */ 1168e93258fSBjoern A. Zeeb 0xaaffffaa, /* 14 */ 1178e93258fSBjoern A. Zeeb 0xaa5555aa, /* 15 */ 1188e93258fSBjoern A. Zeeb 0xfafafafa, /* 16 */ 1198e93258fSBjoern A. Zeeb 0xffffddff, /* 17 */ 1208e93258fSBjoern A. Zeeb 0xdaffdaff, /* 18 */ 121e2340276SBjoern A. Zeeb 0xfafadafa, /* 19 */ 122e2340276SBjoern A. Zeeb 0xea6a6a6a, /* 20 */ 123e2340276SBjoern A. Zeeb 0xea55556a, /* 21 */ 124e2340276SBjoern A. Zeeb 0xaafafafa, /* 22 */ 125e2340276SBjoern A. Zeeb 0xfafaaafa, /* 23 */ 126*6d67aabdSBjoern A. Zeeb 0xfafffaff, /* 24 */ 127*6d67aabdSBjoern A. Zeeb 0xea6a5a5a, /* 25 */ 1288e93258fSBjoern A. Zeeb }; 1298e93258fSBjoern A. Zeeb 130e2340276SBjoern A. Zeeb static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = { 131e2340276SBjoern A. Zeeb /* firmware version must be in decreasing order for each chip */ 132*6d67aabdSBjoern A. Zeeb {RTL8922A, RTW89_FW_VER_CODE(0, 35, 8, 0), 133*6d67aabdSBjoern A. Zeeb .fcxbtcrpt = 8, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7, 134*6d67aabdSBjoern A. Zeeb .fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7, 135*6d67aabdSBjoern A. Zeeb .fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7, 136*6d67aabdSBjoern A. Zeeb .fwlrole = 8, .frptmap = 3, .fcxctrl = 7, .fcxinit = 7, 137*6d67aabdSBjoern A. Zeeb .fwevntrptl = 1, .drvinfo_type = 1, .info_buf = 1800, .max_role_num = 6, 138*6d67aabdSBjoern A. Zeeb }, 139e2340276SBjoern A. Zeeb {RTL8851B, RTW89_FW_VER_CODE(0, 29, 29, 0), 140e2340276SBjoern A. Zeeb .fcxbtcrpt = 105, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 5, 141e2340276SBjoern A. Zeeb .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 2, .fcxgpiodbg = 1, 142e2340276SBjoern A. Zeeb .fcxbtver = 1, .fcxbtscan = 2, .fcxbtafh = 2, .fcxbtdevinfo = 1, 143*6d67aabdSBjoern A. Zeeb .fwlrole = 2, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0, 144*6d67aabdSBjoern A. Zeeb .fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1800, .max_role_num = 6, 145e2340276SBjoern A. Zeeb }, 146e2340276SBjoern A. Zeeb {RTL8852C, RTW89_FW_VER_CODE(0, 27, 57, 0), 147e2340276SBjoern A. Zeeb .fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3, 148e2340276SBjoern A. Zeeb .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1, 149e2340276SBjoern A. Zeeb .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1, 150*6d67aabdSBjoern A. Zeeb .fwlrole = 1, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0, 151*6d67aabdSBjoern A. Zeeb .fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1280, .max_role_num = 5, 152e2340276SBjoern A. Zeeb }, 153e2340276SBjoern A. Zeeb {RTL8852C, RTW89_FW_VER_CODE(0, 27, 42, 0), 154e2340276SBjoern A. Zeeb .fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3, 155e2340276SBjoern A. Zeeb .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1, 156e2340276SBjoern A. Zeeb .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1, 157*6d67aabdSBjoern A. Zeeb .fwlrole = 1, .frptmap = 2, .fcxctrl = 1, .fcxinit = 0, 158*6d67aabdSBjoern A. Zeeb .fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1280, .max_role_num = 5, 159e2340276SBjoern A. Zeeb }, 160e2340276SBjoern A. Zeeb {RTL8852C, RTW89_FW_VER_CODE(0, 27, 0, 0), 161e2340276SBjoern A. Zeeb .fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3, 162e2340276SBjoern A. Zeeb .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1, 163e2340276SBjoern A. Zeeb .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1, 164*6d67aabdSBjoern A. Zeeb .fwlrole = 1, .frptmap = 2, .fcxctrl = 1, .fcxinit = 0, 165*6d67aabdSBjoern A. Zeeb .fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1280, .max_role_num = 5, 166e2340276SBjoern A. Zeeb }, 167e2340276SBjoern A. Zeeb {RTL8852B, RTW89_FW_VER_CODE(0, 29, 29, 0), 168e2340276SBjoern A. Zeeb .fcxbtcrpt = 105, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 5, 169e2340276SBjoern A. Zeeb .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 2, .fcxgpiodbg = 1, 170e2340276SBjoern A. Zeeb .fcxbtver = 1, .fcxbtscan = 2, .fcxbtafh = 2, .fcxbtdevinfo = 1, 171*6d67aabdSBjoern A. Zeeb .fwlrole = 2, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0, 172*6d67aabdSBjoern A. Zeeb .fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1800, .max_role_num = 6, 173e2340276SBjoern A. Zeeb }, 174e2340276SBjoern A. Zeeb {RTL8852B, RTW89_FW_VER_CODE(0, 29, 14, 0), 175e2340276SBjoern A. Zeeb .fcxbtcrpt = 5, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 4, 176e2340276SBjoern A. Zeeb .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1, 177e2340276SBjoern A. Zeeb .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1, 178*6d67aabdSBjoern A. Zeeb .fwlrole = 1, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0, 179*6d67aabdSBjoern A. Zeeb .fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1800, .max_role_num = 6, 180e2340276SBjoern A. Zeeb }, 181e2340276SBjoern A. Zeeb {RTL8852B, RTW89_FW_VER_CODE(0, 27, 0, 0), 182e2340276SBjoern A. Zeeb .fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3, 183e2340276SBjoern A. Zeeb .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1, 184e2340276SBjoern A. Zeeb .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1, 185*6d67aabdSBjoern A. Zeeb .fwlrole = 1, .frptmap = 1, .fcxctrl = 1, .fcxinit = 0, 186*6d67aabdSBjoern A. Zeeb .fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1280, .max_role_num = 5, 187e2340276SBjoern A. Zeeb }, 188e2340276SBjoern A. Zeeb {RTL8852A, RTW89_FW_VER_CODE(0, 13, 37, 0), 189e2340276SBjoern A. Zeeb .fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3, 190e2340276SBjoern A. Zeeb .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1, 191e2340276SBjoern A. Zeeb .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1, 192*6d67aabdSBjoern A. Zeeb .fwlrole = 1, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0, 193*6d67aabdSBjoern A. Zeeb .fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1280, .max_role_num = 5, 194e2340276SBjoern A. Zeeb }, 195e2340276SBjoern A. Zeeb {RTL8852A, RTW89_FW_VER_CODE(0, 13, 0, 0), 196e2340276SBjoern A. Zeeb .fcxbtcrpt = 1, .fcxtdma = 1, .fcxslots = 1, .fcxcysta = 2, 197e2340276SBjoern A. Zeeb .fcxstep = 2, .fcxnullsta = 1, .fcxmreg = 1, .fcxgpiodbg = 1, 198e2340276SBjoern A. Zeeb .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1, 199*6d67aabdSBjoern A. Zeeb .fwlrole = 0, .frptmap = 0, .fcxctrl = 0, .fcxinit = 0, 200*6d67aabdSBjoern A. Zeeb .fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1024, .max_role_num = 5, 201e2340276SBjoern A. Zeeb }, 202e2340276SBjoern A. Zeeb 203e2340276SBjoern A. Zeeb /* keep it to be the last as default entry */ 204e2340276SBjoern A. Zeeb {0, RTW89_FW_VER_CODE(0, 0, 0, 0), 205e2340276SBjoern A. Zeeb .fcxbtcrpt = 1, .fcxtdma = 1, .fcxslots = 1, .fcxcysta = 2, 206e2340276SBjoern A. Zeeb .fcxstep = 2, .fcxnullsta = 1, .fcxmreg = 1, .fcxgpiodbg = 1, 207e2340276SBjoern A. Zeeb .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1, 208*6d67aabdSBjoern A. Zeeb .fwlrole = 0, .frptmap = 0, .fcxctrl = 0, .fcxinit = 0, 209*6d67aabdSBjoern A. Zeeb .fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1024, .max_role_num = 5, 210e2340276SBjoern A. Zeeb }, 211e2340276SBjoern A. Zeeb }; 212e2340276SBjoern A. Zeeb 213e2340276SBjoern A. Zeeb #define RTW89_DEFAULT_BTC_VER_IDX (ARRAY_SIZE(rtw89_btc_ver_defs) - 1) 214e2340276SBjoern A. Zeeb 215*6d67aabdSBjoern A. Zeeb static const union rtw89_btc_wl_state_map btc_scanning_map = { 216*6d67aabdSBjoern A. Zeeb .map = { 217*6d67aabdSBjoern A. Zeeb .scan = 1, 218*6d67aabdSBjoern A. Zeeb .connecting = 1, 219*6d67aabdSBjoern A. Zeeb .roaming = 1, 220*6d67aabdSBjoern A. Zeeb .transacting = 1, 221*6d67aabdSBjoern A. Zeeb ._4way = 1, 222*6d67aabdSBjoern A. Zeeb }, 223*6d67aabdSBjoern A. Zeeb }; 224*6d67aabdSBjoern A. Zeeb 225*6d67aabdSBjoern A. Zeeb static u32 chip_id_to_bt_rom_code_id(u32 id) 226*6d67aabdSBjoern A. Zeeb { 227*6d67aabdSBjoern A. Zeeb switch (id) { 228*6d67aabdSBjoern A. Zeeb case RTL8852A: 229*6d67aabdSBjoern A. Zeeb case RTL8852B: 230*6d67aabdSBjoern A. Zeeb case RTL8852C: 231*6d67aabdSBjoern A. Zeeb case RTL8852BT: 232*6d67aabdSBjoern A. Zeeb return 0x8852; 233*6d67aabdSBjoern A. Zeeb case RTL8851B: 234*6d67aabdSBjoern A. Zeeb return 0x8851; 235*6d67aabdSBjoern A. Zeeb case RTL8922A: 236*6d67aabdSBjoern A. Zeeb return 0x8922; 237*6d67aabdSBjoern A. Zeeb default: 238*6d67aabdSBjoern A. Zeeb return 0; 239*6d67aabdSBjoern A. Zeeb } 240*6d67aabdSBjoern A. Zeeb } 241*6d67aabdSBjoern A. Zeeb 2428e93258fSBjoern A. Zeeb struct rtw89_btc_btf_tlv { 2438e93258fSBjoern A. Zeeb u8 type; 2448e93258fSBjoern A. Zeeb u8 len; 245e2340276SBjoern A. Zeeb u8 val[]; 2468e93258fSBjoern A. Zeeb } __packed; 2478e93258fSBjoern A. Zeeb 248*6d67aabdSBjoern A. Zeeb struct rtw89_btc_btf_tlv_v7 { 249*6d67aabdSBjoern A. Zeeb u8 type; 250*6d67aabdSBjoern A. Zeeb u8 ver; 251*6d67aabdSBjoern A. Zeeb u8 len; 252*6d67aabdSBjoern A. Zeeb u8 val[]; 253*6d67aabdSBjoern A. Zeeb } __packed; 254*6d67aabdSBjoern A. Zeeb 2558e93258fSBjoern A. Zeeb enum btc_btf_set_report_en { 256e2340276SBjoern A. Zeeb RPT_EN_TDMA, 257e2340276SBjoern A. Zeeb RPT_EN_CYCLE, 258e2340276SBjoern A. Zeeb RPT_EN_MREG, 259e2340276SBjoern A. Zeeb RPT_EN_BT_VER_INFO, 260e2340276SBjoern A. Zeeb RPT_EN_BT_SCAN_INFO, 261e2340276SBjoern A. Zeeb RPT_EN_BT_DEVICE_INFO, 262e2340276SBjoern A. Zeeb RPT_EN_BT_AFH_MAP, 263e2340276SBjoern A. Zeeb RPT_EN_BT_AFH_MAP_LE, 264e2340276SBjoern A. Zeeb RPT_EN_FW_STEP_INFO, 265e2340276SBjoern A. Zeeb RPT_EN_TEST, 266e2340276SBjoern A. Zeeb RPT_EN_WL_ALL, 267e2340276SBjoern A. Zeeb RPT_EN_BT_ALL, 268e2340276SBjoern A. Zeeb RPT_EN_ALL, 269e2340276SBjoern A. Zeeb RPT_EN_MONITER, 2708e93258fSBjoern A. Zeeb }; 2718e93258fSBjoern A. Zeeb 272*6d67aabdSBjoern A. Zeeb struct rtw89_btc_btf_set_report_v1 { 2738e93258fSBjoern A. Zeeb u8 fver; 2748e93258fSBjoern A. Zeeb __le32 enable; 2758e93258fSBjoern A. Zeeb __le32 para; 2768e93258fSBjoern A. Zeeb } __packed; 2778e93258fSBjoern A. Zeeb 278*6d67aabdSBjoern A. Zeeb struct rtw89_btc_btf_set_report_v8 { 279*6d67aabdSBjoern A. Zeeb u8 type; 280*6d67aabdSBjoern A. Zeeb u8 fver; 281*6d67aabdSBjoern A. Zeeb u8 len; 282*6d67aabdSBjoern A. Zeeb __le32 map; 283*6d67aabdSBjoern A. Zeeb } __packed; 284*6d67aabdSBjoern A. Zeeb 285*6d67aabdSBjoern A. Zeeb union rtw89_fbtc_rtp_ctrl { 286*6d67aabdSBjoern A. Zeeb struct rtw89_btc_btf_set_report_v1 v1; 287*6d67aabdSBjoern A. Zeeb struct rtw89_btc_btf_set_report_v8 v8; 288*6d67aabdSBjoern A. Zeeb }; 289*6d67aabdSBjoern A. Zeeb 2908e93258fSBjoern A. Zeeb #define BTF_SET_SLOT_TABLE_VER 1 2918e93258fSBjoern A. Zeeb struct rtw89_btc_btf_set_slot_table { 2928e93258fSBjoern A. Zeeb u8 fver; 2938e93258fSBjoern A. Zeeb u8 tbl_num; 294*6d67aabdSBjoern A. Zeeb struct rtw89_btc_fbtc_slot tbls[] __counted_by(tbl_num); 2958e93258fSBjoern A. Zeeb } __packed; 2968e93258fSBjoern A. Zeeb 297*6d67aabdSBjoern A. Zeeb struct rtw89_btc_btf_set_slot_table_v7 { 298*6d67aabdSBjoern A. Zeeb u8 type; 299*6d67aabdSBjoern A. Zeeb u8 ver; 300*6d67aabdSBjoern A. Zeeb u8 len; 301*6d67aabdSBjoern A. Zeeb struct rtw89_btc_fbtc_slot_v7 v7[CXST_MAX]; 302*6d67aabdSBjoern A. Zeeb } __packed; 303*6d67aabdSBjoern A. Zeeb 304*6d67aabdSBjoern A. Zeeb struct rtw89_btc_btf_set_mon_reg_v1 { 3058e93258fSBjoern A. Zeeb u8 fver; 3068e93258fSBjoern A. Zeeb u8 reg_num; 307*6d67aabdSBjoern A. Zeeb struct rtw89_btc_fbtc_mreg regs[] __counted_by(reg_num); 3088e93258fSBjoern A. Zeeb } __packed; 3098e93258fSBjoern A. Zeeb 310*6d67aabdSBjoern A. Zeeb struct rtw89_btc_btf_set_mon_reg_v7 { 311*6d67aabdSBjoern A. Zeeb u8 type; 312*6d67aabdSBjoern A. Zeeb u8 fver; 313*6d67aabdSBjoern A. Zeeb u8 len; 314*6d67aabdSBjoern A. Zeeb struct rtw89_btc_fbtc_mreg regs[] __counted_by(len); 315*6d67aabdSBjoern A. Zeeb } __packed; 316*6d67aabdSBjoern A. Zeeb 317*6d67aabdSBjoern A. Zeeb union rtw89_fbtc_set_mon_reg { 318*6d67aabdSBjoern A. Zeeb struct rtw89_btc_btf_set_mon_reg_v1 v1; 319*6d67aabdSBjoern A. Zeeb struct rtw89_btc_btf_set_mon_reg_v7 v7; 320*6d67aabdSBjoern A. Zeeb } __packed; 321*6d67aabdSBjoern A. Zeeb 322*6d67aabdSBjoern A. Zeeb struct _wl_rinfo_now { 323*6d67aabdSBjoern A. Zeeb u8 link_mode; 324*6d67aabdSBjoern A. Zeeb u32 dbcc_2g_phy: 2; 325*6d67aabdSBjoern A. Zeeb }; 326*6d67aabdSBjoern A. Zeeb 3278e93258fSBjoern A. Zeeb enum btc_btf_set_cx_policy { 3288e93258fSBjoern A. Zeeb CXPOLICY_TDMA = 0x0, 3298e93258fSBjoern A. Zeeb CXPOLICY_SLOT = 0x1, 3308e93258fSBjoern A. Zeeb CXPOLICY_TYPE = 0x2, 3318e93258fSBjoern A. Zeeb CXPOLICY_MAX, 3328e93258fSBjoern A. Zeeb }; 3338e93258fSBjoern A. Zeeb 3348e93258fSBjoern A. Zeeb enum btc_b2w_scoreboard { 3358e93258fSBjoern A. Zeeb BTC_BSCB_ACT = BIT(0), 3368e93258fSBjoern A. Zeeb BTC_BSCB_ON = BIT(1), 3378e93258fSBjoern A. Zeeb BTC_BSCB_WHQL = BIT(2), 3388e93258fSBjoern A. Zeeb BTC_BSCB_BT_S1 = BIT(3), 3398e93258fSBjoern A. Zeeb BTC_BSCB_A2DP_ACT = BIT(4), 3408e93258fSBjoern A. Zeeb BTC_BSCB_RFK_RUN = BIT(5), 3418e93258fSBjoern A. Zeeb BTC_BSCB_RFK_REQ = BIT(6), 3428e93258fSBjoern A. Zeeb BTC_BSCB_LPS = BIT(7), 343*6d67aabdSBjoern A. Zeeb BTC_BSCB_BT_LNAB0 = BIT(8), 344*6d67aabdSBjoern A. Zeeb BTC_BSCB_BT_LNAB1 = BIT(10), 3458e93258fSBjoern A. Zeeb BTC_BSCB_WLRFK = BIT(11), 3468e93258fSBjoern A. Zeeb BTC_BSCB_BT_HILNA = BIT(13), 3478e93258fSBjoern A. Zeeb BTC_BSCB_BT_CONNECT = BIT(16), 3488e93258fSBjoern A. Zeeb BTC_BSCB_PATCH_CODE = BIT(30), 3498e93258fSBjoern A. Zeeb BTC_BSCB_ALL = GENMASK(30, 0), 3508e93258fSBjoern A. Zeeb }; 3518e93258fSBjoern A. Zeeb 3528e93258fSBjoern A. Zeeb enum btc_phymap { 3538e93258fSBjoern A. Zeeb BTC_PHY_0 = BIT(0), 3548e93258fSBjoern A. Zeeb BTC_PHY_1 = BIT(1), 3558e93258fSBjoern A. Zeeb BTC_PHY_ALL = BIT(0) | BIT(1), 3568e93258fSBjoern A. Zeeb }; 3578e93258fSBjoern A. Zeeb 3588e93258fSBjoern A. Zeeb enum btc_cx_state_map { 3598e93258fSBjoern A. Zeeb BTC_WIDLE = 0, 3608e93258fSBjoern A. Zeeb BTC_WBUSY_BNOSCAN, 3618e93258fSBjoern A. Zeeb BTC_WBUSY_BSCAN, 3628e93258fSBjoern A. Zeeb BTC_WSCAN_BNOSCAN, 3638e93258fSBjoern A. Zeeb BTC_WSCAN_BSCAN, 3648e93258fSBjoern A. Zeeb BTC_WLINKING 3658e93258fSBjoern A. Zeeb }; 3668e93258fSBjoern A. Zeeb 3678e93258fSBjoern A. Zeeb enum btc_ant_phase { 3688e93258fSBjoern A. Zeeb BTC_ANT_WPOWERON = 0, 3698e93258fSBjoern A. Zeeb BTC_ANT_WINIT, 3708e93258fSBjoern A. Zeeb BTC_ANT_WONLY, 3718e93258fSBjoern A. Zeeb BTC_ANT_WOFF, 3728e93258fSBjoern A. Zeeb BTC_ANT_W2G, 3738e93258fSBjoern A. Zeeb BTC_ANT_W5G, 3748e93258fSBjoern A. Zeeb BTC_ANT_W25G, 3758e93258fSBjoern A. Zeeb BTC_ANT_FREERUN, 3768e93258fSBjoern A. Zeeb BTC_ANT_WRFK, 377*6d67aabdSBjoern A. Zeeb BTC_ANT_WRFK2, 3788e93258fSBjoern A. Zeeb BTC_ANT_BRFK, 3798e93258fSBjoern A. Zeeb BTC_ANT_MAX 3808e93258fSBjoern A. Zeeb }; 3818e93258fSBjoern A. Zeeb 3828e93258fSBjoern A. Zeeb enum btc_plt { 3838e93258fSBjoern A. Zeeb BTC_PLT_NONE = 0, 3848e93258fSBjoern A. Zeeb BTC_PLT_LTE_RX = BIT(0), 3858e93258fSBjoern A. Zeeb BTC_PLT_GNT_BT_TX = BIT(1), 3868e93258fSBjoern A. Zeeb BTC_PLT_GNT_BT_RX = BIT(2), 3878e93258fSBjoern A. Zeeb BTC_PLT_GNT_WL = BIT(3), 3888e93258fSBjoern A. Zeeb BTC_PLT_BT = BIT(1) | BIT(2), 3898e93258fSBjoern A. Zeeb BTC_PLT_ALL = 0xf 3908e93258fSBjoern A. Zeeb }; 3918e93258fSBjoern A. Zeeb 3928e93258fSBjoern A. Zeeb enum btc_cx_poicy_main_type { 3938e93258fSBjoern A. Zeeb BTC_CXP_OFF = 0, 3948e93258fSBjoern A. Zeeb BTC_CXP_OFFB, 3958e93258fSBjoern A. Zeeb BTC_CXP_OFFE, 3968e93258fSBjoern A. Zeeb BTC_CXP_FIX, 3978e93258fSBjoern A. Zeeb BTC_CXP_PFIX, 3988e93258fSBjoern A. Zeeb BTC_CXP_AUTO, 3998e93258fSBjoern A. Zeeb BTC_CXP_PAUTO, 4008e93258fSBjoern A. Zeeb BTC_CXP_AUTO2, 4018e93258fSBjoern A. Zeeb BTC_CXP_PAUTO2, 4028e93258fSBjoern A. Zeeb BTC_CXP_MANUAL, 4038e93258fSBjoern A. Zeeb BTC_CXP_USERDEF0, 4048e93258fSBjoern A. Zeeb BTC_CXP_MAIN_MAX 4058e93258fSBjoern A. Zeeb }; 4068e93258fSBjoern A. Zeeb 4078e93258fSBjoern A. Zeeb enum btc_cx_poicy_type { 4088e93258fSBjoern A. Zeeb /* TDMA off + pri: BT > WL */ 4098e93258fSBjoern A. Zeeb BTC_CXP_OFF_BT = (BTC_CXP_OFF << 8) | 0, 4108e93258fSBjoern A. Zeeb 4118e93258fSBjoern A. Zeeb /* TDMA off + pri: WL > BT */ 4128e93258fSBjoern A. Zeeb BTC_CXP_OFF_WL = (BTC_CXP_OFF << 8) | 1, 4138e93258fSBjoern A. Zeeb 4148e93258fSBjoern A. Zeeb /* TDMA off + pri: BT = WL */ 4158e93258fSBjoern A. Zeeb BTC_CXP_OFF_EQ0 = (BTC_CXP_OFF << 8) | 2, 4168e93258fSBjoern A. Zeeb 4178e93258fSBjoern A. Zeeb /* TDMA off + pri: BT = WL > BT_Lo */ 4188e93258fSBjoern A. Zeeb BTC_CXP_OFF_EQ1 = (BTC_CXP_OFF << 8) | 3, 4198e93258fSBjoern A. Zeeb 4208e93258fSBjoern A. Zeeb /* TDMA off + pri: WL = BT, BT_Rx > WL_Lo_Tx */ 4218e93258fSBjoern A. Zeeb BTC_CXP_OFF_EQ2 = (BTC_CXP_OFF << 8) | 4, 4228e93258fSBjoern A. Zeeb 4238e93258fSBjoern A. Zeeb /* TDMA off + pri: WL_Rx = BT, BT_HI > WL_Tx > BT_Lo */ 4248e93258fSBjoern A. Zeeb BTC_CXP_OFF_EQ3 = (BTC_CXP_OFF << 8) | 5, 4258e93258fSBjoern A. Zeeb 426*6d67aabdSBjoern A. Zeeb /* TDMA off + pri: WL_Rx = BT, BT_HI > WL_Tx > BT_Lo */ 427*6d67aabdSBjoern A. Zeeb BTC_CXP_OFF_EQ4 = (BTC_CXP_OFF << 8) | 6, 428*6d67aabdSBjoern A. Zeeb 429*6d67aabdSBjoern A. Zeeb /* TDMA off + pri: WL_Rx = BT, BT_HI > WL_Tx > BT_Lo */ 430*6d67aabdSBjoern A. Zeeb BTC_CXP_OFF_EQ5 = (BTC_CXP_OFF << 8) | 7, 431*6d67aabdSBjoern A. Zeeb 4328e93258fSBjoern A. Zeeb /* TDMA off + pri: BT_Hi > WL > BT_Lo */ 433*6d67aabdSBjoern A. Zeeb BTC_CXP_OFF_BWB0 = (BTC_CXP_OFF << 8) | 8, 4348e93258fSBjoern A. Zeeb 4358e93258fSBjoern A. Zeeb /* TDMA off + pri: WL_Hi-Tx > BT_Hi_Rx, BT_Hi > WL > BT_Lo */ 436*6d67aabdSBjoern A. Zeeb BTC_CXP_OFF_BWB1 = (BTC_CXP_OFF << 8) | 9, 4378e93258fSBjoern A. Zeeb 4388e93258fSBjoern A. Zeeb /* TDMA off + pri: WL_Hi-Tx > BT, BT_Hi > other-WL > BT_Lo */ 439*6d67aabdSBjoern A. Zeeb BTC_CXP_OFF_BWB2 = (BTC_CXP_OFF << 8) | 10, 4408e93258fSBjoern A. Zeeb 441e2340276SBjoern A. Zeeb /* TDMA off + pri: WL_Hi-Tx = BT */ 442*6d67aabdSBjoern A. Zeeb BTC_CXP_OFF_BWB3 = (BTC_CXP_OFF << 8) | 11, 443*6d67aabdSBjoern A. Zeeb 444*6d67aabdSBjoern A. Zeeb /* TDMA off + pri: WL > BT, Block-BT*/ 445*6d67aabdSBjoern A. Zeeb BTC_CXP_OFF_WL2 = (BTC_CXP_OFF << 8) | 12, 446e2340276SBjoern A. Zeeb 4478e93258fSBjoern A. Zeeb /* TDMA off+Bcn-Protect + pri: WL_Hi-Tx > BT_Hi_Rx, BT_Hi > WL > BT_Lo*/ 4488e93258fSBjoern A. Zeeb BTC_CXP_OFFB_BWB0 = (BTC_CXP_OFFB << 8) | 0, 4498e93258fSBjoern A. Zeeb 4508e93258fSBjoern A. Zeeb /* TDMA off + Ext-Ctrl + pri: default */ 4518e93258fSBjoern A. Zeeb BTC_CXP_OFFE_DEF = (BTC_CXP_OFFE << 8) | 0, 4528e93258fSBjoern A. Zeeb 4538e93258fSBjoern A. Zeeb /* TDMA off + Ext-Ctrl + pri: E2G-slot block all BT */ 4548e93258fSBjoern A. Zeeb BTC_CXP_OFFE_DEF2 = (BTC_CXP_OFFE << 8) | 1, 4558e93258fSBjoern A. Zeeb 4568e93258fSBjoern A. Zeeb /* TDMA off + Ext-Ctrl + pri: default */ 4578e93258fSBjoern A. Zeeb BTC_CXP_OFFE_2GBWISOB = (BTC_CXP_OFFE << 8) | 2, 4588e93258fSBjoern A. Zeeb 4598e93258fSBjoern A. Zeeb /* TDMA off + Ext-Ctrl + pri: E2G-slot block all BT */ 4608e93258fSBjoern A. Zeeb BTC_CXP_OFFE_2GISOB = (BTC_CXP_OFFE << 8) | 3, 4618e93258fSBjoern A. Zeeb 4628e93258fSBjoern A. Zeeb /* TDMA off + Ext-Ctrl + pri: E2G-slot WL > BT */ 4638e93258fSBjoern A. Zeeb BTC_CXP_OFFE_2GBWMIXB = (BTC_CXP_OFFE << 8) | 4, 4648e93258fSBjoern A. Zeeb 4658e93258fSBjoern A. Zeeb /* TDMA off + Ext-Ctrl + pri: E2G/EBT-slot WL > BT */ 4668e93258fSBjoern A. Zeeb BTC_CXP_OFFE_WL = (BTC_CXP_OFFE << 8) | 5, 4678e93258fSBjoern A. Zeeb 4688e93258fSBjoern A. Zeeb /* TDMA off + Ext-Ctrl + pri: default */ 4698e93258fSBjoern A. Zeeb BTC_CXP_OFFE_2GBWMIXB2 = (BTC_CXP_OFFE << 8) | 6, 4708e93258fSBjoern A. Zeeb 4718e93258fSBjoern A. Zeeb /* TDMA Fix slot-0: W1:B1 = 30:30 */ 4728e93258fSBjoern A. Zeeb BTC_CXP_FIX_TD3030 = (BTC_CXP_FIX << 8) | 0, 4738e93258fSBjoern A. Zeeb 4748e93258fSBjoern A. Zeeb /* TDMA Fix slot-1: W1:B1 = 50:50 */ 4758e93258fSBjoern A. Zeeb BTC_CXP_FIX_TD5050 = (BTC_CXP_FIX << 8) | 1, 4768e93258fSBjoern A. Zeeb 4778e93258fSBjoern A. Zeeb /* TDMA Fix slot-2: W1:B1 = 20:30 */ 4788e93258fSBjoern A. Zeeb BTC_CXP_FIX_TD2030 = (BTC_CXP_FIX << 8) | 2, 4798e93258fSBjoern A. Zeeb 4808e93258fSBjoern A. Zeeb /* TDMA Fix slot-3: W1:B1 = 40:10 */ 4818e93258fSBjoern A. Zeeb BTC_CXP_FIX_TD4010 = (BTC_CXP_FIX << 8) | 3, 4828e93258fSBjoern A. Zeeb 4838e93258fSBjoern A. Zeeb /* TDMA Fix slot-4: W1:B1 = 70:10 */ 4848e93258fSBjoern A. Zeeb BTC_CXP_FIX_TD7010 = (BTC_CXP_FIX << 8) | 4, 4858e93258fSBjoern A. Zeeb 4868e93258fSBjoern A. Zeeb /* TDMA Fix slot-5: W1:B1 = 20:60 */ 4878e93258fSBjoern A. Zeeb BTC_CXP_FIX_TD2060 = (BTC_CXP_FIX << 8) | 5, 4888e93258fSBjoern A. Zeeb 4898e93258fSBjoern A. Zeeb /* TDMA Fix slot-6: W1:B1 = 30:60 */ 4908e93258fSBjoern A. Zeeb BTC_CXP_FIX_TD3060 = (BTC_CXP_FIX << 8) | 6, 4918e93258fSBjoern A. Zeeb 4928e93258fSBjoern A. Zeeb /* TDMA Fix slot-7: W1:B1 = 20:80 */ 4938e93258fSBjoern A. Zeeb BTC_CXP_FIX_TD2080 = (BTC_CXP_FIX << 8) | 7, 4948e93258fSBjoern A. Zeeb 4958e93258fSBjoern A. Zeeb /* TDMA Fix slot-8: W1:B1 = user-define */ 4968e93258fSBjoern A. Zeeb BTC_CXP_FIX_TDW1B1 = (BTC_CXP_FIX << 8) | 8, 4978e93258fSBjoern A. Zeeb 4988e93258fSBjoern A. Zeeb /* TDMA Fix slot-9: W1:B1 = 40:10 */ 499*6d67aabdSBjoern A. Zeeb BTC_CXP_FIX_TD4010ISO = (BTC_CXP_FIX << 8) | 9, 500*6d67aabdSBjoern A. Zeeb 501*6d67aabdSBjoern A. Zeeb /* TDMA Fix slot-10: W1:B1 = 40:10 */ 502*6d67aabdSBjoern A. Zeeb BTC_CXP_FIX_TD4010ISO_DL = (BTC_CXP_FIX << 8) | 10, 503*6d67aabdSBjoern A. Zeeb 504*6d67aabdSBjoern A. Zeeb /* TDMA Fix slot-11: W1:B1 = 40:10 */ 505*6d67aabdSBjoern A. Zeeb BTC_CXP_FIX_TD4010ISO_UL = (BTC_CXP_FIX << 8) | 11, 5068e93258fSBjoern A. Zeeb 5078e93258fSBjoern A. Zeeb /* PS-TDMA Fix slot-0: W1:B1 = 30:30 */ 5088e93258fSBjoern A. Zeeb BTC_CXP_PFIX_TD3030 = (BTC_CXP_PFIX << 8) | 0, 5098e93258fSBjoern A. Zeeb 5108e93258fSBjoern A. Zeeb /* PS-TDMA Fix slot-1: W1:B1 = 50:50 */ 5118e93258fSBjoern A. Zeeb BTC_CXP_PFIX_TD5050 = (BTC_CXP_PFIX << 8) | 1, 5128e93258fSBjoern A. Zeeb 5138e93258fSBjoern A. Zeeb /* PS-TDMA Fix slot-2: W1:B1 = 20:30 */ 5148e93258fSBjoern A. Zeeb BTC_CXP_PFIX_TD2030 = (BTC_CXP_PFIX << 8) | 2, 5158e93258fSBjoern A. Zeeb 5168e93258fSBjoern A. Zeeb /* PS-TDMA Fix slot-3: W1:B1 = 20:60 */ 5178e93258fSBjoern A. Zeeb BTC_CXP_PFIX_TD2060 = (BTC_CXP_PFIX << 8) | 3, 5188e93258fSBjoern A. Zeeb 5198e93258fSBjoern A. Zeeb /* PS-TDMA Fix slot-4: W1:B1 = 30:70 */ 5208e93258fSBjoern A. Zeeb BTC_CXP_PFIX_TD3070 = (BTC_CXP_PFIX << 8) | 4, 5218e93258fSBjoern A. Zeeb 5228e93258fSBjoern A. Zeeb /* PS-TDMA Fix slot-5: W1:B1 = 20:80 */ 5238e93258fSBjoern A. Zeeb BTC_CXP_PFIX_TD2080 = (BTC_CXP_PFIX << 8) | 5, 5248e93258fSBjoern A. Zeeb 5258e93258fSBjoern A. Zeeb /* PS-TDMA Fix slot-6: W1:B1 = user-define */ 5268e93258fSBjoern A. Zeeb BTC_CXP_PFIX_TDW1B1 = (BTC_CXP_PFIX << 8) | 6, 5278e93258fSBjoern A. Zeeb 5288e93258fSBjoern A. Zeeb /* TDMA Auto slot-0: W1:B1 = 50:200 */ 5298e93258fSBjoern A. Zeeb BTC_CXP_AUTO_TD50B1 = (BTC_CXP_AUTO << 8) | 0, 5308e93258fSBjoern A. Zeeb 5318e93258fSBjoern A. Zeeb /* TDMA Auto slot-1: W1:B1 = 60:200 */ 5328e93258fSBjoern A. Zeeb BTC_CXP_AUTO_TD60B1 = (BTC_CXP_AUTO << 8) | 1, 5338e93258fSBjoern A. Zeeb 5348e93258fSBjoern A. Zeeb /* TDMA Auto slot-2: W1:B1 = 20:200 */ 5358e93258fSBjoern A. Zeeb BTC_CXP_AUTO_TD20B1 = (BTC_CXP_AUTO << 8) | 2, 5368e93258fSBjoern A. Zeeb 5378e93258fSBjoern A. Zeeb /* TDMA Auto slot-3: W1:B1 = user-define */ 5388e93258fSBjoern A. Zeeb BTC_CXP_AUTO_TDW1B1 = (BTC_CXP_AUTO << 8) | 3, 5398e93258fSBjoern A. Zeeb 5408e93258fSBjoern A. Zeeb /* PS-TDMA Auto slot-0: W1:B1 = 50:200 */ 5418e93258fSBjoern A. Zeeb BTC_CXP_PAUTO_TD50B1 = (BTC_CXP_PAUTO << 8) | 0, 5428e93258fSBjoern A. Zeeb 5438e93258fSBjoern A. Zeeb /* PS-TDMA Auto slot-1: W1:B1 = 60:200 */ 5448e93258fSBjoern A. Zeeb BTC_CXP_PAUTO_TD60B1 = (BTC_CXP_PAUTO << 8) | 1, 5458e93258fSBjoern A. Zeeb 5468e93258fSBjoern A. Zeeb /* PS-TDMA Auto slot-2: W1:B1 = 20:200 */ 5478e93258fSBjoern A. Zeeb BTC_CXP_PAUTO_TD20B1 = (BTC_CXP_PAUTO << 8) | 2, 5488e93258fSBjoern A. Zeeb 5498e93258fSBjoern A. Zeeb /* PS-TDMA Auto slot-3: W1:B1 = user-define */ 5508e93258fSBjoern A. Zeeb BTC_CXP_PAUTO_TDW1B1 = (BTC_CXP_PAUTO << 8) | 3, 5518e93258fSBjoern A. Zeeb 5528e93258fSBjoern A. Zeeb /* TDMA Auto slot2-0: W1:B4 = 30:50 */ 5538e93258fSBjoern A. Zeeb BTC_CXP_AUTO2_TD3050 = (BTC_CXP_AUTO2 << 8) | 0, 5548e93258fSBjoern A. Zeeb 5558e93258fSBjoern A. Zeeb /* TDMA Auto slot2-1: W1:B4 = 30:70 */ 5568e93258fSBjoern A. Zeeb BTC_CXP_AUTO2_TD3070 = (BTC_CXP_AUTO2 << 8) | 1, 5578e93258fSBjoern A. Zeeb 5588e93258fSBjoern A. Zeeb /* TDMA Auto slot2-2: W1:B4 = 50:50 */ 5598e93258fSBjoern A. Zeeb BTC_CXP_AUTO2_TD5050 = (BTC_CXP_AUTO2 << 8) | 2, 5608e93258fSBjoern A. Zeeb 5618e93258fSBjoern A. Zeeb /* TDMA Auto slot2-3: W1:B4 = 60:60 */ 5628e93258fSBjoern A. Zeeb BTC_CXP_AUTO2_TD6060 = (BTC_CXP_AUTO2 << 8) | 3, 5638e93258fSBjoern A. Zeeb 5648e93258fSBjoern A. Zeeb /* TDMA Auto slot2-4: W1:B4 = 20:80 */ 5658e93258fSBjoern A. Zeeb BTC_CXP_AUTO2_TD2080 = (BTC_CXP_AUTO2 << 8) | 4, 5668e93258fSBjoern A. Zeeb 5678e93258fSBjoern A. Zeeb /* TDMA Auto slot2-5: W1:B4 = user-define */ 5688e93258fSBjoern A. Zeeb BTC_CXP_AUTO2_TDW1B4 = (BTC_CXP_AUTO2 << 8) | 5, 5698e93258fSBjoern A. Zeeb 5708e93258fSBjoern A. Zeeb /* PS-TDMA Auto slot2-0: W1:B4 = 30:50 */ 5718e93258fSBjoern A. Zeeb BTC_CXP_PAUTO2_TD3050 = (BTC_CXP_PAUTO2 << 8) | 0, 5728e93258fSBjoern A. Zeeb 5738e93258fSBjoern A. Zeeb /* PS-TDMA Auto slot2-1: W1:B4 = 30:70 */ 5748e93258fSBjoern A. Zeeb BTC_CXP_PAUTO2_TD3070 = (BTC_CXP_PAUTO2 << 8) | 1, 5758e93258fSBjoern A. Zeeb 5768e93258fSBjoern A. Zeeb /* PS-TDMA Auto slot2-2: W1:B4 = 50:50 */ 5778e93258fSBjoern A. Zeeb BTC_CXP_PAUTO2_TD5050 = (BTC_CXP_PAUTO2 << 8) | 2, 5788e93258fSBjoern A. Zeeb 5798e93258fSBjoern A. Zeeb /* PS-TDMA Auto slot2-3: W1:B4 = 60:60 */ 5808e93258fSBjoern A. Zeeb BTC_CXP_PAUTO2_TD6060 = (BTC_CXP_PAUTO2 << 8) | 3, 5818e93258fSBjoern A. Zeeb 5828e93258fSBjoern A. Zeeb /* PS-TDMA Auto slot2-4: W1:B4 = 20:80 */ 5838e93258fSBjoern A. Zeeb BTC_CXP_PAUTO2_TD2080 = (BTC_CXP_PAUTO2 << 8) | 4, 5848e93258fSBjoern A. Zeeb 5858e93258fSBjoern A. Zeeb /* PS-TDMA Auto slot2-5: W1:B4 = user-define */ 5868e93258fSBjoern A. Zeeb BTC_CXP_PAUTO2_TDW1B4 = (BTC_CXP_PAUTO2 << 8) | 5, 5878e93258fSBjoern A. Zeeb 5888e93258fSBjoern A. Zeeb BTC_CXP_MAX = 0xffff 5898e93258fSBjoern A. Zeeb }; 5908e93258fSBjoern A. Zeeb 5918e93258fSBjoern A. Zeeb enum btc_wl_rfk_result { 5928e93258fSBjoern A. Zeeb BTC_WRFK_REJECT = 0, 5938e93258fSBjoern A. Zeeb BTC_WRFK_ALLOW = 1, 5948e93258fSBjoern A. Zeeb }; 5958e93258fSBjoern A. Zeeb 5968e93258fSBjoern A. Zeeb enum btc_coex_info_map_en { 5978e93258fSBjoern A. Zeeb BTC_COEX_INFO_CX = BIT(0), 5988e93258fSBjoern A. Zeeb BTC_COEX_INFO_WL = BIT(1), 5998e93258fSBjoern A. Zeeb BTC_COEX_INFO_BT = BIT(2), 6008e93258fSBjoern A. Zeeb BTC_COEX_INFO_DM = BIT(3), 6018e93258fSBjoern A. Zeeb BTC_COEX_INFO_MREG = BIT(4), 6028e93258fSBjoern A. Zeeb BTC_COEX_INFO_SUMMARY = BIT(5), 6038e93258fSBjoern A. Zeeb BTC_COEX_INFO_ALL = GENMASK(7, 0), 6048e93258fSBjoern A. Zeeb }; 6058e93258fSBjoern A. Zeeb 6068e93258fSBjoern A. Zeeb #define BTC_CXP_MASK GENMASK(15, 8) 6078e93258fSBjoern A. Zeeb 6088e93258fSBjoern A. Zeeb enum btc_w2b_scoreboard { 6098e93258fSBjoern A. Zeeb BTC_WSCB_ACTIVE = BIT(0), 6108e93258fSBjoern A. Zeeb BTC_WSCB_ON = BIT(1), 6118e93258fSBjoern A. Zeeb BTC_WSCB_SCAN = BIT(2), 6128e93258fSBjoern A. Zeeb BTC_WSCB_UNDERTEST = BIT(3), 6138e93258fSBjoern A. Zeeb BTC_WSCB_RXGAIN = BIT(4), 6148e93258fSBjoern A. Zeeb BTC_WSCB_WLBUSY = BIT(7), 6158e93258fSBjoern A. Zeeb BTC_WSCB_EXTFEM = BIT(8), 6168e93258fSBjoern A. Zeeb BTC_WSCB_TDMA = BIT(9), 6178e93258fSBjoern A. Zeeb BTC_WSCB_FIX2M = BIT(10), 6188e93258fSBjoern A. Zeeb BTC_WSCB_WLRFK = BIT(11), 619e2340276SBjoern A. Zeeb BTC_WSCB_RXSCAN_PRI = BIT(12), 6208e93258fSBjoern A. Zeeb BTC_WSCB_BT_HILNA = BIT(13), 6218e93258fSBjoern A. Zeeb BTC_WSCB_BTLOG = BIT(14), 6228e93258fSBjoern A. Zeeb BTC_WSCB_ALL = GENMASK(23, 0), 6238e93258fSBjoern A. Zeeb }; 6248e93258fSBjoern A. Zeeb 6258e93258fSBjoern A. Zeeb enum btc_wl_link_mode { 6268e93258fSBjoern A. Zeeb BTC_WLINK_NOLINK = 0x0, 6278e93258fSBjoern A. Zeeb BTC_WLINK_2G_STA, 6288e93258fSBjoern A. Zeeb BTC_WLINK_2G_AP, 6298e93258fSBjoern A. Zeeb BTC_WLINK_2G_GO, 6308e93258fSBjoern A. Zeeb BTC_WLINK_2G_GC, 6318e93258fSBjoern A. Zeeb BTC_WLINK_2G_SCC, 6328e93258fSBjoern A. Zeeb BTC_WLINK_2G_MCC, 6338e93258fSBjoern A. Zeeb BTC_WLINK_25G_MCC, 6348e93258fSBjoern A. Zeeb BTC_WLINK_25G_DBCC, 6358e93258fSBjoern A. Zeeb BTC_WLINK_5G, 6368e93258fSBjoern A. Zeeb BTC_WLINK_2G_NAN, 6378e93258fSBjoern A. Zeeb BTC_WLINK_OTHER, 6388e93258fSBjoern A. Zeeb BTC_WLINK_MAX 6398e93258fSBjoern A. Zeeb }; 6408e93258fSBjoern A. Zeeb 6418e93258fSBjoern A. Zeeb enum btc_wl_mrole_type { 6428e93258fSBjoern A. Zeeb BTC_WLMROLE_NONE = 0x0, 6438e93258fSBjoern A. Zeeb BTC_WLMROLE_STA_GC, 6448e93258fSBjoern A. Zeeb BTC_WLMROLE_STA_GC_NOA, 6458e93258fSBjoern A. Zeeb BTC_WLMROLE_STA_GO, 6468e93258fSBjoern A. Zeeb BTC_WLMROLE_STA_GO_NOA, 6478e93258fSBjoern A. Zeeb BTC_WLMROLE_STA_STA, 6488e93258fSBjoern A. Zeeb BTC_WLMROLE_MAX 6498e93258fSBjoern A. Zeeb }; 6508e93258fSBjoern A. Zeeb 6518e93258fSBjoern A. Zeeb enum btc_bt_hid_type { 6528e93258fSBjoern A. Zeeb BTC_HID_218 = BIT(0), 6538e93258fSBjoern A. Zeeb BTC_HID_418 = BIT(1), 6548e93258fSBjoern A. Zeeb BTC_HID_BLE = BIT(2), 6558e93258fSBjoern A. Zeeb BTC_HID_RCU = BIT(3), 6568e93258fSBjoern A. Zeeb BTC_HID_RCU_VOICE = BIT(4), 6578e93258fSBjoern A. Zeeb BTC_HID_OTHER_LEGACY = BIT(5) 6588e93258fSBjoern A. Zeeb }; 6598e93258fSBjoern A. Zeeb 6608e93258fSBjoern A. Zeeb enum btc_reset_module { 6618e93258fSBjoern A. Zeeb BTC_RESET_CX = BIT(0), 6628e93258fSBjoern A. Zeeb BTC_RESET_DM = BIT(1), 6638e93258fSBjoern A. Zeeb BTC_RESET_CTRL = BIT(2), 6648e93258fSBjoern A. Zeeb BTC_RESET_CXDM = BIT(0) | BIT(1), 6658e93258fSBjoern A. Zeeb BTC_RESET_BTINFO = BIT(3), 6668e93258fSBjoern A. Zeeb BTC_RESET_MDINFO = BIT(4), 6678e93258fSBjoern A. Zeeb BTC_RESET_ALL = GENMASK(7, 0), 6688e93258fSBjoern A. Zeeb }; 6698e93258fSBjoern A. Zeeb 6708e93258fSBjoern A. Zeeb enum btc_gnt_state { 6718e93258fSBjoern A. Zeeb BTC_GNT_HW = 0, 6728e93258fSBjoern A. Zeeb BTC_GNT_SW_LO, 6738e93258fSBjoern A. Zeeb BTC_GNT_SW_HI, 6748e93258fSBjoern A. Zeeb BTC_GNT_MAX 6758e93258fSBjoern A. Zeeb }; 6768e93258fSBjoern A. Zeeb 677e2340276SBjoern A. Zeeb enum btc_ctr_path { 678e2340276SBjoern A. Zeeb BTC_CTRL_BY_BT = 0, 679e2340276SBjoern A. Zeeb BTC_CTRL_BY_WL 680e2340276SBjoern A. Zeeb }; 681e2340276SBjoern A. Zeeb 682*6d67aabdSBjoern A. Zeeb enum btc_wlact_state { 683*6d67aabdSBjoern A. Zeeb BTC_WLACT_HW = 0, 684*6d67aabdSBjoern A. Zeeb BTC_WLACT_SW_LO, 685*6d67aabdSBjoern A. Zeeb BTC_WLACT_SW_HI, 686*6d67aabdSBjoern A. Zeeb BTC_WLACT_MAX, 687*6d67aabdSBjoern A. Zeeb }; 688*6d67aabdSBjoern A. Zeeb 6898e93258fSBjoern A. Zeeb enum btc_wl_max_tx_time { 6908e93258fSBjoern A. Zeeb BTC_MAX_TX_TIME_L1 = 500, 6918e93258fSBjoern A. Zeeb BTC_MAX_TX_TIME_L2 = 1000, 6928e93258fSBjoern A. Zeeb BTC_MAX_TX_TIME_L3 = 2000, 6938e93258fSBjoern A. Zeeb BTC_MAX_TX_TIME_DEF = 5280 6948e93258fSBjoern A. Zeeb }; 6958e93258fSBjoern A. Zeeb 6968e93258fSBjoern A. Zeeb enum btc_wl_max_tx_retry { 6978e93258fSBjoern A. Zeeb BTC_MAX_TX_RETRY_L1 = 7, 6988e93258fSBjoern A. Zeeb BTC_MAX_TX_RETRY_L2 = 15, 6998e93258fSBjoern A. Zeeb BTC_MAX_TX_RETRY_DEF = 31, 7008e93258fSBjoern A. Zeeb }; 7018e93258fSBjoern A. Zeeb 7028e93258fSBjoern A. Zeeb enum btc_reason_and_action { 7038e93258fSBjoern A. Zeeb BTC_RSN_NONE, 7048e93258fSBjoern A. Zeeb BTC_RSN_NTFY_INIT, 7058e93258fSBjoern A. Zeeb BTC_RSN_NTFY_SWBAND, 7068e93258fSBjoern A. Zeeb BTC_RSN_NTFY_WL_STA, 7078e93258fSBjoern A. Zeeb BTC_RSN_NTFY_RADIO_STATE, 7088e93258fSBjoern A. Zeeb BTC_RSN_UPDATE_BT_SCBD, 7098e93258fSBjoern A. Zeeb BTC_RSN_NTFY_WL_RFK, 7108e93258fSBjoern A. Zeeb BTC_RSN_UPDATE_BT_INFO, 7118e93258fSBjoern A. Zeeb BTC_RSN_NTFY_SCAN_START, 7128e93258fSBjoern A. Zeeb BTC_RSN_NTFY_SCAN_FINISH, 7138e93258fSBjoern A. Zeeb BTC_RSN_NTFY_SPECIFIC_PACKET, 7148e93258fSBjoern A. Zeeb BTC_RSN_NTFY_POWEROFF, 7158e93258fSBjoern A. Zeeb BTC_RSN_NTFY_ROLE_INFO, 7168e93258fSBjoern A. Zeeb BTC_RSN_CMD_SET_COEX, 7178e93258fSBjoern A. Zeeb BTC_RSN_ACT1_WORK, 7188e93258fSBjoern A. Zeeb BTC_RSN_BT_DEVINFO_WORK, 7198e93258fSBjoern A. Zeeb BTC_RSN_RFK_CHK_WORK, 7208e93258fSBjoern A. Zeeb BTC_RSN_NUM, 7218e93258fSBjoern A. Zeeb BTC_ACT_NONE = 100, 7228e93258fSBjoern A. Zeeb BTC_ACT_WL_ONLY, 7238e93258fSBjoern A. Zeeb BTC_ACT_WL_5G, 7248e93258fSBjoern A. Zeeb BTC_ACT_WL_OTHER, 7258e93258fSBjoern A. Zeeb BTC_ACT_WL_IDLE, 7268e93258fSBjoern A. Zeeb BTC_ACT_WL_NC, 7278e93258fSBjoern A. Zeeb BTC_ACT_WL_RFK, 7288e93258fSBjoern A. Zeeb BTC_ACT_WL_INIT, 7298e93258fSBjoern A. Zeeb BTC_ACT_WL_OFF, 7308e93258fSBjoern A. Zeeb BTC_ACT_FREERUN, 7318e93258fSBjoern A. Zeeb BTC_ACT_BT_WHQL, 7328e93258fSBjoern A. Zeeb BTC_ACT_BT_RFK, 7338e93258fSBjoern A. Zeeb BTC_ACT_BT_OFF, 7348e93258fSBjoern A. Zeeb BTC_ACT_BT_IDLE, 7358e93258fSBjoern A. Zeeb BTC_ACT_BT_HFP, 7368e93258fSBjoern A. Zeeb BTC_ACT_BT_HID, 7378e93258fSBjoern A. Zeeb BTC_ACT_BT_A2DP, 7388e93258fSBjoern A. Zeeb BTC_ACT_BT_A2DPSINK, 7398e93258fSBjoern A. Zeeb BTC_ACT_BT_PAN, 7408e93258fSBjoern A. Zeeb BTC_ACT_BT_A2DP_HID, 7418e93258fSBjoern A. Zeeb BTC_ACT_BT_A2DP_PAN, 7428e93258fSBjoern A. Zeeb BTC_ACT_BT_PAN_HID, 7438e93258fSBjoern A. Zeeb BTC_ACT_BT_A2DP_PAN_HID, 7448e93258fSBjoern A. Zeeb BTC_ACT_WL_25G_MCC, 7458e93258fSBjoern A. Zeeb BTC_ACT_WL_2G_MCC, 7468e93258fSBjoern A. Zeeb BTC_ACT_WL_2G_SCC, 7478e93258fSBjoern A. Zeeb BTC_ACT_WL_2G_AP, 7488e93258fSBjoern A. Zeeb BTC_ACT_WL_2G_GO, 7498e93258fSBjoern A. Zeeb BTC_ACT_WL_2G_GC, 7508e93258fSBjoern A. Zeeb BTC_ACT_WL_2G_NAN, 7518e93258fSBjoern A. Zeeb BTC_ACT_LAST, 7528e93258fSBjoern A. Zeeb BTC_ACT_NUM = BTC_ACT_LAST - BTC_ACT_NONE, 7538e93258fSBjoern A. Zeeb BTC_ACT_EXT_BIT = BIT(14), 7548e93258fSBjoern A. Zeeb BTC_POLICY_EXT_BIT = BIT(15), 7558e93258fSBjoern A. Zeeb }; 7568e93258fSBjoern A. Zeeb 7578e93258fSBjoern A. Zeeb #define BTC_FREERUN_ANTISO_MIN 30 7588e93258fSBjoern A. Zeeb #define BTC_TDMA_BTHID_MAX 2 7598e93258fSBjoern A. Zeeb #define BTC_BLINK_NOCONNECT 0 7608e93258fSBjoern A. Zeeb #define BTC_B1_MAX 250 /* unit ms */ 7618e93258fSBjoern A. Zeeb 7628e93258fSBjoern A. Zeeb static void _run_coex(struct rtw89_dev *rtwdev, 7638e93258fSBjoern A. Zeeb enum btc_reason_and_action reason); 7648e93258fSBjoern A. Zeeb static void _write_scbd(struct rtw89_dev *rtwdev, u32 val, bool state); 7658e93258fSBjoern A. Zeeb static void _update_bt_scbd(struct rtw89_dev *rtwdev, bool only_update); 7668e93258fSBjoern A. Zeeb 767*6d67aabdSBjoern A. Zeeb static int _send_fw_cmd(struct rtw89_dev *rtwdev, u8 h2c_class, u8 h2c_func, 7688e93258fSBjoern A. Zeeb void *param, u16 len) 7698e93258fSBjoern A. Zeeb { 7708e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 7718e93258fSBjoern A. Zeeb struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; 7728e93258fSBjoern A. Zeeb struct rtw89_btc_cx *cx = &btc->cx; 7738e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &cx->wl; 774*6d67aabdSBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 7758e93258fSBjoern A. Zeeb int ret; 7768e93258fSBjoern A. Zeeb 777*6d67aabdSBjoern A. Zeeb if (len > BTC_H2C_MAXLEN || len == 0) { 778*6d67aabdSBjoern A. Zeeb btc->fwinfo.cnt_h2c_fail++; 779*6d67aabdSBjoern A. Zeeb dm->error.map.h2c_buffer_over = true; 780*6d67aabdSBjoern A. Zeeb return -EINVAL; 781*6d67aabdSBjoern A. Zeeb } else if (!wl->status.map.init_ok) { 7828e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 7838e93258fSBjoern A. Zeeb "[BTC], %s(): return by btc not init!!\n", __func__); 7848e93258fSBjoern A. Zeeb pfwinfo->cnt_h2c_fail++; 785*6d67aabdSBjoern A. Zeeb return -EINVAL; 7868e93258fSBjoern A. Zeeb } else if ((wl->status.map.rf_off_pre == BTC_LPS_RF_OFF && 7878e93258fSBjoern A. Zeeb wl->status.map.rf_off == BTC_LPS_RF_OFF) || 7888e93258fSBjoern A. Zeeb (wl->status.map.lps_pre == BTC_LPS_RF_OFF && 7898e93258fSBjoern A. Zeeb wl->status.map.lps == BTC_LPS_RF_OFF)) { 7908e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 7918e93258fSBjoern A. Zeeb "[BTC], %s(): return by wl off!!\n", __func__); 7928e93258fSBjoern A. Zeeb pfwinfo->cnt_h2c_fail++; 793*6d67aabdSBjoern A. Zeeb return -EINVAL; 7948e93258fSBjoern A. Zeeb } 7958e93258fSBjoern A. Zeeb 7968e93258fSBjoern A. Zeeb ret = rtw89_fw_h2c_raw_with_hdr(rtwdev, h2c_class, h2c_func, param, len, 7978e93258fSBjoern A. Zeeb false, true); 798*6d67aabdSBjoern A. Zeeb if (ret) 7998e93258fSBjoern A. Zeeb pfwinfo->cnt_h2c_fail++; 800*6d67aabdSBjoern A. Zeeb else 801*6d67aabdSBjoern A. Zeeb pfwinfo->cnt_h2c++; 802*6d67aabdSBjoern A. Zeeb 803*6d67aabdSBjoern A. Zeeb return ret; 8048e93258fSBjoern A. Zeeb } 8058e93258fSBjoern A. Zeeb 8068e93258fSBjoern A. Zeeb static void _reset_btc_var(struct rtw89_dev *rtwdev, u8 type) 8078e93258fSBjoern A. Zeeb { 8088e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 809*6d67aabdSBjoern A. Zeeb const struct rtw89_btc_ver *ver = btc->ver; 8108e93258fSBjoern A. Zeeb struct rtw89_btc_cx *cx = &btc->cx; 8118e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 8128e93258fSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &btc->cx.bt; 8138e93258fSBjoern A. Zeeb struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info; 814*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_link_info *wl_linfo; 8158e93258fSBjoern A. Zeeb u8 i; 8168e93258fSBjoern A. Zeeb 8178e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s\n", __func__); 8188e93258fSBjoern A. Zeeb 8198e93258fSBjoern A. Zeeb if (type & BTC_RESET_CX) 8208e93258fSBjoern A. Zeeb memset(cx, 0, sizeof(*cx)); 821*6d67aabdSBjoern A. Zeeb 822*6d67aabdSBjoern A. Zeeb if (type & BTC_RESET_BTINFO) /* only for BT enable */ 8238e93258fSBjoern A. Zeeb memset(bt, 0, sizeof(*bt)); 8248e93258fSBjoern A. Zeeb 8258e93258fSBjoern A. Zeeb if (type & BTC_RESET_CTRL) { 8268e93258fSBjoern A. Zeeb memset(&btc->ctrl, 0, sizeof(btc->ctrl)); 827*6d67aabdSBjoern A. Zeeb btc->manual_ctrl = false; 828*6d67aabdSBjoern A. Zeeb if (ver->fcxctrl != 7) 829*6d67aabdSBjoern A. Zeeb btc->ctrl.ctrl.trace_step = FCXDEF_STEP; 8308e93258fSBjoern A. Zeeb } 8318e93258fSBjoern A. Zeeb 8328e93258fSBjoern A. Zeeb /* Init Coex variables that are not zero */ 8338e93258fSBjoern A. Zeeb if (type & BTC_RESET_DM) { 8348e93258fSBjoern A. Zeeb memset(&btc->dm, 0, sizeof(btc->dm)); 8358e93258fSBjoern A. Zeeb memset(bt_linfo->rssi_state, 0, sizeof(bt_linfo->rssi_state)); 836*6d67aabdSBjoern A. Zeeb for (i = 0; i < RTW89_PORT_NUM; i++) { 837*6d67aabdSBjoern A. Zeeb if (btc->ver->fwlrole == 8) 838*6d67aabdSBjoern A. Zeeb wl_linfo = &wl->rlink_info[i][0]; 839*6d67aabdSBjoern A. Zeeb else 840*6d67aabdSBjoern A. Zeeb wl_linfo = &wl->link_info[i]; 841*6d67aabdSBjoern A. Zeeb memset(wl_linfo->rssi_state, 0, sizeof(wl_linfo->rssi_state)); 842*6d67aabdSBjoern A. Zeeb } 8438e93258fSBjoern A. Zeeb 8448e93258fSBjoern A. Zeeb /* set the slot_now table to original */ 8458e93258fSBjoern A. Zeeb btc->dm.tdma_now = t_def[CXTD_OFF]; 8468e93258fSBjoern A. Zeeb btc->dm.tdma = t_def[CXTD_OFF]; 847*6d67aabdSBjoern A. Zeeb if (ver->fcxslots >= 7) { 848*6d67aabdSBjoern A. Zeeb for (i = 0; i < ARRAY_SIZE(s_def); i++) { 849*6d67aabdSBjoern A. Zeeb btc->dm.slot.v7[i].dur = s_def[i].dur; 850*6d67aabdSBjoern A. Zeeb btc->dm.slot.v7[i].cxtype = s_def[i].cxtype; 851*6d67aabdSBjoern A. Zeeb btc->dm.slot.v7[i].cxtbl = s_def[i].cxtbl; 852*6d67aabdSBjoern A. Zeeb } 853*6d67aabdSBjoern A. Zeeb memcpy(&btc->dm.slot_now.v7, &btc->dm.slot.v7, 854*6d67aabdSBjoern A. Zeeb sizeof(btc->dm.slot_now.v7)); 855*6d67aabdSBjoern A. Zeeb } else { 856*6d67aabdSBjoern A. Zeeb memcpy(&btc->dm.slot_now.v1, s_def, 857*6d67aabdSBjoern A. Zeeb sizeof(btc->dm.slot_now.v1)); 858*6d67aabdSBjoern A. Zeeb memcpy(&btc->dm.slot.v1, s_def, 859*6d67aabdSBjoern A. Zeeb sizeof(btc->dm.slot.v1)); 860*6d67aabdSBjoern A. Zeeb } 8618e93258fSBjoern A. Zeeb 8628e93258fSBjoern A. Zeeb btc->policy_len = 0; 8638e93258fSBjoern A. Zeeb btc->bt_req_len = 0; 8648e93258fSBjoern A. Zeeb 8658e93258fSBjoern A. Zeeb btc->dm.coex_info_map = BTC_COEX_INFO_ALL; 8668e93258fSBjoern A. Zeeb btc->dm.wl_tx_limit.tx_time = BTC_MAX_TX_TIME_DEF; 8678e93258fSBjoern A. Zeeb btc->dm.wl_tx_limit.tx_retry = BTC_MAX_TX_RETRY_DEF; 868*6d67aabdSBjoern A. Zeeb btc->dm.wl_pre_agc_rb = BTC_PREAGC_NOTFOUND; 869*6d67aabdSBjoern A. Zeeb btc->dm.wl_btg_rx_rb = BTC_BTGCTRL_BB_GNT_NOTFOUND; 8708e93258fSBjoern A. Zeeb } 8718e93258fSBjoern A. Zeeb 8728e93258fSBjoern A. Zeeb if (type & BTC_RESET_MDINFO) 8738e93258fSBjoern A. Zeeb memset(&btc->mdinfo, 0, sizeof(btc->mdinfo)); 8748e93258fSBjoern A. Zeeb } 8758e93258fSBjoern A. Zeeb 876*6d67aabdSBjoern A. Zeeb static u8 _search_reg_index(struct rtw89_dev *rtwdev, u8 mreg_num, u16 reg_type, u32 target) 877*6d67aabdSBjoern A. Zeeb { 878*6d67aabdSBjoern A. Zeeb const struct rtw89_chip_info *chip = rtwdev->chip; 879*6d67aabdSBjoern A. Zeeb u8 i; 880*6d67aabdSBjoern A. Zeeb 881*6d67aabdSBjoern A. Zeeb for (i = 0; i < mreg_num; i++) 882*6d67aabdSBjoern A. Zeeb if (le16_to_cpu(chip->mon_reg[i].type) == reg_type && 883*6d67aabdSBjoern A. Zeeb le32_to_cpu(chip->mon_reg[i].offset) == target) { 884*6d67aabdSBjoern A. Zeeb return i; 885*6d67aabdSBjoern A. Zeeb } 886*6d67aabdSBjoern A. Zeeb return BTC_REG_NOTFOUND; 887*6d67aabdSBjoern A. Zeeb } 888*6d67aabdSBjoern A. Zeeb 889*6d67aabdSBjoern A. Zeeb static void _get_reg_status(struct rtw89_dev *rtwdev, u8 type, u8 *val) 890*6d67aabdSBjoern A. Zeeb { 891*6d67aabdSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 892*6d67aabdSBjoern A. Zeeb const struct rtw89_btc_ver *ver = btc->ver; 893*6d67aabdSBjoern A. Zeeb union rtw89_btc_module_info *md = &btc->mdinfo; 894*6d67aabdSBjoern A. Zeeb union rtw89_btc_fbtc_mreg_val *pmreg; 895*6d67aabdSBjoern A. Zeeb u32 pre_agc_addr = R_BTC_BB_PRE_AGC_S1; 896*6d67aabdSBjoern A. Zeeb u32 reg_val; 897*6d67aabdSBjoern A. Zeeb u8 idx, switch_type; 898*6d67aabdSBjoern A. Zeeb 899*6d67aabdSBjoern A. Zeeb if (ver->fcxinit == 7) 900*6d67aabdSBjoern A. Zeeb switch_type = md->md_v7.switch_type; 901*6d67aabdSBjoern A. Zeeb else 902*6d67aabdSBjoern A. Zeeb switch_type = md->md.switch_type; 903*6d67aabdSBjoern A. Zeeb 904*6d67aabdSBjoern A. Zeeb if (btc->btg_pos == RF_PATH_A) 905*6d67aabdSBjoern A. Zeeb pre_agc_addr = R_BTC_BB_PRE_AGC_S0; 906*6d67aabdSBjoern A. Zeeb 907*6d67aabdSBjoern A. Zeeb switch (type) { 908*6d67aabdSBjoern A. Zeeb case BTC_CSTATUS_TXDIV_POS: 909*6d67aabdSBjoern A. Zeeb if (switch_type == BTC_SWITCH_INTERNAL) 910*6d67aabdSBjoern A. Zeeb *val = BTC_ANT_DIV_MAIN; 911*6d67aabdSBjoern A. Zeeb break; 912*6d67aabdSBjoern A. Zeeb case BTC_CSTATUS_RXDIV_POS: 913*6d67aabdSBjoern A. Zeeb if (switch_type == BTC_SWITCH_INTERNAL) 914*6d67aabdSBjoern A. Zeeb *val = BTC_ANT_DIV_MAIN; 915*6d67aabdSBjoern A. Zeeb break; 916*6d67aabdSBjoern A. Zeeb case BTC_CSTATUS_BB_GNT_MUX: 917*6d67aabdSBjoern A. Zeeb reg_val = rtw89_phy_read32(rtwdev, R_BTC_BB_BTG_RX); 918*6d67aabdSBjoern A. Zeeb *val = !(reg_val & B_BTC_BB_GNT_MUX); 919*6d67aabdSBjoern A. Zeeb break; 920*6d67aabdSBjoern A. Zeeb case BTC_CSTATUS_BB_GNT_MUX_MON: 921*6d67aabdSBjoern A. Zeeb if (!btc->fwinfo.rpt_fbtc_mregval.cinfo.valid) 922*6d67aabdSBjoern A. Zeeb return; 923*6d67aabdSBjoern A. Zeeb 924*6d67aabdSBjoern A. Zeeb pmreg = &btc->fwinfo.rpt_fbtc_mregval.finfo; 925*6d67aabdSBjoern A. Zeeb if (ver->fcxmreg == 1) { 926*6d67aabdSBjoern A. Zeeb idx = _search_reg_index(rtwdev, pmreg->v1.reg_num, 927*6d67aabdSBjoern A. Zeeb REG_BB, R_BTC_BB_BTG_RX); 928*6d67aabdSBjoern A. Zeeb if (idx == BTC_REG_NOTFOUND) { 929*6d67aabdSBjoern A. Zeeb *val = BTC_BTGCTRL_BB_GNT_NOTFOUND; 930*6d67aabdSBjoern A. Zeeb } else { 931*6d67aabdSBjoern A. Zeeb reg_val = le32_to_cpu(pmreg->v1.mreg_val[idx]); 932*6d67aabdSBjoern A. Zeeb *val = !(reg_val & B_BTC_BB_GNT_MUX); 933*6d67aabdSBjoern A. Zeeb } 934*6d67aabdSBjoern A. Zeeb } else if (ver->fcxmreg == 2) { 935*6d67aabdSBjoern A. Zeeb idx = _search_reg_index(rtwdev, pmreg->v2.reg_num, 936*6d67aabdSBjoern A. Zeeb REG_BB, R_BTC_BB_BTG_RX); 937*6d67aabdSBjoern A. Zeeb if (idx == BTC_REG_NOTFOUND) { 938*6d67aabdSBjoern A. Zeeb *val = BTC_BTGCTRL_BB_GNT_NOTFOUND; 939*6d67aabdSBjoern A. Zeeb } else { 940*6d67aabdSBjoern A. Zeeb reg_val = le32_to_cpu(pmreg->v2.mreg_val[idx]); 941*6d67aabdSBjoern A. Zeeb *val = !(reg_val & B_BTC_BB_GNT_MUX); 942*6d67aabdSBjoern A. Zeeb } 943*6d67aabdSBjoern A. Zeeb } 944*6d67aabdSBjoern A. Zeeb break; 945*6d67aabdSBjoern A. Zeeb case BTC_CSTATUS_BB_PRE_AGC: 946*6d67aabdSBjoern A. Zeeb reg_val = rtw89_phy_read32(rtwdev, pre_agc_addr); 947*6d67aabdSBjoern A. Zeeb reg_val &= B_BTC_BB_PRE_AGC_MASK; 948*6d67aabdSBjoern A. Zeeb *val = (reg_val == B_BTC_BB_PRE_AGC_VAL); 949*6d67aabdSBjoern A. Zeeb break; 950*6d67aabdSBjoern A. Zeeb case BTC_CSTATUS_BB_PRE_AGC_MON: 951*6d67aabdSBjoern A. Zeeb if (!btc->fwinfo.rpt_fbtc_mregval.cinfo.valid) 952*6d67aabdSBjoern A. Zeeb return; 953*6d67aabdSBjoern A. Zeeb 954*6d67aabdSBjoern A. Zeeb pmreg = &btc->fwinfo.rpt_fbtc_mregval.finfo; 955*6d67aabdSBjoern A. Zeeb if (ver->fcxmreg == 1) { 956*6d67aabdSBjoern A. Zeeb idx = _search_reg_index(rtwdev, pmreg->v1.reg_num, 957*6d67aabdSBjoern A. Zeeb REG_BB, pre_agc_addr); 958*6d67aabdSBjoern A. Zeeb if (idx == BTC_REG_NOTFOUND) { 959*6d67aabdSBjoern A. Zeeb *val = BTC_PREAGC_NOTFOUND; 960*6d67aabdSBjoern A. Zeeb } else { 961*6d67aabdSBjoern A. Zeeb reg_val = le32_to_cpu(pmreg->v1.mreg_val[idx]) & 962*6d67aabdSBjoern A. Zeeb B_BTC_BB_PRE_AGC_MASK; 963*6d67aabdSBjoern A. Zeeb *val = (reg_val == B_BTC_BB_PRE_AGC_VAL); 964*6d67aabdSBjoern A. Zeeb } 965*6d67aabdSBjoern A. Zeeb } else if (ver->fcxmreg == 2) { 966*6d67aabdSBjoern A. Zeeb idx = _search_reg_index(rtwdev, pmreg->v2.reg_num, 967*6d67aabdSBjoern A. Zeeb REG_BB, pre_agc_addr); 968*6d67aabdSBjoern A. Zeeb if (idx == BTC_REG_NOTFOUND) { 969*6d67aabdSBjoern A. Zeeb *val = BTC_PREAGC_NOTFOUND; 970*6d67aabdSBjoern A. Zeeb } else { 971*6d67aabdSBjoern A. Zeeb reg_val = le32_to_cpu(pmreg->v2.mreg_val[idx]) & 972*6d67aabdSBjoern A. Zeeb B_BTC_BB_PRE_AGC_MASK; 973*6d67aabdSBjoern A. Zeeb *val = (reg_val == B_BTC_BB_PRE_AGC_VAL); 974*6d67aabdSBjoern A. Zeeb } 975*6d67aabdSBjoern A. Zeeb } 976*6d67aabdSBjoern A. Zeeb break; 977*6d67aabdSBjoern A. Zeeb default: 978*6d67aabdSBjoern A. Zeeb break; 979*6d67aabdSBjoern A. Zeeb } 980*6d67aabdSBjoern A. Zeeb } 981*6d67aabdSBjoern A. Zeeb 9828e93258fSBjoern A. Zeeb #define BTC_RPT_HDR_SIZE 3 9838e93258fSBjoern A. Zeeb #define BTC_CHK_WLSLOT_DRIFT_MAX 15 984e2340276SBjoern A. Zeeb #define BTC_CHK_BTSLOT_DRIFT_MAX 15 9858e93258fSBjoern A. Zeeb #define BTC_CHK_HANG_MAX 3 9868e93258fSBjoern A. Zeeb 9878e93258fSBjoern A. Zeeb static void _chk_btc_err(struct rtw89_dev *rtwdev, u8 type, u32 cnt) 9888e93258fSBjoern A. Zeeb { 9898e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 9908e93258fSBjoern A. Zeeb struct rtw89_btc_cx *cx = &btc->cx; 9918e93258fSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &cx->bt; 992*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &cx->wl; 993*6d67aabdSBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 9948e93258fSBjoern A. Zeeb 9958e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 9968e93258fSBjoern A. Zeeb "[BTC], %s(): type:%d cnt:%d\n", 9978e93258fSBjoern A. Zeeb __func__, type, cnt); 9988e93258fSBjoern A. Zeeb 9998e93258fSBjoern A. Zeeb switch (type) { 1000*6d67aabdSBjoern A. Zeeb case BTC_DCNT_WL_FW_VER_MATCH: 1001*6d67aabdSBjoern A. Zeeb if ((wl->ver_info.fw_coex & 0xffff0000) != 1002*6d67aabdSBjoern A. Zeeb rtwdev->chip->wlcx_desired) { 1003*6d67aabdSBjoern A. Zeeb wl->fw_ver_mismatch = true; 1004*6d67aabdSBjoern A. Zeeb dm->error.map.wl_ver_mismatch = true; 1005*6d67aabdSBjoern A. Zeeb } else { 1006*6d67aabdSBjoern A. Zeeb wl->fw_ver_mismatch = false; 1007*6d67aabdSBjoern A. Zeeb dm->error.map.wl_ver_mismatch = false; 1008*6d67aabdSBjoern A. Zeeb } 1009*6d67aabdSBjoern A. Zeeb break; 1010e2340276SBjoern A. Zeeb case BTC_DCNT_RPT_HANG: 10118e93258fSBjoern A. Zeeb if (dm->cnt_dm[BTC_DCNT_RPT] == cnt && btc->fwinfo.rpt_en_map) 1012e2340276SBjoern A. Zeeb dm->cnt_dm[BTC_DCNT_RPT_HANG]++; 10138e93258fSBjoern A. Zeeb else 1014e2340276SBjoern A. Zeeb dm->cnt_dm[BTC_DCNT_RPT_HANG] = 0; 10158e93258fSBjoern A. Zeeb 1016e2340276SBjoern A. Zeeb if (dm->cnt_dm[BTC_DCNT_RPT_HANG] >= BTC_CHK_HANG_MAX) 10178e93258fSBjoern A. Zeeb dm->error.map.wl_fw_hang = true; 10188e93258fSBjoern A. Zeeb else 10198e93258fSBjoern A. Zeeb dm->error.map.wl_fw_hang = false; 10208e93258fSBjoern A. Zeeb 10218e93258fSBjoern A. Zeeb dm->cnt_dm[BTC_DCNT_RPT] = cnt; 10228e93258fSBjoern A. Zeeb break; 1023e2340276SBjoern A. Zeeb case BTC_DCNT_CYCLE_HANG: 10248e93258fSBjoern A. Zeeb if (dm->cnt_dm[BTC_DCNT_CYCLE] == cnt && 10258e93258fSBjoern A. Zeeb (dm->tdma_now.type != CXTDMA_OFF || 10268e93258fSBjoern A. Zeeb dm->tdma_now.ext_ctrl == CXECTL_EXT)) 1027e2340276SBjoern A. Zeeb dm->cnt_dm[BTC_DCNT_CYCLE_HANG]++; 10288e93258fSBjoern A. Zeeb else 1029e2340276SBjoern A. Zeeb dm->cnt_dm[BTC_DCNT_CYCLE_HANG] = 0; 10308e93258fSBjoern A. Zeeb 1031e2340276SBjoern A. Zeeb if (dm->cnt_dm[BTC_DCNT_CYCLE_HANG] >= BTC_CHK_HANG_MAX) 10328e93258fSBjoern A. Zeeb dm->error.map.cycle_hang = true; 10338e93258fSBjoern A. Zeeb else 10348e93258fSBjoern A. Zeeb dm->error.map.cycle_hang = false; 10358e93258fSBjoern A. Zeeb 10368e93258fSBjoern A. Zeeb dm->cnt_dm[BTC_DCNT_CYCLE] = cnt; 10378e93258fSBjoern A. Zeeb break; 1038e2340276SBjoern A. Zeeb case BTC_DCNT_W1_HANG: 10398e93258fSBjoern A. Zeeb if (dm->cnt_dm[BTC_DCNT_W1] == cnt && 10408e93258fSBjoern A. Zeeb dm->tdma_now.type != CXTDMA_OFF) 1041e2340276SBjoern A. Zeeb dm->cnt_dm[BTC_DCNT_W1_HANG]++; 10428e93258fSBjoern A. Zeeb else 1043e2340276SBjoern A. Zeeb dm->cnt_dm[BTC_DCNT_W1_HANG] = 0; 10448e93258fSBjoern A. Zeeb 1045e2340276SBjoern A. Zeeb if (dm->cnt_dm[BTC_DCNT_W1_HANG] >= BTC_CHK_HANG_MAX) 10468e93258fSBjoern A. Zeeb dm->error.map.w1_hang = true; 10478e93258fSBjoern A. Zeeb else 10488e93258fSBjoern A. Zeeb dm->error.map.w1_hang = false; 10498e93258fSBjoern A. Zeeb 10508e93258fSBjoern A. Zeeb dm->cnt_dm[BTC_DCNT_W1] = cnt; 10518e93258fSBjoern A. Zeeb break; 1052e2340276SBjoern A. Zeeb case BTC_DCNT_B1_HANG: 10538e93258fSBjoern A. Zeeb if (dm->cnt_dm[BTC_DCNT_B1] == cnt && 10548e93258fSBjoern A. Zeeb dm->tdma_now.type != CXTDMA_OFF) 1055e2340276SBjoern A. Zeeb dm->cnt_dm[BTC_DCNT_B1_HANG]++; 10568e93258fSBjoern A. Zeeb else 1057e2340276SBjoern A. Zeeb dm->cnt_dm[BTC_DCNT_B1_HANG] = 0; 10588e93258fSBjoern A. Zeeb 1059e2340276SBjoern A. Zeeb if (dm->cnt_dm[BTC_DCNT_B1_HANG] >= BTC_CHK_HANG_MAX) 10608e93258fSBjoern A. Zeeb dm->error.map.b1_hang = true; 10618e93258fSBjoern A. Zeeb else 10628e93258fSBjoern A. Zeeb dm->error.map.b1_hang = false; 10638e93258fSBjoern A. Zeeb 10648e93258fSBjoern A. Zeeb dm->cnt_dm[BTC_DCNT_B1] = cnt; 10658e93258fSBjoern A. Zeeb break; 1066e2340276SBjoern A. Zeeb case BTC_DCNT_E2G_HANG: 1067e2340276SBjoern A. Zeeb if (dm->cnt_dm[BTC_DCNT_E2G] == cnt && 1068e2340276SBjoern A. Zeeb dm->tdma_now.ext_ctrl == CXECTL_EXT) 1069e2340276SBjoern A. Zeeb dm->cnt_dm[BTC_DCNT_E2G_HANG]++; 1070e2340276SBjoern A. Zeeb else 1071e2340276SBjoern A. Zeeb dm->cnt_dm[BTC_DCNT_E2G_HANG] = 0; 1072e2340276SBjoern A. Zeeb 1073e2340276SBjoern A. Zeeb if (dm->cnt_dm[BTC_DCNT_E2G_HANG] >= BTC_CHK_HANG_MAX) 1074e2340276SBjoern A. Zeeb dm->error.map.wl_e2g_hang = true; 1075e2340276SBjoern A. Zeeb else 1076e2340276SBjoern A. Zeeb dm->error.map.wl_e2g_hang = false; 1077e2340276SBjoern A. Zeeb 1078e2340276SBjoern A. Zeeb dm->cnt_dm[BTC_DCNT_E2G] = cnt; 1079e2340276SBjoern A. Zeeb break; 10808e93258fSBjoern A. Zeeb case BTC_DCNT_TDMA_NONSYNC: 10818e93258fSBjoern A. Zeeb if (cnt != 0) /* if tdma not sync between drv/fw */ 10828e93258fSBjoern A. Zeeb dm->cnt_dm[BTC_DCNT_TDMA_NONSYNC]++; 10838e93258fSBjoern A. Zeeb else 10848e93258fSBjoern A. Zeeb dm->cnt_dm[BTC_DCNT_TDMA_NONSYNC] = 0; 10858e93258fSBjoern A. Zeeb 10868e93258fSBjoern A. Zeeb if (dm->cnt_dm[BTC_DCNT_TDMA_NONSYNC] >= BTC_CHK_HANG_MAX) 10878e93258fSBjoern A. Zeeb dm->error.map.tdma_no_sync = true; 10888e93258fSBjoern A. Zeeb else 10898e93258fSBjoern A. Zeeb dm->error.map.tdma_no_sync = false; 10908e93258fSBjoern A. Zeeb break; 10918e93258fSBjoern A. Zeeb case BTC_DCNT_SLOT_NONSYNC: 10928e93258fSBjoern A. Zeeb if (cnt != 0) /* if slot not sync between drv/fw */ 10938e93258fSBjoern A. Zeeb dm->cnt_dm[BTC_DCNT_SLOT_NONSYNC]++; 10948e93258fSBjoern A. Zeeb else 10958e93258fSBjoern A. Zeeb dm->cnt_dm[BTC_DCNT_SLOT_NONSYNC] = 0; 10968e93258fSBjoern A. Zeeb 10978e93258fSBjoern A. Zeeb if (dm->cnt_dm[BTC_DCNT_SLOT_NONSYNC] >= BTC_CHK_HANG_MAX) 1098e2340276SBjoern A. Zeeb dm->error.map.slot_no_sync = true; 10998e93258fSBjoern A. Zeeb else 1100e2340276SBjoern A. Zeeb dm->error.map.slot_no_sync = false; 11018e93258fSBjoern A. Zeeb break; 1102*6d67aabdSBjoern A. Zeeb case BTC_DCNT_BTTX_HANG: 1103*6d67aabdSBjoern A. Zeeb cnt = cx->cnt_bt[BTC_BCNT_LOPRI_TX]; 1104*6d67aabdSBjoern A. Zeeb 1105*6d67aabdSBjoern A. Zeeb if (cnt == 0 && bt->link_info.slave_role) 1106*6d67aabdSBjoern A. Zeeb dm->cnt_dm[BTC_DCNT_BTTX_HANG]++; 1107*6d67aabdSBjoern A. Zeeb else 1108*6d67aabdSBjoern A. Zeeb dm->cnt_dm[BTC_DCNT_BTTX_HANG] = 0; 1109*6d67aabdSBjoern A. Zeeb 1110*6d67aabdSBjoern A. Zeeb if (dm->cnt_dm[BTC_DCNT_BTTX_HANG] >= BTC_CHK_HANG_MAX) 1111*6d67aabdSBjoern A. Zeeb dm->error.map.bt_tx_hang = true; 1112*6d67aabdSBjoern A. Zeeb else 1113*6d67aabdSBjoern A. Zeeb dm->error.map.bt_tx_hang = false; 1114*6d67aabdSBjoern A. Zeeb break; 1115e2340276SBjoern A. Zeeb case BTC_DCNT_BTCNT_HANG: 11168e93258fSBjoern A. Zeeb cnt = cx->cnt_bt[BTC_BCNT_HIPRI_RX] + 11178e93258fSBjoern A. Zeeb cx->cnt_bt[BTC_BCNT_HIPRI_TX] + 11188e93258fSBjoern A. Zeeb cx->cnt_bt[BTC_BCNT_LOPRI_RX] + 11198e93258fSBjoern A. Zeeb cx->cnt_bt[BTC_BCNT_LOPRI_TX]; 11208e93258fSBjoern A. Zeeb 11218e93258fSBjoern A. Zeeb if (cnt == 0) 1122e2340276SBjoern A. Zeeb dm->cnt_dm[BTC_DCNT_BTCNT_HANG]++; 11238e93258fSBjoern A. Zeeb else 1124e2340276SBjoern A. Zeeb dm->cnt_dm[BTC_DCNT_BTCNT_HANG] = 0; 11258e93258fSBjoern A. Zeeb 1126e2340276SBjoern A. Zeeb if ((dm->cnt_dm[BTC_DCNT_BTCNT_HANG] >= BTC_CHK_HANG_MAX && 1127e2340276SBjoern A. Zeeb bt->enable.now) || (!dm->cnt_dm[BTC_DCNT_BTCNT_HANG] && 11288e93258fSBjoern A. Zeeb !bt->enable.now)) 11298e93258fSBjoern A. Zeeb _update_bt_scbd(rtwdev, false); 11308e93258fSBjoern A. Zeeb break; 11318e93258fSBjoern A. Zeeb case BTC_DCNT_WL_SLOT_DRIFT: 11328e93258fSBjoern A. Zeeb if (cnt >= BTC_CHK_WLSLOT_DRIFT_MAX) 11338e93258fSBjoern A. Zeeb dm->cnt_dm[BTC_DCNT_WL_SLOT_DRIFT]++; 11348e93258fSBjoern A. Zeeb else 11358e93258fSBjoern A. Zeeb dm->cnt_dm[BTC_DCNT_WL_SLOT_DRIFT] = 0; 11368e93258fSBjoern A. Zeeb 11378e93258fSBjoern A. Zeeb if (dm->cnt_dm[BTC_DCNT_WL_SLOT_DRIFT] >= BTC_CHK_HANG_MAX) 11388e93258fSBjoern A. Zeeb dm->error.map.wl_slot_drift = true; 11398e93258fSBjoern A. Zeeb else 11408e93258fSBjoern A. Zeeb dm->error.map.wl_slot_drift = false; 11418e93258fSBjoern A. Zeeb break; 1142e2340276SBjoern A. Zeeb case BTC_DCNT_BT_SLOT_DRIFT: 1143e2340276SBjoern A. Zeeb if (cnt >= BTC_CHK_BTSLOT_DRIFT_MAX) 1144e2340276SBjoern A. Zeeb dm->cnt_dm[BTC_DCNT_BT_SLOT_DRIFT]++; 1145e2340276SBjoern A. Zeeb else 1146e2340276SBjoern A. Zeeb dm->cnt_dm[BTC_DCNT_BT_SLOT_DRIFT] = 0; 1147e2340276SBjoern A. Zeeb 1148e2340276SBjoern A. Zeeb if (dm->cnt_dm[BTC_DCNT_BT_SLOT_DRIFT] >= BTC_CHK_HANG_MAX) 1149e2340276SBjoern A. Zeeb dm->error.map.bt_slot_drift = true; 1150e2340276SBjoern A. Zeeb else 1151e2340276SBjoern A. Zeeb dm->error.map.bt_slot_drift = false; 1152e2340276SBjoern A. Zeeb 1153e2340276SBjoern A. Zeeb break; 11548e93258fSBjoern A. Zeeb } 11558e93258fSBjoern A. Zeeb } 11568e93258fSBjoern A. Zeeb 11578e93258fSBjoern A. Zeeb static void _update_bt_report(struct rtw89_dev *rtwdev, u8 rpt_type, u8 *pfinfo) 11588e93258fSBjoern A. Zeeb { 11598e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 1160e2340276SBjoern A. Zeeb const struct rtw89_btc_ver *ver = btc->ver; 11618e93258fSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &btc->cx.bt; 11628e93258fSBjoern A. Zeeb struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info; 11638e93258fSBjoern A. Zeeb struct rtw89_btc_bt_a2dp_desc *a2dp = &bt_linfo->a2dp_desc; 1164*6d67aabdSBjoern A. Zeeb union rtw89_btc_fbtc_btver *pver = &btc->fwinfo.rpt_fbtc_btver.finfo; 1165*6d67aabdSBjoern A. Zeeb struct rtw89_btc_fbtc_btafh_v2 *pafh_v2 = NULL; 1166*6d67aabdSBjoern A. Zeeb struct rtw89_btc_fbtc_btafh_v7 *pafh_v7 = NULL; 1167*6d67aabdSBjoern A. Zeeb struct rtw89_btc_fbtc_btdevinfo *pdev = NULL; 1168*6d67aabdSBjoern A. Zeeb struct rtw89_btc_fbtc_btafh *pafh_v1 = NULL; 1169e2340276SBjoern A. Zeeb struct rtw89_btc_fbtc_btscan_v1 *pscan_v1; 1170e2340276SBjoern A. Zeeb struct rtw89_btc_fbtc_btscan_v2 *pscan_v2; 1171*6d67aabdSBjoern A. Zeeb struct rtw89_btc_fbtc_btscan_v7 *pscan_v7; 1172e2340276SBjoern A. Zeeb bool scan_update = true; 1173e2340276SBjoern A. Zeeb int i; 11748e93258fSBjoern A. Zeeb 11758e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 11768e93258fSBjoern A. Zeeb "[BTC], %s(): rpt_type:%d\n", 11778e93258fSBjoern A. Zeeb __func__, rpt_type); 11788e93258fSBjoern A. Zeeb 11798e93258fSBjoern A. Zeeb switch (rpt_type) { 11808e93258fSBjoern A. Zeeb case BTC_RPT_TYPE_BT_VER: 1181*6d67aabdSBjoern A. Zeeb if (ver->fcxbtver == 7) { 1182*6d67aabdSBjoern A. Zeeb pver->v7 = *(struct rtw89_btc_fbtc_btver_v7 *)pfinfo; 1183*6d67aabdSBjoern A. Zeeb bt->ver_info.fw = le32_to_cpu(pver->v7.fw_ver); 1184*6d67aabdSBjoern A. Zeeb bt->ver_info.fw_coex = le32_get_bits(pver->v7.coex_ver, 1185*6d67aabdSBjoern A. Zeeb GENMASK(7, 0)); 1186*6d67aabdSBjoern A. Zeeb bt->feature = le32_to_cpu(pver->v7.feature); 1187*6d67aabdSBjoern A. Zeeb } else { 1188*6d67aabdSBjoern A. Zeeb pver->v1 = *(struct rtw89_btc_fbtc_btver_v1 *)pfinfo; 1189*6d67aabdSBjoern A. Zeeb bt->ver_info.fw = le32_to_cpu(pver->v1.fw_ver); 1190*6d67aabdSBjoern A. Zeeb bt->ver_info.fw_coex = le32_get_bits(pver->v1.coex_ver, 1191*6d67aabdSBjoern A. Zeeb GENMASK(7, 0)); 1192*6d67aabdSBjoern A. Zeeb bt->feature = le32_to_cpu(pver->v1.feature); 1193*6d67aabdSBjoern A. Zeeb } 11948e93258fSBjoern A. Zeeb break; 11958e93258fSBjoern A. Zeeb case BTC_RPT_TYPE_BT_SCAN: 1196e2340276SBjoern A. Zeeb if (ver->fcxbtscan == 1) { 1197e2340276SBjoern A. Zeeb pscan_v1 = (struct rtw89_btc_fbtc_btscan_v1 *)pfinfo; 1198e2340276SBjoern A. Zeeb for (i = 0; i < BTC_SCAN_MAX1; i++) { 1199e2340276SBjoern A. Zeeb bt->scan_info_v1[i] = pscan_v1->scan[i]; 1200e2340276SBjoern A. Zeeb if (bt->scan_info_v1[i].win == 0 && 1201e2340276SBjoern A. Zeeb bt->scan_info_v1[i].intvl == 0) 1202e2340276SBjoern A. Zeeb scan_update = false; 1203e2340276SBjoern A. Zeeb } 1204e2340276SBjoern A. Zeeb } else if (ver->fcxbtscan == 2) { 1205e2340276SBjoern A. Zeeb pscan_v2 = (struct rtw89_btc_fbtc_btscan_v2 *)pfinfo; 1206e2340276SBjoern A. Zeeb for (i = 0; i < CXSCAN_MAX; i++) { 1207e2340276SBjoern A. Zeeb bt->scan_info_v2[i] = pscan_v2->para[i]; 1208e2340276SBjoern A. Zeeb if ((pscan_v2->type & BIT(i)) && 1209e2340276SBjoern A. Zeeb pscan_v2->para[i].win == 0 && 1210e2340276SBjoern A. Zeeb pscan_v2->para[i].intvl == 0) 1211e2340276SBjoern A. Zeeb scan_update = false; 1212e2340276SBjoern A. Zeeb } 1213*6d67aabdSBjoern A. Zeeb } else if (ver->fcxbtscan == 7) { 1214*6d67aabdSBjoern A. Zeeb pscan_v7 = (struct rtw89_btc_fbtc_btscan_v7 *)pfinfo; 1215*6d67aabdSBjoern A. Zeeb for (i = 0; i < CXSCAN_MAX; i++) { 1216*6d67aabdSBjoern A. Zeeb bt->scan_info_v2[i] = pscan_v7->para[i]; 1217*6d67aabdSBjoern A. Zeeb if ((pscan_v7->type & BIT(i)) && 1218*6d67aabdSBjoern A. Zeeb pscan_v7->para[i].win == 0 && 1219*6d67aabdSBjoern A. Zeeb pscan_v7->para[i].intvl == 0) 1220*6d67aabdSBjoern A. Zeeb scan_update = false; 1221*6d67aabdSBjoern A. Zeeb } 1222e2340276SBjoern A. Zeeb } 1223e2340276SBjoern A. Zeeb if (scan_update) 1224e2340276SBjoern A. Zeeb bt->scan_info_update = 1; 12258e93258fSBjoern A. Zeeb break; 12268e93258fSBjoern A. Zeeb case BTC_RPT_TYPE_BT_AFH: 1227e2340276SBjoern A. Zeeb if (ver->fcxbtafh == 2) { 1228e2340276SBjoern A. Zeeb pafh_v2 = (struct rtw89_btc_fbtc_btafh_v2 *)pfinfo; 1229e2340276SBjoern A. Zeeb if (pafh_v2->map_type & RPT_BT_AFH_SEQ_LEGACY) { 1230e2340276SBjoern A. Zeeb memcpy(&bt_linfo->afh_map[0], pafh_v2->afh_l, 4); 1231e2340276SBjoern A. Zeeb memcpy(&bt_linfo->afh_map[4], pafh_v2->afh_m, 4); 1232e2340276SBjoern A. Zeeb memcpy(&bt_linfo->afh_map[8], pafh_v2->afh_h, 2); 1233e2340276SBjoern A. Zeeb } 1234e2340276SBjoern A. Zeeb if (pafh_v2->map_type & RPT_BT_AFH_SEQ_LE) { 1235e2340276SBjoern A. Zeeb memcpy(&bt_linfo->afh_map_le[0], pafh_v2->afh_le_a, 4); 1236e2340276SBjoern A. Zeeb memcpy(&bt_linfo->afh_map_le[4], pafh_v2->afh_le_b, 1); 1237e2340276SBjoern A. Zeeb } 1238*6d67aabdSBjoern A. Zeeb } else if (ver->fcxbtafh == 7) { 1239*6d67aabdSBjoern A. Zeeb pafh_v7 = (struct rtw89_btc_fbtc_btafh_v7 *)pfinfo; 1240*6d67aabdSBjoern A. Zeeb if (pafh_v7->map_type & RPT_BT_AFH_SEQ_LEGACY) { 1241*6d67aabdSBjoern A. Zeeb memcpy(&bt_linfo->afh_map[0], pafh_v7->afh_l, 4); 1242*6d67aabdSBjoern A. Zeeb memcpy(&bt_linfo->afh_map[4], pafh_v7->afh_m, 4); 1243*6d67aabdSBjoern A. Zeeb memcpy(&bt_linfo->afh_map[8], pafh_v7->afh_h, 2); 1244*6d67aabdSBjoern A. Zeeb } 1245*6d67aabdSBjoern A. Zeeb if (pafh_v7->map_type & RPT_BT_AFH_SEQ_LE) { 1246*6d67aabdSBjoern A. Zeeb memcpy(&bt_linfo->afh_map_le[0], pafh_v7->afh_le_a, 4); 1247*6d67aabdSBjoern A. Zeeb memcpy(&bt_linfo->afh_map_le[4], pafh_v7->afh_le_b, 1); 1248*6d67aabdSBjoern A. Zeeb } 1249e2340276SBjoern A. Zeeb } else if (ver->fcxbtafh == 1) { 1250e2340276SBjoern A. Zeeb pafh_v1 = (struct rtw89_btc_fbtc_btafh *)pfinfo; 1251e2340276SBjoern A. Zeeb memcpy(&bt_linfo->afh_map[0], pafh_v1->afh_l, 4); 1252e2340276SBjoern A. Zeeb memcpy(&bt_linfo->afh_map[4], pafh_v1->afh_m, 4); 1253e2340276SBjoern A. Zeeb memcpy(&bt_linfo->afh_map[8], pafh_v1->afh_h, 2); 1254e2340276SBjoern A. Zeeb } 12558e93258fSBjoern A. Zeeb break; 12568e93258fSBjoern A. Zeeb case BTC_RPT_TYPE_BT_DEVICE: 1257*6d67aabdSBjoern A. Zeeb pdev = (struct rtw89_btc_fbtc_btdevinfo *)pfinfo; 12588e93258fSBjoern A. Zeeb a2dp->device_name = le32_to_cpu(pdev->dev_name); 12598e93258fSBjoern A. Zeeb a2dp->vendor_id = le16_to_cpu(pdev->vendor_id); 12608e93258fSBjoern A. Zeeb a2dp->flush_time = le32_to_cpu(pdev->flush_time); 12618e93258fSBjoern A. Zeeb break; 12628e93258fSBjoern A. Zeeb default: 12638e93258fSBjoern A. Zeeb break; 12648e93258fSBjoern A. Zeeb } 12658e93258fSBjoern A. Zeeb } 12668e93258fSBjoern A. Zeeb 1267*6d67aabdSBjoern A. Zeeb static void rtw89_btc_fw_rpt_evnt_ver(struct rtw89_dev *rtwdev, u8 *index) 1268*6d67aabdSBjoern A. Zeeb { 1269*6d67aabdSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 1270*6d67aabdSBjoern A. Zeeb const struct rtw89_btc_ver *ver = btc->ver; 1271*6d67aabdSBjoern A. Zeeb 1272*6d67aabdSBjoern A. Zeeb if (ver->fwevntrptl == 1) 1273*6d67aabdSBjoern A. Zeeb return; 1274*6d67aabdSBjoern A. Zeeb 1275*6d67aabdSBjoern A. Zeeb if (*index <= __BTC_RPT_TYPE_V0_SAME) 1276*6d67aabdSBjoern A. Zeeb return; 1277*6d67aabdSBjoern A. Zeeb else if (*index <= __BTC_RPT_TYPE_V0_MAX) 1278*6d67aabdSBjoern A. Zeeb (*index)++; 1279*6d67aabdSBjoern A. Zeeb else 1280*6d67aabdSBjoern A. Zeeb *index = BTC_RPT_TYPE_MAX; 1281*6d67aabdSBjoern A. Zeeb } 1282*6d67aabdSBjoern A. Zeeb 12838e93258fSBjoern A. Zeeb #define BTC_LEAK_AP_TH 10 12848e93258fSBjoern A. Zeeb #define BTC_CYSTA_CHK_PERIOD 100 12858e93258fSBjoern A. Zeeb 12868e93258fSBjoern A. Zeeb struct rtw89_btc_prpt { 12878e93258fSBjoern A. Zeeb u8 type; 12888e93258fSBjoern A. Zeeb __le16 len; 12898e93258fSBjoern A. Zeeb u8 content[]; 12908e93258fSBjoern A. Zeeb } __packed; 12918e93258fSBjoern A. Zeeb 12928e93258fSBjoern A. Zeeb static u32 _chk_btc_report(struct rtw89_dev *rtwdev, 12938e93258fSBjoern A. Zeeb struct rtw89_btc_btf_fwinfo *pfwinfo, 12948e93258fSBjoern A. Zeeb u8 *prptbuf, u32 index) 12958e93258fSBjoern A. Zeeb { 12968e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 1297e2340276SBjoern A. Zeeb const struct rtw89_btc_ver *ver = btc->ver; 12988e93258fSBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 12998e93258fSBjoern A. Zeeb struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; 13008e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 13018e93258fSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &btc->cx.bt; 1302e2340276SBjoern A. Zeeb union rtw89_btc_fbtc_rpt_ctrl_ver_info *prpt = NULL; 1303e2340276SBjoern A. Zeeb union rtw89_btc_fbtc_cysta_info *pcysta = NULL; 13048e93258fSBjoern A. Zeeb struct rtw89_btc_prpt *btc_prpt = NULL; 1305e2340276SBjoern A. Zeeb void *rpt_content = NULL, *pfinfo = NULL; 1306e2340276SBjoern A. Zeeb u8 rpt_type = 0; 1307*6d67aabdSBjoern A. Zeeb u16 wl_slot_set = 0, wl_slot_real = 0, val16; 1308*6d67aabdSBjoern A. Zeeb u32 trace_step = 0, rpt_len = 0, diff_t = 0; 1309e2340276SBjoern A. Zeeb u32 cnt_leak_slot, bt_slot_real, bt_slot_set, cnt_rx_imr; 1310*6d67aabdSBjoern A. Zeeb u8 i, val = 0, val1, val2; 13118e93258fSBjoern A. Zeeb 13128e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 13138e93258fSBjoern A. Zeeb "[BTC], %s(): index:%d\n", 13148e93258fSBjoern A. Zeeb __func__, index); 13158e93258fSBjoern A. Zeeb 13168e93258fSBjoern A. Zeeb if (!prptbuf) { 13178e93258fSBjoern A. Zeeb pfwinfo->err[BTFRE_INVALID_INPUT]++; 13188e93258fSBjoern A. Zeeb return 0; 13198e93258fSBjoern A. Zeeb } 13208e93258fSBjoern A. Zeeb 13218e93258fSBjoern A. Zeeb btc_prpt = (struct rtw89_btc_prpt *)&prptbuf[index]; 13228e93258fSBjoern A. Zeeb rpt_type = btc_prpt->type; 13238e93258fSBjoern A. Zeeb rpt_len = le16_to_cpu(btc_prpt->len); 13248e93258fSBjoern A. Zeeb rpt_content = btc_prpt->content; 13258e93258fSBjoern A. Zeeb 13268e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 13278e93258fSBjoern A. Zeeb "[BTC], %s(): rpt_type:%d\n", 13288e93258fSBjoern A. Zeeb __func__, rpt_type); 13298e93258fSBjoern A. Zeeb 1330*6d67aabdSBjoern A. Zeeb rtw89_btc_fw_rpt_evnt_ver(rtwdev, &rpt_type); 1331*6d67aabdSBjoern A. Zeeb 13328e93258fSBjoern A. Zeeb switch (rpt_type) { 13338e93258fSBjoern A. Zeeb case BTC_RPT_TYPE_CTRL: 13348e93258fSBjoern A. Zeeb pcinfo = &pfwinfo->rpt_ctrl.cinfo; 1335e2340276SBjoern A. Zeeb prpt = &pfwinfo->rpt_ctrl.finfo; 1336e2340276SBjoern A. Zeeb if (ver->fcxbtcrpt == 1) { 1337e2340276SBjoern A. Zeeb pfinfo = &pfwinfo->rpt_ctrl.finfo.v1; 1338e2340276SBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v1); 1339e2340276SBjoern A. Zeeb } else if (ver->fcxbtcrpt == 4) { 1340e2340276SBjoern A. Zeeb pfinfo = &pfwinfo->rpt_ctrl.finfo.v4; 1341e2340276SBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v4); 1342e2340276SBjoern A. Zeeb } else if (ver->fcxbtcrpt == 5) { 1343e2340276SBjoern A. Zeeb pfinfo = &pfwinfo->rpt_ctrl.finfo.v5; 1344e2340276SBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v5); 1345e2340276SBjoern A. Zeeb } else if (ver->fcxbtcrpt == 105) { 1346e2340276SBjoern A. Zeeb pfinfo = &pfwinfo->rpt_ctrl.finfo.v105; 1347e2340276SBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v105); 1348e2340276SBjoern A. Zeeb pcinfo->req_fver = 5; 1349e2340276SBjoern A. Zeeb break; 1350*6d67aabdSBjoern A. Zeeb } else if (ver->fcxbtcrpt == 8) { 1351*6d67aabdSBjoern A. Zeeb pfinfo = &pfwinfo->rpt_ctrl.finfo.v8; 1352*6d67aabdSBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v8); 1353*6d67aabdSBjoern A. Zeeb break; 13548e93258fSBjoern A. Zeeb } else { 1355e2340276SBjoern A. Zeeb goto err; 13568e93258fSBjoern A. Zeeb } 1357e2340276SBjoern A. Zeeb pcinfo->req_fver = ver->fcxbtcrpt; 13588e93258fSBjoern A. Zeeb break; 13598e93258fSBjoern A. Zeeb case BTC_RPT_TYPE_TDMA: 13608e93258fSBjoern A. Zeeb pcinfo = &pfwinfo->rpt_fbtc_tdma.cinfo; 1361e2340276SBjoern A. Zeeb if (ver->fcxtdma == 1) { 1362e2340276SBjoern A. Zeeb pfinfo = &pfwinfo->rpt_fbtc_tdma.finfo.v1; 1363e2340276SBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_tdma.finfo.v1); 1364*6d67aabdSBjoern A. Zeeb } else if (ver->fcxtdma == 3 || ver->fcxtdma == 7) { 1365e2340276SBjoern A. Zeeb pfinfo = &pfwinfo->rpt_fbtc_tdma.finfo.v3; 1366e2340276SBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_tdma.finfo.v3); 13678e93258fSBjoern A. Zeeb } else { 1368e2340276SBjoern A. Zeeb goto err; 13698e93258fSBjoern A. Zeeb } 1370e2340276SBjoern A. Zeeb pcinfo->req_fver = ver->fcxtdma; 13718e93258fSBjoern A. Zeeb break; 13728e93258fSBjoern A. Zeeb case BTC_RPT_TYPE_SLOT: 13738e93258fSBjoern A. Zeeb pcinfo = &pfwinfo->rpt_fbtc_slots.cinfo; 1374*6d67aabdSBjoern A. Zeeb if (ver->fcxslots == 1) { 1375*6d67aabdSBjoern A. Zeeb pfinfo = &pfwinfo->rpt_fbtc_slots.finfo.v1; 1376*6d67aabdSBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_slots.finfo.v1); 1377*6d67aabdSBjoern A. Zeeb } else if (ver->fcxslots == 7) { 1378*6d67aabdSBjoern A. Zeeb pfinfo = &pfwinfo->rpt_fbtc_slots.finfo.v7; 1379*6d67aabdSBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_slots.finfo.v7); 1380*6d67aabdSBjoern A. Zeeb } else { 1381*6d67aabdSBjoern A. Zeeb goto err; 1382*6d67aabdSBjoern A. Zeeb } 1383e2340276SBjoern A. Zeeb pcinfo->req_fver = ver->fcxslots; 13848e93258fSBjoern A. Zeeb break; 13858e93258fSBjoern A. Zeeb case BTC_RPT_TYPE_CYSTA: 13868e93258fSBjoern A. Zeeb pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; 1387e2340276SBjoern A. Zeeb pcysta = &pfwinfo->rpt_fbtc_cysta.finfo; 1388e2340276SBjoern A. Zeeb if (ver->fcxcysta == 2) { 1389e2340276SBjoern A. Zeeb pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo.v2; 1390e2340276SBjoern A. Zeeb pcysta->v2 = pfwinfo->rpt_fbtc_cysta.finfo.v2; 1391e2340276SBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo.v2); 1392e2340276SBjoern A. Zeeb } else if (ver->fcxcysta == 3) { 1393e2340276SBjoern A. Zeeb pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo.v3; 1394e2340276SBjoern A. Zeeb pcysta->v3 = pfwinfo->rpt_fbtc_cysta.finfo.v3; 1395e2340276SBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo.v3); 1396e2340276SBjoern A. Zeeb } else if (ver->fcxcysta == 4) { 1397e2340276SBjoern A. Zeeb pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo.v4; 1398e2340276SBjoern A. Zeeb pcysta->v4 = pfwinfo->rpt_fbtc_cysta.finfo.v4; 1399e2340276SBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo.v4); 1400e2340276SBjoern A. Zeeb } else if (ver->fcxcysta == 5) { 1401e2340276SBjoern A. Zeeb pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo.v5; 1402e2340276SBjoern A. Zeeb pcysta->v5 = pfwinfo->rpt_fbtc_cysta.finfo.v5; 1403e2340276SBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo.v5); 1404*6d67aabdSBjoern A. Zeeb } else if (ver->fcxcysta == 7) { 1405*6d67aabdSBjoern A. Zeeb pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo.v7; 1406*6d67aabdSBjoern A. Zeeb pcysta->v7 = pfwinfo->rpt_fbtc_cysta.finfo.v7; 1407*6d67aabdSBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo.v7); 14088e93258fSBjoern A. Zeeb } else { 1409e2340276SBjoern A. Zeeb goto err; 14108e93258fSBjoern A. Zeeb } 1411e2340276SBjoern A. Zeeb pcinfo->req_fver = ver->fcxcysta; 14128e93258fSBjoern A. Zeeb break; 14138e93258fSBjoern A. Zeeb case BTC_RPT_TYPE_STEP: 14148e93258fSBjoern A. Zeeb pcinfo = &pfwinfo->rpt_fbtc_step.cinfo; 1415*6d67aabdSBjoern A. Zeeb if (ver->fcxctrl != 7) 1416*6d67aabdSBjoern A. Zeeb trace_step = btc->ctrl.ctrl.trace_step; 1417*6d67aabdSBjoern A. Zeeb 1418e2340276SBjoern A. Zeeb if (ver->fcxstep == 2) { 1419e2340276SBjoern A. Zeeb pfinfo = &pfwinfo->rpt_fbtc_step.finfo.v2; 1420e2340276SBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_step.finfo.v2.step[0]) * 1421e2340276SBjoern A. Zeeb trace_step + 1422e2340276SBjoern A. Zeeb offsetof(struct rtw89_btc_fbtc_steps_v2, step); 1423e2340276SBjoern A. Zeeb } else if (ver->fcxstep == 3) { 1424e2340276SBjoern A. Zeeb pfinfo = &pfwinfo->rpt_fbtc_step.finfo.v3; 1425e2340276SBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_step.finfo.v3.step[0]) * 1426e2340276SBjoern A. Zeeb trace_step + 1427e2340276SBjoern A. Zeeb offsetof(struct rtw89_btc_fbtc_steps_v3, step); 1428e2340276SBjoern A. Zeeb } else { 1429e2340276SBjoern A. Zeeb goto err; 1430e2340276SBjoern A. Zeeb } 1431e2340276SBjoern A. Zeeb pcinfo->req_fver = ver->fcxstep; 14328e93258fSBjoern A. Zeeb break; 14338e93258fSBjoern A. Zeeb case BTC_RPT_TYPE_NULLSTA: 14348e93258fSBjoern A. Zeeb pcinfo = &pfwinfo->rpt_fbtc_nullsta.cinfo; 1435e2340276SBjoern A. Zeeb if (ver->fcxnullsta == 1) { 1436e2340276SBjoern A. Zeeb pfinfo = &pfwinfo->rpt_fbtc_nullsta.finfo.v1; 1437e2340276SBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_nullsta.finfo.v1); 1438e2340276SBjoern A. Zeeb } else if (ver->fcxnullsta == 2) { 1439e2340276SBjoern A. Zeeb pfinfo = &pfwinfo->rpt_fbtc_nullsta.finfo.v2; 1440e2340276SBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_nullsta.finfo.v2); 1441*6d67aabdSBjoern A. Zeeb } else if (ver->fcxnullsta == 7) { 1442*6d67aabdSBjoern A. Zeeb pfinfo = &pfwinfo->rpt_fbtc_nullsta.finfo.v7; 1443*6d67aabdSBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_nullsta.finfo.v7); 1444e2340276SBjoern A. Zeeb } else { 1445e2340276SBjoern A. Zeeb goto err; 1446e2340276SBjoern A. Zeeb } 1447e2340276SBjoern A. Zeeb pcinfo->req_fver = ver->fcxnullsta; 14488e93258fSBjoern A. Zeeb break; 14498e93258fSBjoern A. Zeeb case BTC_RPT_TYPE_MREG: 14508e93258fSBjoern A. Zeeb pcinfo = &pfwinfo->rpt_fbtc_mregval.cinfo; 1451e2340276SBjoern A. Zeeb if (ver->fcxmreg == 1) { 1452e2340276SBjoern A. Zeeb pfinfo = &pfwinfo->rpt_fbtc_mregval.finfo.v1; 1453e2340276SBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_mregval.finfo.v1); 1454e2340276SBjoern A. Zeeb } else if (ver->fcxmreg == 2) { 1455e2340276SBjoern A. Zeeb pfinfo = &pfwinfo->rpt_fbtc_mregval.finfo.v2; 1456e2340276SBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_mregval.finfo.v2); 1457*6d67aabdSBjoern A. Zeeb } else if (ver->fcxmreg == 7) { 1458*6d67aabdSBjoern A. Zeeb pfinfo = &pfwinfo->rpt_fbtc_mregval.finfo.v7; 1459*6d67aabdSBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_mregval.finfo.v7); 1460e2340276SBjoern A. Zeeb } else { 1461e2340276SBjoern A. Zeeb goto err; 1462e2340276SBjoern A. Zeeb } 1463e2340276SBjoern A. Zeeb pcinfo->req_fver = ver->fcxmreg; 14648e93258fSBjoern A. Zeeb break; 14658e93258fSBjoern A. Zeeb case BTC_RPT_TYPE_GPIO_DBG: 14668e93258fSBjoern A. Zeeb pcinfo = &pfwinfo->rpt_fbtc_gpio_dbg.cinfo; 1467*6d67aabdSBjoern A. Zeeb if (ver->fcxgpiodbg == 7) { 1468*6d67aabdSBjoern A. Zeeb pfinfo = &pfwinfo->rpt_fbtc_gpio_dbg.finfo.v7; 1469*6d67aabdSBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_gpio_dbg.finfo.v7); 1470*6d67aabdSBjoern A. Zeeb } else { 1471*6d67aabdSBjoern A. Zeeb pfinfo = &pfwinfo->rpt_fbtc_gpio_dbg.finfo.v1; 1472*6d67aabdSBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_gpio_dbg.finfo.v1); 1473*6d67aabdSBjoern A. Zeeb } 1474e2340276SBjoern A. Zeeb pcinfo->req_fver = ver->fcxgpiodbg; 14758e93258fSBjoern A. Zeeb break; 14768e93258fSBjoern A. Zeeb case BTC_RPT_TYPE_BT_VER: 14778e93258fSBjoern A. Zeeb pcinfo = &pfwinfo->rpt_fbtc_btver.cinfo; 1478*6d67aabdSBjoern A. Zeeb if (ver->fcxbtver == 1) { 1479*6d67aabdSBjoern A. Zeeb pfinfo = &pfwinfo->rpt_fbtc_btver.finfo.v1; 1480*6d67aabdSBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btver.finfo.v1); 1481*6d67aabdSBjoern A. Zeeb } else if (ver->fcxbtver == 7) { 1482*6d67aabdSBjoern A. Zeeb pfinfo = &pfwinfo->rpt_fbtc_btver.finfo.v7; 1483*6d67aabdSBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btver.finfo.v7); 1484*6d67aabdSBjoern A. Zeeb } 1485e2340276SBjoern A. Zeeb pcinfo->req_fver = ver->fcxbtver; 14868e93258fSBjoern A. Zeeb break; 14878e93258fSBjoern A. Zeeb case BTC_RPT_TYPE_BT_SCAN: 14888e93258fSBjoern A. Zeeb pcinfo = &pfwinfo->rpt_fbtc_btscan.cinfo; 1489e2340276SBjoern A. Zeeb if (ver->fcxbtscan == 1) { 1490e2340276SBjoern A. Zeeb pfinfo = &pfwinfo->rpt_fbtc_btscan.finfo.v1; 1491e2340276SBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btscan.finfo.v1); 1492e2340276SBjoern A. Zeeb } else if (ver->fcxbtscan == 2) { 1493e2340276SBjoern A. Zeeb pfinfo = &pfwinfo->rpt_fbtc_btscan.finfo.v2; 1494e2340276SBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btscan.finfo.v2); 1495*6d67aabdSBjoern A. Zeeb } else if (ver->fcxbtscan == 7) { 1496*6d67aabdSBjoern A. Zeeb pfinfo = &pfwinfo->rpt_fbtc_btscan.finfo.v7; 1497*6d67aabdSBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btscan.finfo.v7); 1498*6d67aabdSBjoern A. Zeeb } else { 1499*6d67aabdSBjoern A. Zeeb goto err; 1500e2340276SBjoern A. Zeeb } 1501e2340276SBjoern A. Zeeb pcinfo->req_fver = ver->fcxbtscan; 15028e93258fSBjoern A. Zeeb break; 15038e93258fSBjoern A. Zeeb case BTC_RPT_TYPE_BT_AFH: 15048e93258fSBjoern A. Zeeb pcinfo = &pfwinfo->rpt_fbtc_btafh.cinfo; 1505e2340276SBjoern A. Zeeb if (ver->fcxbtafh == 1) { 1506e2340276SBjoern A. Zeeb pfinfo = &pfwinfo->rpt_fbtc_btafh.finfo.v1; 1507e2340276SBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btafh.finfo.v1); 1508e2340276SBjoern A. Zeeb } else if (ver->fcxbtafh == 2) { 1509e2340276SBjoern A. Zeeb pfinfo = &pfwinfo->rpt_fbtc_btafh.finfo.v2; 1510e2340276SBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btafh.finfo.v2); 1511e2340276SBjoern A. Zeeb } else { 1512e2340276SBjoern A. Zeeb goto err; 1513e2340276SBjoern A. Zeeb } 1514e2340276SBjoern A. Zeeb pcinfo->req_fver = ver->fcxbtafh; 15158e93258fSBjoern A. Zeeb break; 15168e93258fSBjoern A. Zeeb case BTC_RPT_TYPE_BT_DEVICE: 15178e93258fSBjoern A. Zeeb pcinfo = &pfwinfo->rpt_fbtc_btdev.cinfo; 1518e2340276SBjoern A. Zeeb pfinfo = &pfwinfo->rpt_fbtc_btdev.finfo; 15198e93258fSBjoern A. Zeeb pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btdev.finfo); 1520e2340276SBjoern A. Zeeb pcinfo->req_fver = ver->fcxbtdevinfo; 15218e93258fSBjoern A. Zeeb break; 15228e93258fSBjoern A. Zeeb default: 15238e93258fSBjoern A. Zeeb pfwinfo->err[BTFRE_UNDEF_TYPE]++; 15248e93258fSBjoern A. Zeeb return 0; 15258e93258fSBjoern A. Zeeb } 15268e93258fSBjoern A. Zeeb 1527e2340276SBjoern A. Zeeb pcinfo->rx_len = rpt_len; 1528e2340276SBjoern A. Zeeb pcinfo->rx_cnt++; 1529e2340276SBjoern A. Zeeb 15308e93258fSBjoern A. Zeeb if (rpt_len != pcinfo->req_len) { 15318e93258fSBjoern A. Zeeb if (rpt_type < BTC_RPT_TYPE_MAX) 15328e93258fSBjoern A. Zeeb pfwinfo->len_mismch |= (0x1 << rpt_type); 15338e93258fSBjoern A. Zeeb else 15348e93258fSBjoern A. Zeeb pfwinfo->len_mismch |= BIT(31); 15358e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 15368e93258fSBjoern A. Zeeb "[BTC], %s(): %d rpt_len:%d!=req_len:%d\n", 15378e93258fSBjoern A. Zeeb __func__, rpt_type, rpt_len, pcinfo->req_len); 15388e93258fSBjoern A. Zeeb 15398e93258fSBjoern A. Zeeb pcinfo->valid = 0; 15408e93258fSBjoern A. Zeeb return 0; 15418e93258fSBjoern A. Zeeb } else if (!pfinfo || !rpt_content || !pcinfo->req_len) { 15428e93258fSBjoern A. Zeeb pfwinfo->err[BTFRE_EXCEPTION]++; 15438e93258fSBjoern A. Zeeb pcinfo->valid = 0; 15448e93258fSBjoern A. Zeeb return 0; 15458e93258fSBjoern A. Zeeb } 15468e93258fSBjoern A. Zeeb 15478e93258fSBjoern A. Zeeb memcpy(pfinfo, rpt_content, pcinfo->req_len); 15488e93258fSBjoern A. Zeeb pcinfo->valid = 1; 15498e93258fSBjoern A. Zeeb 1550e2340276SBjoern A. Zeeb switch (rpt_type) { 1551e2340276SBjoern A. Zeeb case BTC_RPT_TYPE_CTRL: 1552e2340276SBjoern A. Zeeb if (ver->fcxbtcrpt == 1) { 1553e2340276SBjoern A. Zeeb prpt->v1 = pfwinfo->rpt_ctrl.finfo.v1; 1554e2340276SBjoern A. Zeeb btc->fwinfo.rpt_en_map = prpt->v1.rpt_enable; 1555e2340276SBjoern A. Zeeb wl->ver_info.fw_coex = prpt->v1.wl_fw_coex_ver; 1556e2340276SBjoern A. Zeeb wl->ver_info.fw = prpt->v1.wl_fw_ver; 1557e2340276SBjoern A. Zeeb dm->wl_fw_cx_offload = !!prpt->v1.wl_fw_cx_offload; 1558e2340276SBjoern A. Zeeb 1559e2340276SBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_RPT_HANG, 1560e2340276SBjoern A. Zeeb pfwinfo->event[BTF_EVNT_RPT]); 1561e2340276SBjoern A. Zeeb 1562e2340276SBjoern A. Zeeb /* To avoid I/O if WL LPS or power-off */ 1563e2340276SBjoern A. Zeeb if (wl->status.map.lps != BTC_LPS_RF_OFF && 1564e2340276SBjoern A. Zeeb !wl->status.map.rf_off) { 1565e2340276SBjoern A. Zeeb rtwdev->chip->ops->btc_update_bt_cnt(rtwdev); 1566e2340276SBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0); 1567e2340276SBjoern A. Zeeb 1568e2340276SBjoern A. Zeeb btc->cx.cnt_bt[BTC_BCNT_POLUT] = 1569e2340276SBjoern A. Zeeb rtw89_mac_get_plt_cnt(rtwdev, 1570e2340276SBjoern A. Zeeb RTW89_MAC_0); 1571e2340276SBjoern A. Zeeb } 1572e2340276SBjoern A. Zeeb } else if (ver->fcxbtcrpt == 4) { 1573e2340276SBjoern A. Zeeb prpt->v4 = pfwinfo->rpt_ctrl.finfo.v4; 1574e2340276SBjoern A. Zeeb btc->fwinfo.rpt_en_map = le32_to_cpu(prpt->v4.rpt_info.en); 1575e2340276SBjoern A. Zeeb wl->ver_info.fw_coex = le32_to_cpu(prpt->v4.wl_fw_info.cx_ver); 1576e2340276SBjoern A. Zeeb wl->ver_info.fw = le32_to_cpu(prpt->v4.wl_fw_info.fw_ver); 1577e2340276SBjoern A. Zeeb dm->wl_fw_cx_offload = !!le32_to_cpu(prpt->v4.wl_fw_info.cx_offload); 1578e2340276SBjoern A. Zeeb 1579e2340276SBjoern A. Zeeb for (i = RTW89_PHY_0; i < RTW89_PHY_MAX; i++) 1580e2340276SBjoern A. Zeeb memcpy(&dm->gnt.band[i], &prpt->v4.gnt_val[i], 1581e2340276SBjoern A. Zeeb sizeof(dm->gnt.band[i])); 1582e2340276SBjoern A. Zeeb 1583e2340276SBjoern A. Zeeb btc->cx.cnt_bt[BTC_BCNT_HIPRI_TX] = 1584e2340276SBjoern A. Zeeb le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_HI_TX]); 1585e2340276SBjoern A. Zeeb btc->cx.cnt_bt[BTC_BCNT_HIPRI_RX] = 1586e2340276SBjoern A. Zeeb le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_HI_RX]); 1587e2340276SBjoern A. Zeeb btc->cx.cnt_bt[BTC_BCNT_LOPRI_TX] = 1588e2340276SBjoern A. Zeeb le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_LO_TX]); 1589e2340276SBjoern A. Zeeb btc->cx.cnt_bt[BTC_BCNT_LOPRI_RX] = 1590e2340276SBjoern A. Zeeb le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_LO_RX]); 1591e2340276SBjoern A. Zeeb btc->cx.cnt_bt[BTC_BCNT_POLUT] = 1592e2340276SBjoern A. Zeeb le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_POLLUTED]); 1593e2340276SBjoern A. Zeeb 1594e2340276SBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0); 1595e2340276SBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_RPT_HANG, 1596e2340276SBjoern A. Zeeb pfwinfo->event[BTF_EVNT_RPT]); 1597e2340276SBjoern A. Zeeb 1598e2340276SBjoern A. Zeeb if (le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_RFK_TIMEOUT]) > 0) 1599e2340276SBjoern A. Zeeb bt->rfk_info.map.timeout = 1; 1600e2340276SBjoern A. Zeeb else 1601e2340276SBjoern A. Zeeb bt->rfk_info.map.timeout = 0; 1602e2340276SBjoern A. Zeeb 1603e2340276SBjoern A. Zeeb dm->error.map.bt_rfk_timeout = bt->rfk_info.map.timeout; 1604e2340276SBjoern A. Zeeb } else if (ver->fcxbtcrpt == 5) { 1605e2340276SBjoern A. Zeeb prpt->v5 = pfwinfo->rpt_ctrl.finfo.v5; 1606e2340276SBjoern A. Zeeb pfwinfo->rpt_en_map = le32_to_cpu(prpt->v5.rpt_info.en); 1607e2340276SBjoern A. Zeeb wl->ver_info.fw_coex = le32_to_cpu(prpt->v5.rpt_info.cx_ver); 1608e2340276SBjoern A. Zeeb wl->ver_info.fw = le32_to_cpu(prpt->v5.rpt_info.fw_ver); 1609e2340276SBjoern A. Zeeb dm->wl_fw_cx_offload = 0; 1610e2340276SBjoern A. Zeeb 1611e2340276SBjoern A. Zeeb for (i = RTW89_PHY_0; i < RTW89_PHY_MAX; i++) 1612e2340276SBjoern A. Zeeb memcpy(&dm->gnt.band[i], &prpt->v5.gnt_val[i][0], 1613e2340276SBjoern A. Zeeb sizeof(dm->gnt.band[i])); 1614e2340276SBjoern A. Zeeb 1615e2340276SBjoern A. Zeeb btc->cx.cnt_bt[BTC_BCNT_HIPRI_TX] = 1616e2340276SBjoern A. Zeeb le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_HI_TX]); 1617e2340276SBjoern A. Zeeb btc->cx.cnt_bt[BTC_BCNT_HIPRI_RX] = 1618e2340276SBjoern A. Zeeb le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_HI_RX]); 1619e2340276SBjoern A. Zeeb btc->cx.cnt_bt[BTC_BCNT_LOPRI_TX] = 1620e2340276SBjoern A. Zeeb le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_LO_TX]); 1621e2340276SBjoern A. Zeeb btc->cx.cnt_bt[BTC_BCNT_LOPRI_RX] = 1622e2340276SBjoern A. Zeeb le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_LO_RX]); 1623e2340276SBjoern A. Zeeb btc->cx.cnt_bt[BTC_BCNT_POLUT] = 1624e2340276SBjoern A. Zeeb le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_POLLUTED]); 1625e2340276SBjoern A. Zeeb 1626e2340276SBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0); 1627e2340276SBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_RPT_HANG, 1628e2340276SBjoern A. Zeeb pfwinfo->event[BTF_EVNT_RPT]); 1629e2340276SBjoern A. Zeeb 1630e2340276SBjoern A. Zeeb dm->error.map.bt_rfk_timeout = bt->rfk_info.map.timeout; 1631e2340276SBjoern A. Zeeb } else if (ver->fcxbtcrpt == 105) { 1632e2340276SBjoern A. Zeeb prpt->v105 = pfwinfo->rpt_ctrl.finfo.v105; 1633e2340276SBjoern A. Zeeb pfwinfo->rpt_en_map = le32_to_cpu(prpt->v105.rpt_info.en); 1634e2340276SBjoern A. Zeeb wl->ver_info.fw_coex = le32_to_cpu(prpt->v105.rpt_info.cx_ver); 1635e2340276SBjoern A. Zeeb wl->ver_info.fw = le32_to_cpu(prpt->v105.rpt_info.fw_ver); 1636e2340276SBjoern A. Zeeb dm->wl_fw_cx_offload = 0; 1637e2340276SBjoern A. Zeeb 1638e2340276SBjoern A. Zeeb for (i = RTW89_PHY_0; i < RTW89_PHY_MAX; i++) 1639e2340276SBjoern A. Zeeb memcpy(&dm->gnt.band[i], &prpt->v105.gnt_val[i][0], 1640e2340276SBjoern A. Zeeb sizeof(dm->gnt.band[i])); 1641e2340276SBjoern A. Zeeb 1642e2340276SBjoern A. Zeeb btc->cx.cnt_bt[BTC_BCNT_HIPRI_TX] = 1643e2340276SBjoern A. Zeeb le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_HI_TX_V105]); 1644e2340276SBjoern A. Zeeb btc->cx.cnt_bt[BTC_BCNT_HIPRI_RX] = 1645e2340276SBjoern A. Zeeb le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_HI_RX_V105]); 1646e2340276SBjoern A. Zeeb btc->cx.cnt_bt[BTC_BCNT_LOPRI_TX] = 1647e2340276SBjoern A. Zeeb le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_LO_TX_V105]); 1648e2340276SBjoern A. Zeeb btc->cx.cnt_bt[BTC_BCNT_LOPRI_RX] = 1649e2340276SBjoern A. Zeeb le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_LO_RX_V105]); 1650e2340276SBjoern A. Zeeb btc->cx.cnt_bt[BTC_BCNT_POLUT] = 1651e2340276SBjoern A. Zeeb le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_POLLUTED_V105]); 1652e2340276SBjoern A. Zeeb 1653e2340276SBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0); 1654e2340276SBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_RPT_HANG, 1655e2340276SBjoern A. Zeeb pfwinfo->event[BTF_EVNT_RPT]); 1656e2340276SBjoern A. Zeeb 1657e2340276SBjoern A. Zeeb dm->error.map.bt_rfk_timeout = bt->rfk_info.map.timeout; 1658*6d67aabdSBjoern A. Zeeb } else if (ver->fcxbtcrpt == 8) { 1659*6d67aabdSBjoern A. Zeeb prpt->v8 = pfwinfo->rpt_ctrl.finfo.v8; 1660*6d67aabdSBjoern A. Zeeb pfwinfo->rpt_en_map = le32_to_cpu(prpt->v8.rpt_info.en); 1661*6d67aabdSBjoern A. Zeeb wl->ver_info.fw_coex = le32_to_cpu(prpt->v8.rpt_info.cx_ver); 1662*6d67aabdSBjoern A. Zeeb wl->ver_info.fw = le32_to_cpu(prpt->v8.rpt_info.fw_ver); 1663*6d67aabdSBjoern A. Zeeb 1664*6d67aabdSBjoern A. Zeeb for (i = RTW89_PHY_0; i < RTW89_PHY_MAX; i++) 1665*6d67aabdSBjoern A. Zeeb memcpy(&dm->gnt.band[i], &prpt->v8.gnt_val[i][0], 1666*6d67aabdSBjoern A. Zeeb sizeof(dm->gnt.band[i])); 1667*6d67aabdSBjoern A. Zeeb 1668*6d67aabdSBjoern A. Zeeb btc->cx.cnt_bt[BTC_BCNT_HIPRI_TX] = 1669*6d67aabdSBjoern A. Zeeb le16_to_cpu(prpt->v8.bt_cnt[BTC_BCNT_HI_TX_V105]); 1670*6d67aabdSBjoern A. Zeeb btc->cx.cnt_bt[BTC_BCNT_HIPRI_RX] = 1671*6d67aabdSBjoern A. Zeeb le16_to_cpu(prpt->v8.bt_cnt[BTC_BCNT_HI_RX_V105]); 1672*6d67aabdSBjoern A. Zeeb btc->cx.cnt_bt[BTC_BCNT_LOPRI_TX] = 1673*6d67aabdSBjoern A. Zeeb le16_to_cpu(prpt->v8.bt_cnt[BTC_BCNT_LO_TX_V105]); 1674*6d67aabdSBjoern A. Zeeb btc->cx.cnt_bt[BTC_BCNT_LOPRI_RX] = 1675*6d67aabdSBjoern A. Zeeb le16_to_cpu(prpt->v8.bt_cnt[BTC_BCNT_LO_RX_V105]); 1676*6d67aabdSBjoern A. Zeeb 1677*6d67aabdSBjoern A. Zeeb val1 = le16_to_cpu(prpt->v8.bt_cnt[BTC_BCNT_POLLUTED_V105]); 1678*6d67aabdSBjoern A. Zeeb if (val1 > btc->cx.cnt_bt[BTC_BCNT_POLUT_NOW]) 1679*6d67aabdSBjoern A. Zeeb val1 -= btc->cx.cnt_bt[BTC_BCNT_POLUT_NOW]; /* diff */ 1680*6d67aabdSBjoern A. Zeeb 1681*6d67aabdSBjoern A. Zeeb btc->cx.cnt_bt[BTC_BCNT_POLUT_DIFF] = val1; 1682*6d67aabdSBjoern A. Zeeb btc->cx.cnt_bt[BTC_BCNT_POLUT_NOW] = 1683*6d67aabdSBjoern A. Zeeb le16_to_cpu(prpt->v8.bt_cnt[BTC_BCNT_POLLUTED_V105]); 1684*6d67aabdSBjoern A. Zeeb 1685*6d67aabdSBjoern A. Zeeb val1 = pfwinfo->event[BTF_EVNT_RPT]; 1686*6d67aabdSBjoern A. Zeeb if (((prpt->v8.rpt_len_max_h << 8) + 1687*6d67aabdSBjoern A. Zeeb prpt->v8.rpt_len_max_l) != ver->info_buf) 1688*6d67aabdSBjoern A. Zeeb dm->error.map.h2c_c2h_buffer_mismatch = true; 1689*6d67aabdSBjoern A. Zeeb else 1690*6d67aabdSBjoern A. Zeeb dm->error.map.h2c_c2h_buffer_mismatch = false; 1691*6d67aabdSBjoern A. Zeeb 1692*6d67aabdSBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0); 1693*6d67aabdSBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_RPT_HANG, val1); 1694*6d67aabdSBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_WL_FW_VER_MATCH, 0); 1695*6d67aabdSBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_BTTX_HANG, 0); 1696e2340276SBjoern A. Zeeb } else { 1697e2340276SBjoern A. Zeeb goto err; 1698e2340276SBjoern A. Zeeb } 1699e2340276SBjoern A. Zeeb break; 1700e2340276SBjoern A. Zeeb case BTC_RPT_TYPE_TDMA: 17018e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 17028e93258fSBjoern A. Zeeb "[BTC], %s(): check %d %zu\n", __func__, 1703e2340276SBjoern A. Zeeb BTC_DCNT_TDMA_NONSYNC, 1704e2340276SBjoern A. Zeeb sizeof(dm->tdma_now)); 1705e2340276SBjoern A. Zeeb if (ver->fcxtdma == 1) 17068e93258fSBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_TDMA_NONSYNC, 17078e93258fSBjoern A. Zeeb memcmp(&dm->tdma_now, 1708e2340276SBjoern A. Zeeb &pfwinfo->rpt_fbtc_tdma.finfo.v1, 17098e93258fSBjoern A. Zeeb sizeof(dm->tdma_now))); 1710*6d67aabdSBjoern A. Zeeb else if (ver->fcxtdma == 3 || ver->fcxtdma == 7) 17118e93258fSBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_TDMA_NONSYNC, 17128e93258fSBjoern A. Zeeb memcmp(&dm->tdma_now, 1713e2340276SBjoern A. Zeeb &pfwinfo->rpt_fbtc_tdma.finfo.v3.tdma, 17148e93258fSBjoern A. Zeeb sizeof(dm->tdma_now))); 1715e2340276SBjoern A. Zeeb else 1716e2340276SBjoern A. Zeeb goto err; 1717e2340276SBjoern A. Zeeb break; 1718e2340276SBjoern A. Zeeb case BTC_RPT_TYPE_SLOT: 1719*6d67aabdSBjoern A. Zeeb if (ver->fcxslots == 7) { 17208e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 17218e93258fSBjoern A. Zeeb "[BTC], %s(): check %d %zu\n", 17228e93258fSBjoern A. Zeeb __func__, BTC_DCNT_SLOT_NONSYNC, 1723*6d67aabdSBjoern A. Zeeb sizeof(dm->slot_now.v7)); 17248e93258fSBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_SLOT_NONSYNC, 1725*6d67aabdSBjoern A. Zeeb memcmp(dm->slot_now.v7, 1726*6d67aabdSBjoern A. Zeeb pfwinfo->rpt_fbtc_slots.finfo.v7.slot, 1727*6d67aabdSBjoern A. Zeeb sizeof(dm->slot_now.v7))); 1728*6d67aabdSBjoern A. Zeeb } else if (ver->fcxslots == 1) { 1729*6d67aabdSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 1730*6d67aabdSBjoern A. Zeeb "[BTC], %s(): check %d %zu\n", 1731*6d67aabdSBjoern A. Zeeb __func__, BTC_DCNT_SLOT_NONSYNC, 1732*6d67aabdSBjoern A. Zeeb sizeof(dm->slot_now.v1)); 1733*6d67aabdSBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_SLOT_NONSYNC, 1734*6d67aabdSBjoern A. Zeeb memcmp(dm->slot_now.v1, 1735*6d67aabdSBjoern A. Zeeb pfwinfo->rpt_fbtc_slots.finfo.v1.slot, 1736*6d67aabdSBjoern A. Zeeb sizeof(dm->slot_now.v1))); 1737*6d67aabdSBjoern A. Zeeb } 1738e2340276SBjoern A. Zeeb break; 1739e2340276SBjoern A. Zeeb case BTC_RPT_TYPE_CYSTA: 1740e2340276SBjoern A. Zeeb if (ver->fcxcysta == 2) { 1741e2340276SBjoern A. Zeeb if (le16_to_cpu(pcysta->v2.cycles) < BTC_CYSTA_CHK_PERIOD) 1742e2340276SBjoern A. Zeeb break; 17438e93258fSBjoern A. Zeeb /* Check Leak-AP */ 1744e2340276SBjoern A. Zeeb if (le32_to_cpu(pcysta->v2.slot_cnt[CXST_LK]) != 0 && 1745e2340276SBjoern A. Zeeb le32_to_cpu(pcysta->v2.leakrx_cnt) != 0 && dm->tdma_now.rxflctrl) { 1746e2340276SBjoern A. Zeeb if (le32_to_cpu(pcysta->v2.slot_cnt[CXST_LK]) < 1747e2340276SBjoern A. Zeeb BTC_LEAK_AP_TH * le32_to_cpu(pcysta->v2.leakrx_cnt)) 17488e93258fSBjoern A. Zeeb dm->leak_ap = 1; 17498e93258fSBjoern A. Zeeb } 17508e93258fSBjoern A. Zeeb 17518e93258fSBjoern A. Zeeb /* Check diff time between WL slot and W1/E2G slot */ 17528e93258fSBjoern A. Zeeb if (dm->tdma_now.type == CXTDMA_OFF && 1753*6d67aabdSBjoern A. Zeeb dm->tdma_now.ext_ctrl == CXECTL_EXT) { 1754*6d67aabdSBjoern A. Zeeb if (ver->fcxslots == 1) 1755*6d67aabdSBjoern A. Zeeb wl_slot_set = le16_to_cpu(dm->slot_now.v1[CXST_E2G].dur); 1756*6d67aabdSBjoern A. Zeeb else if (ver->fcxslots == 7) 1757*6d67aabdSBjoern A. Zeeb wl_slot_set = le16_to_cpu(dm->slot_now.v7[CXST_E2G].dur); 1758*6d67aabdSBjoern A. Zeeb } else { 1759*6d67aabdSBjoern A. Zeeb if (ver->fcxslots == 1) 1760*6d67aabdSBjoern A. Zeeb wl_slot_set = le16_to_cpu(dm->slot_now.v1[CXST_W1].dur); 1761*6d67aabdSBjoern A. Zeeb else if (ver->fcxslots == 7) 1762*6d67aabdSBjoern A. Zeeb wl_slot_set = le16_to_cpu(dm->slot_now.v7[CXST_W1].dur); 1763*6d67aabdSBjoern A. Zeeb } 17648e93258fSBjoern A. Zeeb 1765e2340276SBjoern A. Zeeb if (le16_to_cpu(pcysta->v2.tavg_cycle[CXT_WL]) > wl_slot_set) { 1766e2340276SBjoern A. Zeeb diff_t = le16_to_cpu(pcysta->v2.tavg_cycle[CXT_WL]) - wl_slot_set; 1767e2340276SBjoern A. Zeeb _chk_btc_err(rtwdev, 1768e2340276SBjoern A. Zeeb BTC_DCNT_WL_SLOT_DRIFT, diff_t); 17698e93258fSBjoern A. Zeeb } 17708e93258fSBjoern A. Zeeb 1771e2340276SBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_W1_HANG, 1772e2340276SBjoern A. Zeeb le32_to_cpu(pcysta->v2.slot_cnt[CXST_W1])); 1773e2340276SBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_W1_HANG, 1774e2340276SBjoern A. Zeeb le32_to_cpu(pcysta->v2.slot_cnt[CXST_B1])); 1775e2340276SBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_HANG, 1776e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->v2.cycles)); 1777e2340276SBjoern A. Zeeb } else if (ver->fcxcysta == 3) { 1778e2340276SBjoern A. Zeeb if (le16_to_cpu(pcysta->v3.cycles) < BTC_CYSTA_CHK_PERIOD) 1779e2340276SBjoern A. Zeeb break; 1780e2340276SBjoern A. Zeeb 1781e2340276SBjoern A. Zeeb cnt_leak_slot = le32_to_cpu(pcysta->v3.slot_cnt[CXST_LK]); 1782e2340276SBjoern A. Zeeb cnt_rx_imr = le32_to_cpu(pcysta->v3.leak_slot.cnt_rximr); 1783e2340276SBjoern A. Zeeb 17848e93258fSBjoern A. Zeeb /* Check Leak-AP */ 17858e93258fSBjoern A. Zeeb if (cnt_leak_slot != 0 && cnt_rx_imr != 0 && 17868e93258fSBjoern A. Zeeb dm->tdma_now.rxflctrl) { 17878e93258fSBjoern A. Zeeb if (cnt_leak_slot < BTC_LEAK_AP_TH * cnt_rx_imr) 17888e93258fSBjoern A. Zeeb dm->leak_ap = 1; 17898e93258fSBjoern A. Zeeb } 17908e93258fSBjoern A. Zeeb 17918e93258fSBjoern A. Zeeb /* Check diff time between real WL slot and W1 slot */ 17928e93258fSBjoern A. Zeeb if (dm->tdma_now.type == CXTDMA_OFF) { 1793*6d67aabdSBjoern A. Zeeb if (ver->fcxslots == 1) 1794*6d67aabdSBjoern A. Zeeb wl_slot_set = le16_to_cpu(dm->slot_now.v1[CXST_W1].dur); 1795*6d67aabdSBjoern A. Zeeb else if (ver->fcxslots == 7) 1796*6d67aabdSBjoern A. Zeeb wl_slot_set = le16_to_cpu(dm->slot_now.v7[CXST_W1].dur); 1797e2340276SBjoern A. Zeeb wl_slot_real = le16_to_cpu(pcysta->v3.cycle_time.tavg[CXT_WL]); 17988e93258fSBjoern A. Zeeb if (wl_slot_real > wl_slot_set) { 17998e93258fSBjoern A. Zeeb diff_t = wl_slot_real - wl_slot_set; 18008e93258fSBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_WL_SLOT_DRIFT, diff_t); 18018e93258fSBjoern A. Zeeb } 18028e93258fSBjoern A. Zeeb } 18038e93258fSBjoern A. Zeeb 18048e93258fSBjoern A. Zeeb /* Check diff time between real BT slot and EBT/E5G slot */ 18058e93258fSBjoern A. Zeeb if (dm->tdma_now.type == CXTDMA_OFF && 18068e93258fSBjoern A. Zeeb dm->tdma_now.ext_ctrl == CXECTL_EXT && 18078e93258fSBjoern A. Zeeb btc->bt_req_len != 0) { 1808e2340276SBjoern A. Zeeb bt_slot_real = le16_to_cpu(pcysta->v3.cycle_time.tavg[CXT_BT]); 1809e2340276SBjoern A. Zeeb if (btc->bt_req_len > bt_slot_real) { 1810e2340276SBjoern A. Zeeb diff_t = btc->bt_req_len - bt_slot_real; 1811e2340276SBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_BT_SLOT_DRIFT, diff_t); 1812e2340276SBjoern A. Zeeb } 1813e2340276SBjoern A. Zeeb } 1814e2340276SBjoern A. Zeeb 1815e2340276SBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_W1_HANG, 1816e2340276SBjoern A. Zeeb le32_to_cpu(pcysta->v3.slot_cnt[CXST_W1])); 1817e2340276SBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_B1_HANG, 1818e2340276SBjoern A. Zeeb le32_to_cpu(pcysta->v3.slot_cnt[CXST_B1])); 1819e2340276SBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_HANG, 1820e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->v3.cycles)); 1821e2340276SBjoern A. Zeeb } else if (ver->fcxcysta == 4) { 1822e2340276SBjoern A. Zeeb if (le16_to_cpu(pcysta->v4.cycles) < BTC_CYSTA_CHK_PERIOD) 1823e2340276SBjoern A. Zeeb break; 1824e2340276SBjoern A. Zeeb 1825e2340276SBjoern A. Zeeb cnt_leak_slot = le16_to_cpu(pcysta->v4.slot_cnt[CXST_LK]); 1826e2340276SBjoern A. Zeeb cnt_rx_imr = le32_to_cpu(pcysta->v4.leak_slot.cnt_rximr); 1827e2340276SBjoern A. Zeeb 1828e2340276SBjoern A. Zeeb /* Check Leak-AP */ 1829e2340276SBjoern A. Zeeb if (cnt_leak_slot != 0 && cnt_rx_imr != 0 && 1830e2340276SBjoern A. Zeeb dm->tdma_now.rxflctrl) { 1831e2340276SBjoern A. Zeeb if (cnt_leak_slot < BTC_LEAK_AP_TH * cnt_rx_imr) 1832e2340276SBjoern A. Zeeb dm->leak_ap = 1; 1833e2340276SBjoern A. Zeeb } 1834e2340276SBjoern A. Zeeb 1835e2340276SBjoern A. Zeeb /* Check diff time between real WL slot and W1 slot */ 1836e2340276SBjoern A. Zeeb if (dm->tdma_now.type == CXTDMA_OFF) { 1837*6d67aabdSBjoern A. Zeeb if (ver->fcxslots == 1) 1838*6d67aabdSBjoern A. Zeeb wl_slot_set = le16_to_cpu(dm->slot_now.v1[CXST_W1].dur); 1839*6d67aabdSBjoern A. Zeeb else if (ver->fcxslots == 7) 1840*6d67aabdSBjoern A. Zeeb wl_slot_set = le16_to_cpu(dm->slot_now.v7[CXST_W1].dur); 1841e2340276SBjoern A. Zeeb wl_slot_real = le16_to_cpu(pcysta->v4.cycle_time.tavg[CXT_WL]); 1842e2340276SBjoern A. Zeeb if (wl_slot_real > wl_slot_set) { 1843e2340276SBjoern A. Zeeb diff_t = wl_slot_real - wl_slot_set; 1844e2340276SBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_WL_SLOT_DRIFT, diff_t); 1845e2340276SBjoern A. Zeeb } 1846e2340276SBjoern A. Zeeb } 1847e2340276SBjoern A. Zeeb 1848e2340276SBjoern A. Zeeb /* Check diff time between real BT slot and EBT/E5G slot */ 1849e2340276SBjoern A. Zeeb if (dm->tdma_now.type == CXTDMA_OFF && 1850e2340276SBjoern A. Zeeb dm->tdma_now.ext_ctrl == CXECTL_EXT && 1851e2340276SBjoern A. Zeeb btc->bt_req_len != 0) { 1852e2340276SBjoern A. Zeeb bt_slot_real = le16_to_cpu(pcysta->v4.cycle_time.tavg[CXT_BT]); 18538e93258fSBjoern A. Zeeb 18548e93258fSBjoern A. Zeeb if (btc->bt_req_len > bt_slot_real) { 18558e93258fSBjoern A. Zeeb diff_t = btc->bt_req_len - bt_slot_real; 18568e93258fSBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_BT_SLOT_DRIFT, diff_t); 18578e93258fSBjoern A. Zeeb } 18588e93258fSBjoern A. Zeeb } 18598e93258fSBjoern A. Zeeb 1860e2340276SBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_W1_HANG, 1861e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->v4.slot_cnt[CXST_W1])); 1862e2340276SBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_B1_HANG, 1863e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->v4.slot_cnt[CXST_B1])); 1864e2340276SBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_HANG, 1865e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->v4.cycles)); 1866e2340276SBjoern A. Zeeb } else if (ver->fcxcysta == 5) { 1867e2340276SBjoern A. Zeeb if (dm->fddt_train == BTC_FDDT_ENABLE) 1868e2340276SBjoern A. Zeeb break; 1869e2340276SBjoern A. Zeeb cnt_leak_slot = le16_to_cpu(pcysta->v5.slot_cnt[CXST_LK]); 1870e2340276SBjoern A. Zeeb cnt_rx_imr = le32_to_cpu(pcysta->v5.leak_slot.cnt_rximr); 1871e2340276SBjoern A. Zeeb 1872e2340276SBjoern A. Zeeb /* Check Leak-AP */ 1873e2340276SBjoern A. Zeeb if (cnt_leak_slot != 0 && cnt_rx_imr != 0 && 1874e2340276SBjoern A. Zeeb dm->tdma_now.rxflctrl) { 1875e2340276SBjoern A. Zeeb if (le16_to_cpu(pcysta->v5.cycles) >= BTC_CYSTA_CHK_PERIOD && 1876e2340276SBjoern A. Zeeb cnt_leak_slot < BTC_LEAK_AP_TH * cnt_rx_imr) 1877e2340276SBjoern A. Zeeb dm->leak_ap = 1; 18788e93258fSBjoern A. Zeeb } 18798e93258fSBjoern A. Zeeb 1880e2340276SBjoern A. Zeeb /* Check diff time between real WL slot and W1 slot */ 1881e2340276SBjoern A. Zeeb if (dm->tdma_now.type == CXTDMA_OFF) { 1882*6d67aabdSBjoern A. Zeeb if (ver->fcxslots == 1) 1883*6d67aabdSBjoern A. Zeeb wl_slot_set = le16_to_cpu(dm->slot_now.v1[CXST_W1].dur); 1884*6d67aabdSBjoern A. Zeeb else if (ver->fcxslots == 7) 1885*6d67aabdSBjoern A. Zeeb wl_slot_set = le16_to_cpu(dm->slot_now.v7[CXST_W1].dur); 1886e2340276SBjoern A. Zeeb wl_slot_real = le16_to_cpu(pcysta->v5.cycle_time.tavg[CXT_WL]); 18878e93258fSBjoern A. Zeeb 1888e2340276SBjoern A. Zeeb if (wl_slot_real > wl_slot_set) 1889e2340276SBjoern A. Zeeb diff_t = wl_slot_real - wl_slot_set; 18908e93258fSBjoern A. Zeeb else 1891e2340276SBjoern A. Zeeb diff_t = wl_slot_set - wl_slot_real; 1892e2340276SBjoern A. Zeeb } 1893e2340276SBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_WL_SLOT_DRIFT, diff_t); 18948e93258fSBjoern A. Zeeb 1895e2340276SBjoern A. Zeeb /* Check diff time between real BT slot and EBT/E5G slot */ 1896e2340276SBjoern A. Zeeb bt_slot_set = btc->bt_req_len; 1897e2340276SBjoern A. Zeeb bt_slot_real = le16_to_cpu(pcysta->v5.cycle_time.tavg[CXT_BT]); 1898e2340276SBjoern A. Zeeb diff_t = 0; 1899e2340276SBjoern A. Zeeb if (dm->tdma_now.type == CXTDMA_OFF && 1900e2340276SBjoern A. Zeeb dm->tdma_now.ext_ctrl == CXECTL_EXT && 1901e2340276SBjoern A. Zeeb bt_slot_set != 0) { 1902e2340276SBjoern A. Zeeb if (bt_slot_set > bt_slot_real) 1903e2340276SBjoern A. Zeeb diff_t = bt_slot_set - bt_slot_real; 1904e2340276SBjoern A. Zeeb else 1905e2340276SBjoern A. Zeeb diff_t = bt_slot_real - bt_slot_set; 19068e93258fSBjoern A. Zeeb } 19078e93258fSBjoern A. Zeeb 1908e2340276SBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_BT_SLOT_DRIFT, diff_t); 1909e2340276SBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_E2G_HANG, 1910e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->v5.slot_cnt[CXST_E2G])); 1911e2340276SBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_W1_HANG, 1912e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->v5.slot_cnt[CXST_W1])); 1913e2340276SBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_B1_HANG, 1914e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->v5.slot_cnt[CXST_B1])); 1915e2340276SBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_HANG, 1916e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->v5.cycles)); 1917*6d67aabdSBjoern A. Zeeb } else if (ver->fcxcysta == 7) { 1918*6d67aabdSBjoern A. Zeeb if (dm->fddt_train == BTC_FDDT_ENABLE) 1919*6d67aabdSBjoern A. Zeeb break; 1920*6d67aabdSBjoern A. Zeeb 1921*6d67aabdSBjoern A. Zeeb pcysta = &pfwinfo->rpt_fbtc_cysta.finfo; 1922*6d67aabdSBjoern A. Zeeb 1923*6d67aabdSBjoern A. Zeeb if (dm->tdma_now.type != CXTDMA_OFF) { 1924*6d67aabdSBjoern A. Zeeb /* Check diff time between real WL slot and W1 slot */ 1925*6d67aabdSBjoern A. Zeeb val16 = le16_to_cpu(pcysta->v7.cycle_time.tavg[CXT_WL]); 1926*6d67aabdSBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_WL_SLOT_DRIFT, val16); 1927*6d67aabdSBjoern A. Zeeb 1928*6d67aabdSBjoern A. Zeeb /* Check Leak-AP */ 1929*6d67aabdSBjoern A. Zeeb val1 = le32_to_cpu(pcysta->v7.leak_slot.cnt_rximr) * 1930*6d67aabdSBjoern A. Zeeb BTC_LEAK_AP_TH; 1931*6d67aabdSBjoern A. Zeeb val2 = le16_to_cpu(pcysta->v7.slot_cnt[CXST_LK]); 1932*6d67aabdSBjoern A. Zeeb 1933*6d67aabdSBjoern A. Zeeb val16 = le16_to_cpu(pcysta->v7.cycles); 1934*6d67aabdSBjoern A. Zeeb if (dm->tdma_now.rxflctrl && 1935*6d67aabdSBjoern A. Zeeb val16 >= BTC_CYSTA_CHK_PERIOD && val1 > val2) 1936*6d67aabdSBjoern A. Zeeb dm->leak_ap = 1; 1937*6d67aabdSBjoern A. Zeeb } else if (dm->tdma_now.ext_ctrl == CXECTL_EXT) { 1938*6d67aabdSBjoern A. Zeeb val16 = le16_to_cpu(pcysta->v7.cycle_time.tavg[CXT_BT]); 1939*6d67aabdSBjoern A. Zeeb /* Check diff between real BT slot and EBT/E5G slot */ 1940*6d67aabdSBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_BT_SLOT_DRIFT, val16); 1941*6d67aabdSBjoern A. Zeeb 1942*6d67aabdSBjoern A. Zeeb /* Check bt slot length for P2P mode*/ 1943*6d67aabdSBjoern A. Zeeb val1 = le16_to_cpu(pcysta->v7.a2dp_ept.cnt_timeout) * 1944*6d67aabdSBjoern A. Zeeb BTC_SLOT_REQ_TH; 1945*6d67aabdSBjoern A. Zeeb val2 = le16_to_cpu(pcysta->v7.a2dp_ept.cnt); 1946*6d67aabdSBjoern A. Zeeb 1947*6d67aabdSBjoern A. Zeeb val16 = le16_to_cpu(pcysta->v7.cycles); 1948*6d67aabdSBjoern A. Zeeb if (val16 >= BTC_CYSTA_CHK_PERIOD && val1 > val2) 1949*6d67aabdSBjoern A. Zeeb dm->slot_req_more = 1; 1950*6d67aabdSBjoern A. Zeeb else if (bt->link_info.status.map.connect == 0) 1951*6d67aabdSBjoern A. Zeeb dm->slot_req_more = 0; 1952*6d67aabdSBjoern A. Zeeb } 1953*6d67aabdSBjoern A. Zeeb 1954*6d67aabdSBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_E2G_HANG, 1955*6d67aabdSBjoern A. Zeeb le16_to_cpu(pcysta->v7.slot_cnt[CXST_E2G])); 1956*6d67aabdSBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_W1_HANG, 1957*6d67aabdSBjoern A. Zeeb le16_to_cpu(pcysta->v7.slot_cnt[CXST_W1])); 1958*6d67aabdSBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_B1_HANG, 1959*6d67aabdSBjoern A. Zeeb le16_to_cpu(pcysta->v7.slot_cnt[CXST_B1])); 1960*6d67aabdSBjoern A. Zeeb 1961*6d67aabdSBjoern A. Zeeb /* "BT_SLOT_FLOOD" error-check MUST before "CYCLE_HANG" */ 1962*6d67aabdSBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_BT_SLOT_FLOOD, 1963*6d67aabdSBjoern A. Zeeb le16_to_cpu(pcysta->v7.cycles)); 1964*6d67aabdSBjoern A. Zeeb _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_HANG, 1965*6d67aabdSBjoern A. Zeeb le16_to_cpu(pcysta->v7.cycles)); 1966e2340276SBjoern A. Zeeb } else { 1967e2340276SBjoern A. Zeeb goto err; 1968e2340276SBjoern A. Zeeb } 1969e2340276SBjoern A. Zeeb break; 1970*6d67aabdSBjoern A. Zeeb case BTC_RPT_TYPE_MREG: 1971*6d67aabdSBjoern A. Zeeb if (ver->fcxmreg == 7) 1972*6d67aabdSBjoern A. Zeeb break; 1973*6d67aabdSBjoern A. Zeeb _get_reg_status(rtwdev, BTC_CSTATUS_BB_GNT_MUX_MON, &val); 1974*6d67aabdSBjoern A. Zeeb if (dm->wl_btg_rx == BTC_BTGCTRL_BB_GNT_FWCTRL) 1975*6d67aabdSBjoern A. Zeeb dm->wl_btg_rx_rb = BTC_BTGCTRL_BB_GNT_FWCTRL; 1976*6d67aabdSBjoern A. Zeeb else 1977*6d67aabdSBjoern A. Zeeb dm->wl_btg_rx_rb = val; 1978*6d67aabdSBjoern A. Zeeb 1979*6d67aabdSBjoern A. Zeeb _get_reg_status(rtwdev, BTC_CSTATUS_BB_PRE_AGC_MON, &val); 1980*6d67aabdSBjoern A. Zeeb if (dm->wl_pre_agc == BTC_PREAGC_BB_FWCTRL) 1981*6d67aabdSBjoern A. Zeeb dm->wl_pre_agc_rb = BTC_PREAGC_BB_FWCTRL; 1982*6d67aabdSBjoern A. Zeeb else 1983*6d67aabdSBjoern A. Zeeb dm->wl_pre_agc_rb = val; 1984*6d67aabdSBjoern A. Zeeb break; 1985e2340276SBjoern A. Zeeb case BTC_RPT_TYPE_BT_VER: 1986e2340276SBjoern A. Zeeb case BTC_RPT_TYPE_BT_SCAN: 1987e2340276SBjoern A. Zeeb case BTC_RPT_TYPE_BT_AFH: 1988e2340276SBjoern A. Zeeb case BTC_RPT_TYPE_BT_DEVICE: 19898e93258fSBjoern A. Zeeb _update_bt_report(rtwdev, rpt_type, pfinfo); 1990e2340276SBjoern A. Zeeb break; 1991e2340276SBjoern A. Zeeb } 19928e93258fSBjoern A. Zeeb return (rpt_len + BTC_RPT_HDR_SIZE); 1993e2340276SBjoern A. Zeeb 1994e2340276SBjoern A. Zeeb err: 1995e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 1996e2340276SBjoern A. Zeeb "[BTC], %s(): Undefined version for type=%d\n", __func__, rpt_type); 1997e2340276SBjoern A. Zeeb return 0; 19988e93258fSBjoern A. Zeeb } 19998e93258fSBjoern A. Zeeb 20008e93258fSBjoern A. Zeeb static void _parse_btc_report(struct rtw89_dev *rtwdev, 20018e93258fSBjoern A. Zeeb struct rtw89_btc_btf_fwinfo *pfwinfo, 20028e93258fSBjoern A. Zeeb u8 *pbuf, u32 buf_len) 20038e93258fSBjoern A. Zeeb { 2004e2340276SBjoern A. Zeeb const struct rtw89_btc_ver *ver = rtwdev->btc.ver; 20058e93258fSBjoern A. Zeeb struct rtw89_btc_prpt *btc_prpt = NULL; 20068e93258fSBjoern A. Zeeb u32 index = 0, rpt_len = 0; 20078e93258fSBjoern A. Zeeb 20088e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 20098e93258fSBjoern A. Zeeb "[BTC], %s(): buf_len:%d\n", 20108e93258fSBjoern A. Zeeb __func__, buf_len); 20118e93258fSBjoern A. Zeeb 20128e93258fSBjoern A. Zeeb while (pbuf) { 20138e93258fSBjoern A. Zeeb btc_prpt = (struct rtw89_btc_prpt *)&pbuf[index]; 2014e2340276SBjoern A. Zeeb if (index + 2 >= ver->info_buf) 20158e93258fSBjoern A. Zeeb break; 20168e93258fSBjoern A. Zeeb /* At least 3 bytes: type(1) & len(2) */ 20178e93258fSBjoern A. Zeeb rpt_len = le16_to_cpu(btc_prpt->len); 20188e93258fSBjoern A. Zeeb if ((index + rpt_len + BTC_RPT_HDR_SIZE) > buf_len) 20198e93258fSBjoern A. Zeeb break; 20208e93258fSBjoern A. Zeeb 20218e93258fSBjoern A. Zeeb rpt_len = _chk_btc_report(rtwdev, pfwinfo, pbuf, index); 20228e93258fSBjoern A. Zeeb if (!rpt_len) 20238e93258fSBjoern A. Zeeb break; 20248e93258fSBjoern A. Zeeb index += rpt_len; 20258e93258fSBjoern A. Zeeb } 20268e93258fSBjoern A. Zeeb } 20278e93258fSBjoern A. Zeeb 20288e93258fSBjoern A. Zeeb #define BTC_TLV_HDR_LEN 2 2029*6d67aabdSBjoern A. Zeeb #define BTC_TLV_HDR_LEN_V7 3 20308e93258fSBjoern A. Zeeb 20318e93258fSBjoern A. Zeeb static void _append_tdma(struct rtw89_dev *rtwdev) 20328e93258fSBjoern A. Zeeb { 20338e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 2034e2340276SBjoern A. Zeeb const struct rtw89_btc_ver *ver = btc->ver; 20358e93258fSBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 20368e93258fSBjoern A. Zeeb struct rtw89_btc_btf_tlv *tlv; 2037*6d67aabdSBjoern A. Zeeb struct rtw89_btc_btf_tlv_v7 *tlv_v7; 20388e93258fSBjoern A. Zeeb struct rtw89_btc_fbtc_tdma *v; 2039e2340276SBjoern A. Zeeb struct rtw89_btc_fbtc_tdma_v3 *v3; 20408e93258fSBjoern A. Zeeb u16 len = btc->policy_len; 20418e93258fSBjoern A. Zeeb 20428e93258fSBjoern A. Zeeb if (!btc->update_policy_force && 20438e93258fSBjoern A. Zeeb !memcmp(&dm->tdma, &dm->tdma_now, sizeof(dm->tdma))) { 20448e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, 20458e93258fSBjoern A. Zeeb RTW89_DBG_BTC, "[BTC], %s(): tdma no change!\n", 20468e93258fSBjoern A. Zeeb __func__); 20478e93258fSBjoern A. Zeeb return; 20488e93258fSBjoern A. Zeeb } 20498e93258fSBjoern A. Zeeb 20508e93258fSBjoern A. Zeeb tlv = (struct rtw89_btc_btf_tlv *)&btc->policy[len]; 20518e93258fSBjoern A. Zeeb tlv->type = CXPOLICY_TDMA; 2052e2340276SBjoern A. Zeeb if (ver->fcxtdma == 1) { 20538e93258fSBjoern A. Zeeb v = (struct rtw89_btc_fbtc_tdma *)&tlv->val[0]; 20548e93258fSBjoern A. Zeeb tlv->len = sizeof(*v); 2055*6d67aabdSBjoern A. Zeeb *v = dm->tdma; 20568e93258fSBjoern A. Zeeb btc->policy_len += BTC_TLV_HDR_LEN + sizeof(*v); 2057*6d67aabdSBjoern A. Zeeb } else if (ver->fcxtdma == 7) { 2058*6d67aabdSBjoern A. Zeeb tlv_v7 = (struct rtw89_btc_btf_tlv_v7 *)&btc->policy[len]; 2059*6d67aabdSBjoern A. Zeeb tlv_v7->len = sizeof(dm->tdma); 2060*6d67aabdSBjoern A. Zeeb tlv_v7->ver = ver->fcxtdma; 2061*6d67aabdSBjoern A. Zeeb tlv_v7->type = CXPOLICY_TDMA; 2062*6d67aabdSBjoern A. Zeeb memcpy(tlv_v7->val, &dm->tdma, tlv_v7->len); 2063*6d67aabdSBjoern A. Zeeb btc->policy_len += BTC_TLV_HDR_LEN_V7 + tlv_v7->len; 20648e93258fSBjoern A. Zeeb } else { 2065e2340276SBjoern A. Zeeb tlv->len = sizeof(*v3); 2066e2340276SBjoern A. Zeeb v3 = (struct rtw89_btc_fbtc_tdma_v3 *)&tlv->val[0]; 2067e2340276SBjoern A. Zeeb v3->fver = ver->fcxtdma; 2068*6d67aabdSBjoern A. Zeeb v3->tdma = dm->tdma; 2069e2340276SBjoern A. Zeeb btc->policy_len += BTC_TLV_HDR_LEN + sizeof(*v3); 20708e93258fSBjoern A. Zeeb } 20718e93258fSBjoern A. Zeeb 20728e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 20738e93258fSBjoern A. Zeeb "[BTC], %s(): type:%d, rxflctrl=%d, txpause=%d, wtgle_n=%d, leak_n=%d, ext_ctrl=%d\n", 20748e93258fSBjoern A. Zeeb __func__, dm->tdma.type, dm->tdma.rxflctrl, 20758e93258fSBjoern A. Zeeb dm->tdma.txpause, dm->tdma.wtgle_n, dm->tdma.leak_n, 20768e93258fSBjoern A. Zeeb dm->tdma.ext_ctrl); 20778e93258fSBjoern A. Zeeb } 20788e93258fSBjoern A. Zeeb 2079*6d67aabdSBjoern A. Zeeb static void _append_slot_v1(struct rtw89_dev *rtwdev) 20808e93258fSBjoern A. Zeeb { 20818e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 20828e93258fSBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 20838e93258fSBjoern A. Zeeb struct rtw89_btc_btf_tlv *tlv = NULL; 20848e93258fSBjoern A. Zeeb struct btc_fbtc_1slot *v = NULL; 20858e93258fSBjoern A. Zeeb u16 len = 0; 20868e93258fSBjoern A. Zeeb u8 i, cnt = 0; 20878e93258fSBjoern A. Zeeb 20888e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 20898e93258fSBjoern A. Zeeb "[BTC], %s(): A:btc->policy_len = %d\n", 20908e93258fSBjoern A. Zeeb __func__, btc->policy_len); 20918e93258fSBjoern A. Zeeb 20928e93258fSBjoern A. Zeeb for (i = 0; i < CXST_MAX; i++) { 20938e93258fSBjoern A. Zeeb if (!btc->update_policy_force && 2094*6d67aabdSBjoern A. Zeeb !memcmp(&dm->slot.v1[i], &dm->slot_now.v1[i], 2095*6d67aabdSBjoern A. Zeeb sizeof(dm->slot.v1[i]))) 20968e93258fSBjoern A. Zeeb continue; 20978e93258fSBjoern A. Zeeb 20988e93258fSBjoern A. Zeeb len = btc->policy_len; 20998e93258fSBjoern A. Zeeb 21008e93258fSBjoern A. Zeeb tlv = (struct rtw89_btc_btf_tlv *)&btc->policy[len]; 21018e93258fSBjoern A. Zeeb v = (struct btc_fbtc_1slot *)&tlv->val[0]; 21028e93258fSBjoern A. Zeeb tlv->type = CXPOLICY_SLOT; 21038e93258fSBjoern A. Zeeb tlv->len = sizeof(*v); 21048e93258fSBjoern A. Zeeb 2105*6d67aabdSBjoern A. Zeeb v->fver = btc->ver->fcxslots; 21068e93258fSBjoern A. Zeeb v->sid = i; 2107*6d67aabdSBjoern A. Zeeb v->slot = dm->slot.v1[i]; 21088e93258fSBjoern A. Zeeb 21098e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 21108e93258fSBjoern A. Zeeb "[BTC], %s(): slot-%d: dur=%d, table=0x%08x, type=%d\n", 2111*6d67aabdSBjoern A. Zeeb __func__, i, dm->slot.v1[i].dur, dm->slot.v1[i].cxtbl, 2112*6d67aabdSBjoern A. Zeeb dm->slot.v1[i].cxtype); 21138e93258fSBjoern A. Zeeb cnt++; 21148e93258fSBjoern A. Zeeb 21158e93258fSBjoern A. Zeeb btc->policy_len += BTC_TLV_HDR_LEN + sizeof(*v); 21168e93258fSBjoern A. Zeeb } 21178e93258fSBjoern A. Zeeb 21188e93258fSBjoern A. Zeeb if (cnt > 0) 21198e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 21208e93258fSBjoern A. Zeeb "[BTC], %s(): slot update (cnt=%d)!!\n", 21218e93258fSBjoern A. Zeeb __func__, cnt); 21228e93258fSBjoern A. Zeeb } 21238e93258fSBjoern A. Zeeb 2124*6d67aabdSBjoern A. Zeeb static void _append_slot_v7(struct rtw89_dev *rtwdev) 2125*6d67aabdSBjoern A. Zeeb { 2126*6d67aabdSBjoern A. Zeeb struct rtw89_btc_btf_tlv_v7 *tlv = NULL; 2127*6d67aabdSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 2128*6d67aabdSBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 2129*6d67aabdSBjoern A. Zeeb u8 i, cnt = 0; 2130*6d67aabdSBjoern A. Zeeb u16 len; 2131*6d67aabdSBjoern A. Zeeb 2132*6d67aabdSBjoern A. Zeeb for (i = 0; i < CXST_MAX; i++) { 2133*6d67aabdSBjoern A. Zeeb if (!btc->update_policy_force && 2134*6d67aabdSBjoern A. Zeeb !memcmp(&dm->slot.v7[i], &dm->slot_now.v7[i], 2135*6d67aabdSBjoern A. Zeeb sizeof(dm->slot.v7[i]))) 2136*6d67aabdSBjoern A. Zeeb continue; 2137*6d67aabdSBjoern A. Zeeb 2138*6d67aabdSBjoern A. Zeeb len = btc->policy_len; 2139*6d67aabdSBjoern A. Zeeb 2140*6d67aabdSBjoern A. Zeeb if (!tlv) { 2141*6d67aabdSBjoern A. Zeeb if ((len + BTC_TLV_HDR_LEN_V7) > RTW89_BTC_POLICY_MAXLEN) { 2142*6d67aabdSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 2143*6d67aabdSBjoern A. Zeeb "[BTC], %s(): buff overflow!\n", __func__); 2144*6d67aabdSBjoern A. Zeeb break; 2145*6d67aabdSBjoern A. Zeeb } 2146*6d67aabdSBjoern A. Zeeb 2147*6d67aabdSBjoern A. Zeeb tlv = (struct rtw89_btc_btf_tlv_v7 *)&btc->policy[len]; 2148*6d67aabdSBjoern A. Zeeb tlv->type = CXPOLICY_SLOT; 2149*6d67aabdSBjoern A. Zeeb tlv->ver = btc->ver->fcxslots; 2150*6d67aabdSBjoern A. Zeeb tlv->len = sizeof(dm->slot.v7[0]) + BTC_TLV_SLOT_ID_LEN_V7; 2151*6d67aabdSBjoern A. Zeeb len += BTC_TLV_HDR_LEN_V7; 2152*6d67aabdSBjoern A. Zeeb } 2153*6d67aabdSBjoern A. Zeeb 2154*6d67aabdSBjoern A. Zeeb if ((len + (u16)tlv->len) > RTW89_BTC_POLICY_MAXLEN) { 2155*6d67aabdSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 2156*6d67aabdSBjoern A. Zeeb "[BTC], %s(): buff overflow!\n", __func__); 2157*6d67aabdSBjoern A. Zeeb break; 2158*6d67aabdSBjoern A. Zeeb } 2159*6d67aabdSBjoern A. Zeeb 2160*6d67aabdSBjoern A. Zeeb btc->policy[len] = i; /* slot-id */ 2161*6d67aabdSBjoern A. Zeeb memcpy(&btc->policy[len + 1], &dm->slot.v7[i], 2162*6d67aabdSBjoern A. Zeeb sizeof(dm->slot.v7[0])); 2163*6d67aabdSBjoern A. Zeeb len += tlv->len; 2164*6d67aabdSBjoern A. Zeeb 2165*6d67aabdSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 2166*6d67aabdSBjoern A. Zeeb "[BTC], %s: policy_len=%d, slot-%d: dur=%d, type=%d, table=0x%08x\n", 2167*6d67aabdSBjoern A. Zeeb __func__, btc->policy_len, i, dm->slot.v7[i].dur, 2168*6d67aabdSBjoern A. Zeeb dm->slot.v7[i].cxtype, dm->slot.v7[i].cxtbl); 2169*6d67aabdSBjoern A. Zeeb cnt++; 2170*6d67aabdSBjoern A. Zeeb btc->policy_len = len; /* update total length */ 2171*6d67aabdSBjoern A. Zeeb } 2172*6d67aabdSBjoern A. Zeeb 2173*6d67aabdSBjoern A. Zeeb if (cnt > 0) 2174*6d67aabdSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 2175*6d67aabdSBjoern A. Zeeb "[BTC], %s: slot update (cnt=%d, len=%d)!!\n", 2176*6d67aabdSBjoern A. Zeeb __func__, cnt, btc->policy_len); 2177*6d67aabdSBjoern A. Zeeb } 2178*6d67aabdSBjoern A. Zeeb 2179*6d67aabdSBjoern A. Zeeb static void _append_slot(struct rtw89_dev *rtwdev) 2180*6d67aabdSBjoern A. Zeeb { 2181*6d67aabdSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 2182*6d67aabdSBjoern A. Zeeb 2183*6d67aabdSBjoern A. Zeeb if (btc->ver->fcxslots == 7) 2184*6d67aabdSBjoern A. Zeeb _append_slot_v7(rtwdev); 2185*6d67aabdSBjoern A. Zeeb else 2186*6d67aabdSBjoern A. Zeeb _append_slot_v1(rtwdev); 2187*6d67aabdSBjoern A. Zeeb } 2188*6d67aabdSBjoern A. Zeeb 2189e2340276SBjoern A. Zeeb static u32 rtw89_btc_fw_rpt_ver(struct rtw89_dev *rtwdev, u32 rpt_map) 2190e2340276SBjoern A. Zeeb { 2191e2340276SBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 2192e2340276SBjoern A. Zeeb const struct rtw89_btc_ver *ver = btc->ver; 2193e2340276SBjoern A. Zeeb u32 bit_map = 0; 2194e2340276SBjoern A. Zeeb 2195e2340276SBjoern A. Zeeb switch (rpt_map) { 2196e2340276SBjoern A. Zeeb case RPT_EN_TDMA: 2197e2340276SBjoern A. Zeeb bit_map = BIT(0); 2198e2340276SBjoern A. Zeeb break; 2199e2340276SBjoern A. Zeeb case RPT_EN_CYCLE: 2200e2340276SBjoern A. Zeeb bit_map = BIT(1); 2201e2340276SBjoern A. Zeeb break; 2202e2340276SBjoern A. Zeeb case RPT_EN_MREG: 2203e2340276SBjoern A. Zeeb bit_map = BIT(2); 2204e2340276SBjoern A. Zeeb break; 2205e2340276SBjoern A. Zeeb case RPT_EN_BT_VER_INFO: 2206e2340276SBjoern A. Zeeb bit_map = BIT(3); 2207e2340276SBjoern A. Zeeb break; 2208e2340276SBjoern A. Zeeb case RPT_EN_BT_SCAN_INFO: 2209e2340276SBjoern A. Zeeb bit_map = BIT(4); 2210e2340276SBjoern A. Zeeb break; 2211e2340276SBjoern A. Zeeb case RPT_EN_BT_DEVICE_INFO: 2212e2340276SBjoern A. Zeeb switch (ver->frptmap) { 2213e2340276SBjoern A. Zeeb case 0: 2214e2340276SBjoern A. Zeeb case 1: 2215e2340276SBjoern A. Zeeb case 2: 2216e2340276SBjoern A. Zeeb bit_map = BIT(6); 2217e2340276SBjoern A. Zeeb break; 2218e2340276SBjoern A. Zeeb case 3: 2219e2340276SBjoern A. Zeeb bit_map = BIT(5); 2220e2340276SBjoern A. Zeeb break; 2221e2340276SBjoern A. Zeeb default: 2222e2340276SBjoern A. Zeeb break; 2223e2340276SBjoern A. Zeeb } 2224e2340276SBjoern A. Zeeb break; 2225e2340276SBjoern A. Zeeb case RPT_EN_BT_AFH_MAP: 2226e2340276SBjoern A. Zeeb switch (ver->frptmap) { 2227e2340276SBjoern A. Zeeb case 0: 2228e2340276SBjoern A. Zeeb case 1: 2229e2340276SBjoern A. Zeeb case 2: 2230e2340276SBjoern A. Zeeb bit_map = BIT(5); 2231e2340276SBjoern A. Zeeb break; 2232e2340276SBjoern A. Zeeb case 3: 2233e2340276SBjoern A. Zeeb bit_map = BIT(6); 2234e2340276SBjoern A. Zeeb break; 2235e2340276SBjoern A. Zeeb default: 2236e2340276SBjoern A. Zeeb break; 2237e2340276SBjoern A. Zeeb } 2238e2340276SBjoern A. Zeeb break; 2239e2340276SBjoern A. Zeeb case RPT_EN_BT_AFH_MAP_LE: 2240e2340276SBjoern A. Zeeb switch (ver->frptmap) { 2241e2340276SBjoern A. Zeeb case 2: 2242e2340276SBjoern A. Zeeb bit_map = BIT(8); 2243e2340276SBjoern A. Zeeb break; 2244e2340276SBjoern A. Zeeb case 3: 2245e2340276SBjoern A. Zeeb bit_map = BIT(7); 2246e2340276SBjoern A. Zeeb break; 2247e2340276SBjoern A. Zeeb default: 2248e2340276SBjoern A. Zeeb break; 2249e2340276SBjoern A. Zeeb } 2250e2340276SBjoern A. Zeeb break; 2251e2340276SBjoern A. Zeeb case RPT_EN_FW_STEP_INFO: 2252e2340276SBjoern A. Zeeb switch (ver->frptmap) { 2253e2340276SBjoern A. Zeeb case 1: 2254e2340276SBjoern A. Zeeb case 2: 2255e2340276SBjoern A. Zeeb bit_map = BIT(7); 2256e2340276SBjoern A. Zeeb break; 2257e2340276SBjoern A. Zeeb case 3: 2258e2340276SBjoern A. Zeeb bit_map = BIT(8); 2259e2340276SBjoern A. Zeeb break; 2260e2340276SBjoern A. Zeeb default: 2261e2340276SBjoern A. Zeeb break; 2262e2340276SBjoern A. Zeeb } 2263e2340276SBjoern A. Zeeb break; 2264e2340276SBjoern A. Zeeb case RPT_EN_TEST: 2265e2340276SBjoern A. Zeeb bit_map = BIT(31); 2266e2340276SBjoern A. Zeeb break; 2267e2340276SBjoern A. Zeeb case RPT_EN_WL_ALL: 2268e2340276SBjoern A. Zeeb switch (ver->frptmap) { 2269e2340276SBjoern A. Zeeb case 0: 2270e2340276SBjoern A. Zeeb case 1: 2271e2340276SBjoern A. Zeeb case 2: 2272e2340276SBjoern A. Zeeb bit_map = GENMASK(2, 0); 2273e2340276SBjoern A. Zeeb break; 2274e2340276SBjoern A. Zeeb case 3: 2275e2340276SBjoern A. Zeeb bit_map = GENMASK(2, 0) | BIT(8); 2276e2340276SBjoern A. Zeeb break; 2277e2340276SBjoern A. Zeeb default: 2278e2340276SBjoern A. Zeeb break; 2279e2340276SBjoern A. Zeeb } 2280e2340276SBjoern A. Zeeb break; 2281e2340276SBjoern A. Zeeb case RPT_EN_BT_ALL: 2282e2340276SBjoern A. Zeeb switch (ver->frptmap) { 2283e2340276SBjoern A. Zeeb case 0: 2284e2340276SBjoern A. Zeeb case 1: 2285e2340276SBjoern A. Zeeb bit_map = GENMASK(6, 3); 2286e2340276SBjoern A. Zeeb break; 2287e2340276SBjoern A. Zeeb case 2: 2288e2340276SBjoern A. Zeeb bit_map = GENMASK(6, 3) | BIT(8); 2289e2340276SBjoern A. Zeeb break; 2290e2340276SBjoern A. Zeeb case 3: 2291e2340276SBjoern A. Zeeb bit_map = GENMASK(7, 3); 2292e2340276SBjoern A. Zeeb break; 2293e2340276SBjoern A. Zeeb default: 2294e2340276SBjoern A. Zeeb break; 2295e2340276SBjoern A. Zeeb } 2296e2340276SBjoern A. Zeeb break; 2297e2340276SBjoern A. Zeeb case RPT_EN_ALL: 2298e2340276SBjoern A. Zeeb switch (ver->frptmap) { 2299e2340276SBjoern A. Zeeb case 0: 2300e2340276SBjoern A. Zeeb bit_map = GENMASK(6, 0); 2301e2340276SBjoern A. Zeeb break; 2302e2340276SBjoern A. Zeeb case 1: 2303e2340276SBjoern A. Zeeb bit_map = GENMASK(7, 0); 2304e2340276SBjoern A. Zeeb break; 2305e2340276SBjoern A. Zeeb case 2: 2306e2340276SBjoern A. Zeeb case 3: 2307e2340276SBjoern A. Zeeb bit_map = GENMASK(8, 0); 2308e2340276SBjoern A. Zeeb break; 2309e2340276SBjoern A. Zeeb default: 2310e2340276SBjoern A. Zeeb break; 2311e2340276SBjoern A. Zeeb } 2312e2340276SBjoern A. Zeeb break; 2313e2340276SBjoern A. Zeeb case RPT_EN_MONITER: 2314e2340276SBjoern A. Zeeb switch (ver->frptmap) { 2315e2340276SBjoern A. Zeeb case 0: 2316e2340276SBjoern A. Zeeb case 1: 2317e2340276SBjoern A. Zeeb bit_map = GENMASK(6, 2); 2318e2340276SBjoern A. Zeeb break; 2319e2340276SBjoern A. Zeeb case 2: 2320e2340276SBjoern A. Zeeb bit_map = GENMASK(6, 2) | BIT(8); 2321e2340276SBjoern A. Zeeb break; 2322e2340276SBjoern A. Zeeb case 3: 2323e2340276SBjoern A. Zeeb bit_map = GENMASK(8, 2); 2324e2340276SBjoern A. Zeeb break; 2325e2340276SBjoern A. Zeeb default: 2326e2340276SBjoern A. Zeeb break; 2327e2340276SBjoern A. Zeeb } 2328e2340276SBjoern A. Zeeb break; 2329e2340276SBjoern A. Zeeb } 2330e2340276SBjoern A. Zeeb 2331e2340276SBjoern A. Zeeb return bit_map; 2332e2340276SBjoern A. Zeeb } 2333e2340276SBjoern A. Zeeb 2334*6d67aabdSBjoern A. Zeeb static void rtw89_btc_fw_set_slots(struct rtw89_dev *rtwdev) 2335*6d67aabdSBjoern A. Zeeb { 2336*6d67aabdSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 2337*6d67aabdSBjoern A. Zeeb const struct rtw89_btc_ver *ver = btc->ver; 2338*6d67aabdSBjoern A. Zeeb struct rtw89_btc_btf_tlv_v7 *tlv_v7 = NULL; 2339*6d67aabdSBjoern A. Zeeb struct rtw89_btc_btf_set_slot_table *tbl; 2340*6d67aabdSBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 2341*6d67aabdSBjoern A. Zeeb u16 n, len; 2342*6d67aabdSBjoern A. Zeeb 2343*6d67aabdSBjoern A. Zeeb if (ver->fcxslots == 7) { 2344*6d67aabdSBjoern A. Zeeb len = sizeof(*tlv_v7) + sizeof(dm->slot.v7); 2345*6d67aabdSBjoern A. Zeeb tlv_v7 = kmalloc(len, GFP_KERNEL); 2346*6d67aabdSBjoern A. Zeeb if (!tlv_v7) 2347*6d67aabdSBjoern A. Zeeb return; 2348*6d67aabdSBjoern A. Zeeb 2349*6d67aabdSBjoern A. Zeeb tlv_v7->type = SET_SLOT_TABLE; 2350*6d67aabdSBjoern A. Zeeb tlv_v7->ver = ver->fcxslots; 2351*6d67aabdSBjoern A. Zeeb tlv_v7->len = ARRAY_SIZE(dm->slot.v7); 2352*6d67aabdSBjoern A. Zeeb memcpy(tlv_v7->val, dm->slot.v7, sizeof(dm->slot.v7)); 2353*6d67aabdSBjoern A. Zeeb 2354*6d67aabdSBjoern A. Zeeb _send_fw_cmd(rtwdev, BTFC_SET, SET_SLOT_TABLE, (u8 *)tlv_v7, len); 2355*6d67aabdSBjoern A. Zeeb 2356*6d67aabdSBjoern A. Zeeb kfree(tlv_v7); 2357*6d67aabdSBjoern A. Zeeb } else { 2358*6d67aabdSBjoern A. Zeeb n = struct_size(tbl, tbls, CXST_MAX); 2359*6d67aabdSBjoern A. Zeeb tbl = kmalloc(n, GFP_KERNEL); 2360*6d67aabdSBjoern A. Zeeb if (!tbl) 2361*6d67aabdSBjoern A. Zeeb return; 2362*6d67aabdSBjoern A. Zeeb 2363*6d67aabdSBjoern A. Zeeb tbl->fver = BTF_SET_SLOT_TABLE_VER; 2364*6d67aabdSBjoern A. Zeeb tbl->tbl_num = CXST_MAX; 2365*6d67aabdSBjoern A. Zeeb memcpy(tbl->tbls, dm->slot.v1, flex_array_size(tbl, tbls, CXST_MAX)); 2366*6d67aabdSBjoern A. Zeeb 2367*6d67aabdSBjoern A. Zeeb _send_fw_cmd(rtwdev, BTFC_SET, SET_SLOT_TABLE, tbl, n); 2368*6d67aabdSBjoern A. Zeeb 2369*6d67aabdSBjoern A. Zeeb kfree(tbl); 2370*6d67aabdSBjoern A. Zeeb } 2371*6d67aabdSBjoern A. Zeeb } 2372*6d67aabdSBjoern A. Zeeb 23738e93258fSBjoern A. Zeeb static void rtw89_btc_fw_en_rpt(struct rtw89_dev *rtwdev, 23748e93258fSBjoern A. Zeeb u32 rpt_map, bool rpt_state) 23758e93258fSBjoern A. Zeeb { 23768e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 2377e2340276SBjoern A. Zeeb struct rtw89_btc_wl_smap *wl_smap = &btc->cx.wl.status.map; 23788e93258fSBjoern A. Zeeb struct rtw89_btc_btf_fwinfo *fwinfo = &btc->fwinfo; 2379*6d67aabdSBjoern A. Zeeb union rtw89_fbtc_rtp_ctrl r; 2380e2340276SBjoern A. Zeeb u32 val, bit_map; 2381*6d67aabdSBjoern A. Zeeb int ret; 2382e2340276SBjoern A. Zeeb 2383e2340276SBjoern A. Zeeb if ((wl_smap->rf_off || wl_smap->lps != BTC_LPS_OFF) && rpt_state != 0) 2384e2340276SBjoern A. Zeeb return; 2385e2340276SBjoern A. Zeeb 2386e2340276SBjoern A. Zeeb bit_map = rtw89_btc_fw_rpt_ver(rtwdev, rpt_map); 23878e93258fSBjoern A. Zeeb 23888e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 23898e93258fSBjoern A. Zeeb "[BTC], %s(): rpt_map=%x, rpt_state=%x\n", 23908e93258fSBjoern A. Zeeb __func__, rpt_map, rpt_state); 23918e93258fSBjoern A. Zeeb 23928e93258fSBjoern A. Zeeb if (rpt_state) 2393e2340276SBjoern A. Zeeb val = fwinfo->rpt_en_map | bit_map; 23948e93258fSBjoern A. Zeeb else 2395e2340276SBjoern A. Zeeb val = fwinfo->rpt_en_map & ~bit_map; 23968e93258fSBjoern A. Zeeb 23978e93258fSBjoern A. Zeeb if (val == fwinfo->rpt_en_map) 23988e93258fSBjoern A. Zeeb return; 23998e93258fSBjoern A. Zeeb 2400*6d67aabdSBjoern A. Zeeb if (btc->ver->fcxbtcrpt == 8) { 2401*6d67aabdSBjoern A. Zeeb r.v8.type = SET_REPORT_EN; 2402*6d67aabdSBjoern A. Zeeb r.v8.fver = btc->ver->fcxbtcrpt; 2403*6d67aabdSBjoern A. Zeeb r.v8.len = sizeof(r.v8.map); 2404*6d67aabdSBjoern A. Zeeb r.v8.map = cpu_to_le32(val); 2405*6d67aabdSBjoern A. Zeeb ret = _send_fw_cmd(rtwdev, BTFC_SET, SET_REPORT_EN, &r.v8, 2406*6d67aabdSBjoern A. Zeeb sizeof(r.v8)); 2407*6d67aabdSBjoern A. Zeeb } else { 2408*6d67aabdSBjoern A. Zeeb if (btc->ver->fcxbtcrpt == 105) 2409*6d67aabdSBjoern A. Zeeb r.v1.fver = 5; 2410*6d67aabdSBjoern A. Zeeb else 2411*6d67aabdSBjoern A. Zeeb r.v1.fver = btc->ver->fcxbtcrpt; 2412*6d67aabdSBjoern A. Zeeb r.v1.enable = cpu_to_le32(val); 2413*6d67aabdSBjoern A. Zeeb r.v1.para = cpu_to_le32(rpt_state); 2414*6d67aabdSBjoern A. Zeeb ret = _send_fw_cmd(rtwdev, BTFC_SET, SET_REPORT_EN, &r.v1, 2415*6d67aabdSBjoern A. Zeeb sizeof(r.v1)); 24168e93258fSBjoern A. Zeeb } 24178e93258fSBjoern A. Zeeb 2418*6d67aabdSBjoern A. Zeeb if (!ret) 2419*6d67aabdSBjoern A. Zeeb fwinfo->rpt_en_map = val; 24208e93258fSBjoern A. Zeeb } 24218e93258fSBjoern A. Zeeb 24228e93258fSBjoern A. Zeeb static void btc_fw_set_monreg(struct rtw89_dev *rtwdev) 24238e93258fSBjoern A. Zeeb { 24248e93258fSBjoern A. Zeeb const struct rtw89_chip_info *chip = rtwdev->chip; 2425e2340276SBjoern A. Zeeb const struct rtw89_btc_ver *ver = rtwdev->btc.ver; 2426*6d67aabdSBjoern A. Zeeb struct rtw89_btc_btf_set_mon_reg_v1 *v1 = NULL; 2427*6d67aabdSBjoern A. Zeeb struct rtw89_btc_btf_set_mon_reg_v7 *v7 = NULL; 2428*6d67aabdSBjoern A. Zeeb u8 i, n, ulen, cxmreg_max; 24298e93258fSBjoern A. Zeeb u16 sz = 0; 24308e93258fSBjoern A. Zeeb 24318e93258fSBjoern A. Zeeb n = chip->mon_reg_num; 24328e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 24338e93258fSBjoern A. Zeeb "[BTC], %s(): mon_reg_num=%d\n", __func__, n); 2434e2340276SBjoern A. Zeeb 2435e2340276SBjoern A. Zeeb if (ver->fcxmreg == 1) 2436e2340276SBjoern A. Zeeb cxmreg_max = CXMREG_MAX; 2437e2340276SBjoern A. Zeeb else 2438*6d67aabdSBjoern A. Zeeb cxmreg_max = CXMREG_MAX_V2; 2439e2340276SBjoern A. Zeeb 2440e2340276SBjoern A. Zeeb if (n > cxmreg_max) { 24418e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 24428e93258fSBjoern A. Zeeb "[BTC], %s(): mon reg count %d > %d\n", 2443e2340276SBjoern A. Zeeb __func__, n, cxmreg_max); 24448e93258fSBjoern A. Zeeb return; 24458e93258fSBjoern A. Zeeb } 24468e93258fSBjoern A. Zeeb 24478e93258fSBjoern A. Zeeb ulen = sizeof(struct rtw89_btc_fbtc_mreg); 24488e93258fSBjoern A. Zeeb 2449*6d67aabdSBjoern A. Zeeb if (ver->fcxmreg == 7) { 2450*6d67aabdSBjoern A. Zeeb sz = struct_size(v7, regs, n); 2451*6d67aabdSBjoern A. Zeeb v7 = kmalloc(sz, GFP_KERNEL); 2452*6d67aabdSBjoern A. Zeeb v7->type = RPT_EN_MREG; 2453*6d67aabdSBjoern A. Zeeb v7->fver = ver->fcxmreg; 2454*6d67aabdSBjoern A. Zeeb v7->len = n; 2455*6d67aabdSBjoern A. Zeeb for (i = 0; i < n; i++) { 2456*6d67aabdSBjoern A. Zeeb v7->regs[i].type = chip->mon_reg[i].type; 2457*6d67aabdSBjoern A. Zeeb v7->regs[i].bytes = chip->mon_reg[i].bytes; 2458*6d67aabdSBjoern A. Zeeb v7->regs[i].offset = chip->mon_reg[i].offset; 2459*6d67aabdSBjoern A. Zeeb } 2460*6d67aabdSBjoern A. Zeeb 2461*6d67aabdSBjoern A. Zeeb _send_fw_cmd(rtwdev, BTFC_SET, SET_MREG_TABLE, v7, sz); 2462*6d67aabdSBjoern A. Zeeb kfree(v7); 2463*6d67aabdSBjoern A. Zeeb } else { 2464*6d67aabdSBjoern A. Zeeb sz = struct_size(v1, regs, n); 2465*6d67aabdSBjoern A. Zeeb v1 = kmalloc(sz, GFP_KERNEL); 2466*6d67aabdSBjoern A. Zeeb v1->fver = ver->fcxmreg; 2467*6d67aabdSBjoern A. Zeeb v1->reg_num = n; 2468*6d67aabdSBjoern A. Zeeb memcpy(v1->regs, chip->mon_reg, flex_array_size(v1, regs, n)); 2469*6d67aabdSBjoern A. Zeeb 2470*6d67aabdSBjoern A. Zeeb _send_fw_cmd(rtwdev, BTFC_SET, SET_MREG_TABLE, v1, sz); 2471*6d67aabdSBjoern A. Zeeb kfree(v1); 2472*6d67aabdSBjoern A. Zeeb } 2473*6d67aabdSBjoern A. Zeeb 24748e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 24758e93258fSBjoern A. Zeeb "[BTC], %s(): sz=%d ulen=%d n=%d\n", 24768e93258fSBjoern A. Zeeb __func__, sz, ulen, n); 24778e93258fSBjoern A. Zeeb 24788e93258fSBjoern A. Zeeb rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_MREG, 1); 24798e93258fSBjoern A. Zeeb } 24808e93258fSBjoern A. Zeeb 24818e93258fSBjoern A. Zeeb static void _update_dm_step(struct rtw89_dev *rtwdev, 24828e93258fSBjoern A. Zeeb enum btc_reason_and_action reason_or_action) 24838e93258fSBjoern A. Zeeb { 24848e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 24858e93258fSBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 24868e93258fSBjoern A. Zeeb 24878e93258fSBjoern A. Zeeb /* use ring-structure to store dm step */ 24888e93258fSBjoern A. Zeeb dm->dm_step.step[dm->dm_step.step_pos] = reason_or_action; 24898e93258fSBjoern A. Zeeb dm->dm_step.step_pos++; 24908e93258fSBjoern A. Zeeb 24918e93258fSBjoern A. Zeeb if (dm->dm_step.step_pos >= ARRAY_SIZE(dm->dm_step.step)) { 24928e93258fSBjoern A. Zeeb dm->dm_step.step_pos = 0; 24938e93258fSBjoern A. Zeeb dm->dm_step.step_ov = true; 24948e93258fSBjoern A. Zeeb } 24958e93258fSBjoern A. Zeeb } 24968e93258fSBjoern A. Zeeb 24978e93258fSBjoern A. Zeeb static void _fw_set_policy(struct rtw89_dev *rtwdev, u16 policy_type, 24988e93258fSBjoern A. Zeeb enum btc_reason_and_action action) 24998e93258fSBjoern A. Zeeb { 25008e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 25018e93258fSBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 2502*6d67aabdSBjoern A. Zeeb int ret; 25038e93258fSBjoern A. Zeeb 25048e93258fSBjoern A. Zeeb dm->run_action = action; 25058e93258fSBjoern A. Zeeb 25068e93258fSBjoern A. Zeeb _update_dm_step(rtwdev, action | BTC_ACT_EXT_BIT); 25078e93258fSBjoern A. Zeeb _update_dm_step(rtwdev, policy_type | BTC_POLICY_EXT_BIT); 25088e93258fSBjoern A. Zeeb 25098e93258fSBjoern A. Zeeb btc->policy_len = 0; 25108e93258fSBjoern A. Zeeb btc->policy_type = policy_type; 25118e93258fSBjoern A. Zeeb 25128e93258fSBjoern A. Zeeb _append_tdma(rtwdev); 25138e93258fSBjoern A. Zeeb _append_slot(rtwdev); 25148e93258fSBjoern A. Zeeb 25158e93258fSBjoern A. Zeeb if (btc->policy_len == 0 || btc->policy_len > RTW89_BTC_POLICY_MAXLEN) 25168e93258fSBjoern A. Zeeb return; 25178e93258fSBjoern A. Zeeb 25188e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 25198e93258fSBjoern A. Zeeb "[BTC], %s(): action = %d -> policy type/len: 0x%04x/%d\n", 25208e93258fSBjoern A. Zeeb __func__, action, policy_type, btc->policy_len); 25218e93258fSBjoern A. Zeeb 25228e93258fSBjoern A. Zeeb if (dm->tdma.rxflctrl == CXFLC_NULLP || 25238e93258fSBjoern A. Zeeb dm->tdma.rxflctrl == CXFLC_QOSNULL) 25248e93258fSBjoern A. Zeeb btc->lps = 1; 25258e93258fSBjoern A. Zeeb else 25268e93258fSBjoern A. Zeeb btc->lps = 0; 25278e93258fSBjoern A. Zeeb 25288e93258fSBjoern A. Zeeb if (btc->lps == 1) 25298e93258fSBjoern A. Zeeb rtw89_set_coex_ctrl_lps(rtwdev, btc->lps); 25308e93258fSBjoern A. Zeeb 2531*6d67aabdSBjoern A. Zeeb ret = _send_fw_cmd(rtwdev, BTFC_SET, SET_CX_POLICY, 25328e93258fSBjoern A. Zeeb btc->policy, btc->policy_len); 2533*6d67aabdSBjoern A. Zeeb if (!ret) { 25348e93258fSBjoern A. Zeeb memcpy(&dm->tdma_now, &dm->tdma, sizeof(dm->tdma_now)); 2535*6d67aabdSBjoern A. Zeeb if (btc->ver->fcxslots == 7) 2536*6d67aabdSBjoern A. Zeeb memcpy(&dm->slot_now.v7, &dm->slot.v7, sizeof(dm->slot_now.v7)); 2537*6d67aabdSBjoern A. Zeeb else 2538*6d67aabdSBjoern A. Zeeb memcpy(&dm->slot_now.v1, &dm->slot.v1, sizeof(dm->slot_now.v1)); 2539*6d67aabdSBjoern A. Zeeb } 25408e93258fSBjoern A. Zeeb 25418e93258fSBjoern A. Zeeb if (btc->update_policy_force) 25428e93258fSBjoern A. Zeeb btc->update_policy_force = false; 25438e93258fSBjoern A. Zeeb 25448e93258fSBjoern A. Zeeb if (btc->lps == 0) 25458e93258fSBjoern A. Zeeb rtw89_set_coex_ctrl_lps(rtwdev, btc->lps); 25468e93258fSBjoern A. Zeeb } 25478e93258fSBjoern A. Zeeb 25488e93258fSBjoern A. Zeeb static void _fw_set_drv_info(struct rtw89_dev *rtwdev, u8 type) 25498e93258fSBjoern A. Zeeb { 2550e2340276SBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 2551e2340276SBjoern A. Zeeb const struct rtw89_btc_ver *ver = btc->ver; 2552e2340276SBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 2553e2340276SBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 2554e2340276SBjoern A. Zeeb struct rtw89_btc_rf_trx_para rf_para = dm->rf_trx_para; 25558e93258fSBjoern A. Zeeb 25568e93258fSBjoern A. Zeeb switch (type) { 25578e93258fSBjoern A. Zeeb case CXDRVINFO_INIT: 2558*6d67aabdSBjoern A. Zeeb if (ver->fcxinit == 7) 2559*6d67aabdSBjoern A. Zeeb rtw89_fw_h2c_cxdrv_init_v7(rtwdev, type); 2560*6d67aabdSBjoern A. Zeeb else 2561*6d67aabdSBjoern A. Zeeb rtw89_fw_h2c_cxdrv_init(rtwdev, type); 25628e93258fSBjoern A. Zeeb break; 25638e93258fSBjoern A. Zeeb case CXDRVINFO_ROLE: 2564e2340276SBjoern A. Zeeb if (ver->fwlrole == 0) 2565*6d67aabdSBjoern A. Zeeb rtw89_fw_h2c_cxdrv_role(rtwdev, type); 2566e2340276SBjoern A. Zeeb else if (ver->fwlrole == 1) 2567*6d67aabdSBjoern A. Zeeb rtw89_fw_h2c_cxdrv_role_v1(rtwdev, type); 2568e2340276SBjoern A. Zeeb else if (ver->fwlrole == 2) 2569*6d67aabdSBjoern A. Zeeb rtw89_fw_h2c_cxdrv_role_v2(rtwdev, type); 25708e93258fSBjoern A. Zeeb break; 25718e93258fSBjoern A. Zeeb case CXDRVINFO_CTRL: 2572*6d67aabdSBjoern A. Zeeb if (ver->drvinfo_type == 1) 2573*6d67aabdSBjoern A. Zeeb type = 2; 2574*6d67aabdSBjoern A. Zeeb 2575*6d67aabdSBjoern A. Zeeb if (ver->fcxctrl == 7) 2576*6d67aabdSBjoern A. Zeeb rtw89_fw_h2c_cxdrv_ctrl_v7(rtwdev, type); 2577*6d67aabdSBjoern A. Zeeb else 2578*6d67aabdSBjoern A. Zeeb rtw89_fw_h2c_cxdrv_ctrl(rtwdev, type); 25798e93258fSBjoern A. Zeeb break; 2580e2340276SBjoern A. Zeeb case CXDRVINFO_TRX: 2581*6d67aabdSBjoern A. Zeeb if (ver->drvinfo_type == 1) 2582*6d67aabdSBjoern A. Zeeb type = 3; 2583*6d67aabdSBjoern A. Zeeb 2584e2340276SBjoern A. Zeeb dm->trx_info.tx_power = u32_get_bits(rf_para.wl_tx_power, 2585e2340276SBjoern A. Zeeb RTW89_BTC_WL_DEF_TX_PWR); 2586e2340276SBjoern A. Zeeb dm->trx_info.rx_gain = u32_get_bits(rf_para.wl_rx_gain, 2587e2340276SBjoern A. Zeeb RTW89_BTC_WL_DEF_TX_PWR); 2588e2340276SBjoern A. Zeeb dm->trx_info.bt_tx_power = u32_get_bits(rf_para.bt_tx_power, 2589e2340276SBjoern A. Zeeb RTW89_BTC_WL_DEF_TX_PWR); 2590e2340276SBjoern A. Zeeb dm->trx_info.bt_rx_gain = u32_get_bits(rf_para.bt_rx_gain, 2591e2340276SBjoern A. Zeeb RTW89_BTC_WL_DEF_TX_PWR); 2592e2340276SBjoern A. Zeeb dm->trx_info.cn = wl->cn_report; 2593e2340276SBjoern A. Zeeb dm->trx_info.nhm = wl->nhm.pwr; 2594*6d67aabdSBjoern A. Zeeb rtw89_fw_h2c_cxdrv_trx(rtwdev, type); 2595e2340276SBjoern A. Zeeb break; 25968e93258fSBjoern A. Zeeb case CXDRVINFO_RFK: 2597*6d67aabdSBjoern A. Zeeb if (ver->drvinfo_type == 1) 2598*6d67aabdSBjoern A. Zeeb return; 2599*6d67aabdSBjoern A. Zeeb 2600*6d67aabdSBjoern A. Zeeb rtw89_fw_h2c_cxdrv_rfk(rtwdev, type); 26018e93258fSBjoern A. Zeeb break; 2602*6d67aabdSBjoern A. Zeeb case CXDRVINFO_TXPWR: 2603*6d67aabdSBjoern A. Zeeb case CXDRVINFO_FDDT: 2604*6d67aabdSBjoern A. Zeeb case CXDRVINFO_MLO: 2605*6d67aabdSBjoern A. Zeeb case CXDRVINFO_OSI: 26068e93258fSBjoern A. Zeeb default: 26078e93258fSBjoern A. Zeeb break; 26088e93258fSBjoern A. Zeeb } 26098e93258fSBjoern A. Zeeb } 26108e93258fSBjoern A. Zeeb 26118e93258fSBjoern A. Zeeb static 26128e93258fSBjoern A. Zeeb void btc_fw_event(struct rtw89_dev *rtwdev, u8 evt_id, void *data, u32 len) 26138e93258fSBjoern A. Zeeb { 26148e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 26158e93258fSBjoern A. Zeeb struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; 26168e93258fSBjoern A. Zeeb 26178e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 26188e93258fSBjoern A. Zeeb "[BTC], %s(): evt_id:%d len:%d\n", 26198e93258fSBjoern A. Zeeb __func__, evt_id, len); 26208e93258fSBjoern A. Zeeb 26218e93258fSBjoern A. Zeeb if (!len || !data) 26228e93258fSBjoern A. Zeeb return; 26238e93258fSBjoern A. Zeeb 26248e93258fSBjoern A. Zeeb switch (evt_id) { 26258e93258fSBjoern A. Zeeb case BTF_EVNT_RPT: 26268e93258fSBjoern A. Zeeb _parse_btc_report(rtwdev, pfwinfo, data, len); 26278e93258fSBjoern A. Zeeb break; 26288e93258fSBjoern A. Zeeb default: 26298e93258fSBjoern A. Zeeb break; 26308e93258fSBjoern A. Zeeb } 26318e93258fSBjoern A. Zeeb } 26328e93258fSBjoern A. Zeeb 2633e2340276SBjoern A. Zeeb static void _set_gnt(struct rtw89_dev *rtwdev, u8 phy_map, u8 wl_state, u8 bt_state) 26348e93258fSBjoern A. Zeeb { 26358e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 26368e93258fSBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 26378e93258fSBjoern A. Zeeb struct rtw89_mac_ax_gnt *g = dm->gnt.band; 26388e93258fSBjoern A. Zeeb u8 i; 26398e93258fSBjoern A. Zeeb 26408e93258fSBjoern A. Zeeb if (phy_map > BTC_PHY_ALL) 26418e93258fSBjoern A. Zeeb return; 26428e93258fSBjoern A. Zeeb 26438e93258fSBjoern A. Zeeb for (i = 0; i < RTW89_PHY_MAX; i++) { 26448e93258fSBjoern A. Zeeb if (!(phy_map & BIT(i))) 26458e93258fSBjoern A. Zeeb continue; 26468e93258fSBjoern A. Zeeb 2647e2340276SBjoern A. Zeeb switch (wl_state) { 26488e93258fSBjoern A. Zeeb case BTC_GNT_HW: 26498e93258fSBjoern A. Zeeb g[i].gnt_wl_sw_en = 0; 26508e93258fSBjoern A. Zeeb g[i].gnt_wl = 0; 26518e93258fSBjoern A. Zeeb break; 26528e93258fSBjoern A. Zeeb case BTC_GNT_SW_LO: 26538e93258fSBjoern A. Zeeb g[i].gnt_wl_sw_en = 1; 26548e93258fSBjoern A. Zeeb g[i].gnt_wl = 0; 26558e93258fSBjoern A. Zeeb break; 26568e93258fSBjoern A. Zeeb case BTC_GNT_SW_HI: 26578e93258fSBjoern A. Zeeb g[i].gnt_wl_sw_en = 1; 26588e93258fSBjoern A. Zeeb g[i].gnt_wl = 1; 26598e93258fSBjoern A. Zeeb break; 26608e93258fSBjoern A. Zeeb } 2661e2340276SBjoern A. Zeeb 2662e2340276SBjoern A. Zeeb switch (bt_state) { 2663e2340276SBjoern A. Zeeb case BTC_GNT_HW: 2664e2340276SBjoern A. Zeeb g[i].gnt_bt_sw_en = 0; 2665e2340276SBjoern A. Zeeb g[i].gnt_bt = 0; 2666e2340276SBjoern A. Zeeb break; 2667e2340276SBjoern A. Zeeb case BTC_GNT_SW_LO: 2668e2340276SBjoern A. Zeeb g[i].gnt_bt_sw_en = 1; 2669e2340276SBjoern A. Zeeb g[i].gnt_bt = 0; 2670e2340276SBjoern A. Zeeb break; 2671e2340276SBjoern A. Zeeb case BTC_GNT_SW_HI: 2672e2340276SBjoern A. Zeeb g[i].gnt_bt_sw_en = 1; 2673e2340276SBjoern A. Zeeb g[i].gnt_bt = 1; 2674e2340276SBjoern A. Zeeb break; 2675e2340276SBjoern A. Zeeb } 26768e93258fSBjoern A. Zeeb } 26778e93258fSBjoern A. Zeeb 26788e93258fSBjoern A. Zeeb rtw89_chip_mac_cfg_gnt(rtwdev, &dm->gnt); 26798e93258fSBjoern A. Zeeb } 26808e93258fSBjoern A. Zeeb 2681*6d67aabdSBjoern A. Zeeb static void _set_gnt_v1(struct rtw89_dev *rtwdev, u8 phy_map, 2682*6d67aabdSBjoern A. Zeeb u8 wl_state, u8 bt_state, u8 wlact_state) 2683*6d67aabdSBjoern A. Zeeb { 2684*6d67aabdSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 2685*6d67aabdSBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 2686*6d67aabdSBjoern A. Zeeb struct rtw89_mac_ax_gnt *g = dm->gnt.band; 2687*6d67aabdSBjoern A. Zeeb u8 i, bt_idx = dm->bt_select + 1; 2688*6d67aabdSBjoern A. Zeeb 2689*6d67aabdSBjoern A. Zeeb if (phy_map > BTC_PHY_ALL) 2690*6d67aabdSBjoern A. Zeeb return; 2691*6d67aabdSBjoern A. Zeeb 2692*6d67aabdSBjoern A. Zeeb for (i = 0; i < RTW89_PHY_MAX; i++) { 2693*6d67aabdSBjoern A. Zeeb if (!(phy_map & BIT(i))) 2694*6d67aabdSBjoern A. Zeeb continue; 2695*6d67aabdSBjoern A. Zeeb 2696*6d67aabdSBjoern A. Zeeb switch (wl_state) { 2697*6d67aabdSBjoern A. Zeeb case BTC_GNT_HW: 2698*6d67aabdSBjoern A. Zeeb g[i].gnt_wl_sw_en = 0; 2699*6d67aabdSBjoern A. Zeeb g[i].gnt_wl = 0; 2700*6d67aabdSBjoern A. Zeeb break; 2701*6d67aabdSBjoern A. Zeeb case BTC_GNT_SW_LO: 2702*6d67aabdSBjoern A. Zeeb g[i].gnt_wl_sw_en = 1; 2703*6d67aabdSBjoern A. Zeeb g[i].gnt_wl = 0; 2704*6d67aabdSBjoern A. Zeeb break; 2705*6d67aabdSBjoern A. Zeeb case BTC_GNT_SW_HI: 2706*6d67aabdSBjoern A. Zeeb g[i].gnt_wl_sw_en = 1; 2707*6d67aabdSBjoern A. Zeeb g[i].gnt_wl = 1; 2708*6d67aabdSBjoern A. Zeeb break; 2709*6d67aabdSBjoern A. Zeeb } 2710*6d67aabdSBjoern A. Zeeb 2711*6d67aabdSBjoern A. Zeeb switch (bt_state) { 2712*6d67aabdSBjoern A. Zeeb case BTC_GNT_HW: 2713*6d67aabdSBjoern A. Zeeb g[i].gnt_bt_sw_en = 0; 2714*6d67aabdSBjoern A. Zeeb g[i].gnt_bt = 0; 2715*6d67aabdSBjoern A. Zeeb break; 2716*6d67aabdSBjoern A. Zeeb case BTC_GNT_SW_LO: 2717*6d67aabdSBjoern A. Zeeb g[i].gnt_bt_sw_en = 1; 2718*6d67aabdSBjoern A. Zeeb g[i].gnt_bt = 0; 2719*6d67aabdSBjoern A. Zeeb break; 2720*6d67aabdSBjoern A. Zeeb case BTC_GNT_SW_HI: 2721*6d67aabdSBjoern A. Zeeb g[i].gnt_bt_sw_en = 1; 2722*6d67aabdSBjoern A. Zeeb g[i].gnt_bt = 1; 2723*6d67aabdSBjoern A. Zeeb break; 2724*6d67aabdSBjoern A. Zeeb } 2725*6d67aabdSBjoern A. Zeeb } 2726*6d67aabdSBjoern A. Zeeb 2727*6d67aabdSBjoern A. Zeeb if (rtwdev->chip->para_ver & BTC_FEAT_WLAN_ACT_MUX) { 2728*6d67aabdSBjoern A. Zeeb for (i = 0; i < 2; i++) { 2729*6d67aabdSBjoern A. Zeeb if (!(bt_idx & BIT(i))) 2730*6d67aabdSBjoern A. Zeeb continue; 2731*6d67aabdSBjoern A. Zeeb 2732*6d67aabdSBjoern A. Zeeb switch (wlact_state) { 2733*6d67aabdSBjoern A. Zeeb case BTC_WLACT_HW: 2734*6d67aabdSBjoern A. Zeeb dm->gnt.bt[i].wlan_act_en = 0; 2735*6d67aabdSBjoern A. Zeeb dm->gnt.bt[i].wlan_act = 0; 2736*6d67aabdSBjoern A. Zeeb break; 2737*6d67aabdSBjoern A. Zeeb case BTC_WLACT_SW_LO: 2738*6d67aabdSBjoern A. Zeeb dm->gnt.bt[i].wlan_act_en = 1; 2739*6d67aabdSBjoern A. Zeeb dm->gnt.bt[i].wlan_act = 0; 2740*6d67aabdSBjoern A. Zeeb break; 2741*6d67aabdSBjoern A. Zeeb case BTC_WLACT_SW_HI: 2742*6d67aabdSBjoern A. Zeeb dm->gnt.bt[i].wlan_act_en = 1; 2743*6d67aabdSBjoern A. Zeeb dm->gnt.bt[i].wlan_act = 1; 2744*6d67aabdSBjoern A. Zeeb break; 2745*6d67aabdSBjoern A. Zeeb } 2746*6d67aabdSBjoern A. Zeeb } 2747*6d67aabdSBjoern A. Zeeb } 2748*6d67aabdSBjoern A. Zeeb rtw89_mac_cfg_gnt_v2(rtwdev, &dm->gnt); 2749*6d67aabdSBjoern A. Zeeb } 2750*6d67aabdSBjoern A. Zeeb 27518e93258fSBjoern A. Zeeb #define BTC_TDMA_WLROLE_MAX 2 27528e93258fSBjoern A. Zeeb 27538e93258fSBjoern A. Zeeb static void _set_bt_ignore_wlan_act(struct rtw89_dev *rtwdev, u8 enable) 27548e93258fSBjoern A. Zeeb { 27558e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 27568e93258fSBjoern A. Zeeb "[BTC], %s(): set bt %s wlan_act\n", __func__, 27578e93258fSBjoern A. Zeeb enable ? "ignore" : "do not ignore"); 27588e93258fSBjoern A. Zeeb 27598e93258fSBjoern A. Zeeb _send_fw_cmd(rtwdev, BTFC_SET, SET_BT_IGNORE_WLAN_ACT, &enable, 1); 27608e93258fSBjoern A. Zeeb } 27618e93258fSBjoern A. Zeeb 27628e93258fSBjoern A. Zeeb #define WL_TX_POWER_NO_BTC_CTRL GENMASK(31, 0) 27638e93258fSBjoern A. Zeeb #define WL_TX_POWER_ALL_TIME GENMASK(15, 0) 27648e93258fSBjoern A. Zeeb #define WL_TX_POWER_WITH_BT GENMASK(31, 16) 27658e93258fSBjoern A. Zeeb #define WL_TX_POWER_INT_PART GENMASK(8, 2) 27668e93258fSBjoern A. Zeeb #define WL_TX_POWER_FRA_PART GENMASK(1, 0) 27678e93258fSBjoern A. Zeeb #define B_BTC_WL_TX_POWER_SIGN BIT(7) 27688e93258fSBjoern A. Zeeb #define B_TSSI_WL_TX_POWER_SIGN BIT(8) 27698e93258fSBjoern A. Zeeb 27708e93258fSBjoern A. Zeeb static void _set_wl_tx_power(struct rtw89_dev *rtwdev, u32 level) 27718e93258fSBjoern A. Zeeb { 27728e93258fSBjoern A. Zeeb const struct rtw89_chip_info *chip = rtwdev->chip; 27738e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 27748e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 27758e93258fSBjoern A. Zeeb u32 pwr_val; 27768e93258fSBjoern A. Zeeb 27778e93258fSBjoern A. Zeeb if (wl->rf_para.tx_pwr_freerun == level) 27788e93258fSBjoern A. Zeeb return; 27798e93258fSBjoern A. Zeeb 27808e93258fSBjoern A. Zeeb wl->rf_para.tx_pwr_freerun = level; 27818e93258fSBjoern A. Zeeb btc->dm.rf_trx_para.wl_tx_power = level; 27828e93258fSBjoern A. Zeeb 27838e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 27848e93258fSBjoern A. Zeeb "[BTC], %s(): level = %d\n", 27858e93258fSBjoern A. Zeeb __func__, level); 27868e93258fSBjoern A. Zeeb 27878e93258fSBjoern A. Zeeb if (level == RTW89_BTC_WL_DEF_TX_PWR) { 27888e93258fSBjoern A. Zeeb pwr_val = WL_TX_POWER_NO_BTC_CTRL; 27898e93258fSBjoern A. Zeeb } else { /* only apply "force tx power" */ 27908e93258fSBjoern A. Zeeb pwr_val = FIELD_PREP(WL_TX_POWER_INT_PART, level); 27918e93258fSBjoern A. Zeeb if (pwr_val > RTW89_BTC_WL_DEF_TX_PWR) 27928e93258fSBjoern A. Zeeb pwr_val = RTW89_BTC_WL_DEF_TX_PWR; 27938e93258fSBjoern A. Zeeb 27948e93258fSBjoern A. Zeeb if (level & B_BTC_WL_TX_POWER_SIGN) 27958e93258fSBjoern A. Zeeb pwr_val |= B_TSSI_WL_TX_POWER_SIGN; 27968e93258fSBjoern A. Zeeb pwr_val |= WL_TX_POWER_WITH_BT; 27978e93258fSBjoern A. Zeeb } 27988e93258fSBjoern A. Zeeb 27998e93258fSBjoern A. Zeeb chip->ops->btc_set_wl_txpwr_ctrl(rtwdev, pwr_val); 28008e93258fSBjoern A. Zeeb } 28018e93258fSBjoern A. Zeeb 28028e93258fSBjoern A. Zeeb static void _set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level) 28038e93258fSBjoern A. Zeeb { 2804e2340276SBjoern A. Zeeb const struct rtw89_chip_info *chip = rtwdev->chip; 28058e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 28068e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 28078e93258fSBjoern A. Zeeb 28088e93258fSBjoern A. Zeeb if (wl->rf_para.rx_gain_freerun == level) 28098e93258fSBjoern A. Zeeb return; 28108e93258fSBjoern A. Zeeb 28118e93258fSBjoern A. Zeeb wl->rf_para.rx_gain_freerun = level; 28128e93258fSBjoern A. Zeeb btc->dm.rf_trx_para.wl_rx_gain = level; 28138e93258fSBjoern A. Zeeb 28148e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 28158e93258fSBjoern A. Zeeb "[BTC], %s(): level = %d\n", 28168e93258fSBjoern A. Zeeb __func__, level); 2817e2340276SBjoern A. Zeeb 2818e2340276SBjoern A. Zeeb chip->ops->btc_set_wl_rx_gain(rtwdev, level); 28198e93258fSBjoern A. Zeeb } 28208e93258fSBjoern A. Zeeb 28218e93258fSBjoern A. Zeeb static void _set_bt_tx_power(struct rtw89_dev *rtwdev, u8 level) 28228e93258fSBjoern A. Zeeb { 28238e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 28248e93258fSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &btc->cx.bt; 2825*6d67aabdSBjoern A. Zeeb int ret; 28268e93258fSBjoern A. Zeeb u8 buf; 28278e93258fSBjoern A. Zeeb 2828*6d67aabdSBjoern A. Zeeb if (btc->cx.cnt_bt[BTC_BCNT_INFOUPDATE] == 0) 2829*6d67aabdSBjoern A. Zeeb return; 2830*6d67aabdSBjoern A. Zeeb 28318e93258fSBjoern A. Zeeb if (bt->rf_para.tx_pwr_freerun == level) 28328e93258fSBjoern A. Zeeb return; 28338e93258fSBjoern A. Zeeb 28348e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 28358e93258fSBjoern A. Zeeb "[BTC], %s(): level = %d\n", 28368e93258fSBjoern A. Zeeb __func__, level); 28378e93258fSBjoern A. Zeeb 28388e93258fSBjoern A. Zeeb buf = (s8)(-level); 2839*6d67aabdSBjoern A. Zeeb ret = _send_fw_cmd(rtwdev, BTFC_SET, SET_BT_TX_PWR, &buf, 1); 2840*6d67aabdSBjoern A. Zeeb if (!ret) { 2841*6d67aabdSBjoern A. Zeeb bt->rf_para.tx_pwr_freerun = level; 2842*6d67aabdSBjoern A. Zeeb btc->dm.rf_trx_para.bt_tx_power = level; 2843*6d67aabdSBjoern A. Zeeb } 28448e93258fSBjoern A. Zeeb } 28458e93258fSBjoern A. Zeeb 28468e93258fSBjoern A. Zeeb #define BTC_BT_RX_NORMAL_LVL 7 28478e93258fSBjoern A. Zeeb 28488e93258fSBjoern A. Zeeb static void _set_bt_rx_gain(struct rtw89_dev *rtwdev, u8 level) 28498e93258fSBjoern A. Zeeb { 28508e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 28518e93258fSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &btc->cx.bt; 28528e93258fSBjoern A. Zeeb 2853*6d67aabdSBjoern A. Zeeb if (btc->cx.cnt_bt[BTC_BCNT_INFOUPDATE] == 0) 2854*6d67aabdSBjoern A. Zeeb return; 2855*6d67aabdSBjoern A. Zeeb 2856*6d67aabdSBjoern A. Zeeb if ((bt->rf_para.rx_gain_freerun == level || 2857*6d67aabdSBjoern A. Zeeb level > BTC_BT_RX_NORMAL_LVL) && 2858*6d67aabdSBjoern A. Zeeb (!rtwdev->chip->scbd || bt->lna_constrain == level)) 28598e93258fSBjoern A. Zeeb return; 28608e93258fSBjoern A. Zeeb 28618e93258fSBjoern A. Zeeb bt->rf_para.rx_gain_freerun = level; 28628e93258fSBjoern A. Zeeb btc->dm.rf_trx_para.bt_rx_gain = level; 28638e93258fSBjoern A. Zeeb 28648e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 28658e93258fSBjoern A. Zeeb "[BTC], %s(): level = %d\n", 28668e93258fSBjoern A. Zeeb __func__, level); 28678e93258fSBjoern A. Zeeb 28688e93258fSBjoern A. Zeeb if (level == BTC_BT_RX_NORMAL_LVL) 28698e93258fSBjoern A. Zeeb _write_scbd(rtwdev, BTC_WSCB_RXGAIN, false); 28708e93258fSBjoern A. Zeeb else 28718e93258fSBjoern A. Zeeb _write_scbd(rtwdev, BTC_WSCB_RXGAIN, true); 28728e93258fSBjoern A. Zeeb 2873*6d67aabdSBjoern A. Zeeb _send_fw_cmd(rtwdev, BTFC_SET, SET_BT_LNA_CONSTRAIN, &level, sizeof(level)); 28748e93258fSBjoern A. Zeeb } 28758e93258fSBjoern A. Zeeb 28768e93258fSBjoern A. Zeeb static void _set_rf_trx_para(struct rtw89_dev *rtwdev) 28778e93258fSBjoern A. Zeeb { 28788e93258fSBjoern A. Zeeb const struct rtw89_chip_info *chip = rtwdev->chip; 28798e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 2880*6d67aabdSBjoern A. Zeeb const struct rtw89_btc_ver *ver = btc->ver; 28818e93258fSBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 28828e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 28838e93258fSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &btc->cx.bt; 2884e2340276SBjoern A. Zeeb struct rtw89_btc_bt_link_info *b = &bt->link_info; 2885*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_smap *wl_smap = &wl->status.map; 28868e93258fSBjoern A. Zeeb struct rtw89_btc_rf_trx_para para; 28878e93258fSBjoern A. Zeeb u32 wl_stb_chg = 0; 2888*6d67aabdSBjoern A. Zeeb u8 level_id = 0, link_mode = 0, i, dbcc_2g_phy = 0; 28898e93258fSBjoern A. Zeeb 2890*6d67aabdSBjoern A. Zeeb if (ver->fwlrole == 0) { 2891*6d67aabdSBjoern A. Zeeb link_mode = wl->role_info.link_mode; 2892*6d67aabdSBjoern A. Zeeb for (i = 0; i < RTW89_PHY_MAX; i++) { 2893*6d67aabdSBjoern A. Zeeb if (wl->dbcc_info.real_band[i] == RTW89_BAND_2G) 2894*6d67aabdSBjoern A. Zeeb dbcc_2g_phy = i; 2895*6d67aabdSBjoern A. Zeeb } 2896*6d67aabdSBjoern A. Zeeb } else if (ver->fwlrole == 1) { 2897*6d67aabdSBjoern A. Zeeb link_mode = wl->role_info_v1.link_mode; 2898*6d67aabdSBjoern A. Zeeb dbcc_2g_phy = wl->role_info_v1.dbcc_2g_phy; 2899*6d67aabdSBjoern A. Zeeb } else if (ver->fwlrole == 2) { 2900*6d67aabdSBjoern A. Zeeb link_mode = wl->role_info_v2.link_mode; 2901*6d67aabdSBjoern A. Zeeb dbcc_2g_phy = wl->role_info_v2.dbcc_2g_phy; 29028e93258fSBjoern A. Zeeb } 29038e93258fSBjoern A. Zeeb 2904*6d67aabdSBjoern A. Zeeb /* decide trx_para_level */ 2905*6d67aabdSBjoern A. Zeeb if (btc->ant_type == BTC_ANT_SHARED) { 2906*6d67aabdSBjoern A. Zeeb /* fix LNA2 + TIA gain not change by GNT_BT */ 2907*6d67aabdSBjoern A. Zeeb if ((btc->dm.wl_btg_rx && b->profile_cnt.now != 0) || 2908*6d67aabdSBjoern A. Zeeb dm->bt_only == 1) 2909*6d67aabdSBjoern A. Zeeb dm->trx_para_level = 1; /* for better BT ACI issue */ 2910*6d67aabdSBjoern A. Zeeb else 2911*6d67aabdSBjoern A. Zeeb dm->trx_para_level = 0; 2912*6d67aabdSBjoern A. Zeeb } else { /* non-shared antenna */ 2913*6d67aabdSBjoern A. Zeeb dm->trx_para_level = 5; 2914*6d67aabdSBjoern A. Zeeb /* modify trx_para if WK 2.4G-STA-DL + bt link */ 2915*6d67aabdSBjoern A. Zeeb if (b->profile_cnt.now != 0 && 2916*6d67aabdSBjoern A. Zeeb link_mode == BTC_WLINK_2G_STA && 2917*6d67aabdSBjoern A. Zeeb wl->status.map.traffic_dir & BIT(RTW89_TFC_UL)) { /* uplink */ 2918*6d67aabdSBjoern A. Zeeb if (wl->rssi_level == 4 && bt->rssi_level > 2) 2919*6d67aabdSBjoern A. Zeeb dm->trx_para_level = 6; 2920*6d67aabdSBjoern A. Zeeb else if (wl->rssi_level == 3 && bt->rssi_level > 3) 2921*6d67aabdSBjoern A. Zeeb dm->trx_para_level = 7; 2922*6d67aabdSBjoern A. Zeeb } 2923*6d67aabdSBjoern A. Zeeb } 29248e93258fSBjoern A. Zeeb 2925*6d67aabdSBjoern A. Zeeb level_id = dm->trx_para_level; 29268e93258fSBjoern A. Zeeb if (level_id >= chip->rf_para_dlink_num || 29278e93258fSBjoern A. Zeeb level_id >= chip->rf_para_ulink_num) { 29288e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 29298e93258fSBjoern A. Zeeb "[BTC], %s(): invalid level_id: %d\n", 29308e93258fSBjoern A. Zeeb __func__, level_id); 29318e93258fSBjoern A. Zeeb return; 29328e93258fSBjoern A. Zeeb } 29338e93258fSBjoern A. Zeeb 29348e93258fSBjoern A. Zeeb if (wl->status.map.traffic_dir & BIT(RTW89_TFC_UL)) 29358e93258fSBjoern A. Zeeb para = chip->rf_para_ulink[level_id]; 29368e93258fSBjoern A. Zeeb else 29378e93258fSBjoern A. Zeeb para = chip->rf_para_dlink[level_id]; 29388e93258fSBjoern A. Zeeb 2939*6d67aabdSBjoern A. Zeeb if (dm->fddt_train) { 2940*6d67aabdSBjoern A. Zeeb _set_wl_rx_gain(rtwdev, 1); 2941*6d67aabdSBjoern A. Zeeb _write_scbd(rtwdev, BTC_WSCB_RXGAIN, true); 2942*6d67aabdSBjoern A. Zeeb } else { 29438e93258fSBjoern A. Zeeb _set_wl_tx_power(rtwdev, para.wl_tx_power); 29448e93258fSBjoern A. Zeeb _set_wl_rx_gain(rtwdev, para.wl_rx_gain); 29458e93258fSBjoern A. Zeeb _set_bt_tx_power(rtwdev, para.bt_tx_power); 29468e93258fSBjoern A. Zeeb _set_bt_rx_gain(rtwdev, para.bt_rx_gain); 2947*6d67aabdSBjoern A. Zeeb } 29488e93258fSBjoern A. Zeeb 2949*6d67aabdSBjoern A. Zeeb if (!bt->enable.now || dm->wl_only || wl_smap->rf_off || 2950*6d67aabdSBjoern A. Zeeb wl_smap->lps == BTC_LPS_RF_OFF || 2951*6d67aabdSBjoern A. Zeeb link_mode == BTC_WLINK_5G || 2952*6d67aabdSBjoern A. Zeeb link_mode == BTC_WLINK_NOLINK || 2953*6d67aabdSBjoern A. Zeeb (rtwdev->dbcc_en && dbcc_2g_phy != RTW89_PHY_1)) 29548e93258fSBjoern A. Zeeb wl_stb_chg = 0; 29558e93258fSBjoern A. Zeeb else 29568e93258fSBjoern A. Zeeb wl_stb_chg = 1; 29578e93258fSBjoern A. Zeeb 29588e93258fSBjoern A. Zeeb if (wl_stb_chg != dm->wl_stb_chg) { 29598e93258fSBjoern A. Zeeb dm->wl_stb_chg = wl_stb_chg; 29608e93258fSBjoern A. Zeeb chip->ops->btc_wl_s1_standby(rtwdev, dm->wl_stb_chg); 29618e93258fSBjoern A. Zeeb } 29628e93258fSBjoern A. Zeeb } 29638e93258fSBjoern A. Zeeb 29648e93258fSBjoern A. Zeeb static void _update_btc_state_map(struct rtw89_dev *rtwdev) 29658e93258fSBjoern A. Zeeb { 29668e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 29678e93258fSBjoern A. Zeeb struct rtw89_btc_cx *cx = &btc->cx; 29688e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &cx->wl; 29698e93258fSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &cx->bt; 29708e93258fSBjoern A. Zeeb struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info; 29718e93258fSBjoern A. Zeeb 29728e93258fSBjoern A. Zeeb if (wl->status.map.connecting || wl->status.map._4way || 29738e93258fSBjoern A. Zeeb wl->status.map.roaming) { 29748e93258fSBjoern A. Zeeb cx->state_map = BTC_WLINKING; 29758e93258fSBjoern A. Zeeb } else if (wl->status.map.scan) { /* wl scan */ 29768e93258fSBjoern A. Zeeb if (bt_linfo->status.map.inq_pag) 29778e93258fSBjoern A. Zeeb cx->state_map = BTC_WSCAN_BSCAN; 29788e93258fSBjoern A. Zeeb else 29798e93258fSBjoern A. Zeeb cx->state_map = BTC_WSCAN_BNOSCAN; 29808e93258fSBjoern A. Zeeb } else if (wl->status.map.busy) { /* only busy */ 29818e93258fSBjoern A. Zeeb if (bt_linfo->status.map.inq_pag) 29828e93258fSBjoern A. Zeeb cx->state_map = BTC_WBUSY_BSCAN; 29838e93258fSBjoern A. Zeeb else 29848e93258fSBjoern A. Zeeb cx->state_map = BTC_WBUSY_BNOSCAN; 29858e93258fSBjoern A. Zeeb } else { /* wl idle */ 29868e93258fSBjoern A. Zeeb cx->state_map = BTC_WIDLE; 29878e93258fSBjoern A. Zeeb } 29888e93258fSBjoern A. Zeeb } 29898e93258fSBjoern A. Zeeb 29908e93258fSBjoern A. Zeeb static void _set_bt_afh_info(struct rtw89_dev *rtwdev) 29918e93258fSBjoern A. Zeeb { 29928e93258fSBjoern A. Zeeb const struct rtw89_chip_info *chip = rtwdev->chip; 29938e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 2994e2340276SBjoern A. Zeeb const struct rtw89_btc_ver *ver = btc->ver; 29958e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 29968e93258fSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &btc->cx.bt; 29978e93258fSBjoern A. Zeeb struct rtw89_btc_bt_link_info *b = &bt->link_info; 29988e93258fSBjoern A. Zeeb struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; 29998e93258fSBjoern A. Zeeb struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1; 3000e2340276SBjoern A. Zeeb struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2; 3001*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_role_info_v8 *wl_rinfo_v8 = &wl->role_info_v8; 30028e93258fSBjoern A. Zeeb struct rtw89_btc_wl_active_role *r; 30038e93258fSBjoern A. Zeeb struct rtw89_btc_wl_active_role_v1 *r1; 3004e2340276SBjoern A. Zeeb struct rtw89_btc_wl_active_role_v2 *r2; 3005*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_rlink *rlink; 30068e93258fSBjoern A. Zeeb u8 en = 0, i, ch = 0, bw = 0; 30078e93258fSBjoern A. Zeeb u8 mode, connect_cnt; 30088e93258fSBjoern A. Zeeb 3009*6d67aabdSBjoern A. Zeeb if (btc->manual_ctrl || wl->status.map.scan) 30108e93258fSBjoern A. Zeeb return; 30118e93258fSBjoern A. Zeeb 3012e2340276SBjoern A. Zeeb if (ver->fwlrole == 0) { 30138e93258fSBjoern A. Zeeb mode = wl_rinfo->link_mode; 30148e93258fSBjoern A. Zeeb connect_cnt = wl_rinfo->connect_cnt; 3015e2340276SBjoern A. Zeeb } else if (ver->fwlrole == 1) { 30168e93258fSBjoern A. Zeeb mode = wl_rinfo_v1->link_mode; 30178e93258fSBjoern A. Zeeb connect_cnt = wl_rinfo_v1->connect_cnt; 3018e2340276SBjoern A. Zeeb } else if (ver->fwlrole == 2) { 3019e2340276SBjoern A. Zeeb mode = wl_rinfo_v2->link_mode; 3020e2340276SBjoern A. Zeeb connect_cnt = wl_rinfo_v2->connect_cnt; 3021*6d67aabdSBjoern A. Zeeb } else if (ver->fwlrole == 8) { 3022*6d67aabdSBjoern A. Zeeb mode = wl_rinfo_v8->link_mode; 3023*6d67aabdSBjoern A. Zeeb connect_cnt = wl_rinfo_v8->connect_cnt; 3024e2340276SBjoern A. Zeeb } else { 3025e2340276SBjoern A. Zeeb return; 30268e93258fSBjoern A. Zeeb } 30278e93258fSBjoern A. Zeeb 30288e93258fSBjoern A. Zeeb if (wl->status.map.rf_off || bt->whql_test || 30298e93258fSBjoern A. Zeeb mode == BTC_WLINK_NOLINK || mode == BTC_WLINK_5G || 30308e93258fSBjoern A. Zeeb connect_cnt > BTC_TDMA_WLROLE_MAX) { 30318e93258fSBjoern A. Zeeb en = false; 30328e93258fSBjoern A. Zeeb } else if (mode == BTC_WLINK_2G_MCC || mode == BTC_WLINK_2G_SCC) { 30338e93258fSBjoern A. Zeeb en = true; 30348e93258fSBjoern A. Zeeb /* get p2p channel */ 30358e93258fSBjoern A. Zeeb for (i = 0; i < RTW89_PORT_NUM; i++) { 30368e93258fSBjoern A. Zeeb r = &wl_rinfo->active_role[i]; 30378e93258fSBjoern A. Zeeb r1 = &wl_rinfo_v1->active_role_v1[i]; 3038e2340276SBjoern A. Zeeb r2 = &wl_rinfo_v2->active_role_v2[i]; 3039*6d67aabdSBjoern A. Zeeb rlink = &wl_rinfo_v8->rlink[i][0]; 30408e93258fSBjoern A. Zeeb 3041e2340276SBjoern A. Zeeb if (ver->fwlrole == 0 && 30428e93258fSBjoern A. Zeeb (r->role == RTW89_WIFI_ROLE_P2P_GO || 30438e93258fSBjoern A. Zeeb r->role == RTW89_WIFI_ROLE_P2P_CLIENT)) { 30448e93258fSBjoern A. Zeeb ch = r->ch; 30458e93258fSBjoern A. Zeeb bw = r->bw; 30468e93258fSBjoern A. Zeeb break; 3047e2340276SBjoern A. Zeeb } else if (ver->fwlrole == 1 && 30488e93258fSBjoern A. Zeeb (r1->role == RTW89_WIFI_ROLE_P2P_GO || 30498e93258fSBjoern A. Zeeb r1->role == RTW89_WIFI_ROLE_P2P_CLIENT)) { 30508e93258fSBjoern A. Zeeb ch = r1->ch; 30518e93258fSBjoern A. Zeeb bw = r1->bw; 30528e93258fSBjoern A. Zeeb break; 3053e2340276SBjoern A. Zeeb } else if (ver->fwlrole == 2 && 3054e2340276SBjoern A. Zeeb (r2->role == RTW89_WIFI_ROLE_P2P_GO || 3055e2340276SBjoern A. Zeeb r2->role == RTW89_WIFI_ROLE_P2P_CLIENT)) { 3056e2340276SBjoern A. Zeeb ch = r2->ch; 3057e2340276SBjoern A. Zeeb bw = r2->bw; 3058e2340276SBjoern A. Zeeb break; 3059*6d67aabdSBjoern A. Zeeb } else if (ver->fwlrole == 8 && 3060*6d67aabdSBjoern A. Zeeb (rlink->role == RTW89_WIFI_ROLE_P2P_GO || 3061*6d67aabdSBjoern A. Zeeb rlink->role == RTW89_WIFI_ROLE_P2P_CLIENT)) { 3062*6d67aabdSBjoern A. Zeeb ch = rlink->ch; 3063*6d67aabdSBjoern A. Zeeb bw = rlink->bw; 3064*6d67aabdSBjoern A. Zeeb break; 30658e93258fSBjoern A. Zeeb } 30668e93258fSBjoern A. Zeeb } 30678e93258fSBjoern A. Zeeb } else { 30688e93258fSBjoern A. Zeeb en = true; 30698e93258fSBjoern A. Zeeb /* get 2g channel */ 30708e93258fSBjoern A. Zeeb for (i = 0; i < RTW89_PORT_NUM; i++) { 30718e93258fSBjoern A. Zeeb r = &wl_rinfo->active_role[i]; 30728e93258fSBjoern A. Zeeb r1 = &wl_rinfo_v1->active_role_v1[i]; 3073e2340276SBjoern A. Zeeb r2 = &wl_rinfo_v2->active_role_v2[i]; 3074*6d67aabdSBjoern A. Zeeb rlink = &wl_rinfo_v8->rlink[i][0]; 30758e93258fSBjoern A. Zeeb 3076e2340276SBjoern A. Zeeb if (ver->fwlrole == 0 && 30778e93258fSBjoern A. Zeeb r->connected && r->band == RTW89_BAND_2G) { 30788e93258fSBjoern A. Zeeb ch = r->ch; 30798e93258fSBjoern A. Zeeb bw = r->bw; 30808e93258fSBjoern A. Zeeb break; 3081e2340276SBjoern A. Zeeb } else if (ver->fwlrole == 1 && 30828e93258fSBjoern A. Zeeb r1->connected && r1->band == RTW89_BAND_2G) { 30838e93258fSBjoern A. Zeeb ch = r1->ch; 30848e93258fSBjoern A. Zeeb bw = r1->bw; 30858e93258fSBjoern A. Zeeb break; 3086e2340276SBjoern A. Zeeb } else if (ver->fwlrole == 2 && 3087e2340276SBjoern A. Zeeb r2->connected && r2->band == RTW89_BAND_2G) { 3088e2340276SBjoern A. Zeeb ch = r2->ch; 3089e2340276SBjoern A. Zeeb bw = r2->bw; 3090e2340276SBjoern A. Zeeb break; 3091*6d67aabdSBjoern A. Zeeb } else if (ver->fwlrole == 8 && 3092*6d67aabdSBjoern A. Zeeb rlink->connected && rlink->rf_band == RTW89_BAND_2G) { 3093*6d67aabdSBjoern A. Zeeb ch = rlink->ch; 3094*6d67aabdSBjoern A. Zeeb bw = rlink->bw; 3095*6d67aabdSBjoern A. Zeeb break; 30968e93258fSBjoern A. Zeeb } 30978e93258fSBjoern A. Zeeb } 30988e93258fSBjoern A. Zeeb } 30998e93258fSBjoern A. Zeeb 31008e93258fSBjoern A. Zeeb switch (bw) { 31018e93258fSBjoern A. Zeeb case RTW89_CHANNEL_WIDTH_20: 31028e93258fSBjoern A. Zeeb bw = 20 + chip->afh_guard_ch * 2; 31038e93258fSBjoern A. Zeeb break; 31048e93258fSBjoern A. Zeeb case RTW89_CHANNEL_WIDTH_40: 31058e93258fSBjoern A. Zeeb bw = 40 + chip->afh_guard_ch * 2; 31068e93258fSBjoern A. Zeeb break; 31078e93258fSBjoern A. Zeeb case RTW89_CHANNEL_WIDTH_5: 31088e93258fSBjoern A. Zeeb bw = 5 + chip->afh_guard_ch * 2; 31098e93258fSBjoern A. Zeeb break; 31108e93258fSBjoern A. Zeeb case RTW89_CHANNEL_WIDTH_10: 31118e93258fSBjoern A. Zeeb bw = 10 + chip->afh_guard_ch * 2; 31128e93258fSBjoern A. Zeeb break; 31138e93258fSBjoern A. Zeeb default: 31148e93258fSBjoern A. Zeeb bw = 0; 31158e93258fSBjoern A. Zeeb en = false; /* turn off AFH info if BW > 40 */ 31168e93258fSBjoern A. Zeeb break; 31178e93258fSBjoern A. Zeeb } 31188e93258fSBjoern A. Zeeb 31198e93258fSBjoern A. Zeeb if (wl->afh_info.en == en && 31208e93258fSBjoern A. Zeeb wl->afh_info.ch == ch && 31218e93258fSBjoern A. Zeeb wl->afh_info.bw == bw && 31228e93258fSBjoern A. Zeeb b->profile_cnt.last == b->profile_cnt.now) { 31238e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 31248e93258fSBjoern A. Zeeb "[BTC], %s(): return because no change!\n", 31258e93258fSBjoern A. Zeeb __func__); 31268e93258fSBjoern A. Zeeb return; 31278e93258fSBjoern A. Zeeb } 31288e93258fSBjoern A. Zeeb 31298e93258fSBjoern A. Zeeb wl->afh_info.en = en; 31308e93258fSBjoern A. Zeeb wl->afh_info.ch = ch; 31318e93258fSBjoern A. Zeeb wl->afh_info.bw = bw; 31328e93258fSBjoern A. Zeeb 31338e93258fSBjoern A. Zeeb _send_fw_cmd(rtwdev, BTFC_SET, SET_BT_WL_CH_INFO, &wl->afh_info, 3); 31348e93258fSBjoern A. Zeeb 31358e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 31368e93258fSBjoern A. Zeeb "[BTC], %s(): en=%d, ch=%d, bw=%d\n", 31378e93258fSBjoern A. Zeeb __func__, en, ch, bw); 31388e93258fSBjoern A. Zeeb btc->cx.cnt_wl[BTC_WCNT_CH_UPDATE]++; 31398e93258fSBjoern A. Zeeb } 31408e93258fSBjoern A. Zeeb 31418e93258fSBjoern A. Zeeb static bool _check_freerun(struct rtw89_dev *rtwdev) 31428e93258fSBjoern A. Zeeb { 31438e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 31448e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 31458e93258fSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &btc->cx.bt; 31468e93258fSBjoern A. Zeeb struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; 31478e93258fSBjoern A. Zeeb struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1; 3148*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2; 3149*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_role_info_v8 *wl_rinfo_v8 = &wl->role_info_v8; 31508e93258fSBjoern A. Zeeb struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info; 31518e93258fSBjoern A. Zeeb struct rtw89_btc_bt_hid_desc *hid = &bt_linfo->hid_desc; 3152*6d67aabdSBjoern A. Zeeb union rtw89_btc_module_info *md = &btc->mdinfo; 3153*6d67aabdSBjoern A. Zeeb const struct rtw89_btc_ver *ver = btc->ver; 3154*6d67aabdSBjoern A. Zeeb u8 isolation, connect_cnt = 0; 31558e93258fSBjoern A. Zeeb 3156*6d67aabdSBjoern A. Zeeb if (ver->fcxinit == 7) 3157*6d67aabdSBjoern A. Zeeb isolation = md->md_v7.ant.isolation; 3158*6d67aabdSBjoern A. Zeeb else 3159*6d67aabdSBjoern A. Zeeb isolation = md->md.ant.isolation; 3160*6d67aabdSBjoern A. Zeeb 3161*6d67aabdSBjoern A. Zeeb if (ver->fwlrole == 0) 3162*6d67aabdSBjoern A. Zeeb connect_cnt = wl_rinfo->connect_cnt; 3163*6d67aabdSBjoern A. Zeeb else if (ver->fwlrole == 1) 3164*6d67aabdSBjoern A. Zeeb connect_cnt = wl_rinfo_v1->connect_cnt; 3165*6d67aabdSBjoern A. Zeeb else if (ver->fwlrole == 2) 3166*6d67aabdSBjoern A. Zeeb connect_cnt = wl_rinfo_v2->connect_cnt; 3167*6d67aabdSBjoern A. Zeeb else if (ver->fwlrole == 8) 3168*6d67aabdSBjoern A. Zeeb connect_cnt = wl_rinfo_v8->connect_cnt; 3169*6d67aabdSBjoern A. Zeeb 3170*6d67aabdSBjoern A. Zeeb if (btc->ant_type == BTC_ANT_SHARED) { 31718e93258fSBjoern A. Zeeb btc->dm.trx_para_level = 0; 31728e93258fSBjoern A. Zeeb return false; 31738e93258fSBjoern A. Zeeb } 31748e93258fSBjoern A. Zeeb 31758e93258fSBjoern A. Zeeb /* The below is dedicated antenna case */ 3176*6d67aabdSBjoern A. Zeeb if (connect_cnt > BTC_TDMA_WLROLE_MAX) { 31778e93258fSBjoern A. Zeeb btc->dm.trx_para_level = 5; 31788e93258fSBjoern A. Zeeb return true; 31798e93258fSBjoern A. Zeeb } 31808e93258fSBjoern A. Zeeb 31818e93258fSBjoern A. Zeeb if (bt_linfo->profile_cnt.now == 0) { 31828e93258fSBjoern A. Zeeb btc->dm.trx_para_level = 5; 31838e93258fSBjoern A. Zeeb return true; 31848e93258fSBjoern A. Zeeb } 31858e93258fSBjoern A. Zeeb 31868e93258fSBjoern A. Zeeb if (hid->pair_cnt > BTC_TDMA_BTHID_MAX) { 31878e93258fSBjoern A. Zeeb btc->dm.trx_para_level = 5; 31888e93258fSBjoern A. Zeeb return true; 31898e93258fSBjoern A. Zeeb } 31908e93258fSBjoern A. Zeeb 31918e93258fSBjoern A. Zeeb /* TODO get isolation by BT psd */ 3192*6d67aabdSBjoern A. Zeeb if (isolation >= BTC_FREERUN_ANTISO_MIN) { 31938e93258fSBjoern A. Zeeb btc->dm.trx_para_level = 5; 31948e93258fSBjoern A. Zeeb return true; 31958e93258fSBjoern A. Zeeb } 31968e93258fSBjoern A. Zeeb 31978e93258fSBjoern A. Zeeb if (!wl->status.map.busy) {/* wl idle -> freerun */ 31988e93258fSBjoern A. Zeeb btc->dm.trx_para_level = 5; 31998e93258fSBjoern A. Zeeb return true; 32008e93258fSBjoern A. Zeeb } else if (wl->rssi_level > 1) {/* WL rssi < 50% (-60dBm) */ 32018e93258fSBjoern A. Zeeb btc->dm.trx_para_level = 0; 32028e93258fSBjoern A. Zeeb return false; 32038e93258fSBjoern A. Zeeb } else if (wl->status.map.traffic_dir & BIT(RTW89_TFC_UL)) { 32048e93258fSBjoern A. Zeeb if (wl->rssi_level == 0 && bt_linfo->rssi > 31) { 32058e93258fSBjoern A. Zeeb btc->dm.trx_para_level = 6; 32068e93258fSBjoern A. Zeeb return true; 32078e93258fSBjoern A. Zeeb } else if (wl->rssi_level == 1 && bt_linfo->rssi > 36) { 32088e93258fSBjoern A. Zeeb btc->dm.trx_para_level = 7; 32098e93258fSBjoern A. Zeeb return true; 32108e93258fSBjoern A. Zeeb } 32118e93258fSBjoern A. Zeeb btc->dm.trx_para_level = 0; 32128e93258fSBjoern A. Zeeb return false; 32138e93258fSBjoern A. Zeeb } else if (wl->status.map.traffic_dir & BIT(RTW89_TFC_DL)) { 32148e93258fSBjoern A. Zeeb if (bt_linfo->rssi > 28) { 32158e93258fSBjoern A. Zeeb btc->dm.trx_para_level = 6; 32168e93258fSBjoern A. Zeeb return true; 32178e93258fSBjoern A. Zeeb } 32188e93258fSBjoern A. Zeeb } 32198e93258fSBjoern A. Zeeb 32208e93258fSBjoern A. Zeeb btc->dm.trx_para_level = 0; 32218e93258fSBjoern A. Zeeb return false; 32228e93258fSBjoern A. Zeeb } 32238e93258fSBjoern A. Zeeb 32248e93258fSBjoern A. Zeeb #define _tdma_set_flctrl(btc, flc) ({(btc)->dm.tdma.rxflctrl = flc; }) 32258e93258fSBjoern A. Zeeb #define _tdma_set_flctrl_role(btc, role) ({(btc)->dm.tdma.rxflctrl_role = role; }) 32268e93258fSBjoern A. Zeeb #define _tdma_set_tog(btc, wtg) ({(btc)->dm.tdma.wtgle_n = wtg; }) 32278e93258fSBjoern A. Zeeb #define _tdma_set_lek(btc, lek) ({(btc)->dm.tdma.leak_n = lek; }) 32288e93258fSBjoern A. Zeeb 32298e93258fSBjoern A. Zeeb struct btc_btinfo_lb2 { 32308e93258fSBjoern A. Zeeb u8 connect: 1; 32318e93258fSBjoern A. Zeeb u8 sco_busy: 1; 32328e93258fSBjoern A. Zeeb u8 inq_pag: 1; 32338e93258fSBjoern A. Zeeb u8 acl_busy: 1; 32348e93258fSBjoern A. Zeeb u8 hfp: 1; 32358e93258fSBjoern A. Zeeb u8 hid: 1; 32368e93258fSBjoern A. Zeeb u8 a2dp: 1; 32378e93258fSBjoern A. Zeeb u8 pan: 1; 32388e93258fSBjoern A. Zeeb }; 32398e93258fSBjoern A. Zeeb 32408e93258fSBjoern A. Zeeb struct btc_btinfo_lb3 { 32418e93258fSBjoern A. Zeeb u8 retry: 4; 32428e93258fSBjoern A. Zeeb u8 cqddr: 1; 32438e93258fSBjoern A. Zeeb u8 inq: 1; 32448e93258fSBjoern A. Zeeb u8 mesh_busy: 1; 32458e93258fSBjoern A. Zeeb u8 pag: 1; 32468e93258fSBjoern A. Zeeb }; 32478e93258fSBjoern A. Zeeb 32488e93258fSBjoern A. Zeeb struct btc_btinfo_hb0 { 32498e93258fSBjoern A. Zeeb s8 rssi; 32508e93258fSBjoern A. Zeeb }; 32518e93258fSBjoern A. Zeeb 32528e93258fSBjoern A. Zeeb struct btc_btinfo_hb1 { 32538e93258fSBjoern A. Zeeb u8 ble_connect: 1; 32548e93258fSBjoern A. Zeeb u8 reinit: 1; 32558e93258fSBjoern A. Zeeb u8 relink: 1; 32568e93258fSBjoern A. Zeeb u8 igno_wl: 1; 32578e93258fSBjoern A. Zeeb u8 voice: 1; 32588e93258fSBjoern A. Zeeb u8 ble_scan: 1; 32598e93258fSBjoern A. Zeeb u8 role_sw: 1; 32608e93258fSBjoern A. Zeeb u8 multi_link: 1; 32618e93258fSBjoern A. Zeeb }; 32628e93258fSBjoern A. Zeeb 32638e93258fSBjoern A. Zeeb struct btc_btinfo_hb2 { 32648e93258fSBjoern A. Zeeb u8 pan_active: 1; 32658e93258fSBjoern A. Zeeb u8 afh_update: 1; 32668e93258fSBjoern A. Zeeb u8 a2dp_active: 1; 32678e93258fSBjoern A. Zeeb u8 slave: 1; 32688e93258fSBjoern A. Zeeb u8 hid_slot: 2; 32698e93258fSBjoern A. Zeeb u8 hid_cnt: 2; 32708e93258fSBjoern A. Zeeb }; 32718e93258fSBjoern A. Zeeb 32728e93258fSBjoern A. Zeeb struct btc_btinfo_hb3 { 32738e93258fSBjoern A. Zeeb u8 a2dp_bitpool: 6; 32748e93258fSBjoern A. Zeeb u8 tx_3m: 1; 32758e93258fSBjoern A. Zeeb u8 a2dp_sink: 1; 32768e93258fSBjoern A. Zeeb }; 32778e93258fSBjoern A. Zeeb 32788e93258fSBjoern A. Zeeb union btc_btinfo { 32798e93258fSBjoern A. Zeeb u8 val; 32808e93258fSBjoern A. Zeeb struct btc_btinfo_lb2 lb2; 32818e93258fSBjoern A. Zeeb struct btc_btinfo_lb3 lb3; 32828e93258fSBjoern A. Zeeb struct btc_btinfo_hb0 hb0; 32838e93258fSBjoern A. Zeeb struct btc_btinfo_hb1 hb1; 32848e93258fSBjoern A. Zeeb struct btc_btinfo_hb2 hb2; 32858e93258fSBjoern A. Zeeb struct btc_btinfo_hb3 hb3; 32868e93258fSBjoern A. Zeeb }; 32878e93258fSBjoern A. Zeeb 32888e93258fSBjoern A. Zeeb static void _set_policy(struct rtw89_dev *rtwdev, u16 policy_type, 32898e93258fSBjoern A. Zeeb enum btc_reason_and_action action) 32908e93258fSBjoern A. Zeeb { 32918e93258fSBjoern A. Zeeb const struct rtw89_chip_info *chip = rtwdev->chip; 32928e93258fSBjoern A. Zeeb 32938e93258fSBjoern A. Zeeb chip->ops->btc_set_policy(rtwdev, policy_type); 32948e93258fSBjoern A. Zeeb _fw_set_policy(rtwdev, policy_type, action); 32958e93258fSBjoern A. Zeeb } 32968e93258fSBjoern A. Zeeb 32978e93258fSBjoern A. Zeeb #define BTC_B1_MAX 250 /* unit ms */ 32988e93258fSBjoern A. Zeeb void rtw89_btc_set_policy(struct rtw89_dev *rtwdev, u16 policy_type) 32998e93258fSBjoern A. Zeeb { 33008e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 33018e93258fSBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 33028e93258fSBjoern A. Zeeb struct rtw89_btc_fbtc_tdma *t = &dm->tdma; 3303*6d67aabdSBjoern A. Zeeb struct rtw89_btc_fbtc_slot *s = dm->slot.v1; 33048e93258fSBjoern A. Zeeb u8 type; 33058e93258fSBjoern A. Zeeb u32 tbl_w1, tbl_b1, tbl_b4; 33068e93258fSBjoern A. Zeeb 3307*6d67aabdSBjoern A. Zeeb if (btc->ant_type == BTC_ANT_SHARED) { 33088e93258fSBjoern A. Zeeb if (btc->cx.wl.status.map._4way) 33098e93258fSBjoern A. Zeeb tbl_w1 = cxtbl[1]; 33108e93258fSBjoern A. Zeeb else 33118e93258fSBjoern A. Zeeb tbl_w1 = cxtbl[8]; 33128e93258fSBjoern A. Zeeb tbl_b1 = cxtbl[3]; 33138e93258fSBjoern A. Zeeb tbl_b4 = cxtbl[3]; 33148e93258fSBjoern A. Zeeb } else { 33158e93258fSBjoern A. Zeeb tbl_w1 = cxtbl[16]; 33168e93258fSBjoern A. Zeeb tbl_b1 = cxtbl[17]; 33178e93258fSBjoern A. Zeeb tbl_b4 = cxtbl[17]; 33188e93258fSBjoern A. Zeeb } 33198e93258fSBjoern A. Zeeb 33208e93258fSBjoern A. Zeeb type = (u8)((policy_type & BTC_CXP_MASK) >> 8); 33218e93258fSBjoern A. Zeeb btc->bt_req_en = false; 33228e93258fSBjoern A. Zeeb 33238e93258fSBjoern A. Zeeb switch (type) { 33248e93258fSBjoern A. Zeeb case BTC_CXP_USERDEF0: 33258e93258fSBjoern A. Zeeb *t = t_def[CXTD_OFF]; 33268e93258fSBjoern A. Zeeb s[CXST_OFF] = s_def[CXST_OFF]; 33278e93258fSBjoern A. Zeeb _slot_set_tbl(btc, CXST_OFF, cxtbl[2]); 33288e93258fSBjoern A. Zeeb btc->update_policy_force = true; 33298e93258fSBjoern A. Zeeb break; 33308e93258fSBjoern A. Zeeb case BTC_CXP_OFF: /* TDMA off */ 33318e93258fSBjoern A. Zeeb _write_scbd(rtwdev, BTC_WSCB_TDMA, false); 33328e93258fSBjoern A. Zeeb *t = t_def[CXTD_OFF]; 33338e93258fSBjoern A. Zeeb s[CXST_OFF] = s_def[CXST_OFF]; 33348e93258fSBjoern A. Zeeb 33358e93258fSBjoern A. Zeeb switch (policy_type) { 33368e93258fSBjoern A. Zeeb case BTC_CXP_OFF_BT: 33378e93258fSBjoern A. Zeeb _slot_set_tbl(btc, CXST_OFF, cxtbl[2]); 33388e93258fSBjoern A. Zeeb break; 33398e93258fSBjoern A. Zeeb case BTC_CXP_OFF_WL: 33408e93258fSBjoern A. Zeeb _slot_set_tbl(btc, CXST_OFF, cxtbl[1]); 33418e93258fSBjoern A. Zeeb break; 33428e93258fSBjoern A. Zeeb case BTC_CXP_OFF_EQ0: 33438e93258fSBjoern A. Zeeb _slot_set_tbl(btc, CXST_OFF, cxtbl[0]); 33448e93258fSBjoern A. Zeeb break; 33458e93258fSBjoern A. Zeeb case BTC_CXP_OFF_EQ1: 33468e93258fSBjoern A. Zeeb _slot_set_tbl(btc, CXST_OFF, cxtbl[16]); 33478e93258fSBjoern A. Zeeb break; 33488e93258fSBjoern A. Zeeb case BTC_CXP_OFF_EQ2: 33498e93258fSBjoern A. Zeeb _slot_set_tbl(btc, CXST_OFF, cxtbl[17]); 33508e93258fSBjoern A. Zeeb break; 33518e93258fSBjoern A. Zeeb case BTC_CXP_OFF_EQ3: 33528e93258fSBjoern A. Zeeb _slot_set_tbl(btc, CXST_OFF, cxtbl[18]); 33538e93258fSBjoern A. Zeeb break; 33548e93258fSBjoern A. Zeeb case BTC_CXP_OFF_BWB0: 33558e93258fSBjoern A. Zeeb _slot_set_tbl(btc, CXST_OFF, cxtbl[5]); 33568e93258fSBjoern A. Zeeb break; 33578e93258fSBjoern A. Zeeb case BTC_CXP_OFF_BWB1: 33588e93258fSBjoern A. Zeeb _slot_set_tbl(btc, CXST_OFF, cxtbl[8]); 33598e93258fSBjoern A. Zeeb break; 3360e2340276SBjoern A. Zeeb case BTC_CXP_OFF_BWB3: 3361e2340276SBjoern A. Zeeb _slot_set_tbl(btc, CXST_OFF, cxtbl[6]); 3362e2340276SBjoern A. Zeeb break; 33638e93258fSBjoern A. Zeeb } 33648e93258fSBjoern A. Zeeb break; 33658e93258fSBjoern A. Zeeb case BTC_CXP_OFFB: /* TDMA off + beacon protect */ 33668e93258fSBjoern A. Zeeb _write_scbd(rtwdev, BTC_WSCB_TDMA, false); 33678e93258fSBjoern A. Zeeb *t = t_def[CXTD_OFF_B2]; 33688e93258fSBjoern A. Zeeb s[CXST_OFF] = s_def[CXST_OFF]; 33698e93258fSBjoern A. Zeeb switch (policy_type) { 33708e93258fSBjoern A. Zeeb case BTC_CXP_OFFB_BWB0: 33718e93258fSBjoern A. Zeeb _slot_set_tbl(btc, CXST_OFF, cxtbl[8]); 33728e93258fSBjoern A. Zeeb break; 33738e93258fSBjoern A. Zeeb } 33748e93258fSBjoern A. Zeeb break; 33758e93258fSBjoern A. Zeeb case BTC_CXP_OFFE: /* TDMA off + beacon protect + Ext_control */ 33768e93258fSBjoern A. Zeeb btc->bt_req_en = true; 33778e93258fSBjoern A. Zeeb _write_scbd(rtwdev, BTC_WSCB_TDMA, true); 33788e93258fSBjoern A. Zeeb *t = t_def[CXTD_OFF_EXT]; 33798e93258fSBjoern A. Zeeb switch (policy_type) { 33808e93258fSBjoern A. Zeeb case BTC_CXP_OFFE_DEF: 33818e93258fSBjoern A. Zeeb s[CXST_E2G] = s_def[CXST_E2G]; 33828e93258fSBjoern A. Zeeb s[CXST_E5G] = s_def[CXST_E5G]; 33838e93258fSBjoern A. Zeeb s[CXST_EBT] = s_def[CXST_EBT]; 33848e93258fSBjoern A. Zeeb s[CXST_ENULL] = s_def[CXST_ENULL]; 33858e93258fSBjoern A. Zeeb break; 33868e93258fSBjoern A. Zeeb case BTC_CXP_OFFE_DEF2: 33878e93258fSBjoern A. Zeeb _slot_set(btc, CXST_E2G, 20, cxtbl[1], SLOT_ISO); 33888e93258fSBjoern A. Zeeb s[CXST_E5G] = s_def[CXST_E5G]; 33898e93258fSBjoern A. Zeeb s[CXST_EBT] = s_def[CXST_EBT]; 33908e93258fSBjoern A. Zeeb s[CXST_ENULL] = s_def[CXST_ENULL]; 33918e93258fSBjoern A. Zeeb break; 33928e93258fSBjoern A. Zeeb } 33938e93258fSBjoern A. Zeeb break; 33948e93258fSBjoern A. Zeeb case BTC_CXP_FIX: /* TDMA Fix-Slot */ 33958e93258fSBjoern A. Zeeb _write_scbd(rtwdev, BTC_WSCB_TDMA, true); 33968e93258fSBjoern A. Zeeb *t = t_def[CXTD_FIX]; 33978e93258fSBjoern A. Zeeb switch (policy_type) { 33988e93258fSBjoern A. Zeeb case BTC_CXP_FIX_TD3030: 33998e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); 34008e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX); 34018e93258fSBjoern A. Zeeb break; 34028e93258fSBjoern A. Zeeb case BTC_CXP_FIX_TD5050: 34038e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); 34048e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, 50, tbl_b1, SLOT_MIX); 34058e93258fSBjoern A. Zeeb break; 34068e93258fSBjoern A. Zeeb case BTC_CXP_FIX_TD2030: 34078e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); 34088e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX); 34098e93258fSBjoern A. Zeeb break; 34108e93258fSBjoern A. Zeeb case BTC_CXP_FIX_TD4010: 34118e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 40, tbl_w1, SLOT_ISO); 34128e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, 10, tbl_b1, SLOT_MIX); 34138e93258fSBjoern A. Zeeb break; 3414*6d67aabdSBjoern A. Zeeb case BTC_CXP_FIX_TD4010ISO: 3415*6d67aabdSBjoern A. Zeeb _slot_set(btc, CXST_W1, 40, cxtbl[1], SLOT_ISO); 3416*6d67aabdSBjoern A. Zeeb _slot_set(btc, CXST_B1, 10, tbl_b1, SLOT_MIX); 3417*6d67aabdSBjoern A. Zeeb break; 3418*6d67aabdSBjoern A. Zeeb case BTC_CXP_FIX_TD4010ISO_DL: 3419*6d67aabdSBjoern A. Zeeb _slot_set(btc, CXST_W1, 40, cxtbl[25], SLOT_ISO); 3420*6d67aabdSBjoern A. Zeeb _slot_set(btc, CXST_B1, 10, cxtbl[25], SLOT_ISO); 3421*6d67aabdSBjoern A. Zeeb break; 3422*6d67aabdSBjoern A. Zeeb case BTC_CXP_FIX_TD4010ISO_UL: 3423*6d67aabdSBjoern A. Zeeb _slot_set(btc, CXST_W1, 40, cxtbl[20], SLOT_ISO); 3424*6d67aabdSBjoern A. Zeeb _slot_set(btc, CXST_B1, 10, cxtbl[25], SLOT_MIX); 34258e93258fSBjoern A. Zeeb break; 34268e93258fSBjoern A. Zeeb case BTC_CXP_FIX_TD7010: 34278e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 70, tbl_w1, SLOT_ISO); 34288e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, 10, tbl_b1, SLOT_MIX); 34298e93258fSBjoern A. Zeeb break; 34308e93258fSBjoern A. Zeeb case BTC_CXP_FIX_TD2060: 34318e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); 34328e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX); 34338e93258fSBjoern A. Zeeb break; 34348e93258fSBjoern A. Zeeb case BTC_CXP_FIX_TD3060: 34358e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); 34368e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX); 34378e93258fSBjoern A. Zeeb break; 34388e93258fSBjoern A. Zeeb case BTC_CXP_FIX_TD2080: 34398e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); 34408e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, 80, tbl_b1, SLOT_MIX); 34418e93258fSBjoern A. Zeeb break; 34428e93258fSBjoern A. Zeeb case BTC_CXP_FIX_TDW1B1: /* W1:B1 = user-define */ 34438e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], 34448e93258fSBjoern A. Zeeb tbl_w1, SLOT_ISO); 34458e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1], 34468e93258fSBjoern A. Zeeb tbl_b1, SLOT_MIX); 34478e93258fSBjoern A. Zeeb break; 34488e93258fSBjoern A. Zeeb } 34498e93258fSBjoern A. Zeeb break; 34508e93258fSBjoern A. Zeeb case BTC_CXP_PFIX: /* PS-TDMA Fix-Slot */ 34518e93258fSBjoern A. Zeeb _write_scbd(rtwdev, BTC_WSCB_TDMA, true); 34528e93258fSBjoern A. Zeeb *t = t_def[CXTD_PFIX]; 34538e93258fSBjoern A. Zeeb if (btc->cx.wl.role_info.role_map.role.ap) 34548e93258fSBjoern A. Zeeb _tdma_set_flctrl(btc, CXFLC_QOSNULL); 34558e93258fSBjoern A. Zeeb 34568e93258fSBjoern A. Zeeb switch (policy_type) { 34578e93258fSBjoern A. Zeeb case BTC_CXP_PFIX_TD3030: 34588e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); 34598e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX); 34608e93258fSBjoern A. Zeeb break; 34618e93258fSBjoern A. Zeeb case BTC_CXP_PFIX_TD5050: 34628e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); 34638e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, 50, tbl_b1, SLOT_MIX); 34648e93258fSBjoern A. Zeeb break; 34658e93258fSBjoern A. Zeeb case BTC_CXP_PFIX_TD2030: 34668e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); 34678e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX); 34688e93258fSBjoern A. Zeeb break; 34698e93258fSBjoern A. Zeeb case BTC_CXP_PFIX_TD2060: 34708e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); 34718e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX); 34728e93258fSBjoern A. Zeeb break; 34738e93258fSBjoern A. Zeeb case BTC_CXP_PFIX_TD3070: 34748e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); 34758e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX); 34768e93258fSBjoern A. Zeeb break; 34778e93258fSBjoern A. Zeeb case BTC_CXP_PFIX_TD2080: 34788e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); 34798e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, 80, tbl_b1, SLOT_MIX); 34808e93258fSBjoern A. Zeeb break; 34818e93258fSBjoern A. Zeeb } 34828e93258fSBjoern A. Zeeb break; 34838e93258fSBjoern A. Zeeb case BTC_CXP_AUTO: /* TDMA Auto-Slot */ 34848e93258fSBjoern A. Zeeb _write_scbd(rtwdev, BTC_WSCB_TDMA, true); 34858e93258fSBjoern A. Zeeb *t = t_def[CXTD_AUTO]; 34868e93258fSBjoern A. Zeeb switch (policy_type) { 34878e93258fSBjoern A. Zeeb case BTC_CXP_AUTO_TD50B1: 34888e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); 34898e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 34908e93258fSBjoern A. Zeeb break; 34918e93258fSBjoern A. Zeeb case BTC_CXP_AUTO_TD60B1: 34928e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO); 34938e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 34948e93258fSBjoern A. Zeeb break; 34958e93258fSBjoern A. Zeeb case BTC_CXP_AUTO_TD20B1: 34968e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); 34978e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 34988e93258fSBjoern A. Zeeb break; 34998e93258fSBjoern A. Zeeb case BTC_CXP_AUTO_TDW1B1: /* W1:B1 = user-define */ 35008e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], 35018e93258fSBjoern A. Zeeb tbl_w1, SLOT_ISO); 35028e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1], 35038e93258fSBjoern A. Zeeb tbl_b1, SLOT_MIX); 35048e93258fSBjoern A. Zeeb break; 35058e93258fSBjoern A. Zeeb } 35068e93258fSBjoern A. Zeeb break; 35078e93258fSBjoern A. Zeeb case BTC_CXP_PAUTO: /* PS-TDMA Auto-Slot */ 35088e93258fSBjoern A. Zeeb _write_scbd(rtwdev, BTC_WSCB_TDMA, true); 35098e93258fSBjoern A. Zeeb *t = t_def[CXTD_PAUTO]; 35108e93258fSBjoern A. Zeeb switch (policy_type) { 35118e93258fSBjoern A. Zeeb case BTC_CXP_PAUTO_TD50B1: 35128e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); 35138e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 35148e93258fSBjoern A. Zeeb break; 35158e93258fSBjoern A. Zeeb case BTC_CXP_PAUTO_TD60B1: 35168e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO); 35178e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 35188e93258fSBjoern A. Zeeb break; 35198e93258fSBjoern A. Zeeb case BTC_CXP_PAUTO_TD20B1: 35208e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); 35218e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 35228e93258fSBjoern A. Zeeb break; 35238e93258fSBjoern A. Zeeb case BTC_CXP_PAUTO_TDW1B1: 35248e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], 35258e93258fSBjoern A. Zeeb tbl_w1, SLOT_ISO); 35268e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1], 35278e93258fSBjoern A. Zeeb tbl_b1, SLOT_MIX); 35288e93258fSBjoern A. Zeeb break; 35298e93258fSBjoern A. Zeeb } 35308e93258fSBjoern A. Zeeb break; 35318e93258fSBjoern A. Zeeb case BTC_CXP_AUTO2: /* TDMA Auto-Slot2 */ 35328e93258fSBjoern A. Zeeb _write_scbd(rtwdev, BTC_WSCB_TDMA, true); 35338e93258fSBjoern A. Zeeb *t = t_def[CXTD_AUTO2]; 35348e93258fSBjoern A. Zeeb switch (policy_type) { 35358e93258fSBjoern A. Zeeb case BTC_CXP_AUTO2_TD3050: 35368e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); 35378e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX); 35388e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 35398e93258fSBjoern A. Zeeb break; 35408e93258fSBjoern A. Zeeb case BTC_CXP_AUTO2_TD3070: 35418e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); 35428e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B4, 70, tbl_b4, SLOT_MIX); 35438e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 35448e93258fSBjoern A. Zeeb break; 35458e93258fSBjoern A. Zeeb case BTC_CXP_AUTO2_TD5050: 35468e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); 35478e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX); 35488e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 35498e93258fSBjoern A. Zeeb break; 35508e93258fSBjoern A. Zeeb case BTC_CXP_AUTO2_TD6060: 35518e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO); 35528e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B4, 60, tbl_b4, SLOT_MIX); 35538e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 35548e93258fSBjoern A. Zeeb break; 35558e93258fSBjoern A. Zeeb case BTC_CXP_AUTO2_TD2080: 35568e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); 35578e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B4, 80, tbl_b4, SLOT_MIX); 35588e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 35598e93258fSBjoern A. Zeeb break; 35608e93258fSBjoern A. Zeeb case BTC_CXP_AUTO2_TDW1B4: /* W1:B1 = user-define */ 35618e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], 35628e93258fSBjoern A. Zeeb tbl_w1, SLOT_ISO); 35638e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B4, dm->slot_dur[CXST_B4], 35648e93258fSBjoern A. Zeeb tbl_b4, SLOT_MIX); 35658e93258fSBjoern A. Zeeb break; 35668e93258fSBjoern A. Zeeb } 35678e93258fSBjoern A. Zeeb break; 35688e93258fSBjoern A. Zeeb case BTC_CXP_PAUTO2: /* PS-TDMA Auto-Slot2 */ 35698e93258fSBjoern A. Zeeb _write_scbd(rtwdev, BTC_WSCB_TDMA, true); 35708e93258fSBjoern A. Zeeb *t = t_def[CXTD_PAUTO2]; 35718e93258fSBjoern A. Zeeb switch (policy_type) { 35728e93258fSBjoern A. Zeeb case BTC_CXP_PAUTO2_TD3050: 35738e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); 35748e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX); 35758e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 35768e93258fSBjoern A. Zeeb break; 35778e93258fSBjoern A. Zeeb case BTC_CXP_PAUTO2_TD3070: 35788e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); 35798e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B4, 70, tbl_b4, SLOT_MIX); 35808e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 35818e93258fSBjoern A. Zeeb break; 35828e93258fSBjoern A. Zeeb case BTC_CXP_PAUTO2_TD5050: 35838e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); 35848e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX); 35858e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 35868e93258fSBjoern A. Zeeb break; 35878e93258fSBjoern A. Zeeb case BTC_CXP_PAUTO2_TD6060: 35888e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO); 35898e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B4, 60, tbl_b4, SLOT_MIX); 35908e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 35918e93258fSBjoern A. Zeeb break; 35928e93258fSBjoern A. Zeeb case BTC_CXP_PAUTO2_TD2080: 35938e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); 35948e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B4, 80, tbl_b4, SLOT_MIX); 35958e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 35968e93258fSBjoern A. Zeeb break; 35978e93258fSBjoern A. Zeeb case BTC_CXP_PAUTO2_TDW1B4: /* W1:B1 = user-define */ 35988e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], 35998e93258fSBjoern A. Zeeb tbl_w1, SLOT_ISO); 36008e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B4, dm->slot_dur[CXST_B4], 36018e93258fSBjoern A. Zeeb tbl_b4, SLOT_MIX); 36028e93258fSBjoern A. Zeeb break; 36038e93258fSBjoern A. Zeeb } 36048e93258fSBjoern A. Zeeb break; 36058e93258fSBjoern A. Zeeb } 36068e93258fSBjoern A. Zeeb } 36078e93258fSBjoern A. Zeeb EXPORT_SYMBOL(rtw89_btc_set_policy); 36088e93258fSBjoern A. Zeeb 36098e93258fSBjoern A. Zeeb void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type) 36108e93258fSBjoern A. Zeeb { 36118e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 36128e93258fSBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 36138e93258fSBjoern A. Zeeb struct rtw89_btc_fbtc_tdma *t = &dm->tdma; 36148e93258fSBjoern A. Zeeb struct rtw89_btc_wl_role_info_v1 *wl_rinfo = &btc->cx.wl.role_info_v1; 36158e93258fSBjoern A. Zeeb struct rtw89_btc_bt_hid_desc *hid = &btc->cx.bt.link_info.hid_desc; 36168e93258fSBjoern A. Zeeb struct rtw89_btc_bt_hfp_desc *hfp = &btc->cx.bt.link_info.hfp_desc; 3617*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 36188e93258fSBjoern A. Zeeb u8 type, null_role; 36198e93258fSBjoern A. Zeeb u32 tbl_w1, tbl_b1, tbl_b4; 3620*6d67aabdSBjoern A. Zeeb u16 dur_2; 36218e93258fSBjoern A. Zeeb 36228e93258fSBjoern A. Zeeb type = FIELD_GET(BTC_CXP_MASK, policy_type); 36238e93258fSBjoern A. Zeeb 3624*6d67aabdSBjoern A. Zeeb if (btc->ant_type == BTC_ANT_SHARED) { 36258e93258fSBjoern A. Zeeb if (btc->cx.wl.status.map._4way) 36268e93258fSBjoern A. Zeeb tbl_w1 = cxtbl[1]; 36278e93258fSBjoern A. Zeeb else if (hid->exist && hid->type == BTC_HID_218) 36288e93258fSBjoern A. Zeeb tbl_w1 = cxtbl[7]; /* Ack/BA no break bt Hi-Pri-rx */ 36298e93258fSBjoern A. Zeeb else 36308e93258fSBjoern A. Zeeb tbl_w1 = cxtbl[8]; 36318e93258fSBjoern A. Zeeb 36328e93258fSBjoern A. Zeeb if (dm->leak_ap && 36338e93258fSBjoern A. Zeeb (type == BTC_CXP_PFIX || type == BTC_CXP_PAUTO2)) { 36348e93258fSBjoern A. Zeeb tbl_b1 = cxtbl[3]; 36358e93258fSBjoern A. Zeeb tbl_b4 = cxtbl[3]; 36368e93258fSBjoern A. Zeeb } else if (hid->exist && hid->type == BTC_HID_218) { 36378e93258fSBjoern A. Zeeb tbl_b1 = cxtbl[4]; /* Ack/BA no break bt Hi-Pri-rx */ 36388e93258fSBjoern A. Zeeb tbl_b4 = cxtbl[4]; 36398e93258fSBjoern A. Zeeb } else { 36408e93258fSBjoern A. Zeeb tbl_b1 = cxtbl[2]; 36418e93258fSBjoern A. Zeeb tbl_b4 = cxtbl[2]; 36428e93258fSBjoern A. Zeeb } 36438e93258fSBjoern A. Zeeb } else { 36448e93258fSBjoern A. Zeeb tbl_b1 = cxtbl[17]; 36458e93258fSBjoern A. Zeeb tbl_b4 = cxtbl[17]; 3646*6d67aabdSBjoern A. Zeeb 3647*6d67aabdSBjoern A. Zeeb if (wl->bg_mode) 3648*6d67aabdSBjoern A. Zeeb tbl_w1 = cxtbl[8]; 3649*6d67aabdSBjoern A. Zeeb else if ((wl->status.map.traffic_dir & BIT(RTW89_TFC_UL)) && 3650*6d67aabdSBjoern A. Zeeb hid->exist) 3651*6d67aabdSBjoern A. Zeeb tbl_w1 = cxtbl[19]; 3652*6d67aabdSBjoern A. Zeeb else 3653*6d67aabdSBjoern A. Zeeb tbl_w1 = cxtbl[16]; 36548e93258fSBjoern A. Zeeb } 36558e93258fSBjoern A. Zeeb 36568e93258fSBjoern A. Zeeb btc->bt_req_en = false; 36578e93258fSBjoern A. Zeeb 36588e93258fSBjoern A. Zeeb switch (type) { 36598e93258fSBjoern A. Zeeb case BTC_CXP_USERDEF0: 36608e93258fSBjoern A. Zeeb btc->update_policy_force = true; 36618e93258fSBjoern A. Zeeb *t = t_def[CXTD_OFF]; 3662*6d67aabdSBjoern A. Zeeb _slot_set_le(btc, CXST_OFF, s_def[CXST_OFF].dur, 3663*6d67aabdSBjoern A. Zeeb s_def[CXST_OFF].cxtbl, s_def[CXST_OFF].cxtype); 36648e93258fSBjoern A. Zeeb _slot_set_tbl(btc, CXST_OFF, cxtbl[2]); 36658e93258fSBjoern A. Zeeb break; 36668e93258fSBjoern A. Zeeb case BTC_CXP_OFF: /* TDMA off */ 36678e93258fSBjoern A. Zeeb _write_scbd(rtwdev, BTC_WSCB_TDMA, false); 36688e93258fSBjoern A. Zeeb *t = t_def[CXTD_OFF]; 3669*6d67aabdSBjoern A. Zeeb _slot_set_le(btc, CXST_OFF, s_def[CXST_OFF].dur, 3670*6d67aabdSBjoern A. Zeeb s_def[CXST_OFF].cxtbl, s_def[CXST_OFF].cxtype); 36718e93258fSBjoern A. Zeeb 36728e93258fSBjoern A. Zeeb switch (policy_type) { 36738e93258fSBjoern A. Zeeb case BTC_CXP_OFF_BT: 36748e93258fSBjoern A. Zeeb _slot_set_tbl(btc, CXST_OFF, cxtbl[2]); 36758e93258fSBjoern A. Zeeb break; 36768e93258fSBjoern A. Zeeb case BTC_CXP_OFF_WL: 36778e93258fSBjoern A. Zeeb _slot_set_tbl(btc, CXST_OFF, cxtbl[1]); 36788e93258fSBjoern A. Zeeb break; 36798e93258fSBjoern A. Zeeb case BTC_CXP_OFF_EQ0: 36808e93258fSBjoern A. Zeeb _slot_set_tbl(btc, CXST_OFF, cxtbl[0]); 3681e2340276SBjoern A. Zeeb _slot_set_type(btc, CXST_OFF, SLOT_ISO); 36828e93258fSBjoern A. Zeeb break; 36838e93258fSBjoern A. Zeeb case BTC_CXP_OFF_EQ1: 36848e93258fSBjoern A. Zeeb _slot_set_tbl(btc, CXST_OFF, cxtbl[16]); 36858e93258fSBjoern A. Zeeb break; 36868e93258fSBjoern A. Zeeb case BTC_CXP_OFF_EQ2: 3687e2340276SBjoern A. Zeeb _slot_set_tbl(btc, CXST_OFF, cxtbl[0]); 36888e93258fSBjoern A. Zeeb break; 36898e93258fSBjoern A. Zeeb case BTC_CXP_OFF_EQ3: 3690e2340276SBjoern A. Zeeb _slot_set_tbl(btc, CXST_OFF, cxtbl[24]); 36918e93258fSBjoern A. Zeeb break; 36928e93258fSBjoern A. Zeeb case BTC_CXP_OFF_BWB0: 36938e93258fSBjoern A. Zeeb _slot_set_tbl(btc, CXST_OFF, cxtbl[5]); 36948e93258fSBjoern A. Zeeb break; 36958e93258fSBjoern A. Zeeb case BTC_CXP_OFF_BWB1: 36968e93258fSBjoern A. Zeeb _slot_set_tbl(btc, CXST_OFF, cxtbl[8]); 36978e93258fSBjoern A. Zeeb break; 36988e93258fSBjoern A. Zeeb case BTC_CXP_OFF_BWB2: 36998e93258fSBjoern A. Zeeb _slot_set_tbl(btc, CXST_OFF, cxtbl[7]); 37008e93258fSBjoern A. Zeeb break; 3701e2340276SBjoern A. Zeeb case BTC_CXP_OFF_BWB3: 3702e2340276SBjoern A. Zeeb _slot_set_tbl(btc, CXST_OFF, cxtbl[6]); 3703e2340276SBjoern A. Zeeb break; 37048e93258fSBjoern A. Zeeb default: 37058e93258fSBjoern A. Zeeb break; 37068e93258fSBjoern A. Zeeb } 37078e93258fSBjoern A. Zeeb break; 37088e93258fSBjoern A. Zeeb case BTC_CXP_OFFB: /* TDMA off + beacon protect */ 37098e93258fSBjoern A. Zeeb _write_scbd(rtwdev, BTC_WSCB_TDMA, false); 37108e93258fSBjoern A. Zeeb *t = t_def[CXTD_OFF_B2]; 3711*6d67aabdSBjoern A. Zeeb _slot_set_le(btc, CXST_OFF, s_def[CXST_OFF].dur, 3712*6d67aabdSBjoern A. Zeeb s_def[CXST_OFF].cxtbl, s_def[CXST_OFF].cxtype); 37138e93258fSBjoern A. Zeeb 37148e93258fSBjoern A. Zeeb switch (policy_type) { 37158e93258fSBjoern A. Zeeb case BTC_CXP_OFFB_BWB0: 37168e93258fSBjoern A. Zeeb _slot_set_tbl(btc, CXST_OFF, cxtbl[8]); 37178e93258fSBjoern A. Zeeb break; 37188e93258fSBjoern A. Zeeb default: 37198e93258fSBjoern A. Zeeb break; 37208e93258fSBjoern A. Zeeb } 37218e93258fSBjoern A. Zeeb break; 37228e93258fSBjoern A. Zeeb case BTC_CXP_OFFE: /* TDMA off + beacon protect + Ext_control */ 37238e93258fSBjoern A. Zeeb btc->bt_req_en = true; 37248e93258fSBjoern A. Zeeb _write_scbd(rtwdev, BTC_WSCB_TDMA, true); 37258e93258fSBjoern A. Zeeb *t = t_def[CXTD_OFF_EXT]; 37268e93258fSBjoern A. Zeeb 37278e93258fSBjoern A. Zeeb /* To avoid wl-s0 tx break by hid/hfp tx */ 37288e93258fSBjoern A. Zeeb if (hid->exist || hfp->exist) 37298e93258fSBjoern A. Zeeb tbl_w1 = cxtbl[16]; 37308e93258fSBjoern A. Zeeb 3731*6d67aabdSBjoern A. Zeeb dur_2 = dm->e2g_slot_limit; 3732*6d67aabdSBjoern A. Zeeb 37338e93258fSBjoern A. Zeeb switch (policy_type) { 3734*6d67aabdSBjoern A. Zeeb case BTC_CXP_OFFE_2GBWISOB: /* for normal-case */ 3735*6d67aabdSBjoern A. Zeeb _slot_set(btc, CXST_E2G, 0, tbl_w1, SLOT_ISO); 3736*6d67aabdSBjoern A. Zeeb _slot_set_le(btc, CXST_EBT, s_def[CXST_EBT].dur, 3737*6d67aabdSBjoern A. Zeeb s_def[CXST_EBT].cxtbl, s_def[CXST_EBT].cxtype); 3738*6d67aabdSBjoern A. Zeeb _slot_set_dur(btc, CXST_EBT, dur_2); 3739*6d67aabdSBjoern A. Zeeb break; 3740*6d67aabdSBjoern A. Zeeb case BTC_CXP_OFFE_2GISOB: /* for bt no-link */ 3741*6d67aabdSBjoern A. Zeeb _slot_set(btc, CXST_E2G, 0, cxtbl[1], SLOT_ISO); 3742*6d67aabdSBjoern A. Zeeb _slot_set_le(btc, CXST_EBT, s_def[CXST_EBT].dur, 3743*6d67aabdSBjoern A. Zeeb s_def[CXST_EBT].cxtbl, s_def[CXST_EBT].cxtype); 3744*6d67aabdSBjoern A. Zeeb _slot_set_dur(btc, CXST_EBT, dur_2); 3745*6d67aabdSBjoern A. Zeeb break; 37468e93258fSBjoern A. Zeeb case BTC_CXP_OFFE_DEF: 3747*6d67aabdSBjoern A. Zeeb _slot_set_le(btc, CXST_E2G, s_def[CXST_E2G].dur, 3748*6d67aabdSBjoern A. Zeeb s_def[CXST_E2G].cxtbl, s_def[CXST_E2G].cxtype); 3749*6d67aabdSBjoern A. Zeeb _slot_set_le(btc, CXST_E5G, s_def[CXST_E5G].dur, 3750*6d67aabdSBjoern A. Zeeb s_def[CXST_E5G].cxtbl, s_def[CXST_E5G].cxtype); 3751*6d67aabdSBjoern A. Zeeb _slot_set_le(btc, CXST_EBT, s_def[CXST_EBT].dur, 3752*6d67aabdSBjoern A. Zeeb s_def[CXST_EBT].cxtbl, s_def[CXST_EBT].cxtype); 3753*6d67aabdSBjoern A. Zeeb _slot_set_le(btc, CXST_ENULL, s_def[CXST_ENULL].dur, 3754*6d67aabdSBjoern A. Zeeb s_def[CXST_ENULL].cxtbl, s_def[CXST_ENULL].cxtype); 37558e93258fSBjoern A. Zeeb break; 37568e93258fSBjoern A. Zeeb case BTC_CXP_OFFE_DEF2: 37578e93258fSBjoern A. Zeeb _slot_set(btc, CXST_E2G, 20, cxtbl[1], SLOT_ISO); 3758*6d67aabdSBjoern A. Zeeb _slot_set_le(btc, CXST_E5G, s_def[CXST_E5G].dur, 3759*6d67aabdSBjoern A. Zeeb s_def[CXST_E5G].cxtbl, s_def[CXST_E5G].cxtype); 3760*6d67aabdSBjoern A. Zeeb _slot_set_le(btc, CXST_EBT, s_def[CXST_EBT].dur, 3761*6d67aabdSBjoern A. Zeeb s_def[CXST_EBT].cxtbl, s_def[CXST_EBT].cxtype); 3762*6d67aabdSBjoern A. Zeeb _slot_set_le(btc, CXST_ENULL, s_def[CXST_ENULL].dur, 3763*6d67aabdSBjoern A. Zeeb s_def[CXST_ENULL].cxtbl, s_def[CXST_ENULL].cxtype); 3764*6d67aabdSBjoern A. Zeeb break; 3765*6d67aabdSBjoern A. Zeeb case BTC_CXP_OFFE_2GBWMIXB: 3766*6d67aabdSBjoern A. Zeeb _slot_set(btc, CXST_E2G, 0, 0x55555555, SLOT_MIX); 3767*6d67aabdSBjoern A. Zeeb _slot_set_le(btc, CXST_EBT, s_def[CXST_EBT].dur, 3768*6d67aabdSBjoern A. Zeeb cpu_to_le32(0x55555555), s_def[CXST_EBT].cxtype); 3769*6d67aabdSBjoern A. Zeeb break; 3770*6d67aabdSBjoern A. Zeeb case BTC_CXP_OFFE_WL: /* for 4-way */ 3771*6d67aabdSBjoern A. Zeeb _slot_set(btc, CXST_E2G, 0, cxtbl[1], SLOT_MIX); 3772*6d67aabdSBjoern A. Zeeb _slot_set(btc, CXST_EBT, 0, cxtbl[1], SLOT_MIX); 37738e93258fSBjoern A. Zeeb break; 37748e93258fSBjoern A. Zeeb default: 37758e93258fSBjoern A. Zeeb break; 37768e93258fSBjoern A. Zeeb } 3777*6d67aabdSBjoern A. Zeeb _slot_set_le(btc, CXST_OFF, s_def[CXST_OFF].dur, 3778*6d67aabdSBjoern A. Zeeb s_def[CXST_OFF].cxtbl, s_def[CXST_OFF].cxtype); 37798e93258fSBjoern A. Zeeb break; 37808e93258fSBjoern A. Zeeb case BTC_CXP_FIX: /* TDMA Fix-Slot */ 37818e93258fSBjoern A. Zeeb _write_scbd(rtwdev, BTC_WSCB_TDMA, true); 37828e93258fSBjoern A. Zeeb *t = t_def[CXTD_FIX]; 37838e93258fSBjoern A. Zeeb 37848e93258fSBjoern A. Zeeb switch (policy_type) { 37858e93258fSBjoern A. Zeeb case BTC_CXP_FIX_TD3030: 37868e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); 37878e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX); 37888e93258fSBjoern A. Zeeb break; 37898e93258fSBjoern A. Zeeb case BTC_CXP_FIX_TD5050: 37908e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); 37918e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, 50, tbl_b1, SLOT_MIX); 37928e93258fSBjoern A. Zeeb break; 37938e93258fSBjoern A. Zeeb case BTC_CXP_FIX_TD2030: 37948e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); 37958e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX); 37968e93258fSBjoern A. Zeeb break; 37978e93258fSBjoern A. Zeeb case BTC_CXP_FIX_TD4010: 37988e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 40, tbl_w1, SLOT_ISO); 37998e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, 10, tbl_b1, SLOT_MIX); 38008e93258fSBjoern A. Zeeb break; 38018e93258fSBjoern A. Zeeb case BTC_CXP_FIX_TD4010ISO: 38028e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 40, cxtbl[1], SLOT_ISO); 38038e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, 10, tbl_b1, SLOT_MIX); 38048e93258fSBjoern A. Zeeb break; 3805*6d67aabdSBjoern A. Zeeb case BTC_CXP_FIX_TD4010ISO_DL: 3806*6d67aabdSBjoern A. Zeeb _slot_set(btc, CXST_W1, 40, cxtbl[25], SLOT_ISO); 3807*6d67aabdSBjoern A. Zeeb _slot_set(btc, CXST_B1, 10, cxtbl[25], SLOT_ISO); 3808*6d67aabdSBjoern A. Zeeb break; 3809*6d67aabdSBjoern A. Zeeb case BTC_CXP_FIX_TD4010ISO_UL: 3810*6d67aabdSBjoern A. Zeeb _slot_set(btc, CXST_W1, 40, cxtbl[20], SLOT_ISO); 3811*6d67aabdSBjoern A. Zeeb _slot_set(btc, CXST_B1, 10, cxtbl[25], SLOT_MIX); 3812e2340276SBjoern A. Zeeb break; 38138e93258fSBjoern A. Zeeb case BTC_CXP_FIX_TD7010: 38148e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 70, tbl_w1, SLOT_ISO); 38158e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, 10, tbl_b1, SLOT_MIX); 38168e93258fSBjoern A. Zeeb break; 38178e93258fSBjoern A. Zeeb case BTC_CXP_FIX_TD2060: 38188e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); 38198e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX); 38208e93258fSBjoern A. Zeeb break; 38218e93258fSBjoern A. Zeeb case BTC_CXP_FIX_TD3060: 38228e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); 38238e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX); 38248e93258fSBjoern A. Zeeb break; 38258e93258fSBjoern A. Zeeb case BTC_CXP_FIX_TD2080: 38268e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); 38278e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, 80, tbl_b1, SLOT_MIX); 38288e93258fSBjoern A. Zeeb break; 38298e93258fSBjoern A. Zeeb case BTC_CXP_FIX_TDW1B1: /* W1:B1 = user-define */ 38308e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], 38318e93258fSBjoern A. Zeeb tbl_w1, SLOT_ISO); 38328e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1], 38338e93258fSBjoern A. Zeeb tbl_b1, SLOT_MIX); 38348e93258fSBjoern A. Zeeb break; 38358e93258fSBjoern A. Zeeb default: 38368e93258fSBjoern A. Zeeb break; 38378e93258fSBjoern A. Zeeb } 38388e93258fSBjoern A. Zeeb break; 38398e93258fSBjoern A. Zeeb case BTC_CXP_PFIX: /* PS-TDMA Fix-Slot */ 38408e93258fSBjoern A. Zeeb _write_scbd(rtwdev, BTC_WSCB_TDMA, true); 38418e93258fSBjoern A. Zeeb *t = t_def[CXTD_PFIX]; 38428e93258fSBjoern A. Zeeb 38438e93258fSBjoern A. Zeeb switch (policy_type) { 38448e93258fSBjoern A. Zeeb case BTC_CXP_PFIX_TD3030: 38458e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); 38468e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX); 38478e93258fSBjoern A. Zeeb break; 38488e93258fSBjoern A. Zeeb case BTC_CXP_PFIX_TD5050: 38498e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); 38508e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, 50, tbl_b1, SLOT_MIX); 38518e93258fSBjoern A. Zeeb break; 38528e93258fSBjoern A. Zeeb case BTC_CXP_PFIX_TD2030: 38538e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); 38548e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX); 38558e93258fSBjoern A. Zeeb break; 38568e93258fSBjoern A. Zeeb case BTC_CXP_PFIX_TD2060: 38578e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); 38588e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX); 38598e93258fSBjoern A. Zeeb break; 38608e93258fSBjoern A. Zeeb case BTC_CXP_PFIX_TD3070: 38618e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); 38628e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX); 38638e93258fSBjoern A. Zeeb break; 38648e93258fSBjoern A. Zeeb case BTC_CXP_PFIX_TD2080: 38658e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); 38668e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, 80, tbl_b1, SLOT_MIX); 38678e93258fSBjoern A. Zeeb break; 38688e93258fSBjoern A. Zeeb case BTC_CXP_PFIX_TDW1B1: /* W1:B1 = user-define */ 38698e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], 38708e93258fSBjoern A. Zeeb tbl_w1, SLOT_ISO); 38718e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1], 38728e93258fSBjoern A. Zeeb tbl_b1, SLOT_MIX); 38738e93258fSBjoern A. Zeeb break; 38748e93258fSBjoern A. Zeeb default: 38758e93258fSBjoern A. Zeeb break; 38768e93258fSBjoern A. Zeeb } 38778e93258fSBjoern A. Zeeb break; 38788e93258fSBjoern A. Zeeb case BTC_CXP_AUTO: /* TDMA Auto-Slot */ 38798e93258fSBjoern A. Zeeb _write_scbd(rtwdev, BTC_WSCB_TDMA, true); 38808e93258fSBjoern A. Zeeb *t = t_def[CXTD_AUTO]; 38818e93258fSBjoern A. Zeeb 38828e93258fSBjoern A. Zeeb switch (policy_type) { 38838e93258fSBjoern A. Zeeb case BTC_CXP_AUTO_TD50B1: 38848e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); 38858e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 38868e93258fSBjoern A. Zeeb break; 38878e93258fSBjoern A. Zeeb case BTC_CXP_AUTO_TD60B1: 38888e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO); 38898e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 38908e93258fSBjoern A. Zeeb break; 38918e93258fSBjoern A. Zeeb case BTC_CXP_AUTO_TD20B1: 38928e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); 38938e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 38948e93258fSBjoern A. Zeeb break; 38958e93258fSBjoern A. Zeeb case BTC_CXP_AUTO_TDW1B1: /* W1:B1 = user-define */ 38968e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], 38978e93258fSBjoern A. Zeeb tbl_w1, SLOT_ISO); 38988e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1], 38998e93258fSBjoern A. Zeeb tbl_b1, SLOT_MIX); 39008e93258fSBjoern A. Zeeb break; 39018e93258fSBjoern A. Zeeb default: 39028e93258fSBjoern A. Zeeb break; 39038e93258fSBjoern A. Zeeb } 39048e93258fSBjoern A. Zeeb break; 39058e93258fSBjoern A. Zeeb case BTC_CXP_PAUTO: /* PS-TDMA Auto-Slot */ 39068e93258fSBjoern A. Zeeb _write_scbd(rtwdev, BTC_WSCB_TDMA, true); 39078e93258fSBjoern A. Zeeb *t = t_def[CXTD_PAUTO]; 39088e93258fSBjoern A. Zeeb 39098e93258fSBjoern A. Zeeb switch (policy_type) { 39108e93258fSBjoern A. Zeeb case BTC_CXP_PAUTO_TD50B1: 39118e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); 39128e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 39138e93258fSBjoern A. Zeeb break; 39148e93258fSBjoern A. Zeeb case BTC_CXP_PAUTO_TD60B1: 39158e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO); 39168e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 39178e93258fSBjoern A. Zeeb break; 39188e93258fSBjoern A. Zeeb case BTC_CXP_PAUTO_TD20B1: 39198e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); 39208e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 39218e93258fSBjoern A. Zeeb break; 39228e93258fSBjoern A. Zeeb case BTC_CXP_PAUTO_TDW1B1: 39238e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], 39248e93258fSBjoern A. Zeeb tbl_w1, SLOT_ISO); 39258e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1], 39268e93258fSBjoern A. Zeeb tbl_b1, SLOT_MIX); 39278e93258fSBjoern A. Zeeb break; 39288e93258fSBjoern A. Zeeb default: 39298e93258fSBjoern A. Zeeb break; 39308e93258fSBjoern A. Zeeb } 39318e93258fSBjoern A. Zeeb break; 39328e93258fSBjoern A. Zeeb case BTC_CXP_AUTO2: /* TDMA Auto-Slot2 */ 39338e93258fSBjoern A. Zeeb _write_scbd(rtwdev, BTC_WSCB_TDMA, true); 39348e93258fSBjoern A. Zeeb *t = t_def[CXTD_AUTO2]; 39358e93258fSBjoern A. Zeeb 39368e93258fSBjoern A. Zeeb switch (policy_type) { 39378e93258fSBjoern A. Zeeb case BTC_CXP_AUTO2_TD3050: 39388e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); 39398e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 39408e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX); 39418e93258fSBjoern A. Zeeb break; 39428e93258fSBjoern A. Zeeb case BTC_CXP_AUTO2_TD3070: 39438e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); 39448e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 39458e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B4, 70, tbl_b4, SLOT_MIX); 39468e93258fSBjoern A. Zeeb break; 39478e93258fSBjoern A. Zeeb case BTC_CXP_AUTO2_TD5050: 39488e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); 39498e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 39508e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX); 39518e93258fSBjoern A. Zeeb break; 39528e93258fSBjoern A. Zeeb case BTC_CXP_AUTO2_TD6060: 39538e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO); 39548e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 39558e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B4, 60, tbl_b4, SLOT_MIX); 39568e93258fSBjoern A. Zeeb break; 39578e93258fSBjoern A. Zeeb case BTC_CXP_AUTO2_TD2080: 39588e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); 39598e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 39608e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B4, 80, tbl_b4, SLOT_MIX); 39618e93258fSBjoern A. Zeeb break; 39628e93258fSBjoern A. Zeeb case BTC_CXP_AUTO2_TDW1B4: /* W1:B1 = user-define */ 39638e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], 39648e93258fSBjoern A. Zeeb tbl_w1, SLOT_ISO); 39658e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1], 39668e93258fSBjoern A. Zeeb tbl_b1, SLOT_MIX); 39678e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B4, dm->slot_dur[CXST_B4], 39688e93258fSBjoern A. Zeeb tbl_b4, SLOT_MIX); 39698e93258fSBjoern A. Zeeb break; 39708e93258fSBjoern A. Zeeb default: 39718e93258fSBjoern A. Zeeb break; 39728e93258fSBjoern A. Zeeb } 39738e93258fSBjoern A. Zeeb break; 39748e93258fSBjoern A. Zeeb case BTC_CXP_PAUTO2: /* PS-TDMA Auto-Slot2 */ 39758e93258fSBjoern A. Zeeb _write_scbd(rtwdev, BTC_WSCB_TDMA, true); 39768e93258fSBjoern A. Zeeb *t = t_def[CXTD_PAUTO2]; 39778e93258fSBjoern A. Zeeb 39788e93258fSBjoern A. Zeeb switch (policy_type) { 39798e93258fSBjoern A. Zeeb case BTC_CXP_PAUTO2_TD3050: 39808e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); 39818e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 39828e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX); 39838e93258fSBjoern A. Zeeb break; 39848e93258fSBjoern A. Zeeb case BTC_CXP_PAUTO2_TD3070: 39858e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); 39868e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 39878e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B4, 70, tbl_b4, SLOT_MIX); 39888e93258fSBjoern A. Zeeb break; 39898e93258fSBjoern A. Zeeb case BTC_CXP_PAUTO2_TD5050: 39908e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); 39918e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 39928e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX); 39938e93258fSBjoern A. Zeeb break; 39948e93258fSBjoern A. Zeeb case BTC_CXP_PAUTO2_TD6060: 39958e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO); 39968e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 39978e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B4, 60, tbl_b4, SLOT_MIX); 39988e93258fSBjoern A. Zeeb break; 39998e93258fSBjoern A. Zeeb case BTC_CXP_PAUTO2_TD2080: 40008e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); 40018e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX); 40028e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B4, 80, tbl_b4, SLOT_MIX); 40038e93258fSBjoern A. Zeeb break; 40048e93258fSBjoern A. Zeeb case BTC_CXP_PAUTO2_TDW1B4: /* W1:B1 = user-define */ 40058e93258fSBjoern A. Zeeb _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], 40068e93258fSBjoern A. Zeeb tbl_w1, SLOT_ISO); 40078e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1], 40088e93258fSBjoern A. Zeeb tbl_b1, SLOT_MIX); 40098e93258fSBjoern A. Zeeb _slot_set(btc, CXST_B4, dm->slot_dur[CXST_B4], 40108e93258fSBjoern A. Zeeb tbl_b4, SLOT_MIX); 40118e93258fSBjoern A. Zeeb break; 40128e93258fSBjoern A. Zeeb default: 40138e93258fSBjoern A. Zeeb break; 40148e93258fSBjoern A. Zeeb } 40158e93258fSBjoern A. Zeeb break; 40168e93258fSBjoern A. Zeeb } 40178e93258fSBjoern A. Zeeb 40188e93258fSBjoern A. Zeeb if (wl_rinfo->link_mode == BTC_WLINK_2G_SCC && dm->tdma.rxflctrl) { 40198e93258fSBjoern A. Zeeb null_role = FIELD_PREP(0x0f, dm->wl_scc.null_role1) | 40208e93258fSBjoern A. Zeeb FIELD_PREP(0xf0, dm->wl_scc.null_role2); 40218e93258fSBjoern A. Zeeb _tdma_set_flctrl_role(btc, null_role); 40228e93258fSBjoern A. Zeeb } 40238e93258fSBjoern A. Zeeb 40248e93258fSBjoern A. Zeeb /* enter leak_slot after each null-1 */ 40258e93258fSBjoern A. Zeeb if (dm->leak_ap && dm->tdma.leak_n > 1) 40268e93258fSBjoern A. Zeeb _tdma_set_lek(btc, 1); 40278e93258fSBjoern A. Zeeb 40288e93258fSBjoern A. Zeeb if (dm->tdma_instant_excute) { 40298e93258fSBjoern A. Zeeb btc->dm.tdma.option_ctrl |= BIT(0); 40308e93258fSBjoern A. Zeeb btc->update_policy_force = true; 40318e93258fSBjoern A. Zeeb } 40328e93258fSBjoern A. Zeeb } 40338e93258fSBjoern A. Zeeb EXPORT_SYMBOL(rtw89_btc_set_policy_v1); 40348e93258fSBjoern A. Zeeb 40358e93258fSBjoern A. Zeeb static void _set_bt_plut(struct rtw89_dev *rtwdev, u8 phy_map, 40368e93258fSBjoern A. Zeeb u8 tx_val, u8 rx_val) 40378e93258fSBjoern A. Zeeb { 4038*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &rtwdev->btc.cx.wl; 40398e93258fSBjoern A. Zeeb struct rtw89_mac_ax_plt plt; 40408e93258fSBjoern A. Zeeb 40418e93258fSBjoern A. Zeeb plt.tx = tx_val; 40428e93258fSBjoern A. Zeeb plt.rx = rx_val; 40438e93258fSBjoern A. Zeeb 4044*6d67aabdSBjoern A. Zeeb if (rtwdev->btc.ver->fwlrole == 8) { 4045*6d67aabdSBjoern A. Zeeb plt.band = wl->pta_req_mac; 4046*6d67aabdSBjoern A. Zeeb if (wl->bt_polut_type[plt.band] == tx_val) 4047*6d67aabdSBjoern A. Zeeb return; 4048*6d67aabdSBjoern A. Zeeb 4049*6d67aabdSBjoern A. Zeeb wl->bt_polut_type[plt.band] = tx_val; 4050*6d67aabdSBjoern A. Zeeb rtw89_mac_cfg_plt(rtwdev, &plt); 4051*6d67aabdSBjoern A. Zeeb } else { 4052*6d67aabdSBjoern A. Zeeb plt.band = RTW89_MAC_0; 4053*6d67aabdSBjoern A. Zeeb 40548e93258fSBjoern A. Zeeb if (phy_map & BTC_PHY_0) 40558e93258fSBjoern A. Zeeb rtw89_mac_cfg_plt(rtwdev, &plt); 40568e93258fSBjoern A. Zeeb 40578e93258fSBjoern A. Zeeb if (!rtwdev->dbcc_en) 40588e93258fSBjoern A. Zeeb return; 40598e93258fSBjoern A. Zeeb 40608e93258fSBjoern A. Zeeb plt.band = RTW89_MAC_1; 40618e93258fSBjoern A. Zeeb if (phy_map & BTC_PHY_1) 40628e93258fSBjoern A. Zeeb rtw89_mac_cfg_plt(rtwdev, &plt); 40638e93258fSBjoern A. Zeeb } 4064*6d67aabdSBjoern A. Zeeb } 40658e93258fSBjoern A. Zeeb 4066*6d67aabdSBjoern A. Zeeb static void _set_ant_v0(struct rtw89_dev *rtwdev, bool force_exec, 40678e93258fSBjoern A. Zeeb u8 phy_map, u8 type) 40688e93258fSBjoern A. Zeeb { 40698e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 40708e93258fSBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 40718e93258fSBjoern A. Zeeb struct rtw89_btc_cx *cx = &btc->cx; 40728e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 40738e93258fSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &cx->bt; 40748e93258fSBjoern A. Zeeb struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info; 40758e93258fSBjoern A. Zeeb u8 gnt_wl_ctrl, gnt_bt_ctrl, plt_ctrl, i, b2g = 0; 4076*6d67aabdSBjoern A. Zeeb bool dbcc_chg = false; 40778e93258fSBjoern A. Zeeb u32 ant_path_type; 40788e93258fSBjoern A. Zeeb 40798e93258fSBjoern A. Zeeb ant_path_type = ((phy_map << 8) + type); 40808e93258fSBjoern A. Zeeb 4081*6d67aabdSBjoern A. Zeeb if (btc->ver->fwlrole == 1) 4082*6d67aabdSBjoern A. Zeeb dbcc_chg = wl->role_info_v1.dbcc_chg; 4083*6d67aabdSBjoern A. Zeeb else if (btc->ver->fwlrole == 2) 4084*6d67aabdSBjoern A. Zeeb dbcc_chg = wl->role_info_v2.dbcc_chg; 4085*6d67aabdSBjoern A. Zeeb else if (btc->ver->fwlrole == 8) 4086*6d67aabdSBjoern A. Zeeb dbcc_chg = wl->role_info_v8.dbcc_chg; 4087*6d67aabdSBjoern A. Zeeb 40888e93258fSBjoern A. Zeeb if (btc->dm.run_reason == BTC_RSN_NTFY_POWEROFF || 40898e93258fSBjoern A. Zeeb btc->dm.run_reason == BTC_RSN_NTFY_RADIO_STATE || 4090*6d67aabdSBjoern A. Zeeb btc->dm.run_reason == BTC_RSN_CMD_SET_COEX || dbcc_chg) 40918e93258fSBjoern A. Zeeb force_exec = FC_EXEC; 40928e93258fSBjoern A. Zeeb 40938e93258fSBjoern A. Zeeb if (!force_exec && ant_path_type == dm->set_ant_path) { 40948e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 40958e93258fSBjoern A. Zeeb "[BTC], %s(): return by no change!!\n", 40968e93258fSBjoern A. Zeeb __func__); 40978e93258fSBjoern A. Zeeb return; 40988e93258fSBjoern A. Zeeb } else if (bt->rfk_info.map.run) { 40998e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 41008e93258fSBjoern A. Zeeb "[BTC], %s(): return by bt rfk!!\n", __func__); 41018e93258fSBjoern A. Zeeb return; 41028e93258fSBjoern A. Zeeb } else if (btc->dm.run_reason != BTC_RSN_NTFY_WL_RFK && 41038e93258fSBjoern A. Zeeb wl->rfk_info.state != BTC_WRFK_STOP) { 41048e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 41058e93258fSBjoern A. Zeeb "[BTC], %s(): return by wl rfk!!\n", __func__); 41068e93258fSBjoern A. Zeeb return; 41078e93258fSBjoern A. Zeeb } 41088e93258fSBjoern A. Zeeb 41098e93258fSBjoern A. Zeeb dm->set_ant_path = ant_path_type; 41108e93258fSBjoern A. Zeeb 41118e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, 41128e93258fSBjoern A. Zeeb RTW89_DBG_BTC, 41138e93258fSBjoern A. Zeeb "[BTC], %s(): path=0x%x, set_type=0x%x\n", 41148e93258fSBjoern A. Zeeb __func__, phy_map, dm->set_ant_path & 0xff); 41158e93258fSBjoern A. Zeeb 41168e93258fSBjoern A. Zeeb switch (type) { 41178e93258fSBjoern A. Zeeb case BTC_ANT_WPOWERON: 4118e2340276SBjoern A. Zeeb rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_BT); 41198e93258fSBjoern A. Zeeb break; 41208e93258fSBjoern A. Zeeb case BTC_ANT_WINIT: 4121e2340276SBjoern A. Zeeb if (bt->enable.now) 4122e2340276SBjoern A. Zeeb _set_gnt(rtwdev, phy_map, BTC_GNT_SW_LO, BTC_GNT_SW_HI); 4123e2340276SBjoern A. Zeeb else 4124e2340276SBjoern A. Zeeb _set_gnt(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO); 4125e2340276SBjoern A. Zeeb 4126e2340276SBjoern A. Zeeb rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL); 41278e93258fSBjoern A. Zeeb _set_bt_plut(rtwdev, BTC_PHY_ALL, BTC_PLT_BT, BTC_PLT_BT); 41288e93258fSBjoern A. Zeeb break; 41298e93258fSBjoern A. Zeeb case BTC_ANT_WONLY: 4130e2340276SBjoern A. Zeeb _set_gnt(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO); 4131e2340276SBjoern A. Zeeb rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL); 41328e93258fSBjoern A. Zeeb _set_bt_plut(rtwdev, BTC_PHY_ALL, BTC_PLT_NONE, BTC_PLT_NONE); 41338e93258fSBjoern A. Zeeb break; 41348e93258fSBjoern A. Zeeb case BTC_ANT_WOFF: 4135e2340276SBjoern A. Zeeb rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_BT); 41368e93258fSBjoern A. Zeeb _set_bt_plut(rtwdev, BTC_PHY_ALL, BTC_PLT_NONE, BTC_PLT_NONE); 41378e93258fSBjoern A. Zeeb break; 41388e93258fSBjoern A. Zeeb case BTC_ANT_W2G: 4139e2340276SBjoern A. Zeeb rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL); 41408e93258fSBjoern A. Zeeb if (rtwdev->dbcc_en) { 41418e93258fSBjoern A. Zeeb for (i = 0; i < RTW89_PHY_MAX; i++) { 41428e93258fSBjoern A. Zeeb b2g = (wl_dinfo->real_band[i] == RTW89_BAND_2G); 41438e93258fSBjoern A. Zeeb 41448e93258fSBjoern A. Zeeb gnt_wl_ctrl = b2g ? BTC_GNT_HW : BTC_GNT_SW_HI; 41458e93258fSBjoern A. Zeeb gnt_bt_ctrl = b2g ? BTC_GNT_HW : BTC_GNT_SW_HI; 41468e93258fSBjoern A. Zeeb /* BT should control by GNT_BT if WL_2G at S0 */ 41478e93258fSBjoern A. Zeeb if (i == 1 && 41488e93258fSBjoern A. Zeeb wl_dinfo->real_band[0] == RTW89_BAND_2G && 41498e93258fSBjoern A. Zeeb wl_dinfo->real_band[1] == RTW89_BAND_5G) 41508e93258fSBjoern A. Zeeb gnt_bt_ctrl = BTC_GNT_HW; 4151e2340276SBjoern A. Zeeb _set_gnt(rtwdev, BIT(i), gnt_wl_ctrl, gnt_bt_ctrl); 41528e93258fSBjoern A. Zeeb plt_ctrl = b2g ? BTC_PLT_BT : BTC_PLT_NONE; 41538e93258fSBjoern A. Zeeb _set_bt_plut(rtwdev, BIT(i), 41548e93258fSBjoern A. Zeeb plt_ctrl, plt_ctrl); 41558e93258fSBjoern A. Zeeb } 41568e93258fSBjoern A. Zeeb } else { 4157e2340276SBjoern A. Zeeb _set_gnt(rtwdev, phy_map, BTC_GNT_HW, BTC_GNT_HW); 41588e93258fSBjoern A. Zeeb _set_bt_plut(rtwdev, BTC_PHY_ALL, 41598e93258fSBjoern A. Zeeb BTC_PLT_BT, BTC_PLT_BT); 41608e93258fSBjoern A. Zeeb } 41618e93258fSBjoern A. Zeeb break; 41628e93258fSBjoern A. Zeeb case BTC_ANT_W5G: 4163e2340276SBjoern A. Zeeb rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL); 4164e2340276SBjoern A. Zeeb _set_gnt(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_HW); 41658e93258fSBjoern A. Zeeb _set_bt_plut(rtwdev, BTC_PHY_ALL, BTC_PLT_NONE, BTC_PLT_NONE); 41668e93258fSBjoern A. Zeeb break; 41678e93258fSBjoern A. Zeeb case BTC_ANT_W25G: 4168e2340276SBjoern A. Zeeb rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL); 4169e2340276SBjoern A. Zeeb _set_gnt(rtwdev, phy_map, BTC_GNT_HW, BTC_GNT_HW); 41708e93258fSBjoern A. Zeeb _set_bt_plut(rtwdev, BTC_PHY_ALL, 41718e93258fSBjoern A. Zeeb BTC_PLT_GNT_WL, BTC_PLT_GNT_WL); 41728e93258fSBjoern A. Zeeb break; 41738e93258fSBjoern A. Zeeb case BTC_ANT_FREERUN: 4174e2340276SBjoern A. Zeeb rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL); 4175e2340276SBjoern A. Zeeb _set_gnt(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_HI); 41768e93258fSBjoern A. Zeeb _set_bt_plut(rtwdev, BTC_PHY_ALL, BTC_PLT_NONE, BTC_PLT_NONE); 41778e93258fSBjoern A. Zeeb break; 41788e93258fSBjoern A. Zeeb case BTC_ANT_WRFK: 4179e2340276SBjoern A. Zeeb rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL); 4180e2340276SBjoern A. Zeeb _set_gnt(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO); 41818e93258fSBjoern A. Zeeb _set_bt_plut(rtwdev, phy_map, BTC_PLT_NONE, BTC_PLT_NONE); 41828e93258fSBjoern A. Zeeb break; 41838e93258fSBjoern A. Zeeb case BTC_ANT_BRFK: 4184e2340276SBjoern A. Zeeb rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_BT); 4185e2340276SBjoern A. Zeeb _set_gnt(rtwdev, phy_map, BTC_GNT_SW_LO, BTC_GNT_SW_HI); 41868e93258fSBjoern A. Zeeb _set_bt_plut(rtwdev, phy_map, BTC_PLT_NONE, BTC_PLT_NONE); 41878e93258fSBjoern A. Zeeb break; 41888e93258fSBjoern A. Zeeb default: 41898e93258fSBjoern A. Zeeb break; 41908e93258fSBjoern A. Zeeb } 41918e93258fSBjoern A. Zeeb } 41928e93258fSBjoern A. Zeeb 4193*6d67aabdSBjoern A. Zeeb static void _set_ant_v1(struct rtw89_dev *rtwdev, bool force_exec, 4194*6d67aabdSBjoern A. Zeeb u8 phy_map, u8 type) 4195*6d67aabdSBjoern A. Zeeb { 4196*6d67aabdSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 4197*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 4198*6d67aabdSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &btc->cx.bt; 4199*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_role_info_v8 *wl_rinfo = &wl->role_info_v8; 4200*6d67aabdSBjoern A. Zeeb u32 ant_path_type = rtw89_get_antpath_type(phy_map, type); 4201*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info; 4202*6d67aabdSBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 4203*6d67aabdSBjoern A. Zeeb u8 gwl = BTC_GNT_HW; 4204*6d67aabdSBjoern A. Zeeb 4205*6d67aabdSBjoern A. Zeeb if (btc->dm.run_reason == BTC_RSN_NTFY_POWEROFF || 4206*6d67aabdSBjoern A. Zeeb btc->dm.run_reason == BTC_RSN_NTFY_RADIO_STATE || 4207*6d67aabdSBjoern A. Zeeb btc->dm.run_reason == BTC_RSN_CMD_SET_COEX || wl_rinfo->dbcc_chg) 4208*6d67aabdSBjoern A. Zeeb force_exec = FC_EXEC; 4209*6d67aabdSBjoern A. Zeeb 4210*6d67aabdSBjoern A. Zeeb if (wl_rinfo->link_mode != BTC_WLINK_25G_MCC && 4211*6d67aabdSBjoern A. Zeeb btc->dm.wl_btg_rx == 2) 4212*6d67aabdSBjoern A. Zeeb force_exec = FC_EXEC; 4213*6d67aabdSBjoern A. Zeeb 4214*6d67aabdSBjoern A. Zeeb if (!force_exec && ant_path_type == dm->set_ant_path) { 4215*6d67aabdSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 4216*6d67aabdSBjoern A. Zeeb "[BTC], %s(): return by no change!!\n", 4217*6d67aabdSBjoern A. Zeeb __func__); 4218*6d67aabdSBjoern A. Zeeb return; 4219*6d67aabdSBjoern A. Zeeb } else if (bt->rfk_info.map.run) { 4220*6d67aabdSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 4221*6d67aabdSBjoern A. Zeeb "[BTC], %s(): return by bt rfk!!\n", __func__); 4222*6d67aabdSBjoern A. Zeeb return; 4223*6d67aabdSBjoern A. Zeeb } else if (btc->dm.run_reason != BTC_RSN_NTFY_WL_RFK && 4224*6d67aabdSBjoern A. Zeeb wl->rfk_info.state != BTC_WRFK_STOP) { 4225*6d67aabdSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 4226*6d67aabdSBjoern A. Zeeb "[BTC], %s(): return by wl rfk!!\n", __func__); 4227*6d67aabdSBjoern A. Zeeb return; 4228*6d67aabdSBjoern A. Zeeb } 4229*6d67aabdSBjoern A. Zeeb 4230*6d67aabdSBjoern A. Zeeb dm->set_ant_path = ant_path_type; 4231*6d67aabdSBjoern A. Zeeb 4232*6d67aabdSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 4233*6d67aabdSBjoern A. Zeeb "[BTC], %s(): path=0x%x, set_type=0x%x\n", 4234*6d67aabdSBjoern A. Zeeb __func__, phy_map, dm->set_ant_path & 0xff); 4235*6d67aabdSBjoern A. Zeeb 4236*6d67aabdSBjoern A. Zeeb switch (type) { 4237*6d67aabdSBjoern A. Zeeb case BTC_ANT_WINIT: 4238*6d67aabdSBjoern A. Zeeb /* To avoid BT MP driver case (bt_enable but no mailbox) */ 4239*6d67aabdSBjoern A. Zeeb if (bt->enable.now && bt->run_patch_code) 4240*6d67aabdSBjoern A. Zeeb _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_LO, BTC_GNT_SW_HI, 4241*6d67aabdSBjoern A. Zeeb BTC_WLACT_SW_LO); 4242*6d67aabdSBjoern A. Zeeb else 4243*6d67aabdSBjoern A. Zeeb _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO, 4244*6d67aabdSBjoern A. Zeeb BTC_WLACT_SW_HI); 4245*6d67aabdSBjoern A. Zeeb break; 4246*6d67aabdSBjoern A. Zeeb case BTC_ANT_WONLY: 4247*6d67aabdSBjoern A. Zeeb _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO, 4248*6d67aabdSBjoern A. Zeeb BTC_WLACT_SW_HI); 4249*6d67aabdSBjoern A. Zeeb break; 4250*6d67aabdSBjoern A. Zeeb case BTC_ANT_WOFF: 4251*6d67aabdSBjoern A. Zeeb _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_LO, BTC_GNT_SW_HI, 4252*6d67aabdSBjoern A. Zeeb BTC_WLACT_SW_LO); 4253*6d67aabdSBjoern A. Zeeb break; 4254*6d67aabdSBjoern A. Zeeb case BTC_ANT_W2G: 4255*6d67aabdSBjoern A. Zeeb case BTC_ANT_W25G: 4256*6d67aabdSBjoern A. Zeeb if (wl_rinfo->dbcc_en) { 4257*6d67aabdSBjoern A. Zeeb if (wl_dinfo->real_band[RTW89_PHY_0] == RTW89_BAND_2G) 4258*6d67aabdSBjoern A. Zeeb gwl = BTC_GNT_HW; 4259*6d67aabdSBjoern A. Zeeb else 4260*6d67aabdSBjoern A. Zeeb gwl = BTC_GNT_SW_HI; 4261*6d67aabdSBjoern A. Zeeb _set_gnt_v1(rtwdev, BTC_PHY_0, gwl, BTC_GNT_HW, BTC_WLACT_HW); 4262*6d67aabdSBjoern A. Zeeb 4263*6d67aabdSBjoern A. Zeeb if (wl_dinfo->real_band[RTW89_PHY_1] == RTW89_BAND_2G) 4264*6d67aabdSBjoern A. Zeeb gwl = BTC_GNT_HW; 4265*6d67aabdSBjoern A. Zeeb else 4266*6d67aabdSBjoern A. Zeeb gwl = BTC_GNT_SW_HI; 4267*6d67aabdSBjoern A. Zeeb _set_gnt_v1(rtwdev, BTC_PHY_1, gwl, BTC_GNT_HW, BTC_WLACT_HW); 4268*6d67aabdSBjoern A. Zeeb } else { 4269*6d67aabdSBjoern A. Zeeb gwl = BTC_GNT_HW; 4270*6d67aabdSBjoern A. Zeeb _set_gnt_v1(rtwdev, phy_map, gwl, BTC_GNT_HW, BTC_WLACT_HW); 4271*6d67aabdSBjoern A. Zeeb } 4272*6d67aabdSBjoern A. Zeeb break; 4273*6d67aabdSBjoern A. Zeeb case BTC_ANT_W5G: 4274*6d67aabdSBjoern A. Zeeb _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_HW, BTC_WLACT_HW); 4275*6d67aabdSBjoern A. Zeeb break; 4276*6d67aabdSBjoern A. Zeeb case BTC_ANT_FREERUN: 4277*6d67aabdSBjoern A. Zeeb _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_HI, 4278*6d67aabdSBjoern A. Zeeb BTC_WLACT_SW_LO); 4279*6d67aabdSBjoern A. Zeeb break; 4280*6d67aabdSBjoern A. Zeeb case BTC_ANT_WRFK: 4281*6d67aabdSBjoern A. Zeeb _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO, 4282*6d67aabdSBjoern A. Zeeb BTC_WLACT_HW); 4283*6d67aabdSBjoern A. Zeeb break; 4284*6d67aabdSBjoern A. Zeeb case BTC_ANT_WRFK2: 4285*6d67aabdSBjoern A. Zeeb _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO, 4286*6d67aabdSBjoern A. Zeeb BTC_WLACT_SW_HI); /* no BT-Tx */ 4287*6d67aabdSBjoern A. Zeeb break; 4288*6d67aabdSBjoern A. Zeeb default: 4289*6d67aabdSBjoern A. Zeeb return; 4290*6d67aabdSBjoern A. Zeeb } 4291*6d67aabdSBjoern A. Zeeb 4292*6d67aabdSBjoern A. Zeeb _set_bt_plut(rtwdev, phy_map, BTC_PLT_GNT_WL, BTC_PLT_GNT_WL); 4293*6d67aabdSBjoern A. Zeeb } 4294*6d67aabdSBjoern A. Zeeb 4295*6d67aabdSBjoern A. Zeeb static void _set_ant(struct rtw89_dev *rtwdev, bool force_exec, 4296*6d67aabdSBjoern A. Zeeb u8 phy_map, u8 type) 4297*6d67aabdSBjoern A. Zeeb { 4298*6d67aabdSBjoern A. Zeeb if (rtwdev->chip->chip_id == RTL8922A) 4299*6d67aabdSBjoern A. Zeeb _set_ant_v1(rtwdev, force_exec, phy_map, type); 4300*6d67aabdSBjoern A. Zeeb else 4301*6d67aabdSBjoern A. Zeeb _set_ant_v0(rtwdev, force_exec, phy_map, type); 4302*6d67aabdSBjoern A. Zeeb } 4303*6d67aabdSBjoern A. Zeeb 43048e93258fSBjoern A. Zeeb static void _action_wl_only(struct rtw89_dev *rtwdev) 43058e93258fSBjoern A. Zeeb { 43068e93258fSBjoern A. Zeeb _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WONLY); 43078e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_WL_ONLY); 43088e93258fSBjoern A. Zeeb } 43098e93258fSBjoern A. Zeeb 43108e93258fSBjoern A. Zeeb static void _action_wl_init(struct rtw89_dev *rtwdev) 43118e93258fSBjoern A. Zeeb { 43128e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): !!\n", __func__); 43138e93258fSBjoern A. Zeeb 43148e93258fSBjoern A. Zeeb _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WINIT); 43158e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_WL_INIT); 43168e93258fSBjoern A. Zeeb } 43178e93258fSBjoern A. Zeeb 4318*6d67aabdSBjoern A. Zeeb static void _action_wl_off(struct rtw89_dev *rtwdev, u8 mode) 43198e93258fSBjoern A. Zeeb { 43208e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 43218e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 43228e93258fSBjoern A. Zeeb 43238e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): !!\n", __func__); 43248e93258fSBjoern A. Zeeb 4325*6d67aabdSBjoern A. Zeeb if (wl->status.map.rf_off || btc->dm.bt_only) { 43268e93258fSBjoern A. Zeeb _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_WOFF); 4327*6d67aabdSBjoern A. Zeeb } else if (wl->status.map.lps == BTC_LPS_RF_ON) { 4328*6d67aabdSBjoern A. Zeeb if (mode == BTC_WLINK_5G) 4329*6d67aabdSBjoern A. Zeeb _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_W5G); 4330*6d67aabdSBjoern A. Zeeb else 4331*6d67aabdSBjoern A. Zeeb _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); 4332*6d67aabdSBjoern A. Zeeb } 43338e93258fSBjoern A. Zeeb 4334*6d67aabdSBjoern A. Zeeb if (mode == BTC_WLINK_5G) { 4335*6d67aabdSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_OFF); 4336*6d67aabdSBjoern A. Zeeb } else if (wl->status.map.lps == BTC_LPS_RF_ON) { 4337*6d67aabdSBjoern A. Zeeb if (btc->cx.bt.link_info.a2dp_desc.active) 43388e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_WL_OFF); 4339*6d67aabdSBjoern A. Zeeb else 4340*6d67aabdSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFF_BWB1, BTC_ACT_WL_OFF); 4341*6d67aabdSBjoern A. Zeeb } else { 4342*6d67aabdSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_WL_OFF); 4343*6d67aabdSBjoern A. Zeeb } 43448e93258fSBjoern A. Zeeb } 43458e93258fSBjoern A. Zeeb 43468e93258fSBjoern A. Zeeb static void _action_freerun(struct rtw89_dev *rtwdev) 43478e93258fSBjoern A. Zeeb { 43488e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 43498e93258fSBjoern A. Zeeb 43508e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): !!\n", __func__); 43518e93258fSBjoern A. Zeeb 43528e93258fSBjoern A. Zeeb _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_FREERUN); 43538e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_FREERUN); 43548e93258fSBjoern A. Zeeb 43558e93258fSBjoern A. Zeeb btc->dm.freerun = true; 43568e93258fSBjoern A. Zeeb } 43578e93258fSBjoern A. Zeeb 43588e93258fSBjoern A. Zeeb static void _action_bt_whql(struct rtw89_dev *rtwdev) 43598e93258fSBjoern A. Zeeb { 43608e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): !!\n", __func__); 43618e93258fSBjoern A. Zeeb 43628e93258fSBjoern A. Zeeb _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); 43638e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_BT_WHQL); 43648e93258fSBjoern A. Zeeb } 43658e93258fSBjoern A. Zeeb 43668e93258fSBjoern A. Zeeb static void _action_bt_off(struct rtw89_dev *rtwdev) 43678e93258fSBjoern A. Zeeb { 43688e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): !!\n", __func__); 43698e93258fSBjoern A. Zeeb 43708e93258fSBjoern A. Zeeb _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WONLY); 43718e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_BT_OFF); 43728e93258fSBjoern A. Zeeb } 43738e93258fSBjoern A. Zeeb 43748e93258fSBjoern A. Zeeb static void _action_bt_idle(struct rtw89_dev *rtwdev) 43758e93258fSBjoern A. Zeeb { 43768e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 43778e93258fSBjoern A. Zeeb struct rtw89_btc_bt_link_info *b = &btc->cx.bt.link_info; 4378*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 43798e93258fSBjoern A. Zeeb 43808e93258fSBjoern A. Zeeb _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); 43818e93258fSBjoern A. Zeeb 4382*6d67aabdSBjoern A. Zeeb if (btc->ant_type == BTC_ANT_SHARED) { /* shared-antenna */ 43838e93258fSBjoern A. Zeeb switch (btc->cx.state_map) { 43848e93258fSBjoern A. Zeeb case BTC_WBUSY_BNOSCAN: /*wl-busy + bt idle*/ 4385*6d67aabdSBjoern A. Zeeb case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-idle */ 4386*6d67aabdSBjoern A. Zeeb if (b->status.map.connect) 4387*6d67aabdSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_FIX_TD4010, BTC_ACT_BT_IDLE); 4388*6d67aabdSBjoern A. Zeeb else if (wl->status.map.traffic_dir & BIT(RTW89_TFC_DL)) 4389*6d67aabdSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_FIX_TD4010ISO_DL, BTC_ACT_BT_IDLE); 43908e93258fSBjoern A. Zeeb else 4391*6d67aabdSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_FIX_TD4010ISO_UL, BTC_ACT_BT_IDLE); 43928e93258fSBjoern A. Zeeb break; 43938e93258fSBjoern A. Zeeb case BTC_WBUSY_BSCAN: /*wl-busy + bt-inq */ 43948e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_PFIX_TD5050, 43958e93258fSBjoern A. Zeeb BTC_ACT_BT_IDLE); 43968e93258fSBjoern A. Zeeb break; 43978e93258fSBjoern A. Zeeb case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq */ 43988e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_FIX_TD5050, 43998e93258fSBjoern A. Zeeb BTC_ACT_BT_IDLE); 44008e93258fSBjoern A. Zeeb break; 44018e93258fSBjoern A. Zeeb case BTC_WLINKING: /* wl-connecting + bt-inq or bt-idle */ 44028e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_FIX_TD7010, 44038e93258fSBjoern A. Zeeb BTC_ACT_BT_IDLE); 44048e93258fSBjoern A. Zeeb break; 44058e93258fSBjoern A. Zeeb case BTC_WIDLE: /* wl-idle + bt-idle */ 44068e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFF_BWB1, BTC_ACT_BT_IDLE); 44078e93258fSBjoern A. Zeeb break; 44088e93258fSBjoern A. Zeeb } 44098e93258fSBjoern A. Zeeb } else { /* dedicated-antenna */ 44108e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_BT_IDLE); 44118e93258fSBjoern A. Zeeb } 44128e93258fSBjoern A. Zeeb } 44138e93258fSBjoern A. Zeeb 44148e93258fSBjoern A. Zeeb static void _action_bt_hfp(struct rtw89_dev *rtwdev) 44158e93258fSBjoern A. Zeeb { 44168e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 4417e2340276SBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 44188e93258fSBjoern A. Zeeb 44198e93258fSBjoern A. Zeeb _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); 44208e93258fSBjoern A. Zeeb 4421*6d67aabdSBjoern A. Zeeb if (btc->ant_type == BTC_ANT_SHARED) { 4422e2340276SBjoern A. Zeeb if (btc->cx.wl.status.map._4way) { 44238e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFF_WL, BTC_ACT_BT_HFP); 4424e2340276SBjoern A. Zeeb } else if (wl->status.map.traffic_dir & BIT(RTW89_TFC_UL)) { 4425e2340276SBjoern A. Zeeb btc->cx.bt.scan_rx_low_pri = true; 4426e2340276SBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFF_BWB2, BTC_ACT_BT_HFP); 4427e2340276SBjoern A. Zeeb } else { 4428e2340276SBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFF_BWB1, BTC_ACT_BT_HFP); 4429e2340276SBjoern A. Zeeb } 44308e93258fSBjoern A. Zeeb } else { 4431*6d67aabdSBjoern A. Zeeb if (wl->bg_mode) 4432*6d67aabdSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFF_BWB1, BTC_ACT_BT_HFP); 4433*6d67aabdSBjoern A. Zeeb else if (wl->status.map.traffic_dir & BIT(RTW89_TFC_UL)) 4434*6d67aabdSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFF_EQ5, BTC_ACT_BT_HFP); 4435*6d67aabdSBjoern A. Zeeb else 44368e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFF_EQ2, BTC_ACT_BT_HFP); 44378e93258fSBjoern A. Zeeb } 44388e93258fSBjoern A. Zeeb } 44398e93258fSBjoern A. Zeeb 44408e93258fSBjoern A. Zeeb static void _action_bt_hid(struct rtw89_dev *rtwdev) 44418e93258fSBjoern A. Zeeb { 4442e2340276SBjoern A. Zeeb const struct rtw89_chip_info *chip = rtwdev->chip; 44438e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 4444e2340276SBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 4445e2340276SBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &btc->cx.bt; 4446e2340276SBjoern A. Zeeb struct rtw89_btc_bt_hid_desc *hid = &bt->link_info.hid_desc; 4447e2340276SBjoern A. Zeeb u16 policy_type = BTC_CXP_OFF_BT; 44488e93258fSBjoern A. Zeeb 44498e93258fSBjoern A. Zeeb _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); 44508e93258fSBjoern A. Zeeb 4451*6d67aabdSBjoern A. Zeeb if (btc->ant_type == BTC_ANT_SHARED) { /* shared-antenna */ 4452e2340276SBjoern A. Zeeb if (wl->status.map._4way) { 4453e2340276SBjoern A. Zeeb policy_type = BTC_CXP_OFF_WL; 4454e2340276SBjoern A. Zeeb } else if (wl->status.map.traffic_dir & BIT(RTW89_TFC_UL)) { 4455e2340276SBjoern A. Zeeb btc->cx.bt.scan_rx_low_pri = true; 4456e2340276SBjoern A. Zeeb if (hid->type & BTC_HID_BLE) 4457e2340276SBjoern A. Zeeb policy_type = BTC_CXP_OFF_BWB0; 44588e93258fSBjoern A. Zeeb else 4459e2340276SBjoern A. Zeeb policy_type = BTC_CXP_OFF_BWB2; 4460e2340276SBjoern A. Zeeb } else if (hid->type == BTC_HID_218) { 4461e2340276SBjoern A. Zeeb bt->scan_rx_low_pri = true; 4462e2340276SBjoern A. Zeeb policy_type = BTC_CXP_OFF_BWB2; 4463e2340276SBjoern A. Zeeb } else if (chip->para_ver == 0x1) { 4464e2340276SBjoern A. Zeeb policy_type = BTC_CXP_OFF_BWB3; 4465e2340276SBjoern A. Zeeb } else { 4466e2340276SBjoern A. Zeeb policy_type = BTC_CXP_OFF_BWB1; 4467e2340276SBjoern A. Zeeb } 4468e2340276SBjoern A. Zeeb } else { /* dedicated-antenna */ 4469*6d67aabdSBjoern A. Zeeb if (wl->bg_mode) 4470*6d67aabdSBjoern A. Zeeb policy_type = BTC_CXP_OFF_BWB1; 4471*6d67aabdSBjoern A. Zeeb else if (wl->status.map.traffic_dir & BIT(RTW89_TFC_UL)) 4472*6d67aabdSBjoern A. Zeeb policy_type = BTC_CXP_OFF_EQ4; 4473*6d67aabdSBjoern A. Zeeb else 4474e2340276SBjoern A. Zeeb policy_type = BTC_CXP_OFF_EQ3; 4475e2340276SBjoern A. Zeeb } 4476e2340276SBjoern A. Zeeb 4477e2340276SBjoern A. Zeeb _set_policy(rtwdev, policy_type, BTC_ACT_BT_HID); 44788e93258fSBjoern A. Zeeb } 44798e93258fSBjoern A. Zeeb 44808e93258fSBjoern A. Zeeb static void _action_bt_a2dp(struct rtw89_dev *rtwdev) 44818e93258fSBjoern A. Zeeb { 44828e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 44838e93258fSBjoern A. Zeeb struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt.link_info; 44848e93258fSBjoern A. Zeeb struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc; 44858e93258fSBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 44868e93258fSBjoern A. Zeeb 44878e93258fSBjoern A. Zeeb _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); 44888e93258fSBjoern A. Zeeb 44898e93258fSBjoern A. Zeeb switch (btc->cx.state_map) { 44908e93258fSBjoern A. Zeeb case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-A2DP */ 44918e93258fSBjoern A. Zeeb if (a2dp.vendor_id == 0x4c || dm->leak_ap) { 44928e93258fSBjoern A. Zeeb dm->slot_dur[CXST_W1] = 40; 44938e93258fSBjoern A. Zeeb dm->slot_dur[CXST_B1] = 200; 44948e93258fSBjoern A. Zeeb _set_policy(rtwdev, 44958e93258fSBjoern A. Zeeb BTC_CXP_PAUTO_TDW1B1, BTC_ACT_BT_A2DP); 44968e93258fSBjoern A. Zeeb } else { 44978e93258fSBjoern A. Zeeb _set_policy(rtwdev, 44988e93258fSBjoern A. Zeeb BTC_CXP_PAUTO_TD50B1, BTC_ACT_BT_A2DP); 44998e93258fSBjoern A. Zeeb } 45008e93258fSBjoern A. Zeeb break; 45018e93258fSBjoern A. Zeeb case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-A2DP */ 45028e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3050, BTC_ACT_BT_A2DP); 45038e93258fSBjoern A. Zeeb break; 45048e93258fSBjoern A. Zeeb case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-A2DP */ 45058e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_AUTO2_TD3050, BTC_ACT_BT_A2DP); 45068e93258fSBjoern A. Zeeb break; 45078e93258fSBjoern A. Zeeb case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-A2DP */ 45088e93258fSBjoern A. Zeeb case BTC_WLINKING: /* wl-connecting + bt-A2DP */ 45098e93258fSBjoern A. Zeeb if (a2dp.vendor_id == 0x4c || dm->leak_ap) { 45108e93258fSBjoern A. Zeeb dm->slot_dur[CXST_W1] = 40; 45118e93258fSBjoern A. Zeeb dm->slot_dur[CXST_B1] = 200; 45128e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_AUTO_TDW1B1, 45138e93258fSBjoern A. Zeeb BTC_ACT_BT_A2DP); 45148e93258fSBjoern A. Zeeb } else { 45158e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_AUTO_TD50B1, 45168e93258fSBjoern A. Zeeb BTC_ACT_BT_A2DP); 45178e93258fSBjoern A. Zeeb } 45188e93258fSBjoern A. Zeeb break; 45198e93258fSBjoern A. Zeeb case BTC_WIDLE: /* wl-idle + bt-A2DP */ 45208e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_AUTO_TD20B1, BTC_ACT_BT_A2DP); 45218e93258fSBjoern A. Zeeb break; 45228e93258fSBjoern A. Zeeb } 45238e93258fSBjoern A. Zeeb } 45248e93258fSBjoern A. Zeeb 45258e93258fSBjoern A. Zeeb static void _action_bt_a2dpsink(struct rtw89_dev *rtwdev) 45268e93258fSBjoern A. Zeeb { 45278e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 45288e93258fSBjoern A. Zeeb 45298e93258fSBjoern A. Zeeb _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); 45308e93258fSBjoern A. Zeeb 45318e93258fSBjoern A. Zeeb switch (btc->cx.state_map) { 45328e93258fSBjoern A. Zeeb case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-A2dp_Sink */ 45338e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_PFIX_TD2030, BTC_ACT_BT_A2DPSINK); 45348e93258fSBjoern A. Zeeb break; 45358e93258fSBjoern A. Zeeb case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-A2dp_Sink */ 45368e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_PFIX_TD2060, BTC_ACT_BT_A2DPSINK); 45378e93258fSBjoern A. Zeeb break; 45388e93258fSBjoern A. Zeeb case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-A2dp_Sink */ 45398e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_FIX_TD2030, BTC_ACT_BT_A2DPSINK); 45408e93258fSBjoern A. Zeeb break; 45418e93258fSBjoern A. Zeeb case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-A2dp_Sink */ 45428e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_FIX_TD2060, BTC_ACT_BT_A2DPSINK); 45438e93258fSBjoern A. Zeeb break; 45448e93258fSBjoern A. Zeeb case BTC_WLINKING: /* wl-connecting + bt-A2dp_Sink */ 45458e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_FIX_TD3030, BTC_ACT_BT_A2DPSINK); 45468e93258fSBjoern A. Zeeb break; 45478e93258fSBjoern A. Zeeb case BTC_WIDLE: /* wl-idle + bt-A2dp_Sink */ 45488e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_FIX_TD2080, BTC_ACT_BT_A2DPSINK); 45498e93258fSBjoern A. Zeeb break; 45508e93258fSBjoern A. Zeeb } 45518e93258fSBjoern A. Zeeb } 45528e93258fSBjoern A. Zeeb 45538e93258fSBjoern A. Zeeb static void _action_bt_pan(struct rtw89_dev *rtwdev) 45548e93258fSBjoern A. Zeeb { 45558e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 45568e93258fSBjoern A. Zeeb 45578e93258fSBjoern A. Zeeb _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); 45588e93258fSBjoern A. Zeeb 45598e93258fSBjoern A. Zeeb switch (btc->cx.state_map) { 45608e93258fSBjoern A. Zeeb case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-PAN */ 45618e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_PFIX_TD5050, BTC_ACT_BT_PAN); 45628e93258fSBjoern A. Zeeb break; 45638e93258fSBjoern A. Zeeb case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-PAN */ 45648e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_PFIX_TD3070, BTC_ACT_BT_PAN); 45658e93258fSBjoern A. Zeeb break; 45668e93258fSBjoern A. Zeeb case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-PAN */ 45678e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_FIX_TD3030, BTC_ACT_BT_PAN); 45688e93258fSBjoern A. Zeeb break; 45698e93258fSBjoern A. Zeeb case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-PAN */ 45708e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_FIX_TD3060, BTC_ACT_BT_PAN); 45718e93258fSBjoern A. Zeeb break; 45728e93258fSBjoern A. Zeeb case BTC_WLINKING: /* wl-connecting + bt-PAN */ 4573*6d67aabdSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_FIX_TD4010ISO, BTC_ACT_BT_PAN); 45748e93258fSBjoern A. Zeeb break; 45758e93258fSBjoern A. Zeeb case BTC_WIDLE: /* wl-idle + bt-pan */ 45768e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_PFIX_TD2080, BTC_ACT_BT_PAN); 45778e93258fSBjoern A. Zeeb break; 45788e93258fSBjoern A. Zeeb } 45798e93258fSBjoern A. Zeeb } 45808e93258fSBjoern A. Zeeb 45818e93258fSBjoern A. Zeeb static void _action_bt_a2dp_hid(struct rtw89_dev *rtwdev) 45828e93258fSBjoern A. Zeeb { 45838e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 45848e93258fSBjoern A. Zeeb struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt.link_info; 45858e93258fSBjoern A. Zeeb struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc; 45868e93258fSBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 45878e93258fSBjoern A. Zeeb 45888e93258fSBjoern A. Zeeb _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); 45898e93258fSBjoern A. Zeeb 45908e93258fSBjoern A. Zeeb switch (btc->cx.state_map) { 45918e93258fSBjoern A. Zeeb case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-A2DP+HID */ 45928e93258fSBjoern A. Zeeb case BTC_WIDLE: /* wl-idle + bt-A2DP */ 45938e93258fSBjoern A. Zeeb if (a2dp.vendor_id == 0x4c || dm->leak_ap) { 45948e93258fSBjoern A. Zeeb dm->slot_dur[CXST_W1] = 40; 45958e93258fSBjoern A. Zeeb dm->slot_dur[CXST_B1] = 200; 45968e93258fSBjoern A. Zeeb _set_policy(rtwdev, 45978e93258fSBjoern A. Zeeb BTC_CXP_PAUTO_TDW1B1, BTC_ACT_BT_A2DP_HID); 45988e93258fSBjoern A. Zeeb } else { 45998e93258fSBjoern A. Zeeb _set_policy(rtwdev, 46008e93258fSBjoern A. Zeeb BTC_CXP_PAUTO_TD50B1, BTC_ACT_BT_A2DP_HID); 46018e93258fSBjoern A. Zeeb } 46028e93258fSBjoern A. Zeeb break; 46038e93258fSBjoern A. Zeeb case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-A2DP+HID */ 46048e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3050, BTC_ACT_BT_A2DP_HID); 46058e93258fSBjoern A. Zeeb break; 46068e93258fSBjoern A. Zeeb 46078e93258fSBjoern A. Zeeb case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-A2DP+HID */ 46088e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_AUTO2_TD3050, BTC_ACT_BT_A2DP_HID); 46098e93258fSBjoern A. Zeeb break; 46108e93258fSBjoern A. Zeeb case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-A2DP+HID */ 46118e93258fSBjoern A. Zeeb case BTC_WLINKING: /* wl-connecting + bt-A2DP+HID */ 46128e93258fSBjoern A. Zeeb if (a2dp.vendor_id == 0x4c || dm->leak_ap) { 46138e93258fSBjoern A. Zeeb dm->slot_dur[CXST_W1] = 40; 46148e93258fSBjoern A. Zeeb dm->slot_dur[CXST_B1] = 200; 46158e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_AUTO_TDW1B1, 46168e93258fSBjoern A. Zeeb BTC_ACT_BT_A2DP_HID); 46178e93258fSBjoern A. Zeeb } else { 46188e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_AUTO_TD50B1, 46198e93258fSBjoern A. Zeeb BTC_ACT_BT_A2DP_HID); 46208e93258fSBjoern A. Zeeb } 46218e93258fSBjoern A. Zeeb break; 46228e93258fSBjoern A. Zeeb } 46238e93258fSBjoern A. Zeeb } 46248e93258fSBjoern A. Zeeb 46258e93258fSBjoern A. Zeeb static void _action_bt_a2dp_pan(struct rtw89_dev *rtwdev) 46268e93258fSBjoern A. Zeeb { 46278e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 46288e93258fSBjoern A. Zeeb 46298e93258fSBjoern A. Zeeb _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); 46308e93258fSBjoern A. Zeeb 46318e93258fSBjoern A. Zeeb switch (btc->cx.state_map) { 46328e93258fSBjoern A. Zeeb case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-A2DP+PAN */ 46338e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3070, BTC_ACT_BT_A2DP_PAN); 46348e93258fSBjoern A. Zeeb break; 46358e93258fSBjoern A. Zeeb case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-A2DP+PAN */ 46368e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3070, BTC_ACT_BT_A2DP_PAN); 46378e93258fSBjoern A. Zeeb break; 46388e93258fSBjoern A. Zeeb case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-A2DP+PAN */ 46398e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_AUTO2_TD5050, BTC_ACT_BT_A2DP_PAN); 46408e93258fSBjoern A. Zeeb break; 46418e93258fSBjoern A. Zeeb case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-A2DP+PAN */ 46428e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_AUTO2_TD3070, BTC_ACT_BT_A2DP_PAN); 46438e93258fSBjoern A. Zeeb break; 46448e93258fSBjoern A. Zeeb case BTC_WLINKING: /* wl-connecting + bt-A2DP+PAN */ 46458e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_AUTO2_TD3050, BTC_ACT_BT_A2DP_PAN); 46468e93258fSBjoern A. Zeeb break; 46478e93258fSBjoern A. Zeeb case BTC_WIDLE: /* wl-idle + bt-A2DP+PAN */ 46488e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_PAUTO2_TD2080, BTC_ACT_BT_A2DP_PAN); 46498e93258fSBjoern A. Zeeb break; 46508e93258fSBjoern A. Zeeb } 46518e93258fSBjoern A. Zeeb } 46528e93258fSBjoern A. Zeeb 46538e93258fSBjoern A. Zeeb static void _action_bt_pan_hid(struct rtw89_dev *rtwdev) 46548e93258fSBjoern A. Zeeb { 46558e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 46568e93258fSBjoern A. Zeeb 46578e93258fSBjoern A. Zeeb _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); 46588e93258fSBjoern A. Zeeb 46598e93258fSBjoern A. Zeeb switch (btc->cx.state_map) { 46608e93258fSBjoern A. Zeeb case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-PAN+HID */ 46618e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_PFIX_TD3030, BTC_ACT_BT_PAN_HID); 46628e93258fSBjoern A. Zeeb break; 46638e93258fSBjoern A. Zeeb case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-PAN+HID */ 46648e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_PFIX_TD3070, BTC_ACT_BT_PAN_HID); 46658e93258fSBjoern A. Zeeb break; 46668e93258fSBjoern A. Zeeb case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-PAN+HID */ 46678e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_FIX_TD3030, BTC_ACT_BT_PAN_HID); 46688e93258fSBjoern A. Zeeb break; 46698e93258fSBjoern A. Zeeb case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-PAN+HID */ 46708e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_FIX_TD3060, BTC_ACT_BT_PAN_HID); 46718e93258fSBjoern A. Zeeb break; 46728e93258fSBjoern A. Zeeb case BTC_WLINKING: /* wl-connecting + bt-PAN+HID */ 46738e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_FIX_TD4010, BTC_ACT_BT_PAN_HID); 46748e93258fSBjoern A. Zeeb break; 46758e93258fSBjoern A. Zeeb case BTC_WIDLE: /* wl-idle + bt-PAN+HID */ 46768e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_PFIX_TD2080, BTC_ACT_BT_PAN_HID); 46778e93258fSBjoern A. Zeeb break; 46788e93258fSBjoern A. Zeeb } 46798e93258fSBjoern A. Zeeb } 46808e93258fSBjoern A. Zeeb 46818e93258fSBjoern A. Zeeb static void _action_bt_a2dp_pan_hid(struct rtw89_dev *rtwdev) 46828e93258fSBjoern A. Zeeb { 46838e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 46848e93258fSBjoern A. Zeeb 46858e93258fSBjoern A. Zeeb _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); 46868e93258fSBjoern A. Zeeb 46878e93258fSBjoern A. Zeeb switch (btc->cx.state_map) { 46888e93258fSBjoern A. Zeeb case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-A2DP+PAN+HID */ 46898e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3070, 46908e93258fSBjoern A. Zeeb BTC_ACT_BT_A2DP_PAN_HID); 46918e93258fSBjoern A. Zeeb break; 46928e93258fSBjoern A. Zeeb case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-A2DP+PAN+HID */ 46938e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3070, 46948e93258fSBjoern A. Zeeb BTC_ACT_BT_A2DP_PAN_HID); 46958e93258fSBjoern A. Zeeb break; 46968e93258fSBjoern A. Zeeb case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-A2DP+PAN+HID */ 46978e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_AUTO2_TD3070, 46988e93258fSBjoern A. Zeeb BTC_ACT_BT_A2DP_PAN_HID); 46998e93258fSBjoern A. Zeeb break; 47008e93258fSBjoern A. Zeeb case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-A2DP+PAN+HID */ 47018e93258fSBjoern A. Zeeb case BTC_WLINKING: /* wl-connecting + bt-A2DP+PAN+HID */ 47028e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_AUTO2_TD3050, 47038e93258fSBjoern A. Zeeb BTC_ACT_BT_A2DP_PAN_HID); 47048e93258fSBjoern A. Zeeb break; 47058e93258fSBjoern A. Zeeb case BTC_WIDLE: /* wl-idle + bt-A2DP+PAN+HID */ 47068e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_PAUTO2_TD2080, 47078e93258fSBjoern A. Zeeb BTC_ACT_BT_A2DP_PAN_HID); 47088e93258fSBjoern A. Zeeb break; 47098e93258fSBjoern A. Zeeb } 47108e93258fSBjoern A. Zeeb } 47118e93258fSBjoern A. Zeeb 47128e93258fSBjoern A. Zeeb static void _action_wl_5g(struct rtw89_dev *rtwdev) 47138e93258fSBjoern A. Zeeb { 47148e93258fSBjoern A. Zeeb _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W5G); 47158e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_5G); 47168e93258fSBjoern A. Zeeb } 47178e93258fSBjoern A. Zeeb 47188e93258fSBjoern A. Zeeb static void _action_wl_other(struct rtw89_dev *rtwdev) 47198e93258fSBjoern A. Zeeb { 47208e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 47218e93258fSBjoern A. Zeeb 47228e93258fSBjoern A. Zeeb _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); 47238e93258fSBjoern A. Zeeb 4724*6d67aabdSBjoern A. Zeeb if (btc->ant_type == BTC_ANT_SHARED) 47258e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFFB_BWB0, BTC_ACT_WL_OTHER); 47268e93258fSBjoern A. Zeeb else 47278e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_OTHER); 47288e93258fSBjoern A. Zeeb } 47298e93258fSBjoern A. Zeeb 47308e93258fSBjoern A. Zeeb static void _action_wl_nc(struct rtw89_dev *rtwdev) 47318e93258fSBjoern A. Zeeb { 47328e93258fSBjoern A. Zeeb _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); 47338e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_WL_NC); 47348e93258fSBjoern A. Zeeb } 47358e93258fSBjoern A. Zeeb 47368e93258fSBjoern A. Zeeb static void _action_wl_rfk(struct rtw89_dev *rtwdev) 47378e93258fSBjoern A. Zeeb { 47388e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 47398e93258fSBjoern A. Zeeb struct rtw89_btc_wl_rfk_info rfk = btc->cx.wl.rfk_info; 47408e93258fSBjoern A. Zeeb 47418e93258fSBjoern A. Zeeb if (rfk.state != BTC_WRFK_START) 47428e93258fSBjoern A. Zeeb return; 47438e93258fSBjoern A. Zeeb 47448e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): band = %d\n", 47458e93258fSBjoern A. Zeeb __func__, rfk.band); 47468e93258fSBjoern A. Zeeb 47478e93258fSBjoern A. Zeeb _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WRFK); 47488e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFF_WL, BTC_ACT_WL_RFK); 47498e93258fSBjoern A. Zeeb } 47508e93258fSBjoern A. Zeeb 47518e93258fSBjoern A. Zeeb static void _set_btg_ctrl(struct rtw89_dev *rtwdev) 47528e93258fSBjoern A. Zeeb { 47538e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 47548e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 47558e93258fSBjoern A. Zeeb struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1; 4756e2340276SBjoern A. Zeeb struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2; 4757*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_role_info_v8 *wl_rinfo_v8 = &wl->role_info_v8; 4758*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_role_info *wl_rinfo_v0 = &wl->role_info; 47598e93258fSBjoern A. Zeeb struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info; 4760*6d67aabdSBjoern A. Zeeb const struct rtw89_chip_info *chip = rtwdev->chip; 4761*6d67aabdSBjoern A. Zeeb const struct rtw89_btc_ver *ver = btc->ver; 4762*6d67aabdSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &btc->cx.bt; 4763*6d67aabdSBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 4764*6d67aabdSBjoern A. Zeeb struct _wl_rinfo_now wl_rinfo; 4765*6d67aabdSBjoern A. Zeeb u32 run_reason = btc->dm.run_reason; 4766*6d67aabdSBjoern A. Zeeb u32 is_btg; 4767*6d67aabdSBjoern A. Zeeb u8 i, val; 47688e93258fSBjoern A. Zeeb 4769*6d67aabdSBjoern A. Zeeb if (btc->manual_ctrl) 47708e93258fSBjoern A. Zeeb return; 47718e93258fSBjoern A. Zeeb 4772e2340276SBjoern A. Zeeb if (ver->fwlrole == 0) 4773*6d67aabdSBjoern A. Zeeb wl_rinfo.link_mode = wl_rinfo_v0->link_mode; 4774e2340276SBjoern A. Zeeb else if (ver->fwlrole == 1) 4775*6d67aabdSBjoern A. Zeeb wl_rinfo.link_mode = wl_rinfo_v1->link_mode; 4776e2340276SBjoern A. Zeeb else if (ver->fwlrole == 2) 4777*6d67aabdSBjoern A. Zeeb wl_rinfo.link_mode = wl_rinfo_v2->link_mode; 4778*6d67aabdSBjoern A. Zeeb else if (ver->fwlrole == 8) 4779*6d67aabdSBjoern A. Zeeb wl_rinfo.link_mode = wl_rinfo_v8->link_mode; 4780e2340276SBjoern A. Zeeb else 4781e2340276SBjoern A. Zeeb return; 47828e93258fSBjoern A. Zeeb 4783*6d67aabdSBjoern A. Zeeb if (rtwdev->dbcc_en) { 4784*6d67aabdSBjoern A. Zeeb if (ver->fwlrole == 0) { 4785*6d67aabdSBjoern A. Zeeb for (i = 0; i < RTW89_PHY_MAX; i++) { 4786*6d67aabdSBjoern A. Zeeb if (wl_dinfo->real_band[i] == RTW89_BAND_2G) 4787*6d67aabdSBjoern A. Zeeb wl_rinfo.dbcc_2g_phy = i; 4788*6d67aabdSBjoern A. Zeeb } 4789*6d67aabdSBjoern A. Zeeb } else if (ver->fwlrole == 1) { 4790*6d67aabdSBjoern A. Zeeb wl_rinfo.dbcc_2g_phy = wl_rinfo_v1->dbcc_2g_phy; 4791*6d67aabdSBjoern A. Zeeb } else if (ver->fwlrole == 2) { 4792*6d67aabdSBjoern A. Zeeb wl_rinfo.dbcc_2g_phy = wl_rinfo_v2->dbcc_2g_phy; 4793*6d67aabdSBjoern A. Zeeb } else if (ver->fwlrole == 8) { 4794*6d67aabdSBjoern A. Zeeb wl_rinfo.dbcc_2g_phy = wl_rinfo_v8->dbcc_2g_phy; 4795*6d67aabdSBjoern A. Zeeb } else { 4796*6d67aabdSBjoern A. Zeeb return; 4797*6d67aabdSBjoern A. Zeeb } 4798*6d67aabdSBjoern A. Zeeb } 4799*6d67aabdSBjoern A. Zeeb 4800*6d67aabdSBjoern A. Zeeb if (wl_rinfo.link_mode == BTC_WLINK_25G_MCC) 4801*6d67aabdSBjoern A. Zeeb is_btg = BTC_BTGCTRL_BB_GNT_FWCTRL; 4802*6d67aabdSBjoern A. Zeeb else if (!(bt->run_patch_code && bt->enable.now)) 4803*6d67aabdSBjoern A. Zeeb is_btg = BTC_BTGCTRL_DISABLE; 4804*6d67aabdSBjoern A. Zeeb else if (wl_rinfo.link_mode == BTC_WLINK_5G) 4805*6d67aabdSBjoern A. Zeeb is_btg = BTC_BTGCTRL_DISABLE; 4806*6d67aabdSBjoern A. Zeeb else if (dm->freerun) 4807*6d67aabdSBjoern A. Zeeb is_btg = BTC_BTGCTRL_DISABLE; 4808*6d67aabdSBjoern A. Zeeb else if (rtwdev->dbcc_en && wl_rinfo.dbcc_2g_phy != RTW89_PHY_1) 4809*6d67aabdSBjoern A. Zeeb is_btg = BTC_BTGCTRL_DISABLE; 48108e93258fSBjoern A. Zeeb else 4811*6d67aabdSBjoern A. Zeeb is_btg = BTC_BTGCTRL_ENABLE; 48128e93258fSBjoern A. Zeeb 4813*6d67aabdSBjoern A. Zeeb if (dm->wl_btg_rx_rb != dm->wl_btg_rx && 4814*6d67aabdSBjoern A. Zeeb dm->wl_btg_rx_rb != BTC_BTGCTRL_BB_GNT_NOTFOUND) { 4815*6d67aabdSBjoern A. Zeeb _get_reg_status(rtwdev, BTC_CSTATUS_BB_GNT_MUX, &val); 4816*6d67aabdSBjoern A. Zeeb dm->wl_btg_rx_rb = val; 4817*6d67aabdSBjoern A. Zeeb } 4818*6d67aabdSBjoern A. Zeeb 4819*6d67aabdSBjoern A. Zeeb if (run_reason == BTC_RSN_NTFY_INIT || 4820*6d67aabdSBjoern A. Zeeb run_reason == BTC_RSN_NTFY_SWBAND || 4821*6d67aabdSBjoern A. Zeeb dm->wl_btg_rx_rb != dm->wl_btg_rx || 4822*6d67aabdSBjoern A. Zeeb is_btg != dm->wl_btg_rx) { 4823*6d67aabdSBjoern A. Zeeb 4824*6d67aabdSBjoern A. Zeeb dm->wl_btg_rx = is_btg; 4825*6d67aabdSBjoern A. Zeeb 4826*6d67aabdSBjoern A. Zeeb if (is_btg > BTC_BTGCTRL_ENABLE) 48278e93258fSBjoern A. Zeeb return; 48288e93258fSBjoern A. Zeeb 4829*6d67aabdSBjoern A. Zeeb chip->ops->ctrl_btg_bt_rx(rtwdev, is_btg, RTW89_PHY_0); 4830*6d67aabdSBjoern A. Zeeb } 4831*6d67aabdSBjoern A. Zeeb } 48328e93258fSBjoern A. Zeeb 4833*6d67aabdSBjoern A. Zeeb static void _set_wl_preagc_ctrl(struct rtw89_dev *rtwdev) 4834*6d67aabdSBjoern A. Zeeb { 4835*6d67aabdSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 4836*6d67aabdSBjoern A. Zeeb struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt.link_info; 4837*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 4838*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_role_info_v2 *wl_rinfo = &wl->role_info_v2; 4839*6d67aabdSBjoern A. Zeeb const struct rtw89_chip_info *chip = rtwdev->chip; 4840*6d67aabdSBjoern A. Zeeb const struct rtw89_btc_ver *ver = btc->ver; 4841*6d67aabdSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &btc->cx.bt; 4842*6d67aabdSBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 4843*6d67aabdSBjoern A. Zeeb u8 is_preagc, val; 4844*6d67aabdSBjoern A. Zeeb 4845*6d67aabdSBjoern A. Zeeb if (btc->manual_ctrl) 48468e93258fSBjoern A. Zeeb return; 48478e93258fSBjoern A. Zeeb 4848*6d67aabdSBjoern A. Zeeb if (wl_rinfo->link_mode == BTC_WLINK_25G_MCC) 4849*6d67aabdSBjoern A. Zeeb is_preagc = BTC_PREAGC_BB_FWCTRL; 4850*6d67aabdSBjoern A. Zeeb else if (!(bt->run_patch_code && bt->enable.now)) 4851*6d67aabdSBjoern A. Zeeb is_preagc = BTC_PREAGC_DISABLE; 4852*6d67aabdSBjoern A. Zeeb else if (wl_rinfo->link_mode == BTC_WLINK_5G) 4853*6d67aabdSBjoern A. Zeeb is_preagc = BTC_PREAGC_DISABLE; 4854*6d67aabdSBjoern A. Zeeb else if (wl_rinfo->link_mode == BTC_WLINK_NOLINK || 4855*6d67aabdSBjoern A. Zeeb btc->cx.bt.link_info.profile_cnt.now == 0) 4856*6d67aabdSBjoern A. Zeeb is_preagc = BTC_PREAGC_DISABLE; 4857*6d67aabdSBjoern A. Zeeb else if (dm->tdma_now.type != CXTDMA_OFF && 4858*6d67aabdSBjoern A. Zeeb !bt_linfo->hfp_desc.exist && 4859*6d67aabdSBjoern A. Zeeb !bt_linfo->hid_desc.exist && 4860*6d67aabdSBjoern A. Zeeb dm->fddt_train == BTC_FDDT_DISABLE) 4861*6d67aabdSBjoern A. Zeeb is_preagc = BTC_PREAGC_DISABLE; 4862*6d67aabdSBjoern A. Zeeb else if (ver->fwlrole == 2 && wl_rinfo->dbcc_en && 4863*6d67aabdSBjoern A. Zeeb wl_rinfo->dbcc_2g_phy != RTW89_PHY_1) 4864*6d67aabdSBjoern A. Zeeb is_preagc = BTC_PREAGC_DISABLE; 4865*6d67aabdSBjoern A. Zeeb else if (btc->ant_type == BTC_ANT_SHARED) 4866*6d67aabdSBjoern A. Zeeb is_preagc = BTC_PREAGC_DISABLE; 4867*6d67aabdSBjoern A. Zeeb else 4868*6d67aabdSBjoern A. Zeeb is_preagc = BTC_PREAGC_ENABLE; 4869*6d67aabdSBjoern A. Zeeb 4870*6d67aabdSBjoern A. Zeeb if (dm->wl_pre_agc_rb != dm->wl_pre_agc && 4871*6d67aabdSBjoern A. Zeeb dm->wl_pre_agc_rb != BTC_PREAGC_NOTFOUND) { 4872*6d67aabdSBjoern A. Zeeb _get_reg_status(rtwdev, BTC_CSTATUS_BB_PRE_AGC, &val); 4873*6d67aabdSBjoern A. Zeeb dm->wl_pre_agc_rb = val; 4874*6d67aabdSBjoern A. Zeeb } 4875*6d67aabdSBjoern A. Zeeb 4876*6d67aabdSBjoern A. Zeeb if ((wl->coex_mode == BTC_MODE_NORMAL && 4877*6d67aabdSBjoern A. Zeeb (dm->run_reason == BTC_RSN_NTFY_INIT || 4878*6d67aabdSBjoern A. Zeeb dm->run_reason == BTC_RSN_NTFY_SWBAND || 4879*6d67aabdSBjoern A. Zeeb dm->wl_pre_agc_rb != dm->wl_pre_agc)) || 4880*6d67aabdSBjoern A. Zeeb is_preagc != dm->wl_pre_agc) { 4881*6d67aabdSBjoern A. Zeeb dm->wl_pre_agc = is_preagc; 4882*6d67aabdSBjoern A. Zeeb 4883*6d67aabdSBjoern A. Zeeb if (is_preagc > BTC_PREAGC_ENABLE) 4884*6d67aabdSBjoern A. Zeeb return; 4885*6d67aabdSBjoern A. Zeeb chip->ops->ctrl_nbtg_bt_tx(rtwdev, dm->wl_pre_agc, RTW89_PHY_0); 4886*6d67aabdSBjoern A. Zeeb } 48878e93258fSBjoern A. Zeeb } 48888e93258fSBjoern A. Zeeb 48898e93258fSBjoern A. Zeeb struct rtw89_txtime_data { 48908e93258fSBjoern A. Zeeb struct rtw89_dev *rtwdev; 48918e93258fSBjoern A. Zeeb int type; 48928e93258fSBjoern A. Zeeb u32 tx_time; 48938e93258fSBjoern A. Zeeb u8 tx_retry; 48948e93258fSBjoern A. Zeeb u16 enable; 48958e93258fSBjoern A. Zeeb bool reenable; 48968e93258fSBjoern A. Zeeb }; 48978e93258fSBjoern A. Zeeb 48988e93258fSBjoern A. Zeeb static void rtw89_tx_time_iter(void *data, struct ieee80211_sta *sta) 48998e93258fSBjoern A. Zeeb { 49008e93258fSBjoern A. Zeeb struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; 49018e93258fSBjoern A. Zeeb struct rtw89_txtime_data *iter_data = 49028e93258fSBjoern A. Zeeb (struct rtw89_txtime_data *)data; 49038e93258fSBjoern A. Zeeb struct rtw89_dev *rtwdev = iter_data->rtwdev; 49048e93258fSBjoern A. Zeeb struct rtw89_vif *rtwvif = rtwsta->rtwvif; 49058e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 49068e93258fSBjoern A. Zeeb struct rtw89_btc_cx *cx = &btc->cx; 49078e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &cx->wl; 49088e93258fSBjoern A. Zeeb struct rtw89_btc_wl_link_info *plink = NULL; 49098e93258fSBjoern A. Zeeb u8 port = rtwvif->port; 49108e93258fSBjoern A. Zeeb u32 tx_time = iter_data->tx_time; 49118e93258fSBjoern A. Zeeb u8 tx_retry = iter_data->tx_retry; 49128e93258fSBjoern A. Zeeb u16 enable = iter_data->enable; 49138e93258fSBjoern A. Zeeb bool reenable = iter_data->reenable; 49148e93258fSBjoern A. Zeeb 4915*6d67aabdSBjoern A. Zeeb if (btc->ver->fwlrole == 8) 4916*6d67aabdSBjoern A. Zeeb plink = &wl->rlink_info[port][0]; 4917*6d67aabdSBjoern A. Zeeb else 49188e93258fSBjoern A. Zeeb plink = &wl->link_info[port]; 49198e93258fSBjoern A. Zeeb 49208e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 49218e93258fSBjoern A. Zeeb "[BTC], %s(): port = %d\n", __func__, port); 49228e93258fSBjoern A. Zeeb 49238e93258fSBjoern A. Zeeb if (!plink->connected) { 49248e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 49258e93258fSBjoern A. Zeeb "[BTC], %s(): connected = %d\n", 49268e93258fSBjoern A. Zeeb __func__, plink->connected); 49278e93258fSBjoern A. Zeeb return; 49288e93258fSBjoern A. Zeeb } 49298e93258fSBjoern A. Zeeb 49308e93258fSBjoern A. Zeeb /* backup the original tx time before tx-limit on */ 49318e93258fSBjoern A. Zeeb if (reenable) { 49328e93258fSBjoern A. Zeeb rtw89_mac_get_tx_time(rtwdev, rtwsta, &plink->tx_time); 49338e93258fSBjoern A. Zeeb rtw89_mac_get_tx_retry_limit(rtwdev, rtwsta, &plink->tx_retry); 49348e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 49358e93258fSBjoern A. Zeeb "[BTC], %s(): reenable, tx_time=%d tx_retry= %d\n", 49368e93258fSBjoern A. Zeeb __func__, plink->tx_time, plink->tx_retry); 49378e93258fSBjoern A. Zeeb } 49388e93258fSBjoern A. Zeeb 49398e93258fSBjoern A. Zeeb /* restore the original tx time if no tx-limit */ 49408e93258fSBjoern A. Zeeb if (!enable) { 49418e93258fSBjoern A. Zeeb rtw89_mac_set_tx_time(rtwdev, rtwsta, true, plink->tx_time); 49428e93258fSBjoern A. Zeeb rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta, true, 49438e93258fSBjoern A. Zeeb plink->tx_retry); 49448e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 49458e93258fSBjoern A. Zeeb "[BTC], %s(): restore, tx_time=%d tx_retry= %d\n", 49468e93258fSBjoern A. Zeeb __func__, plink->tx_time, plink->tx_retry); 49478e93258fSBjoern A. Zeeb 49488e93258fSBjoern A. Zeeb } else { 49498e93258fSBjoern A. Zeeb rtw89_mac_set_tx_time(rtwdev, rtwsta, false, tx_time); 49508e93258fSBjoern A. Zeeb rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta, false, tx_retry); 49518e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 49528e93258fSBjoern A. Zeeb "[BTC], %s(): set, tx_time=%d tx_retry= %d\n", 49538e93258fSBjoern A. Zeeb __func__, tx_time, tx_retry); 49548e93258fSBjoern A. Zeeb } 49558e93258fSBjoern A. Zeeb } 49568e93258fSBjoern A. Zeeb 49578e93258fSBjoern A. Zeeb static void _set_wl_tx_limit(struct rtw89_dev *rtwdev) 49588e93258fSBjoern A. Zeeb { 49598e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 4960e2340276SBjoern A. Zeeb const struct rtw89_btc_ver *ver = btc->ver; 49618e93258fSBjoern A. Zeeb struct rtw89_btc_cx *cx = &btc->cx; 49628e93258fSBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 49638e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &cx->wl; 49648e93258fSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &cx->bt; 49658e93258fSBjoern A. Zeeb struct rtw89_btc_bt_link_info *b = &bt->link_info; 49668e93258fSBjoern A. Zeeb struct rtw89_btc_bt_hfp_desc *hfp = &b->hfp_desc; 49678e93258fSBjoern A. Zeeb struct rtw89_btc_bt_hid_desc *hid = &b->hid_desc; 49688e93258fSBjoern A. Zeeb struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; 49698e93258fSBjoern A. Zeeb struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1; 4970e2340276SBjoern A. Zeeb struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2; 4971*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_role_info_v8 *wl_rinfo_v8 = &wl->role_info_v8; 49728e93258fSBjoern A. Zeeb struct rtw89_txtime_data data = {.rtwdev = rtwdev}; 4973*6d67aabdSBjoern A. Zeeb u8 mode, igno_bt, tx_retry; 49748e93258fSBjoern A. Zeeb u32 tx_time; 49758e93258fSBjoern A. Zeeb u16 enable; 49768e93258fSBjoern A. Zeeb bool reenable = false; 49778e93258fSBjoern A. Zeeb 4978*6d67aabdSBjoern A. Zeeb if (btc->manual_ctrl) 49798e93258fSBjoern A. Zeeb return; 49808e93258fSBjoern A. Zeeb 4981e2340276SBjoern A. Zeeb if (ver->fwlrole == 0) 49828e93258fSBjoern A. Zeeb mode = wl_rinfo->link_mode; 4983e2340276SBjoern A. Zeeb else if (ver->fwlrole == 1) 49848e93258fSBjoern A. Zeeb mode = wl_rinfo_v1->link_mode; 4985e2340276SBjoern A. Zeeb else if (ver->fwlrole == 2) 4986e2340276SBjoern A. Zeeb mode = wl_rinfo_v2->link_mode; 4987*6d67aabdSBjoern A. Zeeb else if (ver->fwlrole == 8) 4988*6d67aabdSBjoern A. Zeeb mode = wl_rinfo_v8->link_mode; 4989e2340276SBjoern A. Zeeb else 4990e2340276SBjoern A. Zeeb return; 49918e93258fSBjoern A. Zeeb 4992*6d67aabdSBjoern A. Zeeb if (ver->fcxctrl == 7) 4993*6d67aabdSBjoern A. Zeeb igno_bt = btc->ctrl.ctrl_v7.igno_bt; 4994*6d67aabdSBjoern A. Zeeb else 4995*6d67aabdSBjoern A. Zeeb igno_bt = btc->ctrl.ctrl.igno_bt; 4996*6d67aabdSBjoern A. Zeeb 4997*6d67aabdSBjoern A. Zeeb if (btc->dm.freerun || igno_bt || b->profile_cnt.now == 0 || 49988e93258fSBjoern A. Zeeb mode == BTC_WLINK_5G || mode == BTC_WLINK_NOLINK) { 49998e93258fSBjoern A. Zeeb enable = 0; 50008e93258fSBjoern A. Zeeb tx_time = BTC_MAX_TX_TIME_DEF; 50018e93258fSBjoern A. Zeeb tx_retry = BTC_MAX_TX_RETRY_DEF; 50028e93258fSBjoern A. Zeeb } else if ((hfp->exist && hid->exist) || hid->pair_cnt > 1) { 50038e93258fSBjoern A. Zeeb enable = 1; 50048e93258fSBjoern A. Zeeb tx_time = BTC_MAX_TX_TIME_L2; 50058e93258fSBjoern A. Zeeb tx_retry = BTC_MAX_TX_RETRY_L1; 50068e93258fSBjoern A. Zeeb } else if (hfp->exist || hid->exist) { 50078e93258fSBjoern A. Zeeb enable = 1; 50088e93258fSBjoern A. Zeeb tx_time = BTC_MAX_TX_TIME_L3; 50098e93258fSBjoern A. Zeeb tx_retry = BTC_MAX_TX_RETRY_L1; 50108e93258fSBjoern A. Zeeb } else { 50118e93258fSBjoern A. Zeeb enable = 0; 50128e93258fSBjoern A. Zeeb tx_time = BTC_MAX_TX_TIME_DEF; 50138e93258fSBjoern A. Zeeb tx_retry = BTC_MAX_TX_RETRY_DEF; 50148e93258fSBjoern A. Zeeb } 50158e93258fSBjoern A. Zeeb 50168e93258fSBjoern A. Zeeb if (dm->wl_tx_limit.enable == enable && 50178e93258fSBjoern A. Zeeb dm->wl_tx_limit.tx_time == tx_time && 50188e93258fSBjoern A. Zeeb dm->wl_tx_limit.tx_retry == tx_retry) 50198e93258fSBjoern A. Zeeb return; 50208e93258fSBjoern A. Zeeb 50218e93258fSBjoern A. Zeeb if (!dm->wl_tx_limit.enable && enable) 50228e93258fSBjoern A. Zeeb reenable = true; 50238e93258fSBjoern A. Zeeb 50248e93258fSBjoern A. Zeeb dm->wl_tx_limit.enable = enable; 50258e93258fSBjoern A. Zeeb dm->wl_tx_limit.tx_time = tx_time; 50268e93258fSBjoern A. Zeeb dm->wl_tx_limit.tx_retry = tx_retry; 50278e93258fSBjoern A. Zeeb 50288e93258fSBjoern A. Zeeb data.enable = enable; 50298e93258fSBjoern A. Zeeb data.tx_time = tx_time; 50308e93258fSBjoern A. Zeeb data.tx_retry = tx_retry; 50318e93258fSBjoern A. Zeeb data.reenable = reenable; 50328e93258fSBjoern A. Zeeb 50338e93258fSBjoern A. Zeeb ieee80211_iterate_stations_atomic(rtwdev->hw, 50348e93258fSBjoern A. Zeeb rtw89_tx_time_iter, 50358e93258fSBjoern A. Zeeb &data); 50368e93258fSBjoern A. Zeeb } 50378e93258fSBjoern A. Zeeb 50388e93258fSBjoern A. Zeeb static void _set_bt_rx_agc(struct rtw89_dev *rtwdev) 50398e93258fSBjoern A. Zeeb { 50408e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 5041e2340276SBjoern A. Zeeb const struct rtw89_btc_ver *ver = btc->ver; 50428e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 50438e93258fSBjoern A. Zeeb struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; 50448e93258fSBjoern A. Zeeb struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1; 5045e2340276SBjoern A. Zeeb struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2; 5046*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_role_info_v8 *wl_rinfo_v8 = &wl->role_info_v8; 50478e93258fSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &btc->cx.bt; 50488e93258fSBjoern A. Zeeb bool bt_hi_lna_rx = false; 50498e93258fSBjoern A. Zeeb u8 mode; 50508e93258fSBjoern A. Zeeb 5051e2340276SBjoern A. Zeeb if (ver->fwlrole == 0) 50528e93258fSBjoern A. Zeeb mode = wl_rinfo->link_mode; 5053e2340276SBjoern A. Zeeb else if (ver->fwlrole == 1) 50548e93258fSBjoern A. Zeeb mode = wl_rinfo_v1->link_mode; 5055e2340276SBjoern A. Zeeb else if (ver->fwlrole == 2) 5056e2340276SBjoern A. Zeeb mode = wl_rinfo_v2->link_mode; 5057*6d67aabdSBjoern A. Zeeb else if (ver->fwlrole == 8) 5058*6d67aabdSBjoern A. Zeeb mode = wl_rinfo_v8->link_mode; 5059e2340276SBjoern A. Zeeb else 5060e2340276SBjoern A. Zeeb return; 50618e93258fSBjoern A. Zeeb 50628e93258fSBjoern A. Zeeb if (mode != BTC_WLINK_NOLINK && btc->dm.wl_btg_rx) 50638e93258fSBjoern A. Zeeb bt_hi_lna_rx = true; 50648e93258fSBjoern A. Zeeb 50658e93258fSBjoern A. Zeeb if (bt_hi_lna_rx == bt->hi_lna_rx) 50668e93258fSBjoern A. Zeeb return; 50678e93258fSBjoern A. Zeeb 50688e93258fSBjoern A. Zeeb _write_scbd(rtwdev, BTC_WSCB_BT_HILNA, bt_hi_lna_rx); 50698e93258fSBjoern A. Zeeb } 50708e93258fSBjoern A. Zeeb 5071e2340276SBjoern A. Zeeb static void _set_bt_rx_scan_pri(struct rtw89_dev *rtwdev) 5072e2340276SBjoern A. Zeeb { 5073e2340276SBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 5074e2340276SBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &btc->cx.bt; 5075e2340276SBjoern A. Zeeb 5076e2340276SBjoern A. Zeeb _write_scbd(rtwdev, BTC_WSCB_RXSCAN_PRI, (bool)(!!bt->scan_rx_low_pri)); 5077e2340276SBjoern A. Zeeb } 5078e2340276SBjoern A. Zeeb 50798e93258fSBjoern A. Zeeb static void _action_common(struct rtw89_dev *rtwdev) 50808e93258fSBjoern A. Zeeb { 5081e2340276SBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 5082e2340276SBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 5083*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_smap *wl_smap = &wl->status.map; 5084*6d67aabdSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &btc->cx.bt; 5085*6d67aabdSBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 5086*6d67aabdSBjoern A. Zeeb u32 bt_rom_code_id, bt_fw_ver; 5087e2340276SBjoern A. Zeeb 50888e93258fSBjoern A. Zeeb _set_btg_ctrl(rtwdev); 5089*6d67aabdSBjoern A. Zeeb _set_wl_preagc_ctrl(rtwdev); 50908e93258fSBjoern A. Zeeb _set_wl_tx_limit(rtwdev); 50918e93258fSBjoern A. Zeeb _set_bt_afh_info(rtwdev); 50928e93258fSBjoern A. Zeeb _set_bt_rx_agc(rtwdev); 50938e93258fSBjoern A. Zeeb _set_rf_trx_para(rtwdev); 5094e2340276SBjoern A. Zeeb _set_bt_rx_scan_pri(rtwdev); 5095e2340276SBjoern A. Zeeb 5096*6d67aabdSBjoern A. Zeeb bt_rom_code_id = chip_id_to_bt_rom_code_id(rtwdev->btc.ver->chip_id); 5097*6d67aabdSBjoern A. Zeeb bt_fw_ver = bt->ver_info.fw & 0xffff; 5098*6d67aabdSBjoern A. Zeeb if (bt->enable.now && 5099*6d67aabdSBjoern A. Zeeb (bt_fw_ver == 0 || 5100*6d67aabdSBjoern A. Zeeb (bt_fw_ver == bt_rom_code_id && bt->run_patch_code && rtwdev->chip->scbd))) 5101*6d67aabdSBjoern A. Zeeb rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_VER_INFO, 1); 5102*6d67aabdSBjoern A. Zeeb else 5103*6d67aabdSBjoern A. Zeeb rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_VER_INFO, 0); 5104*6d67aabdSBjoern A. Zeeb 5105*6d67aabdSBjoern A. Zeeb if (dm->run_reason == BTC_RSN_NTFY_INIT || 5106*6d67aabdSBjoern A. Zeeb dm->run_reason == BTC_RSN_NTFY_RADIO_STATE || 5107*6d67aabdSBjoern A. Zeeb dm->run_reason == BTC_RSN_NTFY_POWEROFF) { 5108*6d67aabdSBjoern A. Zeeb _fw_set_drv_info(rtwdev, CXDRVINFO_ROLE); 5109*6d67aabdSBjoern A. Zeeb 5110*6d67aabdSBjoern A. Zeeb if (wl_smap->rf_off == 1 || wl_smap->lps != BTC_LPS_OFF) 5111*6d67aabdSBjoern A. Zeeb rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_ALL, 0); 5112*6d67aabdSBjoern A. Zeeb else 5113*6d67aabdSBjoern A. Zeeb rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_MREG, 1); 5114*6d67aabdSBjoern A. Zeeb } 5115*6d67aabdSBjoern A. Zeeb 5116e2340276SBjoern A. Zeeb if (wl->scbd_change) { 5117e2340276SBjoern A. Zeeb rtw89_mac_cfg_sb(rtwdev, wl->scbd); 5118e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], write scbd: 0x%08x\n", 5119e2340276SBjoern A. Zeeb wl->scbd); 5120e2340276SBjoern A. Zeeb wl->scbd_change = false; 5121e2340276SBjoern A. Zeeb btc->cx.cnt_wl[BTC_WCNT_SCBDUPDATE]++; 5122e2340276SBjoern A. Zeeb } 5123e2340276SBjoern A. Zeeb btc->dm.tdma_instant_excute = 0; 51248e93258fSBjoern A. Zeeb } 51258e93258fSBjoern A. Zeeb 51268e93258fSBjoern A. Zeeb static void _action_by_bt(struct rtw89_dev *rtwdev) 51278e93258fSBjoern A. Zeeb { 51288e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 51298e93258fSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &btc->cx.bt; 51308e93258fSBjoern A. Zeeb struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info; 51318e93258fSBjoern A. Zeeb struct rtw89_btc_bt_hid_desc hid = bt_linfo->hid_desc; 51328e93258fSBjoern A. Zeeb struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc; 51338e93258fSBjoern A. Zeeb struct rtw89_btc_bt_pan_desc pan = bt_linfo->pan_desc; 51348e93258fSBjoern A. Zeeb u8 profile_map = 0; 51358e93258fSBjoern A. Zeeb 51368e93258fSBjoern A. Zeeb if (bt_linfo->hfp_desc.exist) 51378e93258fSBjoern A. Zeeb profile_map |= BTC_BT_HFP; 51388e93258fSBjoern A. Zeeb 51398e93258fSBjoern A. Zeeb if (bt_linfo->hid_desc.exist) 51408e93258fSBjoern A. Zeeb profile_map |= BTC_BT_HID; 51418e93258fSBjoern A. Zeeb 51428e93258fSBjoern A. Zeeb if (bt_linfo->a2dp_desc.exist) 51438e93258fSBjoern A. Zeeb profile_map |= BTC_BT_A2DP; 51448e93258fSBjoern A. Zeeb 51458e93258fSBjoern A. Zeeb if (bt_linfo->pan_desc.exist) 51468e93258fSBjoern A. Zeeb profile_map |= BTC_BT_PAN; 51478e93258fSBjoern A. Zeeb 51488e93258fSBjoern A. Zeeb switch (profile_map) { 51498e93258fSBjoern A. Zeeb case BTC_BT_NOPROFILE: 51508e93258fSBjoern A. Zeeb if (_check_freerun(rtwdev)) 51518e93258fSBjoern A. Zeeb _action_freerun(rtwdev); 5152e2340276SBjoern A. Zeeb else if (pan.active) 51538e93258fSBjoern A. Zeeb _action_bt_pan(rtwdev); 51548e93258fSBjoern A. Zeeb else 51558e93258fSBjoern A. Zeeb _action_bt_idle(rtwdev); 51568e93258fSBjoern A. Zeeb break; 51578e93258fSBjoern A. Zeeb case BTC_BT_HFP: 51588e93258fSBjoern A. Zeeb if (_check_freerun(rtwdev)) 51598e93258fSBjoern A. Zeeb _action_freerun(rtwdev); 51608e93258fSBjoern A. Zeeb else 51618e93258fSBjoern A. Zeeb _action_bt_hfp(rtwdev); 51628e93258fSBjoern A. Zeeb break; 51638e93258fSBjoern A. Zeeb case BTC_BT_HFP | BTC_BT_HID: 51648e93258fSBjoern A. Zeeb case BTC_BT_HID: 51658e93258fSBjoern A. Zeeb if (_check_freerun(rtwdev)) 51668e93258fSBjoern A. Zeeb _action_freerun(rtwdev); 51678e93258fSBjoern A. Zeeb else 51688e93258fSBjoern A. Zeeb _action_bt_hid(rtwdev); 51698e93258fSBjoern A. Zeeb break; 51708e93258fSBjoern A. Zeeb case BTC_BT_A2DP: 51718e93258fSBjoern A. Zeeb if (_check_freerun(rtwdev)) 51728e93258fSBjoern A. Zeeb _action_freerun(rtwdev); 51738e93258fSBjoern A. Zeeb else if (a2dp.sink) 51748e93258fSBjoern A. Zeeb _action_bt_a2dpsink(rtwdev); 51758e93258fSBjoern A. Zeeb else if (bt_linfo->multi_link.now && !hid.pair_cnt) 51768e93258fSBjoern A. Zeeb _action_bt_a2dp_pan(rtwdev); 51778e93258fSBjoern A. Zeeb else 51788e93258fSBjoern A. Zeeb _action_bt_a2dp(rtwdev); 51798e93258fSBjoern A. Zeeb break; 51808e93258fSBjoern A. Zeeb case BTC_BT_PAN: 51818e93258fSBjoern A. Zeeb _action_bt_pan(rtwdev); 51828e93258fSBjoern A. Zeeb break; 51838e93258fSBjoern A. Zeeb case BTC_BT_A2DP | BTC_BT_HFP: 51848e93258fSBjoern A. Zeeb case BTC_BT_A2DP | BTC_BT_HID: 51858e93258fSBjoern A. Zeeb case BTC_BT_A2DP | BTC_BT_HFP | BTC_BT_HID: 51868e93258fSBjoern A. Zeeb if (_check_freerun(rtwdev)) 51878e93258fSBjoern A. Zeeb _action_freerun(rtwdev); 51888e93258fSBjoern A. Zeeb else 51898e93258fSBjoern A. Zeeb _action_bt_a2dp_hid(rtwdev); 51908e93258fSBjoern A. Zeeb break; 51918e93258fSBjoern A. Zeeb case BTC_BT_A2DP | BTC_BT_PAN: 51928e93258fSBjoern A. Zeeb _action_bt_a2dp_pan(rtwdev); 51938e93258fSBjoern A. Zeeb break; 51948e93258fSBjoern A. Zeeb case BTC_BT_PAN | BTC_BT_HFP: 51958e93258fSBjoern A. Zeeb case BTC_BT_PAN | BTC_BT_HID: 51968e93258fSBjoern A. Zeeb case BTC_BT_PAN | BTC_BT_HFP | BTC_BT_HID: 51978e93258fSBjoern A. Zeeb _action_bt_pan_hid(rtwdev); 51988e93258fSBjoern A. Zeeb break; 51998e93258fSBjoern A. Zeeb case BTC_BT_A2DP | BTC_BT_PAN | BTC_BT_HID: 52008e93258fSBjoern A. Zeeb case BTC_BT_A2DP | BTC_BT_PAN | BTC_BT_HFP: 52018e93258fSBjoern A. Zeeb default: 52028e93258fSBjoern A. Zeeb _action_bt_a2dp_pan_hid(rtwdev); 52038e93258fSBjoern A. Zeeb break; 52048e93258fSBjoern A. Zeeb } 52058e93258fSBjoern A. Zeeb } 52068e93258fSBjoern A. Zeeb 52078e93258fSBjoern A. Zeeb static void _action_wl_2g_sta(struct rtw89_dev *rtwdev) 52088e93258fSBjoern A. Zeeb { 52098e93258fSBjoern A. Zeeb _action_by_bt(rtwdev); 52108e93258fSBjoern A. Zeeb } 52118e93258fSBjoern A. Zeeb 5212*6d67aabdSBjoern A. Zeeb static void _action_wl_25g_mcc(struct rtw89_dev *rtwdev) 5213*6d67aabdSBjoern A. Zeeb { 5214*6d67aabdSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 5215*6d67aabdSBjoern A. Zeeb u16 policy_type = BTC_CXP_OFF_BT; 5216*6d67aabdSBjoern A. Zeeb 5217*6d67aabdSBjoern A. Zeeb if (btc->ant_type == BTC_ANT_SHARED) { 5218*6d67aabdSBjoern A. Zeeb if (btc->cx.wl.status.map._4way) 5219*6d67aabdSBjoern A. Zeeb policy_type = BTC_CXP_OFFE_WL; 5220*6d67aabdSBjoern A. Zeeb else if (btc->cx.wl.status.val & btc_scanning_map.val) 5221*6d67aabdSBjoern A. Zeeb policy_type = BTC_CXP_OFFE_2GBWMIXB; 5222*6d67aabdSBjoern A. Zeeb else if (btc->cx.bt.link_info.profile_cnt.now == 0) 5223*6d67aabdSBjoern A. Zeeb policy_type = BTC_CXP_OFFE_2GISOB; 5224*6d67aabdSBjoern A. Zeeb else 5225*6d67aabdSBjoern A. Zeeb policy_type = BTC_CXP_OFFE_2GBWISOB; 5226*6d67aabdSBjoern A. Zeeb } else { /* dedicated-antenna */ 5227*6d67aabdSBjoern A. Zeeb policy_type = BTC_CXP_OFF_EQ0; 5228*6d67aabdSBjoern A. Zeeb } 5229*6d67aabdSBjoern A. Zeeb 5230*6d67aabdSBjoern A. Zeeb btc->dm.e2g_slot_limit = BTC_E2G_LIMIT_DEF; 5231*6d67aabdSBjoern A. Zeeb 5232*6d67aabdSBjoern A. Zeeb _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W25G); 5233*6d67aabdSBjoern A. Zeeb _set_policy(rtwdev, policy_type, BTC_ACT_WL_25G_MCC); 5234*6d67aabdSBjoern A. Zeeb } 5235*6d67aabdSBjoern A. Zeeb 52368e93258fSBjoern A. Zeeb static void _action_wl_scan(struct rtw89_dev *rtwdev) 52378e93258fSBjoern A. Zeeb { 52388e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 52398e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 52408e93258fSBjoern A. Zeeb struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info; 52418e93258fSBjoern A. Zeeb 52428e93258fSBjoern A. Zeeb if (RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) { 5243*6d67aabdSBjoern A. Zeeb _action_wl_25g_mcc(rtwdev); 52448e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], Scan offload!\n"); 52458e93258fSBjoern A. Zeeb } else if (rtwdev->dbcc_en) { 52468e93258fSBjoern A. Zeeb if (wl_dinfo->real_band[RTW89_PHY_0] != RTW89_BAND_2G && 52478e93258fSBjoern A. Zeeb wl_dinfo->real_band[RTW89_PHY_1] != RTW89_BAND_2G) 52488e93258fSBjoern A. Zeeb _action_wl_5g(rtwdev); 52498e93258fSBjoern A. Zeeb else 52508e93258fSBjoern A. Zeeb _action_by_bt(rtwdev); 52518e93258fSBjoern A. Zeeb } else { 52528e93258fSBjoern A. Zeeb if (wl->scan_info.band[RTW89_PHY_0] != RTW89_BAND_2G) 52538e93258fSBjoern A. Zeeb _action_wl_5g(rtwdev); 52548e93258fSBjoern A. Zeeb else 52558e93258fSBjoern A. Zeeb _action_by_bt(rtwdev); 52568e93258fSBjoern A. Zeeb } 52578e93258fSBjoern A. Zeeb } 52588e93258fSBjoern A. Zeeb 52598e93258fSBjoern A. Zeeb static void _action_wl_2g_mcc(struct rtw89_dev *rtwdev) 52608e93258fSBjoern A. Zeeb { struct rtw89_btc *btc = &rtwdev->btc; 52618e93258fSBjoern A. Zeeb 52628e93258fSBjoern A. Zeeb _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); 52638e93258fSBjoern A. Zeeb 5264*6d67aabdSBjoern A. Zeeb if (btc->ant_type == BTC_ANT_SHARED) { /* shared-antenna */ 52658e93258fSBjoern A. Zeeb if (btc->cx.bt.link_info.profile_cnt.now == 0) 52668e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFFE_DEF2, 52678e93258fSBjoern A. Zeeb BTC_ACT_WL_2G_MCC); 52688e93258fSBjoern A. Zeeb else 52698e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFFE_DEF, 52708e93258fSBjoern A. Zeeb BTC_ACT_WL_2G_MCC); 52718e93258fSBjoern A. Zeeb } else { /* dedicated-antenna */ 52728e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_2G_MCC); 52738e93258fSBjoern A. Zeeb } 52748e93258fSBjoern A. Zeeb } 52758e93258fSBjoern A. Zeeb 52768e93258fSBjoern A. Zeeb static void _action_wl_2g_scc(struct rtw89_dev *rtwdev) 52778e93258fSBjoern A. Zeeb { 52788e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 52798e93258fSBjoern A. Zeeb 52808e93258fSBjoern A. Zeeb _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); 52818e93258fSBjoern A. Zeeb 5282*6d67aabdSBjoern A. Zeeb if (btc->ant_type == BTC_ANT_SHARED) { /* shared-antenna */ 52838e93258fSBjoern A. Zeeb if (btc->cx.bt.link_info.profile_cnt.now == 0) 52848e93258fSBjoern A. Zeeb _set_policy(rtwdev, 52858e93258fSBjoern A. Zeeb BTC_CXP_OFFE_DEF2, BTC_ACT_WL_2G_SCC); 52868e93258fSBjoern A. Zeeb else 52878e93258fSBjoern A. Zeeb _set_policy(rtwdev, 52888e93258fSBjoern A. Zeeb BTC_CXP_OFFE_DEF, BTC_ACT_WL_2G_SCC); 52898e93258fSBjoern A. Zeeb } else { /* dedicated-antenna */ 52908e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_2G_SCC); 52918e93258fSBjoern A. Zeeb } 52928e93258fSBjoern A. Zeeb } 52938e93258fSBjoern A. Zeeb 52948e93258fSBjoern A. Zeeb static void _action_wl_2g_scc_v1(struct rtw89_dev *rtwdev) 52958e93258fSBjoern A. Zeeb { 52968e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 52978e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 52988e93258fSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &btc->cx.bt; 52998e93258fSBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 53008e93258fSBjoern A. Zeeb struct rtw89_btc_wl_role_info_v1 *wl_rinfo = &wl->role_info_v1; 53018e93258fSBjoern A. Zeeb u16 policy_type = BTC_CXP_OFF_BT; 53028e93258fSBjoern A. Zeeb u32 dur; 53038e93258fSBjoern A. Zeeb 5304*6d67aabdSBjoern A. Zeeb if (btc->ant_type == BTC_ANT_DEDICATED) { 53058e93258fSBjoern A. Zeeb policy_type = BTC_CXP_OFF_EQ0; 53068e93258fSBjoern A. Zeeb } else { 53078e93258fSBjoern A. Zeeb /* shared-antenna */ 53088e93258fSBjoern A. Zeeb switch (wl_rinfo->mrole_type) { 53098e93258fSBjoern A. Zeeb case BTC_WLMROLE_STA_GC: 53108e93258fSBjoern A. Zeeb dm->wl_scc.null_role1 = RTW89_WIFI_ROLE_STATION; 53118e93258fSBjoern A. Zeeb dm->wl_scc.null_role2 = RTW89_WIFI_ROLE_P2P_CLIENT; 53128e93258fSBjoern A. Zeeb dm->wl_scc.ebt_null = 0; /* no ext-slot-control */ 53138e93258fSBjoern A. Zeeb _action_by_bt(rtwdev); 53148e93258fSBjoern A. Zeeb return; 53158e93258fSBjoern A. Zeeb case BTC_WLMROLE_STA_STA: 53168e93258fSBjoern A. Zeeb dm->wl_scc.null_role1 = RTW89_WIFI_ROLE_STATION; 53178e93258fSBjoern A. Zeeb dm->wl_scc.null_role2 = RTW89_WIFI_ROLE_STATION; 53188e93258fSBjoern A. Zeeb dm->wl_scc.ebt_null = 0; /* no ext-slot-control */ 53198e93258fSBjoern A. Zeeb _action_by_bt(rtwdev); 53208e93258fSBjoern A. Zeeb return; 53218e93258fSBjoern A. Zeeb case BTC_WLMROLE_STA_GC_NOA: 53228e93258fSBjoern A. Zeeb case BTC_WLMROLE_STA_GO: 53238e93258fSBjoern A. Zeeb case BTC_WLMROLE_STA_GO_NOA: 53248e93258fSBjoern A. Zeeb dm->wl_scc.null_role1 = RTW89_WIFI_ROLE_STATION; 53258e93258fSBjoern A. Zeeb dm->wl_scc.null_role2 = RTW89_WIFI_ROLE_NONE; 53268e93258fSBjoern A. Zeeb dur = wl_rinfo->mrole_noa_duration; 53278e93258fSBjoern A. Zeeb 53288e93258fSBjoern A. Zeeb if (wl->status.map._4way) { 53298e93258fSBjoern A. Zeeb dm->wl_scc.ebt_null = 0; 53308e93258fSBjoern A. Zeeb policy_type = BTC_CXP_OFFE_WL; 53318e93258fSBjoern A. Zeeb } else if (bt->link_info.status.map.connect == 0) { 53328e93258fSBjoern A. Zeeb dm->wl_scc.ebt_null = 0; 53338e93258fSBjoern A. Zeeb policy_type = BTC_CXP_OFFE_2GISOB; 53348e93258fSBjoern A. Zeeb } else if (bt->link_info.a2dp_desc.exist && 53358e93258fSBjoern A. Zeeb dur < btc->bt_req_len) { 53368e93258fSBjoern A. Zeeb dm->wl_scc.ebt_null = 1; /* tx null at EBT */ 53378e93258fSBjoern A. Zeeb policy_type = BTC_CXP_OFFE_2GBWMIXB2; 53388e93258fSBjoern A. Zeeb } else if (bt->link_info.a2dp_desc.exist || 53398e93258fSBjoern A. Zeeb bt->link_info.pan_desc.exist) { 53408e93258fSBjoern A. Zeeb dm->wl_scc.ebt_null = 1; /* tx null at EBT */ 53418e93258fSBjoern A. Zeeb policy_type = BTC_CXP_OFFE_2GBWISOB; 53428e93258fSBjoern A. Zeeb } else { 53438e93258fSBjoern A. Zeeb dm->wl_scc.ebt_null = 0; 53448e93258fSBjoern A. Zeeb policy_type = BTC_CXP_OFFE_2GBWISOB; 53458e93258fSBjoern A. Zeeb } 53468e93258fSBjoern A. Zeeb break; 53478e93258fSBjoern A. Zeeb default: 53488e93258fSBjoern A. Zeeb break; 53498e93258fSBjoern A. Zeeb } 53508e93258fSBjoern A. Zeeb } 53518e93258fSBjoern A. Zeeb 53528e93258fSBjoern A. Zeeb _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); 53538e93258fSBjoern A. Zeeb _set_policy(rtwdev, policy_type, BTC_ACT_WL_2G_SCC); 53548e93258fSBjoern A. Zeeb } 53558e93258fSBjoern A. Zeeb 5356e2340276SBjoern A. Zeeb static void _action_wl_2g_scc_v2(struct rtw89_dev *rtwdev) 5357e2340276SBjoern A. Zeeb { 5358e2340276SBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 5359e2340276SBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 5360e2340276SBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &btc->cx.bt; 5361e2340276SBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 5362e2340276SBjoern A. Zeeb struct rtw89_btc_wl_role_info_v2 *wl_rinfo = &wl->role_info_v2; 5363e2340276SBjoern A. Zeeb u16 policy_type = BTC_CXP_OFF_BT; 5364e2340276SBjoern A. Zeeb u32 dur; 5365e2340276SBjoern A. Zeeb 5366*6d67aabdSBjoern A. Zeeb if (btc->ant_type == BTC_ANT_DEDICATED) { 5367e2340276SBjoern A. Zeeb policy_type = BTC_CXP_OFF_EQ0; 5368e2340276SBjoern A. Zeeb } else { 5369e2340276SBjoern A. Zeeb /* shared-antenna */ 5370e2340276SBjoern A. Zeeb switch (wl_rinfo->mrole_type) { 5371e2340276SBjoern A. Zeeb case BTC_WLMROLE_STA_GC: 5372e2340276SBjoern A. Zeeb dm->wl_scc.null_role1 = RTW89_WIFI_ROLE_STATION; 5373e2340276SBjoern A. Zeeb dm->wl_scc.null_role2 = RTW89_WIFI_ROLE_P2P_CLIENT; 5374e2340276SBjoern A. Zeeb dm->wl_scc.ebt_null = 0; /* no ext-slot-control */ 5375e2340276SBjoern A. Zeeb _action_by_bt(rtwdev); 5376e2340276SBjoern A. Zeeb return; 5377e2340276SBjoern A. Zeeb case BTC_WLMROLE_STA_STA: 5378e2340276SBjoern A. Zeeb dm->wl_scc.null_role1 = RTW89_WIFI_ROLE_STATION; 5379e2340276SBjoern A. Zeeb dm->wl_scc.null_role2 = RTW89_WIFI_ROLE_STATION; 5380e2340276SBjoern A. Zeeb dm->wl_scc.ebt_null = 0; /* no ext-slot-control */ 5381e2340276SBjoern A. Zeeb _action_by_bt(rtwdev); 5382e2340276SBjoern A. Zeeb return; 5383e2340276SBjoern A. Zeeb case BTC_WLMROLE_STA_GC_NOA: 5384e2340276SBjoern A. Zeeb case BTC_WLMROLE_STA_GO: 5385e2340276SBjoern A. Zeeb case BTC_WLMROLE_STA_GO_NOA: 5386e2340276SBjoern A. Zeeb dm->wl_scc.null_role1 = RTW89_WIFI_ROLE_STATION; 5387e2340276SBjoern A. Zeeb dm->wl_scc.null_role2 = RTW89_WIFI_ROLE_NONE; 5388e2340276SBjoern A. Zeeb dur = wl_rinfo->mrole_noa_duration; 5389e2340276SBjoern A. Zeeb 5390e2340276SBjoern A. Zeeb if (wl->status.map._4way) { 5391e2340276SBjoern A. Zeeb dm->wl_scc.ebt_null = 0; 5392e2340276SBjoern A. Zeeb policy_type = BTC_CXP_OFFE_WL; 5393e2340276SBjoern A. Zeeb } else if (bt->link_info.status.map.connect == 0) { 5394e2340276SBjoern A. Zeeb dm->wl_scc.ebt_null = 0; 5395e2340276SBjoern A. Zeeb policy_type = BTC_CXP_OFFE_2GISOB; 5396e2340276SBjoern A. Zeeb } else if (bt->link_info.a2dp_desc.exist && 5397e2340276SBjoern A. Zeeb dur < btc->bt_req_len) { 5398e2340276SBjoern A. Zeeb dm->wl_scc.ebt_null = 1; /* tx null at EBT */ 5399e2340276SBjoern A. Zeeb policy_type = BTC_CXP_OFFE_2GBWMIXB2; 5400e2340276SBjoern A. Zeeb } else if (bt->link_info.a2dp_desc.exist || 5401e2340276SBjoern A. Zeeb bt->link_info.pan_desc.exist) { 5402e2340276SBjoern A. Zeeb dm->wl_scc.ebt_null = 1; /* tx null at EBT */ 5403e2340276SBjoern A. Zeeb policy_type = BTC_CXP_OFFE_2GBWISOB; 5404e2340276SBjoern A. Zeeb } else { 5405e2340276SBjoern A. Zeeb dm->wl_scc.ebt_null = 0; 5406e2340276SBjoern A. Zeeb policy_type = BTC_CXP_OFFE_2GBWISOB; 5407e2340276SBjoern A. Zeeb } 5408e2340276SBjoern A. Zeeb break; 5409e2340276SBjoern A. Zeeb default: 5410e2340276SBjoern A. Zeeb break; 5411e2340276SBjoern A. Zeeb } 5412e2340276SBjoern A. Zeeb } 5413e2340276SBjoern A. Zeeb 5414e2340276SBjoern A. Zeeb _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); 5415e2340276SBjoern A. Zeeb _set_policy(rtwdev, policy_type, BTC_ACT_WL_2G_SCC); 5416e2340276SBjoern A. Zeeb } 5417e2340276SBjoern A. Zeeb 5418*6d67aabdSBjoern A. Zeeb static void _action_wl_2g_scc_v8(struct rtw89_dev *rtwdev) 5419*6d67aabdSBjoern A. Zeeb { 5420*6d67aabdSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 5421*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 5422*6d67aabdSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &btc->cx.bt; 5423*6d67aabdSBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 5424*6d67aabdSBjoern A. Zeeb u16 policy_type = BTC_CXP_OFF_BT; 5425*6d67aabdSBjoern A. Zeeb 5426*6d67aabdSBjoern A. Zeeb if (btc->ant_type == BTC_ANT_SHARED) { 5427*6d67aabdSBjoern A. Zeeb if (wl->status.map._4way) 5428*6d67aabdSBjoern A. Zeeb policy_type = BTC_CXP_OFFE_WL; 5429*6d67aabdSBjoern A. Zeeb else if (bt->link_info.status.map.connect == 0) 5430*6d67aabdSBjoern A. Zeeb policy_type = BTC_CXP_OFFE_2GISOB; 5431*6d67aabdSBjoern A. Zeeb else 5432*6d67aabdSBjoern A. Zeeb policy_type = BTC_CXP_OFFE_2GBWISOB; 5433*6d67aabdSBjoern A. Zeeb } else { 5434*6d67aabdSBjoern A. Zeeb policy_type = BTC_CXP_OFF_EQ0; 5435*6d67aabdSBjoern A. Zeeb } 5436*6d67aabdSBjoern A. Zeeb 5437*6d67aabdSBjoern A. Zeeb dm->e2g_slot_limit = BTC_E2G_LIMIT_DEF; 5438*6d67aabdSBjoern A. Zeeb 5439*6d67aabdSBjoern A. Zeeb _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); 5440*6d67aabdSBjoern A. Zeeb _set_policy(rtwdev, policy_type, BTC_ACT_WL_2G_SCC); 5441*6d67aabdSBjoern A. Zeeb } 5442*6d67aabdSBjoern A. Zeeb 54438e93258fSBjoern A. Zeeb static void _action_wl_2g_ap(struct rtw89_dev *rtwdev) 54448e93258fSBjoern A. Zeeb { 54458e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 54468e93258fSBjoern A. Zeeb 54478e93258fSBjoern A. Zeeb _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); 54488e93258fSBjoern A. Zeeb 5449*6d67aabdSBjoern A. Zeeb if (btc->ant_type == BTC_ANT_SHARED) { 54508e93258fSBjoern A. Zeeb if (btc->cx.bt.link_info.profile_cnt.now == 0) 54518e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFFE_DEF2, 54528e93258fSBjoern A. Zeeb BTC_ACT_WL_2G_AP); 54538e93258fSBjoern A. Zeeb else 54548e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFFE_DEF, BTC_ACT_WL_2G_AP); 54558e93258fSBjoern A. Zeeb } else {/* dedicated-antenna */ 54568e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_2G_AP); 54578e93258fSBjoern A. Zeeb } 54588e93258fSBjoern A. Zeeb } 54598e93258fSBjoern A. Zeeb 54608e93258fSBjoern A. Zeeb static void _action_wl_2g_go(struct rtw89_dev *rtwdev) 54618e93258fSBjoern A. Zeeb { 54628e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 54638e93258fSBjoern A. Zeeb 54648e93258fSBjoern A. Zeeb _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); 54658e93258fSBjoern A. Zeeb 5466*6d67aabdSBjoern A. Zeeb if (btc->ant_type == BTC_ANT_SHARED) { /* shared-antenna */ 54678e93258fSBjoern A. Zeeb if (btc->cx.bt.link_info.profile_cnt.now == 0) 54688e93258fSBjoern A. Zeeb _set_policy(rtwdev, 54698e93258fSBjoern A. Zeeb BTC_CXP_OFFE_DEF2, BTC_ACT_WL_2G_GO); 54708e93258fSBjoern A. Zeeb else 54718e93258fSBjoern A. Zeeb _set_policy(rtwdev, 54728e93258fSBjoern A. Zeeb BTC_CXP_OFFE_DEF, BTC_ACT_WL_2G_GO); 54738e93258fSBjoern A. Zeeb } else { /* dedicated-antenna */ 54748e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_2G_GO); 54758e93258fSBjoern A. Zeeb } 54768e93258fSBjoern A. Zeeb } 54778e93258fSBjoern A. Zeeb 54788e93258fSBjoern A. Zeeb static void _action_wl_2g_gc(struct rtw89_dev *rtwdev) 54798e93258fSBjoern A. Zeeb { 54808e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 54818e93258fSBjoern A. Zeeb 54828e93258fSBjoern A. Zeeb _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); 54838e93258fSBjoern A. Zeeb 5484*6d67aabdSBjoern A. Zeeb if (btc->ant_type == BTC_ANT_SHARED) { /* shared-antenna */ 54858e93258fSBjoern A. Zeeb _action_by_bt(rtwdev); 54868e93258fSBjoern A. Zeeb } else {/* dedicated-antenna */ 54878e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_2G_GC); 54888e93258fSBjoern A. Zeeb } 54898e93258fSBjoern A. Zeeb } 54908e93258fSBjoern A. Zeeb 54918e93258fSBjoern A. Zeeb static void _action_wl_2g_nan(struct rtw89_dev *rtwdev) 54928e93258fSBjoern A. Zeeb { 54938e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 54948e93258fSBjoern A. Zeeb 54958e93258fSBjoern A. Zeeb _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); 54968e93258fSBjoern A. Zeeb 5497*6d67aabdSBjoern A. Zeeb if (btc->ant_type == BTC_ANT_SHARED) { /* shared-antenna */ 54988e93258fSBjoern A. Zeeb if (btc->cx.bt.link_info.profile_cnt.now == 0) 54998e93258fSBjoern A. Zeeb _set_policy(rtwdev, 55008e93258fSBjoern A. Zeeb BTC_CXP_OFFE_DEF2, BTC_ACT_WL_2G_NAN); 55018e93258fSBjoern A. Zeeb else 55028e93258fSBjoern A. Zeeb _set_policy(rtwdev, 55038e93258fSBjoern A. Zeeb BTC_CXP_OFFE_DEF, BTC_ACT_WL_2G_NAN); 55048e93258fSBjoern A. Zeeb } else { /* dedicated-antenna */ 55058e93258fSBjoern A. Zeeb _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_2G_NAN); 55068e93258fSBjoern A. Zeeb } 55078e93258fSBjoern A. Zeeb } 55088e93258fSBjoern A. Zeeb 55098e93258fSBjoern A. Zeeb static u32 _read_scbd(struct rtw89_dev *rtwdev) 55108e93258fSBjoern A. Zeeb { 55118e93258fSBjoern A. Zeeb const struct rtw89_chip_info *chip = rtwdev->chip; 55128e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 55138e93258fSBjoern A. Zeeb u32 scbd_val = 0; 55148e93258fSBjoern A. Zeeb 55158e93258fSBjoern A. Zeeb if (!chip->scbd) 55168e93258fSBjoern A. Zeeb return 0; 55178e93258fSBjoern A. Zeeb 55188e93258fSBjoern A. Zeeb scbd_val = rtw89_mac_get_sb(rtwdev); 55198e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], read scbd: 0x%08x\n", 55208e93258fSBjoern A. Zeeb scbd_val); 55218e93258fSBjoern A. Zeeb 55228e93258fSBjoern A. Zeeb btc->cx.cnt_bt[BTC_BCNT_SCBDREAD]++; 55238e93258fSBjoern A. Zeeb return scbd_val; 55248e93258fSBjoern A. Zeeb } 55258e93258fSBjoern A. Zeeb 55268e93258fSBjoern A. Zeeb static void _write_scbd(struct rtw89_dev *rtwdev, u32 val, bool state) 55278e93258fSBjoern A. Zeeb { 55288e93258fSBjoern A. Zeeb const struct rtw89_chip_info *chip = rtwdev->chip; 55298e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 55308e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 55318e93258fSBjoern A. Zeeb u32 scbd_val = 0; 5532e2340276SBjoern A. Zeeb u8 force_exec = false; 55338e93258fSBjoern A. Zeeb 55348e93258fSBjoern A. Zeeb if (!chip->scbd) 55358e93258fSBjoern A. Zeeb return; 55368e93258fSBjoern A. Zeeb 55378e93258fSBjoern A. Zeeb scbd_val = state ? wl->scbd | val : wl->scbd & ~val; 55388e93258fSBjoern A. Zeeb 5539e2340276SBjoern A. Zeeb if (val & BTC_WSCB_ACTIVE || val & BTC_WSCB_ON) 5540e2340276SBjoern A. Zeeb force_exec = true; 55418e93258fSBjoern A. Zeeb 5542e2340276SBjoern A. Zeeb if (scbd_val != wl->scbd || force_exec) { 5543e2340276SBjoern A. Zeeb wl->scbd = scbd_val; 5544e2340276SBjoern A. Zeeb wl->scbd_change = true; 5545e2340276SBjoern A. Zeeb } 55468e93258fSBjoern A. Zeeb } 55478e93258fSBjoern A. Zeeb 55488e93258fSBjoern A. Zeeb static u8 55498e93258fSBjoern A. Zeeb _update_rssi_state(struct rtw89_dev *rtwdev, u8 pre_state, u8 rssi, u8 thresh) 55508e93258fSBjoern A. Zeeb { 55518e93258fSBjoern A. Zeeb const struct rtw89_chip_info *chip = rtwdev->chip; 55528e93258fSBjoern A. Zeeb u8 next_state, tol = chip->rssi_tol; 55538e93258fSBjoern A. Zeeb 55548e93258fSBjoern A. Zeeb if (pre_state == BTC_RSSI_ST_LOW || 55558e93258fSBjoern A. Zeeb pre_state == BTC_RSSI_ST_STAY_LOW) { 55568e93258fSBjoern A. Zeeb if (rssi >= (thresh + tol)) 55578e93258fSBjoern A. Zeeb next_state = BTC_RSSI_ST_HIGH; 55588e93258fSBjoern A. Zeeb else 55598e93258fSBjoern A. Zeeb next_state = BTC_RSSI_ST_STAY_LOW; 55608e93258fSBjoern A. Zeeb } else { 55618e93258fSBjoern A. Zeeb if (rssi < thresh) 55628e93258fSBjoern A. Zeeb next_state = BTC_RSSI_ST_LOW; 55638e93258fSBjoern A. Zeeb else 55648e93258fSBjoern A. Zeeb next_state = BTC_RSSI_ST_STAY_HIGH; 55658e93258fSBjoern A. Zeeb } 55668e93258fSBjoern A. Zeeb 55678e93258fSBjoern A. Zeeb return next_state; 55688e93258fSBjoern A. Zeeb } 55698e93258fSBjoern A. Zeeb 55708e93258fSBjoern A. Zeeb static 55718e93258fSBjoern A. Zeeb void _update_dbcc_band(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) 55728e93258fSBjoern A. Zeeb { 55738e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 55748e93258fSBjoern A. Zeeb 55758e93258fSBjoern A. Zeeb btc->cx.wl.dbcc_info.real_band[phy_idx] = 55768e93258fSBjoern A. Zeeb btc->cx.wl.scan_info.phy_map & BIT(phy_idx) ? 55778e93258fSBjoern A. Zeeb btc->cx.wl.dbcc_info.scan_band[phy_idx] : 55788e93258fSBjoern A. Zeeb btc->cx.wl.dbcc_info.op_band[phy_idx]; 55798e93258fSBjoern A. Zeeb } 55808e93258fSBjoern A. Zeeb 55818e93258fSBjoern A. Zeeb static void _update_wl_info(struct rtw89_dev *rtwdev) 55828e93258fSBjoern A. Zeeb { 55838e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 55848e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 55858e93258fSBjoern A. Zeeb struct rtw89_btc_wl_link_info *wl_linfo = wl->link_info; 55868e93258fSBjoern A. Zeeb struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; 55878e93258fSBjoern A. Zeeb struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info; 55888e93258fSBjoern A. Zeeb u8 i, cnt_connect = 0, cnt_connecting = 0, cnt_active = 0; 55898e93258fSBjoern A. Zeeb u8 cnt_2g = 0, cnt_5g = 0, phy; 55908e93258fSBjoern A. Zeeb u32 wl_2g_ch[2] = {0}, wl_5g_ch[2] = {0}; 55918e93258fSBjoern A. Zeeb bool b2g = false, b5g = false, client_joined = false; 55928e93258fSBjoern A. Zeeb 55938e93258fSBjoern A. Zeeb memset(wl_rinfo, 0, sizeof(*wl_rinfo)); 55948e93258fSBjoern A. Zeeb 55958e93258fSBjoern A. Zeeb for (i = 0; i < RTW89_PORT_NUM; i++) { 55968e93258fSBjoern A. Zeeb /* check if role active? */ 55978e93258fSBjoern A. Zeeb if (!wl_linfo[i].active) 55988e93258fSBjoern A. Zeeb continue; 55998e93258fSBjoern A. Zeeb 56008e93258fSBjoern A. Zeeb cnt_active++; 56018e93258fSBjoern A. Zeeb wl_rinfo->active_role[cnt_active - 1].role = wl_linfo[i].role; 56028e93258fSBjoern A. Zeeb wl_rinfo->active_role[cnt_active - 1].pid = wl_linfo[i].pid; 56038e93258fSBjoern A. Zeeb wl_rinfo->active_role[cnt_active - 1].phy = wl_linfo[i].phy; 56048e93258fSBjoern A. Zeeb wl_rinfo->active_role[cnt_active - 1].band = wl_linfo[i].band; 56058e93258fSBjoern A. Zeeb wl_rinfo->active_role[cnt_active - 1].noa = (u8)wl_linfo[i].noa; 56068e93258fSBjoern A. Zeeb wl_rinfo->active_role[cnt_active - 1].connected = 0; 56078e93258fSBjoern A. Zeeb 56088e93258fSBjoern A. Zeeb wl->port_id[wl_linfo[i].role] = wl_linfo[i].pid; 56098e93258fSBjoern A. Zeeb 56108e93258fSBjoern A. Zeeb phy = wl_linfo[i].phy; 56118e93258fSBjoern A. Zeeb 56128e93258fSBjoern A. Zeeb /* check dbcc role */ 56138e93258fSBjoern A. Zeeb if (rtwdev->dbcc_en && phy < RTW89_PHY_MAX) { 56148e93258fSBjoern A. Zeeb wl_dinfo->role[phy] = wl_linfo[i].role; 56158e93258fSBjoern A. Zeeb wl_dinfo->op_band[phy] = wl_linfo[i].band; 56168e93258fSBjoern A. Zeeb _update_dbcc_band(rtwdev, phy); 56178e93258fSBjoern A. Zeeb _fw_set_drv_info(rtwdev, CXDRVINFO_DBCC); 56188e93258fSBjoern A. Zeeb } 56198e93258fSBjoern A. Zeeb 56208e93258fSBjoern A. Zeeb if (wl_linfo[i].connected == MLME_NO_LINK) { 56218e93258fSBjoern A. Zeeb continue; 56228e93258fSBjoern A. Zeeb } else if (wl_linfo[i].connected == MLME_LINKING) { 56238e93258fSBjoern A. Zeeb cnt_connecting++; 56248e93258fSBjoern A. Zeeb } else { 56258e93258fSBjoern A. Zeeb cnt_connect++; 56268e93258fSBjoern A. Zeeb if ((wl_linfo[i].role == RTW89_WIFI_ROLE_P2P_GO || 56278e93258fSBjoern A. Zeeb wl_linfo[i].role == RTW89_WIFI_ROLE_AP) && 56288e93258fSBjoern A. Zeeb wl_linfo[i].client_cnt > 1) 56298e93258fSBjoern A. Zeeb client_joined = true; 56308e93258fSBjoern A. Zeeb } 56318e93258fSBjoern A. Zeeb 56328e93258fSBjoern A. Zeeb wl_rinfo->role_map.val |= BIT(wl_linfo[i].role); 56338e93258fSBjoern A. Zeeb wl_rinfo->active_role[cnt_active - 1].ch = wl_linfo[i].ch; 56348e93258fSBjoern A. Zeeb wl_rinfo->active_role[cnt_active - 1].bw = wl_linfo[i].bw; 56358e93258fSBjoern A. Zeeb wl_rinfo->active_role[cnt_active - 1].connected = 1; 56368e93258fSBjoern A. Zeeb 56378e93258fSBjoern A. Zeeb /* only care 2 roles + BT coex */ 56388e93258fSBjoern A. Zeeb if (wl_linfo[i].band != RTW89_BAND_2G) { 56398e93258fSBjoern A. Zeeb if (cnt_5g <= ARRAY_SIZE(wl_5g_ch) - 1) 56408e93258fSBjoern A. Zeeb wl_5g_ch[cnt_5g] = wl_linfo[i].ch; 56418e93258fSBjoern A. Zeeb cnt_5g++; 56428e93258fSBjoern A. Zeeb b5g = true; 56438e93258fSBjoern A. Zeeb } else { 56448e93258fSBjoern A. Zeeb if (cnt_2g <= ARRAY_SIZE(wl_2g_ch) - 1) 56458e93258fSBjoern A. Zeeb wl_2g_ch[cnt_2g] = wl_linfo[i].ch; 56468e93258fSBjoern A. Zeeb cnt_2g++; 56478e93258fSBjoern A. Zeeb b2g = true; 56488e93258fSBjoern A. Zeeb } 56498e93258fSBjoern A. Zeeb } 56508e93258fSBjoern A. Zeeb 56518e93258fSBjoern A. Zeeb wl_rinfo->connect_cnt = cnt_connect; 56528e93258fSBjoern A. Zeeb 56538e93258fSBjoern A. Zeeb /* Be careful to change the following sequence!! */ 56548e93258fSBjoern A. Zeeb if (cnt_connect == 0) { 56558e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_NOLINK; 56568e93258fSBjoern A. Zeeb wl_rinfo->role_map.role.none = 1; 56578e93258fSBjoern A. Zeeb } else if (!b2g && b5g) { 56588e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_5G; 56598e93258fSBjoern A. Zeeb } else if (wl_rinfo->role_map.role.nan) { 56608e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_NAN; 56618e93258fSBjoern A. Zeeb } else if (cnt_connect > BTC_TDMA_WLROLE_MAX) { 56628e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_OTHER; 56638e93258fSBjoern A. Zeeb } else if (b2g && b5g && cnt_connect == 2) { 56648e93258fSBjoern A. Zeeb if (rtwdev->dbcc_en) { 56658e93258fSBjoern A. Zeeb switch (wl_dinfo->role[RTW89_PHY_0]) { 56668e93258fSBjoern A. Zeeb case RTW89_WIFI_ROLE_STATION: 56678e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_STA; 56688e93258fSBjoern A. Zeeb break; 56698e93258fSBjoern A. Zeeb case RTW89_WIFI_ROLE_P2P_GO: 56708e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_GO; 56718e93258fSBjoern A. Zeeb break; 56728e93258fSBjoern A. Zeeb case RTW89_WIFI_ROLE_P2P_CLIENT: 56738e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_GC; 56748e93258fSBjoern A. Zeeb break; 56758e93258fSBjoern A. Zeeb case RTW89_WIFI_ROLE_AP: 56768e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_AP; 56778e93258fSBjoern A. Zeeb break; 56788e93258fSBjoern A. Zeeb default: 56798e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_OTHER; 56808e93258fSBjoern A. Zeeb break; 56818e93258fSBjoern A. Zeeb } 56828e93258fSBjoern A. Zeeb } else { 56838e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_25G_MCC; 56848e93258fSBjoern A. Zeeb } 56858e93258fSBjoern A. Zeeb } else if (!b5g && cnt_connect == 2) { 56868e93258fSBjoern A. Zeeb if (wl_rinfo->role_map.role.station && 56878e93258fSBjoern A. Zeeb (wl_rinfo->role_map.role.p2p_go || 56888e93258fSBjoern A. Zeeb wl_rinfo->role_map.role.p2p_gc || 56898e93258fSBjoern A. Zeeb wl_rinfo->role_map.role.ap)) { 56908e93258fSBjoern A. Zeeb if (wl_2g_ch[0] == wl_2g_ch[1]) 56918e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_SCC; 56928e93258fSBjoern A. Zeeb else 56938e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_MCC; 56948e93258fSBjoern A. Zeeb } else { 56958e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_MCC; 56968e93258fSBjoern A. Zeeb } 56978e93258fSBjoern A. Zeeb } else if (!b5g && cnt_connect == 1) { 56988e93258fSBjoern A. Zeeb if (wl_rinfo->role_map.role.station) 56998e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_STA; 57008e93258fSBjoern A. Zeeb else if (wl_rinfo->role_map.role.ap) 57018e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_AP; 57028e93258fSBjoern A. Zeeb else if (wl_rinfo->role_map.role.p2p_go) 57038e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_GO; 57048e93258fSBjoern A. Zeeb else if (wl_rinfo->role_map.role.p2p_gc) 57058e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_GC; 57068e93258fSBjoern A. Zeeb else 57078e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_OTHER; 57088e93258fSBjoern A. Zeeb } 57098e93258fSBjoern A. Zeeb 57108e93258fSBjoern A. Zeeb /* if no client_joined, don't care P2P-GO/AP role */ 57118e93258fSBjoern A. Zeeb if (wl_rinfo->role_map.role.p2p_go || wl_rinfo->role_map.role.ap) { 57128e93258fSBjoern A. Zeeb if (!client_joined) { 57138e93258fSBjoern A. Zeeb if (wl_rinfo->link_mode == BTC_WLINK_2G_SCC || 57148e93258fSBjoern A. Zeeb wl_rinfo->link_mode == BTC_WLINK_2G_MCC) { 57158e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_STA; 57168e93258fSBjoern A. Zeeb wl_rinfo->connect_cnt = 1; 57178e93258fSBjoern A. Zeeb } else if (wl_rinfo->link_mode == BTC_WLINK_2G_GO || 57188e93258fSBjoern A. Zeeb wl_rinfo->link_mode == BTC_WLINK_2G_AP) { 57198e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_NOLINK; 57208e93258fSBjoern A. Zeeb wl_rinfo->connect_cnt = 0; 57218e93258fSBjoern A. Zeeb } 57228e93258fSBjoern A. Zeeb } 57238e93258fSBjoern A. Zeeb } 57248e93258fSBjoern A. Zeeb 57258e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 5726700acdc7SBjoern A. Zeeb "[BTC], cnt_connect = %d, connecting = %d, link_mode = %d\n", 5727700acdc7SBjoern A. Zeeb cnt_connect, cnt_connecting, wl_rinfo->link_mode); 57288e93258fSBjoern A. Zeeb 57298e93258fSBjoern A. Zeeb _fw_set_drv_info(rtwdev, CXDRVINFO_ROLE); 57308e93258fSBjoern A. Zeeb } 57318e93258fSBjoern A. Zeeb 57328e93258fSBjoern A. Zeeb static void _update_wl_info_v1(struct rtw89_dev *rtwdev) 57338e93258fSBjoern A. Zeeb { 57348e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 57358e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 57368e93258fSBjoern A. Zeeb struct rtw89_btc_wl_link_info *wl_linfo = wl->link_info; 57378e93258fSBjoern A. Zeeb struct rtw89_btc_wl_role_info_v1 *wl_rinfo = &wl->role_info_v1; 57388e93258fSBjoern A. Zeeb struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info; 57398e93258fSBjoern A. Zeeb u8 cnt_connect = 0, cnt_connecting = 0, cnt_active = 0; 57408e93258fSBjoern A. Zeeb u8 cnt_2g = 0, cnt_5g = 0, phy; 57418e93258fSBjoern A. Zeeb u32 wl_2g_ch[2] = {}, wl_5g_ch[2] = {}; 57428e93258fSBjoern A. Zeeb bool b2g = false, b5g = false, client_joined = false; 57438e93258fSBjoern A. Zeeb u8 i; 57448e93258fSBjoern A. Zeeb 57458e93258fSBjoern A. Zeeb memset(wl_rinfo, 0, sizeof(*wl_rinfo)); 57468e93258fSBjoern A. Zeeb 57478e93258fSBjoern A. Zeeb for (i = 0; i < RTW89_PORT_NUM; i++) { 57488e93258fSBjoern A. Zeeb if (!wl_linfo[i].active) 57498e93258fSBjoern A. Zeeb continue; 57508e93258fSBjoern A. Zeeb 57518e93258fSBjoern A. Zeeb cnt_active++; 57528e93258fSBjoern A. Zeeb wl_rinfo->active_role_v1[cnt_active - 1].role = wl_linfo[i].role; 57538e93258fSBjoern A. Zeeb wl_rinfo->active_role_v1[cnt_active - 1].pid = wl_linfo[i].pid; 57548e93258fSBjoern A. Zeeb wl_rinfo->active_role_v1[cnt_active - 1].phy = wl_linfo[i].phy; 57558e93258fSBjoern A. Zeeb wl_rinfo->active_role_v1[cnt_active - 1].band = wl_linfo[i].band; 57568e93258fSBjoern A. Zeeb wl_rinfo->active_role_v1[cnt_active - 1].noa = (u8)wl_linfo[i].noa; 57578e93258fSBjoern A. Zeeb wl_rinfo->active_role_v1[cnt_active - 1].connected = 0; 57588e93258fSBjoern A. Zeeb 57598e93258fSBjoern A. Zeeb wl->port_id[wl_linfo[i].role] = wl_linfo[i].pid; 57608e93258fSBjoern A. Zeeb 57618e93258fSBjoern A. Zeeb phy = wl_linfo[i].phy; 57628e93258fSBjoern A. Zeeb 57638e93258fSBjoern A. Zeeb if (rtwdev->dbcc_en && phy < RTW89_PHY_MAX) { 57648e93258fSBjoern A. Zeeb wl_dinfo->role[phy] = wl_linfo[i].role; 57658e93258fSBjoern A. Zeeb wl_dinfo->op_band[phy] = wl_linfo[i].band; 57668e93258fSBjoern A. Zeeb _update_dbcc_band(rtwdev, phy); 57678e93258fSBjoern A. Zeeb _fw_set_drv_info(rtwdev, CXDRVINFO_DBCC); 57688e93258fSBjoern A. Zeeb } 57698e93258fSBjoern A. Zeeb 57708e93258fSBjoern A. Zeeb if (wl_linfo[i].connected == MLME_NO_LINK) { 57718e93258fSBjoern A. Zeeb continue; 57728e93258fSBjoern A. Zeeb } else if (wl_linfo[i].connected == MLME_LINKING) { 57738e93258fSBjoern A. Zeeb cnt_connecting++; 57748e93258fSBjoern A. Zeeb } else { 57758e93258fSBjoern A. Zeeb cnt_connect++; 57768e93258fSBjoern A. Zeeb if ((wl_linfo[i].role == RTW89_WIFI_ROLE_P2P_GO || 57778e93258fSBjoern A. Zeeb wl_linfo[i].role == RTW89_WIFI_ROLE_AP) && 57788e93258fSBjoern A. Zeeb wl_linfo[i].client_cnt > 1) 57798e93258fSBjoern A. Zeeb client_joined = true; 57808e93258fSBjoern A. Zeeb } 57818e93258fSBjoern A. Zeeb 57828e93258fSBjoern A. Zeeb wl_rinfo->role_map.val |= BIT(wl_linfo[i].role); 57838e93258fSBjoern A. Zeeb wl_rinfo->active_role_v1[cnt_active - 1].ch = wl_linfo[i].ch; 57848e93258fSBjoern A. Zeeb wl_rinfo->active_role_v1[cnt_active - 1].bw = wl_linfo[i].bw; 57858e93258fSBjoern A. Zeeb wl_rinfo->active_role_v1[cnt_active - 1].connected = 1; 57868e93258fSBjoern A. Zeeb 57878e93258fSBjoern A. Zeeb /* only care 2 roles + BT coex */ 57888e93258fSBjoern A. Zeeb if (wl_linfo[i].band != RTW89_BAND_2G) { 57898e93258fSBjoern A. Zeeb if (cnt_5g <= ARRAY_SIZE(wl_5g_ch) - 1) 57908e93258fSBjoern A. Zeeb wl_5g_ch[cnt_5g] = wl_linfo[i].ch; 57918e93258fSBjoern A. Zeeb cnt_5g++; 57928e93258fSBjoern A. Zeeb b5g = true; 57938e93258fSBjoern A. Zeeb } else { 57948e93258fSBjoern A. Zeeb if (cnt_2g <= ARRAY_SIZE(wl_2g_ch) - 1) 57958e93258fSBjoern A. Zeeb wl_2g_ch[cnt_2g] = wl_linfo[i].ch; 57968e93258fSBjoern A. Zeeb cnt_2g++; 57978e93258fSBjoern A. Zeeb b2g = true; 57988e93258fSBjoern A. Zeeb } 57998e93258fSBjoern A. Zeeb } 58008e93258fSBjoern A. Zeeb 58018e93258fSBjoern A. Zeeb wl_rinfo->connect_cnt = cnt_connect; 58028e93258fSBjoern A. Zeeb 58038e93258fSBjoern A. Zeeb /* Be careful to change the following sequence!! */ 58048e93258fSBjoern A. Zeeb if (cnt_connect == 0) { 58058e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_NOLINK; 58068e93258fSBjoern A. Zeeb wl_rinfo->role_map.role.none = 1; 58078e93258fSBjoern A. Zeeb } else if (!b2g && b5g) { 58088e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_5G; 58098e93258fSBjoern A. Zeeb } else if (wl_rinfo->role_map.role.nan) { 58108e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_NAN; 58118e93258fSBjoern A. Zeeb } else if (cnt_connect > BTC_TDMA_WLROLE_MAX) { 58128e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_OTHER; 58138e93258fSBjoern A. Zeeb } else if (b2g && b5g && cnt_connect == 2) { 58148e93258fSBjoern A. Zeeb if (rtwdev->dbcc_en) { 58158e93258fSBjoern A. Zeeb switch (wl_dinfo->role[RTW89_PHY_0]) { 58168e93258fSBjoern A. Zeeb case RTW89_WIFI_ROLE_STATION: 58178e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_STA; 58188e93258fSBjoern A. Zeeb break; 58198e93258fSBjoern A. Zeeb case RTW89_WIFI_ROLE_P2P_GO: 58208e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_GO; 58218e93258fSBjoern A. Zeeb break; 58228e93258fSBjoern A. Zeeb case RTW89_WIFI_ROLE_P2P_CLIENT: 58238e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_GC; 58248e93258fSBjoern A. Zeeb break; 58258e93258fSBjoern A. Zeeb case RTW89_WIFI_ROLE_AP: 58268e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_AP; 58278e93258fSBjoern A. Zeeb break; 58288e93258fSBjoern A. Zeeb default: 58298e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_OTHER; 58308e93258fSBjoern A. Zeeb break; 58318e93258fSBjoern A. Zeeb } 58328e93258fSBjoern A. Zeeb } else { 58338e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_25G_MCC; 58348e93258fSBjoern A. Zeeb } 58358e93258fSBjoern A. Zeeb } else if (!b5g && cnt_connect == 2) { 58368e93258fSBjoern A. Zeeb if (wl_rinfo->role_map.role.station && 58378e93258fSBjoern A. Zeeb (wl_rinfo->role_map.role.p2p_go || 58388e93258fSBjoern A. Zeeb wl_rinfo->role_map.role.p2p_gc || 58398e93258fSBjoern A. Zeeb wl_rinfo->role_map.role.ap)) { 58408e93258fSBjoern A. Zeeb if (wl_2g_ch[0] == wl_2g_ch[1]) 58418e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_SCC; 58428e93258fSBjoern A. Zeeb else 58438e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_MCC; 58448e93258fSBjoern A. Zeeb } else { 58458e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_MCC; 58468e93258fSBjoern A. Zeeb } 58478e93258fSBjoern A. Zeeb } else if (!b5g && cnt_connect == 1) { 58488e93258fSBjoern A. Zeeb if (wl_rinfo->role_map.role.station) 58498e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_STA; 58508e93258fSBjoern A. Zeeb else if (wl_rinfo->role_map.role.ap) 58518e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_AP; 58528e93258fSBjoern A. Zeeb else if (wl_rinfo->role_map.role.p2p_go) 58538e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_GO; 58548e93258fSBjoern A. Zeeb else if (wl_rinfo->role_map.role.p2p_gc) 58558e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_GC; 58568e93258fSBjoern A. Zeeb else 58578e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_OTHER; 58588e93258fSBjoern A. Zeeb } 58598e93258fSBjoern A. Zeeb 58608e93258fSBjoern A. Zeeb /* if no client_joined, don't care P2P-GO/AP role */ 58618e93258fSBjoern A. Zeeb if (wl_rinfo->role_map.role.p2p_go || wl_rinfo->role_map.role.ap) { 58628e93258fSBjoern A. Zeeb if (!client_joined) { 58638e93258fSBjoern A. Zeeb if (wl_rinfo->link_mode == BTC_WLINK_2G_SCC || 58648e93258fSBjoern A. Zeeb wl_rinfo->link_mode == BTC_WLINK_2G_MCC) { 58658e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_STA; 58668e93258fSBjoern A. Zeeb wl_rinfo->connect_cnt = 1; 58678e93258fSBjoern A. Zeeb } else if (wl_rinfo->link_mode == BTC_WLINK_2G_GO || 58688e93258fSBjoern A. Zeeb wl_rinfo->link_mode == BTC_WLINK_2G_AP) { 58698e93258fSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_NOLINK; 58708e93258fSBjoern A. Zeeb wl_rinfo->connect_cnt = 0; 58718e93258fSBjoern A. Zeeb } 58728e93258fSBjoern A. Zeeb } 58738e93258fSBjoern A. Zeeb } 58748e93258fSBjoern A. Zeeb 58758e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 58768e93258fSBjoern A. Zeeb "[BTC], cnt_connect = %d, connecting = %d, link_mode = %d\n", 58778e93258fSBjoern A. Zeeb cnt_connect, cnt_connecting, wl_rinfo->link_mode); 58788e93258fSBjoern A. Zeeb 58798e93258fSBjoern A. Zeeb _fw_set_drv_info(rtwdev, CXDRVINFO_ROLE); 58808e93258fSBjoern A. Zeeb } 58818e93258fSBjoern A. Zeeb 5882e2340276SBjoern A. Zeeb static void _update_wl_info_v2(struct rtw89_dev *rtwdev) 5883e2340276SBjoern A. Zeeb { 5884e2340276SBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 5885e2340276SBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 5886e2340276SBjoern A. Zeeb struct rtw89_btc_wl_link_info *wl_linfo = wl->link_info; 5887e2340276SBjoern A. Zeeb struct rtw89_btc_wl_role_info_v2 *wl_rinfo = &wl->role_info_v2; 5888e2340276SBjoern A. Zeeb struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info; 5889e2340276SBjoern A. Zeeb u8 cnt_connect = 0, cnt_connecting = 0, cnt_active = 0; 5890e2340276SBjoern A. Zeeb u8 cnt_2g = 0, cnt_5g = 0, phy; 5891e2340276SBjoern A. Zeeb u32 wl_2g_ch[2] = {}, wl_5g_ch[2] = {}; 5892e2340276SBjoern A. Zeeb bool b2g = false, b5g = false, client_joined = false; 5893e2340276SBjoern A. Zeeb u8 i; 5894e2340276SBjoern A. Zeeb 5895e2340276SBjoern A. Zeeb memset(wl_rinfo, 0, sizeof(*wl_rinfo)); 5896e2340276SBjoern A. Zeeb 5897e2340276SBjoern A. Zeeb for (i = 0; i < RTW89_PORT_NUM; i++) { 5898e2340276SBjoern A. Zeeb if (!wl_linfo[i].active) 5899e2340276SBjoern A. Zeeb continue; 5900e2340276SBjoern A. Zeeb 5901e2340276SBjoern A. Zeeb cnt_active++; 5902e2340276SBjoern A. Zeeb wl_rinfo->active_role_v2[cnt_active - 1].role = wl_linfo[i].role; 5903e2340276SBjoern A. Zeeb wl_rinfo->active_role_v2[cnt_active - 1].pid = wl_linfo[i].pid; 5904e2340276SBjoern A. Zeeb wl_rinfo->active_role_v2[cnt_active - 1].phy = wl_linfo[i].phy; 5905e2340276SBjoern A. Zeeb wl_rinfo->active_role_v2[cnt_active - 1].band = wl_linfo[i].band; 5906e2340276SBjoern A. Zeeb wl_rinfo->active_role_v2[cnt_active - 1].noa = (u8)wl_linfo[i].noa; 5907e2340276SBjoern A. Zeeb wl_rinfo->active_role_v2[cnt_active - 1].connected = 0; 5908e2340276SBjoern A. Zeeb 5909e2340276SBjoern A. Zeeb wl->port_id[wl_linfo[i].role] = wl_linfo[i].pid; 5910e2340276SBjoern A. Zeeb 5911e2340276SBjoern A. Zeeb phy = wl_linfo[i].phy; 5912e2340276SBjoern A. Zeeb 5913e2340276SBjoern A. Zeeb if (rtwdev->dbcc_en && phy < RTW89_PHY_MAX) { 5914e2340276SBjoern A. Zeeb wl_dinfo->role[phy] = wl_linfo[i].role; 5915e2340276SBjoern A. Zeeb wl_dinfo->op_band[phy] = wl_linfo[i].band; 5916e2340276SBjoern A. Zeeb _update_dbcc_band(rtwdev, phy); 5917e2340276SBjoern A. Zeeb _fw_set_drv_info(rtwdev, CXDRVINFO_DBCC); 5918e2340276SBjoern A. Zeeb } 5919e2340276SBjoern A. Zeeb 5920e2340276SBjoern A. Zeeb if (wl_linfo[i].connected == MLME_NO_LINK) { 5921e2340276SBjoern A. Zeeb continue; 5922e2340276SBjoern A. Zeeb } else if (wl_linfo[i].connected == MLME_LINKING) { 5923e2340276SBjoern A. Zeeb cnt_connecting++; 5924e2340276SBjoern A. Zeeb } else { 5925e2340276SBjoern A. Zeeb cnt_connect++; 5926e2340276SBjoern A. Zeeb if ((wl_linfo[i].role == RTW89_WIFI_ROLE_P2P_GO || 5927e2340276SBjoern A. Zeeb wl_linfo[i].role == RTW89_WIFI_ROLE_AP) && 5928e2340276SBjoern A. Zeeb wl_linfo[i].client_cnt > 1) 5929e2340276SBjoern A. Zeeb client_joined = true; 5930e2340276SBjoern A. Zeeb } 5931e2340276SBjoern A. Zeeb 5932e2340276SBjoern A. Zeeb wl_rinfo->role_map.val |= BIT(wl_linfo[i].role); 5933e2340276SBjoern A. Zeeb wl_rinfo->active_role_v2[cnt_active - 1].ch = wl_linfo[i].ch; 5934e2340276SBjoern A. Zeeb wl_rinfo->active_role_v2[cnt_active - 1].bw = wl_linfo[i].bw; 5935e2340276SBjoern A. Zeeb wl_rinfo->active_role_v2[cnt_active - 1].connected = 1; 5936e2340276SBjoern A. Zeeb 5937e2340276SBjoern A. Zeeb /* only care 2 roles + BT coex */ 5938e2340276SBjoern A. Zeeb if (wl_linfo[i].band != RTW89_BAND_2G) { 5939e2340276SBjoern A. Zeeb if (cnt_5g <= ARRAY_SIZE(wl_5g_ch) - 1) 5940e2340276SBjoern A. Zeeb wl_5g_ch[cnt_5g] = wl_linfo[i].ch; 5941e2340276SBjoern A. Zeeb cnt_5g++; 5942e2340276SBjoern A. Zeeb b5g = true; 5943e2340276SBjoern A. Zeeb } else { 5944e2340276SBjoern A. Zeeb if (cnt_2g <= ARRAY_SIZE(wl_2g_ch) - 1) 5945e2340276SBjoern A. Zeeb wl_2g_ch[cnt_2g] = wl_linfo[i].ch; 5946e2340276SBjoern A. Zeeb cnt_2g++; 5947e2340276SBjoern A. Zeeb b2g = true; 5948e2340276SBjoern A. Zeeb } 5949e2340276SBjoern A. Zeeb } 5950e2340276SBjoern A. Zeeb 5951e2340276SBjoern A. Zeeb wl_rinfo->connect_cnt = cnt_connect; 5952e2340276SBjoern A. Zeeb 5953e2340276SBjoern A. Zeeb /* Be careful to change the following sequence!! */ 5954e2340276SBjoern A. Zeeb if (cnt_connect == 0) { 5955e2340276SBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_NOLINK; 5956e2340276SBjoern A. Zeeb wl_rinfo->role_map.role.none = 1; 5957e2340276SBjoern A. Zeeb } else if (!b2g && b5g) { 5958e2340276SBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_5G; 5959e2340276SBjoern A. Zeeb } else if (wl_rinfo->role_map.role.nan) { 5960e2340276SBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_NAN; 5961e2340276SBjoern A. Zeeb } else if (cnt_connect > BTC_TDMA_WLROLE_MAX) { 5962e2340276SBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_OTHER; 5963e2340276SBjoern A. Zeeb } else if (b2g && b5g && cnt_connect == 2) { 5964e2340276SBjoern A. Zeeb if (rtwdev->dbcc_en) { 5965e2340276SBjoern A. Zeeb switch (wl_dinfo->role[RTW89_PHY_0]) { 5966e2340276SBjoern A. Zeeb case RTW89_WIFI_ROLE_STATION: 5967e2340276SBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_STA; 5968e2340276SBjoern A. Zeeb break; 5969e2340276SBjoern A. Zeeb case RTW89_WIFI_ROLE_P2P_GO: 5970e2340276SBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_GO; 5971e2340276SBjoern A. Zeeb break; 5972e2340276SBjoern A. Zeeb case RTW89_WIFI_ROLE_P2P_CLIENT: 5973e2340276SBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_GC; 5974e2340276SBjoern A. Zeeb break; 5975e2340276SBjoern A. Zeeb case RTW89_WIFI_ROLE_AP: 5976e2340276SBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_AP; 5977e2340276SBjoern A. Zeeb break; 5978e2340276SBjoern A. Zeeb default: 5979e2340276SBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_OTHER; 5980e2340276SBjoern A. Zeeb break; 5981e2340276SBjoern A. Zeeb } 5982e2340276SBjoern A. Zeeb } else { 5983e2340276SBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_25G_MCC; 5984e2340276SBjoern A. Zeeb } 5985e2340276SBjoern A. Zeeb } else if (!b5g && cnt_connect == 2) { 5986e2340276SBjoern A. Zeeb if (wl_rinfo->role_map.role.station && 5987e2340276SBjoern A. Zeeb (wl_rinfo->role_map.role.p2p_go || 5988e2340276SBjoern A. Zeeb wl_rinfo->role_map.role.p2p_gc || 5989e2340276SBjoern A. Zeeb wl_rinfo->role_map.role.ap)) { 5990e2340276SBjoern A. Zeeb if (wl_2g_ch[0] == wl_2g_ch[1]) 5991e2340276SBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_SCC; 5992e2340276SBjoern A. Zeeb else 5993e2340276SBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_MCC; 5994e2340276SBjoern A. Zeeb } else { 5995e2340276SBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_MCC; 5996e2340276SBjoern A. Zeeb } 5997e2340276SBjoern A. Zeeb } else if (!b5g && cnt_connect == 1) { 5998e2340276SBjoern A. Zeeb if (wl_rinfo->role_map.role.station) 5999e2340276SBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_STA; 6000e2340276SBjoern A. Zeeb else if (wl_rinfo->role_map.role.ap) 6001e2340276SBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_AP; 6002e2340276SBjoern A. Zeeb else if (wl_rinfo->role_map.role.p2p_go) 6003e2340276SBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_GO; 6004e2340276SBjoern A. Zeeb else if (wl_rinfo->role_map.role.p2p_gc) 6005e2340276SBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_GC; 6006e2340276SBjoern A. Zeeb else 6007e2340276SBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_OTHER; 6008e2340276SBjoern A. Zeeb } 6009e2340276SBjoern A. Zeeb 6010e2340276SBjoern A. Zeeb /* if no client_joined, don't care P2P-GO/AP role */ 6011e2340276SBjoern A. Zeeb if (wl_rinfo->role_map.role.p2p_go || wl_rinfo->role_map.role.ap) { 6012e2340276SBjoern A. Zeeb if (!client_joined) { 6013e2340276SBjoern A. Zeeb if (wl_rinfo->link_mode == BTC_WLINK_2G_SCC || 6014e2340276SBjoern A. Zeeb wl_rinfo->link_mode == BTC_WLINK_2G_MCC) { 6015e2340276SBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_STA; 6016e2340276SBjoern A. Zeeb wl_rinfo->connect_cnt = 1; 6017e2340276SBjoern A. Zeeb } else if (wl_rinfo->link_mode == BTC_WLINK_2G_GO || 6018e2340276SBjoern A. Zeeb wl_rinfo->link_mode == BTC_WLINK_2G_AP) { 6019e2340276SBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_NOLINK; 6020e2340276SBjoern A. Zeeb wl_rinfo->connect_cnt = 0; 6021e2340276SBjoern A. Zeeb } 6022e2340276SBjoern A. Zeeb } 6023e2340276SBjoern A. Zeeb } 6024e2340276SBjoern A. Zeeb 6025e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 6026e2340276SBjoern A. Zeeb "[BTC], cnt_connect = %d, connecting = %d, link_mode = %d\n", 6027e2340276SBjoern A. Zeeb cnt_connect, cnt_connecting, wl_rinfo->link_mode); 6028e2340276SBjoern A. Zeeb 6029e2340276SBjoern A. Zeeb _fw_set_drv_info(rtwdev, CXDRVINFO_ROLE); 6030e2340276SBjoern A. Zeeb } 6031e2340276SBjoern A. Zeeb 60328e93258fSBjoern A. Zeeb #define BTC_CHK_HANG_MAX 3 60338e93258fSBjoern A. Zeeb #define BTC_SCB_INV_VALUE GENMASK(31, 0) 60348e93258fSBjoern A. Zeeb 6035*6d67aabdSBjoern A. Zeeb static u8 _get_role_link_mode(u8 role) 6036*6d67aabdSBjoern A. Zeeb { 6037*6d67aabdSBjoern A. Zeeb switch (role) { 6038*6d67aabdSBjoern A. Zeeb case RTW89_WIFI_ROLE_STATION: 6039*6d67aabdSBjoern A. Zeeb return BTC_WLINK_2G_STA; 6040*6d67aabdSBjoern A. Zeeb case RTW89_WIFI_ROLE_P2P_GO: 6041*6d67aabdSBjoern A. Zeeb return BTC_WLINK_2G_GO; 6042*6d67aabdSBjoern A. Zeeb case RTW89_WIFI_ROLE_P2P_CLIENT: 6043*6d67aabdSBjoern A. Zeeb return BTC_WLINK_2G_GC; 6044*6d67aabdSBjoern A. Zeeb case RTW89_WIFI_ROLE_AP: 6045*6d67aabdSBjoern A. Zeeb return BTC_WLINK_2G_AP; 6046*6d67aabdSBjoern A. Zeeb default: 6047*6d67aabdSBjoern A. Zeeb return BTC_WLINK_OTHER; 6048*6d67aabdSBjoern A. Zeeb } 6049*6d67aabdSBjoern A. Zeeb } 6050*6d67aabdSBjoern A. Zeeb 6051*6d67aabdSBjoern A. Zeeb static bool _chk_role_ch_group(const struct rtw89_btc_chdef *r1, 6052*6d67aabdSBjoern A. Zeeb const struct rtw89_btc_chdef *r2) 6053*6d67aabdSBjoern A. Zeeb { 6054*6d67aabdSBjoern A. Zeeb if (r1->chan != r2->chan) { /* primary ch is different */ 6055*6d67aabdSBjoern A. Zeeb return false; 6056*6d67aabdSBjoern A. Zeeb } else if (r1->bw == RTW89_CHANNEL_WIDTH_40 && 6057*6d67aabdSBjoern A. Zeeb r2->bw == RTW89_CHANNEL_WIDTH_40) { 6058*6d67aabdSBjoern A. Zeeb if (r1->offset != r2->offset) 6059*6d67aabdSBjoern A. Zeeb return false; 6060*6d67aabdSBjoern A. Zeeb } 6061*6d67aabdSBjoern A. Zeeb return true; 6062*6d67aabdSBjoern A. Zeeb } 6063*6d67aabdSBjoern A. Zeeb 6064*6d67aabdSBjoern A. Zeeb static u8 _chk_dbcc(struct rtw89_dev *rtwdev, struct rtw89_btc_chdef *ch, 6065*6d67aabdSBjoern A. Zeeb u8 *phy, u8 *role, u8 *dbcc_2g_phy) 6066*6d67aabdSBjoern A. Zeeb { 6067*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &rtwdev->btc.cx.wl; 6068*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_role_info_v8 *wl_rinfo = &wl->role_info_v8; 6069*6d67aabdSBjoern A. Zeeb bool is_2g_ch_exist = false, is_multi_role_in_2g_phy = false; 6070*6d67aabdSBjoern A. Zeeb u8 j, k, dbcc_2g_cid, dbcc_2g_cid2; 6071*6d67aabdSBjoern A. Zeeb 6072*6d67aabdSBjoern A. Zeeb /* find out the 2G-PHY by connect-id ->ch */ 6073*6d67aabdSBjoern A. Zeeb for (j = 0; j < wl_rinfo->connect_cnt; j++) { 6074*6d67aabdSBjoern A. Zeeb if (ch[j].center_ch <= 14) { 6075*6d67aabdSBjoern A. Zeeb is_2g_ch_exist = true; 6076*6d67aabdSBjoern A. Zeeb break; 6077*6d67aabdSBjoern A. Zeeb } 6078*6d67aabdSBjoern A. Zeeb } 6079*6d67aabdSBjoern A. Zeeb 6080*6d67aabdSBjoern A. Zeeb /* If no any 2G-port exist, it's impossible because 5G-exclude */ 6081*6d67aabdSBjoern A. Zeeb if (!is_2g_ch_exist) 6082*6d67aabdSBjoern A. Zeeb return BTC_WLINK_OTHER; 6083*6d67aabdSBjoern A. Zeeb 6084*6d67aabdSBjoern A. Zeeb dbcc_2g_cid = j; 6085*6d67aabdSBjoern A. Zeeb *dbcc_2g_phy = phy[dbcc_2g_cid]; 6086*6d67aabdSBjoern A. Zeeb 6087*6d67aabdSBjoern A. Zeeb /* connect_cnt <= 2 */ 6088*6d67aabdSBjoern A. Zeeb if (wl_rinfo->connect_cnt < BTC_TDMA_WLROLE_MAX) 6089*6d67aabdSBjoern A. Zeeb return (_get_role_link_mode((role[dbcc_2g_cid]))); 6090*6d67aabdSBjoern A. Zeeb 6091*6d67aabdSBjoern A. Zeeb /* find the other-port in the 2G-PHY, ex: PHY-0:6G, PHY1: mcc/scc */ 6092*6d67aabdSBjoern A. Zeeb for (k = 0; k < wl_rinfo->connect_cnt; k++) { 6093*6d67aabdSBjoern A. Zeeb if (k == dbcc_2g_cid) 6094*6d67aabdSBjoern A. Zeeb continue; 6095*6d67aabdSBjoern A. Zeeb 6096*6d67aabdSBjoern A. Zeeb if (phy[k] == *dbcc_2g_phy) { 6097*6d67aabdSBjoern A. Zeeb is_multi_role_in_2g_phy = true; 6098*6d67aabdSBjoern A. Zeeb dbcc_2g_cid2 = k; 6099*6d67aabdSBjoern A. Zeeb break; 6100*6d67aabdSBjoern A. Zeeb } 6101*6d67aabdSBjoern A. Zeeb } 6102*6d67aabdSBjoern A. Zeeb 6103*6d67aabdSBjoern A. Zeeb /* Single-role in 2G-PHY */ 6104*6d67aabdSBjoern A. Zeeb if (!is_multi_role_in_2g_phy) 6105*6d67aabdSBjoern A. Zeeb return (_get_role_link_mode(role[dbcc_2g_cid])); 6106*6d67aabdSBjoern A. Zeeb 6107*6d67aabdSBjoern A. Zeeb /* 2-role in 2G-PHY */ 6108*6d67aabdSBjoern A. Zeeb if (ch[dbcc_2g_cid2].center_ch > 14) 6109*6d67aabdSBjoern A. Zeeb return BTC_WLINK_25G_MCC; 6110*6d67aabdSBjoern A. Zeeb else if (_chk_role_ch_group(&ch[dbcc_2g_cid], &ch[dbcc_2g_cid2])) 6111*6d67aabdSBjoern A. Zeeb return BTC_WLINK_2G_SCC; 6112*6d67aabdSBjoern A. Zeeb else 6113*6d67aabdSBjoern A. Zeeb return BTC_WLINK_2G_MCC; 6114*6d67aabdSBjoern A. Zeeb } 6115*6d67aabdSBjoern A. Zeeb 6116*6d67aabdSBjoern A. Zeeb static void _update_role_link_mode(struct rtw89_dev *rtwdev, 6117*6d67aabdSBjoern A. Zeeb bool client_joined, u32 noa) 6118*6d67aabdSBjoern A. Zeeb { 6119*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_role_info_v8 *wl_rinfo = &rtwdev->btc.cx.wl.role_info_v8; 6120*6d67aabdSBjoern A. Zeeb u32 type = BTC_WLMROLE_NONE, dur = 0; 6121*6d67aabdSBjoern A. Zeeb u32 wl_role = wl_rinfo->role_map; 6122*6d67aabdSBjoern A. Zeeb 6123*6d67aabdSBjoern A. Zeeb /* if no client_joined, don't care P2P-GO/AP role */ 6124*6d67aabdSBjoern A. Zeeb if (((wl_role & BIT(RTW89_WIFI_ROLE_P2P_GO)) || 6125*6d67aabdSBjoern A. Zeeb (wl_role & BIT(RTW89_WIFI_ROLE_AP))) && !client_joined) { 6126*6d67aabdSBjoern A. Zeeb if (wl_rinfo->link_mode == BTC_WLINK_2G_SCC) { 6127*6d67aabdSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_2G_STA; 6128*6d67aabdSBjoern A. Zeeb wl_rinfo->connect_cnt--; 6129*6d67aabdSBjoern A. Zeeb } else if (wl_rinfo->link_mode == BTC_WLINK_2G_GO || 6130*6d67aabdSBjoern A. Zeeb wl_rinfo->link_mode == BTC_WLINK_2G_AP) { 6131*6d67aabdSBjoern A. Zeeb wl_rinfo->link_mode = BTC_WLINK_NOLINK; 6132*6d67aabdSBjoern A. Zeeb wl_rinfo->connect_cnt--; 6133*6d67aabdSBjoern A. Zeeb } 6134*6d67aabdSBjoern A. Zeeb } 6135*6d67aabdSBjoern A. Zeeb 6136*6d67aabdSBjoern A. Zeeb /* Identify 2-Role type */ 6137*6d67aabdSBjoern A. Zeeb if (wl_rinfo->connect_cnt >= 2 && 6138*6d67aabdSBjoern A. Zeeb (wl_rinfo->link_mode == BTC_WLINK_2G_SCC || 6139*6d67aabdSBjoern A. Zeeb wl_rinfo->link_mode == BTC_WLINK_2G_MCC || 6140*6d67aabdSBjoern A. Zeeb wl_rinfo->link_mode == BTC_WLINK_25G_MCC || 6141*6d67aabdSBjoern A. Zeeb wl_rinfo->link_mode == BTC_WLINK_5G)) { 6142*6d67aabdSBjoern A. Zeeb if ((wl_role & BIT(RTW89_WIFI_ROLE_P2P_GO)) || 6143*6d67aabdSBjoern A. Zeeb (wl_role & BIT(RTW89_WIFI_ROLE_AP))) 6144*6d67aabdSBjoern A. Zeeb type = noa ? BTC_WLMROLE_STA_GO_NOA : BTC_WLMROLE_STA_GO; 6145*6d67aabdSBjoern A. Zeeb else if (wl_role & BIT(RTW89_WIFI_ROLE_P2P_CLIENT)) 6146*6d67aabdSBjoern A. Zeeb type = noa ? BTC_WLMROLE_STA_GC_NOA : BTC_WLMROLE_STA_GC; 6147*6d67aabdSBjoern A. Zeeb else 6148*6d67aabdSBjoern A. Zeeb type = BTC_WLMROLE_STA_STA; 6149*6d67aabdSBjoern A. Zeeb 6150*6d67aabdSBjoern A. Zeeb dur = noa; 6151*6d67aabdSBjoern A. Zeeb } 6152*6d67aabdSBjoern A. Zeeb 6153*6d67aabdSBjoern A. Zeeb wl_rinfo->mrole_type = type; 6154*6d67aabdSBjoern A. Zeeb wl_rinfo->mrole_noa_duration = dur; 6155*6d67aabdSBjoern A. Zeeb } 6156*6d67aabdSBjoern A. Zeeb 6157*6d67aabdSBjoern A. Zeeb static void _update_wl_info_v8(struct rtw89_dev *rtwdev, u8 role_id, u8 rlink_id, 6158*6d67aabdSBjoern A. Zeeb enum btc_role_state state) 6159*6d67aabdSBjoern A. Zeeb { 6160*6d67aabdSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 6161*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 6162*6d67aabdSBjoern A. Zeeb struct rtw89_btc_chdef cid_ch[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER]; 6163*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_role_info_v8 *wl_rinfo = &wl->role_info_v8; 6164*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info; 6165*6d67aabdSBjoern A. Zeeb bool client_joined = false, b2g = false, b5g = false; 6166*6d67aabdSBjoern A. Zeeb u8 cid_role[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER] = {}; 6167*6d67aabdSBjoern A. Zeeb u8 cid_phy[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER] = {}; 6168*6d67aabdSBjoern A. Zeeb u8 dbcc_en = 0, pta_req_band = RTW89_MAC_0; 6169*6d67aabdSBjoern A. Zeeb u8 i, j, cnt = 0, cnt_2g = 0, cnt_5g = 0; 6170*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_link_info *wl_linfo; 6171*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_rlink *rlink = NULL; 6172*6d67aabdSBjoern A. Zeeb u8 dbcc_2g_phy = RTW89_PHY_0; 6173*6d67aabdSBjoern A. Zeeb u8 mode = BTC_WLINK_NOLINK; 6174*6d67aabdSBjoern A. Zeeb u32 noa_dur = 0; 6175*6d67aabdSBjoern A. Zeeb 6176*6d67aabdSBjoern A. Zeeb if (role_id >= RTW89_BE_BTC_WL_MAX_ROLE_NUMBER || rlink_id > RTW89_MAC_1) 6177*6d67aabdSBjoern A. Zeeb return; 6178*6d67aabdSBjoern A. Zeeb 6179*6d67aabdSBjoern A. Zeeb /* Extract wl->link_info[role_id][rlink_id] to wl->role_info 6180*6d67aabdSBjoern A. Zeeb * role_id: role index 6181*6d67aabdSBjoern A. Zeeb * rlink_id: rlink index (= HW-band index) 6182*6d67aabdSBjoern A. Zeeb * pid: port_index 6183*6d67aabdSBjoern A. Zeeb */ 6184*6d67aabdSBjoern A. Zeeb 6185*6d67aabdSBjoern A. Zeeb wl_linfo = &wl->rlink_info[role_id][rlink_id]; 6186*6d67aabdSBjoern A. Zeeb if (wl_linfo->connected == MLME_LINKING) 6187*6d67aabdSBjoern A. Zeeb return; 6188*6d67aabdSBjoern A. Zeeb 6189*6d67aabdSBjoern A. Zeeb rlink = &wl_rinfo->rlink[role_id][rlink_id]; 6190*6d67aabdSBjoern A. Zeeb rlink->role = wl_linfo->role; 6191*6d67aabdSBjoern A. Zeeb rlink->active = wl_linfo->active; /* Doze or not */ 6192*6d67aabdSBjoern A. Zeeb rlink->pid = wl_linfo->pid; 6193*6d67aabdSBjoern A. Zeeb rlink->phy = wl_linfo->phy; 6194*6d67aabdSBjoern A. Zeeb rlink->rf_band = wl_linfo->band; 6195*6d67aabdSBjoern A. Zeeb rlink->ch = wl_linfo->ch; 6196*6d67aabdSBjoern A. Zeeb rlink->bw = wl_linfo->bw; 6197*6d67aabdSBjoern A. Zeeb rlink->noa = wl_linfo->noa; 6198*6d67aabdSBjoern A. Zeeb rlink->noa_dur = wl_linfo->noa_duration / 1000; 6199*6d67aabdSBjoern A. Zeeb rlink->client_cnt = wl_linfo->client_cnt; 6200*6d67aabdSBjoern A. Zeeb rlink->mode = wl_linfo->mode; 6201*6d67aabdSBjoern A. Zeeb 6202*6d67aabdSBjoern A. Zeeb switch (wl_linfo->connected) { 6203*6d67aabdSBjoern A. Zeeb case MLME_NO_LINK: 6204*6d67aabdSBjoern A. Zeeb rlink->connected = 0; 6205*6d67aabdSBjoern A. Zeeb if (rlink->role == RTW89_WIFI_ROLE_STATION) 6206*6d67aabdSBjoern A. Zeeb btc->dm.leak_ap = 0; 6207*6d67aabdSBjoern A. Zeeb break; 6208*6d67aabdSBjoern A. Zeeb case MLME_LINKED: 6209*6d67aabdSBjoern A. Zeeb rlink->connected = 1; 6210*6d67aabdSBjoern A. Zeeb break; 6211*6d67aabdSBjoern A. Zeeb default: 6212*6d67aabdSBjoern A. Zeeb return; 6213*6d67aabdSBjoern A. Zeeb } 6214*6d67aabdSBjoern A. Zeeb 6215*6d67aabdSBjoern A. Zeeb wl->is_5g_hi_channel = false; 6216*6d67aabdSBjoern A. Zeeb wl->bg_mode = false; 6217*6d67aabdSBjoern A. Zeeb wl_rinfo->role_map = 0; 6218*6d67aabdSBjoern A. Zeeb wl_rinfo->p2p_2g = 0; 6219*6d67aabdSBjoern A. Zeeb memset(cid_ch, 0, sizeof(cid_ch)); 6220*6d67aabdSBjoern A. Zeeb 6221*6d67aabdSBjoern A. Zeeb for (i = 0; i < RTW89_BE_BTC_WL_MAX_ROLE_NUMBER; i++) { 6222*6d67aabdSBjoern A. Zeeb for (j = RTW89_MAC_0; j <= RTW89_MAC_1; j++) { 6223*6d67aabdSBjoern A. Zeeb rlink = &wl_rinfo->rlink[i][j]; 6224*6d67aabdSBjoern A. Zeeb 6225*6d67aabdSBjoern A. Zeeb if (!rlink->active || !rlink->connected) 6226*6d67aabdSBjoern A. Zeeb continue; 6227*6d67aabdSBjoern A. Zeeb 6228*6d67aabdSBjoern A. Zeeb cnt++; 6229*6d67aabdSBjoern A. Zeeb wl_rinfo->role_map |= BIT(rlink->role); 6230*6d67aabdSBjoern A. Zeeb 6231*6d67aabdSBjoern A. Zeeb /* only if client connect for p2p-Go/AP */ 6232*6d67aabdSBjoern A. Zeeb if ((rlink->role == RTW89_WIFI_ROLE_P2P_GO || 6233*6d67aabdSBjoern A. Zeeb rlink->role == RTW89_WIFI_ROLE_AP) && 6234*6d67aabdSBjoern A. Zeeb rlink->client_cnt > 1) 6235*6d67aabdSBjoern A. Zeeb client_joined = true; 6236*6d67aabdSBjoern A. Zeeb 6237*6d67aabdSBjoern A. Zeeb /* Identufy if P2P-Go (GO/GC/AP) exist at 2G band*/ 6238*6d67aabdSBjoern A. Zeeb if (rlink->rf_band == RTW89_BAND_2G && 6239*6d67aabdSBjoern A. Zeeb (client_joined || rlink->role == RTW89_WIFI_ROLE_P2P_CLIENT)) 6240*6d67aabdSBjoern A. Zeeb wl_rinfo->p2p_2g = 1; 6241*6d67aabdSBjoern A. Zeeb 6242*6d67aabdSBjoern A. Zeeb /* only one noa-role exist */ 6243*6d67aabdSBjoern A. Zeeb if (rlink->noa && rlink->noa_dur > 0) 6244*6d67aabdSBjoern A. Zeeb noa_dur = rlink->noa_dur; 6245*6d67aabdSBjoern A. Zeeb 6246*6d67aabdSBjoern A. Zeeb /* for WL 5G-Rx interfered with BT issue */ 6247*6d67aabdSBjoern A. Zeeb if (rlink->rf_band == RTW89_BAND_5G && rlink->ch >= 100) 6248*6d67aabdSBjoern A. Zeeb wl->is_5g_hi_channel = 1; 6249*6d67aabdSBjoern A. Zeeb 6250*6d67aabdSBjoern A. Zeeb if ((rlink->mode & BIT(BTC_WL_MODE_11B)) || 6251*6d67aabdSBjoern A. Zeeb (rlink->mode & BIT(BTC_WL_MODE_11G))) 6252*6d67aabdSBjoern A. Zeeb wl->bg_mode = 1; 6253*6d67aabdSBjoern A. Zeeb 6254*6d67aabdSBjoern A. Zeeb if (rtwdev->chip->para_ver & BTC_FEAT_MLO_SUPPORT) 6255*6d67aabdSBjoern A. Zeeb continue; 6256*6d67aabdSBjoern A. Zeeb 6257*6d67aabdSBjoern A. Zeeb cid_ch[cnt - 1] = wl_linfo->chdef; 6258*6d67aabdSBjoern A. Zeeb cid_phy[cnt - 1] = rlink->phy; 6259*6d67aabdSBjoern A. Zeeb cid_role[cnt - 1] = rlink->role; 6260*6d67aabdSBjoern A. Zeeb 6261*6d67aabdSBjoern A. Zeeb if (rlink->rf_band != RTW89_BAND_2G) { 6262*6d67aabdSBjoern A. Zeeb cnt_5g++; 6263*6d67aabdSBjoern A. Zeeb b5g = true; 6264*6d67aabdSBjoern A. Zeeb } else { 6265*6d67aabdSBjoern A. Zeeb cnt_2g++; 6266*6d67aabdSBjoern A. Zeeb b2g = true; 6267*6d67aabdSBjoern A. Zeeb } 6268*6d67aabdSBjoern A. Zeeb } 6269*6d67aabdSBjoern A. Zeeb } 6270*6d67aabdSBjoern A. Zeeb 6271*6d67aabdSBjoern A. Zeeb if (rtwdev->chip->para_ver & BTC_FEAT_MLO_SUPPORT) { 6272*6d67aabdSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 6273*6d67aabdSBjoern A. Zeeb "[BTC] rlink cnt_2g=%d cnt_5g=%d\n", cnt_2g, cnt_5g); 6274*6d67aabdSBjoern A. Zeeb rtw89_warn(rtwdev, "not support MLO feature yet"); 6275*6d67aabdSBjoern A. Zeeb } else { 6276*6d67aabdSBjoern A. Zeeb dbcc_en = rtwdev->dbcc_en; 6277*6d67aabdSBjoern A. Zeeb 6278*6d67aabdSBjoern A. Zeeb /* Be careful to change the following sequence!! */ 6279*6d67aabdSBjoern A. Zeeb if (cnt == 0) { 6280*6d67aabdSBjoern A. Zeeb mode = BTC_WLINK_NOLINK; 6281*6d67aabdSBjoern A. Zeeb } else if (!b2g && b5g) { 6282*6d67aabdSBjoern A. Zeeb mode = BTC_WLINK_5G; 6283*6d67aabdSBjoern A. Zeeb } else if (wl_rinfo->role_map & BIT(RTW89_WIFI_ROLE_NAN)) { 6284*6d67aabdSBjoern A. Zeeb mode = BTC_WLINK_2G_NAN; 6285*6d67aabdSBjoern A. Zeeb } else if (cnt > BTC_TDMA_WLROLE_MAX) { 6286*6d67aabdSBjoern A. Zeeb mode = BTC_WLINK_OTHER; 6287*6d67aabdSBjoern A. Zeeb } else if (dbcc_en) { 6288*6d67aabdSBjoern A. Zeeb mode = _chk_dbcc(rtwdev, cid_ch, cid_phy, cid_role, 6289*6d67aabdSBjoern A. Zeeb &dbcc_2g_phy); 6290*6d67aabdSBjoern A. Zeeb } else if (b2g && b5g && cnt == 2) { 6291*6d67aabdSBjoern A. Zeeb mode = BTC_WLINK_25G_MCC; 6292*6d67aabdSBjoern A. Zeeb } else if (!b5g && cnt == 2) { /* cnt_connect = 2 */ 6293*6d67aabdSBjoern A. Zeeb if (_chk_role_ch_group(&cid_ch[0], &cid_ch[cnt - 1])) 6294*6d67aabdSBjoern A. Zeeb mode = BTC_WLINK_2G_SCC; 6295*6d67aabdSBjoern A. Zeeb else 6296*6d67aabdSBjoern A. Zeeb mode = BTC_WLINK_2G_MCC; 6297*6d67aabdSBjoern A. Zeeb } else if (!b5g && cnt == 1) { /* cnt_connect = 1 */ 6298*6d67aabdSBjoern A. Zeeb mode = _get_role_link_mode(cid_role[0]); 6299*6d67aabdSBjoern A. Zeeb } 6300*6d67aabdSBjoern A. Zeeb } 6301*6d67aabdSBjoern A. Zeeb 6302*6d67aabdSBjoern A. Zeeb wl_rinfo->link_mode = mode; 6303*6d67aabdSBjoern A. Zeeb wl_rinfo->connect_cnt = cnt; 6304*6d67aabdSBjoern A. Zeeb if (wl_rinfo->connect_cnt == 0) 6305*6d67aabdSBjoern A. Zeeb wl_rinfo->role_map = BIT(RTW89_WIFI_ROLE_NONE); 6306*6d67aabdSBjoern A. Zeeb _update_role_link_mode(rtwdev, client_joined, noa_dur); 6307*6d67aabdSBjoern A. Zeeb 6308*6d67aabdSBjoern A. Zeeb wl_rinfo->dbcc_2g_phy = dbcc_2g_phy; 6309*6d67aabdSBjoern A. Zeeb if (wl_rinfo->dbcc_en != dbcc_en) { 6310*6d67aabdSBjoern A. Zeeb wl_rinfo->dbcc_en = dbcc_en; 6311*6d67aabdSBjoern A. Zeeb wl_rinfo->dbcc_chg = 1; 6312*6d67aabdSBjoern A. Zeeb btc->cx.cnt_wl[BTC_WCNT_DBCC_CHG]++; 6313*6d67aabdSBjoern A. Zeeb } else { 6314*6d67aabdSBjoern A. Zeeb wl_rinfo->dbcc_chg = 0; 6315*6d67aabdSBjoern A. Zeeb } 6316*6d67aabdSBjoern A. Zeeb 6317*6d67aabdSBjoern A. Zeeb if (wl_rinfo->dbcc_en) { 6318*6d67aabdSBjoern A. Zeeb memset(wl_dinfo, 0, sizeof(struct rtw89_btc_wl_dbcc_info)); 6319*6d67aabdSBjoern A. Zeeb 6320*6d67aabdSBjoern A. Zeeb if (mode == BTC_WLINK_5G) { 6321*6d67aabdSBjoern A. Zeeb pta_req_band = RTW89_PHY_0; 6322*6d67aabdSBjoern A. Zeeb wl_dinfo->op_band[RTW89_PHY_0] = RTW89_BAND_5G; 6323*6d67aabdSBjoern A. Zeeb wl_dinfo->op_band[RTW89_PHY_1] = RTW89_BAND_2G; 6324*6d67aabdSBjoern A. Zeeb } else if (wl_rinfo->dbcc_2g_phy == RTW89_PHY_1) { 6325*6d67aabdSBjoern A. Zeeb pta_req_band = RTW89_PHY_1; 6326*6d67aabdSBjoern A. Zeeb wl_dinfo->op_band[RTW89_PHY_0] = RTW89_BAND_5G; 6327*6d67aabdSBjoern A. Zeeb wl_dinfo->op_band[RTW89_PHY_1] = RTW89_BAND_2G; 6328*6d67aabdSBjoern A. Zeeb } else { 6329*6d67aabdSBjoern A. Zeeb pta_req_band = RTW89_PHY_0; 6330*6d67aabdSBjoern A. Zeeb wl_dinfo->op_band[RTW89_PHY_0] = RTW89_BAND_2G; 6331*6d67aabdSBjoern A. Zeeb wl_dinfo->op_band[RTW89_PHY_1] = RTW89_BAND_5G; 6332*6d67aabdSBjoern A. Zeeb } 6333*6d67aabdSBjoern A. Zeeb _update_dbcc_band(rtwdev, RTW89_PHY_0); 6334*6d67aabdSBjoern A. Zeeb _update_dbcc_band(rtwdev, RTW89_PHY_1); 6335*6d67aabdSBjoern A. Zeeb } 6336*6d67aabdSBjoern A. Zeeb 6337*6d67aabdSBjoern A. Zeeb wl_rinfo->pta_req_band = pta_req_band; 6338*6d67aabdSBjoern A. Zeeb _fw_set_drv_info(rtwdev, CXDRVINFO_ROLE); 6339*6d67aabdSBjoern A. Zeeb } 6340*6d67aabdSBjoern A. Zeeb 63418e93258fSBjoern A. Zeeb void rtw89_coex_act1_work(struct work_struct *work) 63428e93258fSBjoern A. Zeeb { 63438e93258fSBjoern A. Zeeb struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, 63448e93258fSBjoern A. Zeeb coex_act1_work.work); 63458e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 63468e93258fSBjoern A. Zeeb struct rtw89_btc_dm *dm = &rtwdev->btc.dm; 63478e93258fSBjoern A. Zeeb struct rtw89_btc_cx *cx = &btc->cx; 63488e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &cx->wl; 63498e93258fSBjoern A. Zeeb 63508e93258fSBjoern A. Zeeb mutex_lock(&rtwdev->mutex); 63518e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): enter\n", __func__); 63528e93258fSBjoern A. Zeeb dm->cnt_notify[BTC_NCNT_TIMER]++; 63538e93258fSBjoern A. Zeeb if (wl->status.map._4way) 63548e93258fSBjoern A. Zeeb wl->status.map._4way = false; 63558e93258fSBjoern A. Zeeb if (wl->status.map.connecting) 63568e93258fSBjoern A. Zeeb wl->status.map.connecting = false; 63578e93258fSBjoern A. Zeeb 63588e93258fSBjoern A. Zeeb _run_coex(rtwdev, BTC_RSN_ACT1_WORK); 63598e93258fSBjoern A. Zeeb mutex_unlock(&rtwdev->mutex); 63608e93258fSBjoern A. Zeeb } 63618e93258fSBjoern A. Zeeb 63628e93258fSBjoern A. Zeeb void rtw89_coex_bt_devinfo_work(struct work_struct *work) 63638e93258fSBjoern A. Zeeb { 63648e93258fSBjoern A. Zeeb struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, 63658e93258fSBjoern A. Zeeb coex_bt_devinfo_work.work); 63668e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 63678e93258fSBjoern A. Zeeb struct rtw89_btc_dm *dm = &rtwdev->btc.dm; 63688e93258fSBjoern A. Zeeb struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc; 63698e93258fSBjoern A. Zeeb 63708e93258fSBjoern A. Zeeb mutex_lock(&rtwdev->mutex); 63718e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): enter\n", __func__); 63728e93258fSBjoern A. Zeeb dm->cnt_notify[BTC_NCNT_TIMER]++; 63738e93258fSBjoern A. Zeeb a2dp->play_latency = 0; 63748e93258fSBjoern A. Zeeb _run_coex(rtwdev, BTC_RSN_BT_DEVINFO_WORK); 63758e93258fSBjoern A. Zeeb mutex_unlock(&rtwdev->mutex); 63768e93258fSBjoern A. Zeeb } 63778e93258fSBjoern A. Zeeb 63788e93258fSBjoern A. Zeeb void rtw89_coex_rfk_chk_work(struct work_struct *work) 63798e93258fSBjoern A. Zeeb { 63808e93258fSBjoern A. Zeeb struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, 63818e93258fSBjoern A. Zeeb coex_rfk_chk_work.work); 63828e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 63838e93258fSBjoern A. Zeeb struct rtw89_btc_dm *dm = &rtwdev->btc.dm; 63848e93258fSBjoern A. Zeeb struct rtw89_btc_cx *cx = &btc->cx; 63858e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &cx->wl; 63868e93258fSBjoern A. Zeeb 63878e93258fSBjoern A. Zeeb mutex_lock(&rtwdev->mutex); 63888e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): enter\n", __func__); 63898e93258fSBjoern A. Zeeb dm->cnt_notify[BTC_NCNT_TIMER]++; 63908e93258fSBjoern A. Zeeb if (wl->rfk_info.state != BTC_WRFK_STOP) { 63918e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 63928e93258fSBjoern A. Zeeb "[BTC], %s(): RFK timeout\n", __func__); 63938e93258fSBjoern A. Zeeb cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]++; 63948e93258fSBjoern A. Zeeb dm->error.map.wl_rfk_timeout = true; 63958e93258fSBjoern A. Zeeb wl->rfk_info.state = BTC_WRFK_STOP; 63968e93258fSBjoern A. Zeeb _write_scbd(rtwdev, BTC_WSCB_WLRFK, false); 63978e93258fSBjoern A. Zeeb _run_coex(rtwdev, BTC_RSN_RFK_CHK_WORK); 63988e93258fSBjoern A. Zeeb } 63998e93258fSBjoern A. Zeeb mutex_unlock(&rtwdev->mutex); 64008e93258fSBjoern A. Zeeb } 64018e93258fSBjoern A. Zeeb 64028e93258fSBjoern A. Zeeb static void _update_bt_scbd(struct rtw89_dev *rtwdev, bool only_update) 64038e93258fSBjoern A. Zeeb { 64048e93258fSBjoern A. Zeeb const struct rtw89_chip_info *chip = rtwdev->chip; 64058e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 64068e93258fSBjoern A. Zeeb struct rtw89_btc_cx *cx = &btc->cx; 64078e93258fSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &btc->cx.bt; 64088e93258fSBjoern A. Zeeb u32 val; 64098e93258fSBjoern A. Zeeb bool status_change = false; 64108e93258fSBjoern A. Zeeb 64118e93258fSBjoern A. Zeeb if (!chip->scbd) 64128e93258fSBjoern A. Zeeb return; 64138e93258fSBjoern A. Zeeb 64148e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s\n", __func__); 64158e93258fSBjoern A. Zeeb 64168e93258fSBjoern A. Zeeb val = _read_scbd(rtwdev); 64178e93258fSBjoern A. Zeeb if (val == BTC_SCB_INV_VALUE) { 64188e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 64198e93258fSBjoern A. Zeeb "[BTC], %s(): return by invalid scbd value\n", 64208e93258fSBjoern A. Zeeb __func__); 64218e93258fSBjoern A. Zeeb return; 64228e93258fSBjoern A. Zeeb } 64238e93258fSBjoern A. Zeeb 6424*6d67aabdSBjoern A. Zeeb if (!(val & BTC_BSCB_ON)) 64258e93258fSBjoern A. Zeeb bt->enable.now = 0; 64268e93258fSBjoern A. Zeeb else 64278e93258fSBjoern A. Zeeb bt->enable.now = 1; 64288e93258fSBjoern A. Zeeb 64298e93258fSBjoern A. Zeeb if (bt->enable.now != bt->enable.last) 64308e93258fSBjoern A. Zeeb status_change = true; 64318e93258fSBjoern A. Zeeb 64328e93258fSBjoern A. Zeeb /* reset bt info if bt re-enable */ 64338e93258fSBjoern A. Zeeb if (bt->enable.now && !bt->enable.last) { 64348e93258fSBjoern A. Zeeb _reset_btc_var(rtwdev, BTC_RESET_BTINFO); 64358e93258fSBjoern A. Zeeb cx->cnt_bt[BTC_BCNT_REENABLE]++; 64368e93258fSBjoern A. Zeeb bt->enable.now = 1; 64378e93258fSBjoern A. Zeeb } 64388e93258fSBjoern A. Zeeb 64398e93258fSBjoern A. Zeeb bt->enable.last = bt->enable.now; 64408e93258fSBjoern A. Zeeb bt->scbd = val; 64418e93258fSBjoern A. Zeeb bt->mbx_avl = !!(val & BTC_BSCB_ACT); 64428e93258fSBjoern A. Zeeb 64438e93258fSBjoern A. Zeeb if (bt->whql_test != !!(val & BTC_BSCB_WHQL)) 64448e93258fSBjoern A. Zeeb status_change = true; 64458e93258fSBjoern A. Zeeb 64468e93258fSBjoern A. Zeeb bt->whql_test = !!(val & BTC_BSCB_WHQL); 64478e93258fSBjoern A. Zeeb bt->btg_type = val & BTC_BSCB_BT_S1 ? BTC_BT_BTG : BTC_BT_ALONE; 6448e2340276SBjoern A. Zeeb bt->link_info.a2dp_desc.exist = !!(val & BTC_BSCB_A2DP_ACT); 64498e93258fSBjoern A. Zeeb 6450*6d67aabdSBjoern A. Zeeb bt->lna_constrain = !!(val & BTC_BSCB_BT_LNAB0) + 6451*6d67aabdSBjoern A. Zeeb !!(val & BTC_BSCB_BT_LNAB1) * 2 + 4; 6452*6d67aabdSBjoern A. Zeeb 64538e93258fSBjoern A. Zeeb /* if rfk run 1->0 */ 64548e93258fSBjoern A. Zeeb if (bt->rfk_info.map.run && !(val & BTC_BSCB_RFK_RUN)) 64558e93258fSBjoern A. Zeeb status_change = true; 64568e93258fSBjoern A. Zeeb 64578e93258fSBjoern A. Zeeb bt->rfk_info.map.run = !!(val & BTC_BSCB_RFK_RUN); 64588e93258fSBjoern A. Zeeb bt->rfk_info.map.req = !!(val & BTC_BSCB_RFK_REQ); 64598e93258fSBjoern A. Zeeb bt->hi_lna_rx = !!(val & BTC_BSCB_BT_HILNA); 64608e93258fSBjoern A. Zeeb bt->link_info.status.map.connect = !!(val & BTC_BSCB_BT_CONNECT); 64618e93258fSBjoern A. Zeeb bt->run_patch_code = !!(val & BTC_BSCB_PATCH_CODE); 64628e93258fSBjoern A. Zeeb 64638e93258fSBjoern A. Zeeb if (!only_update && status_change) 64648e93258fSBjoern A. Zeeb _run_coex(rtwdev, BTC_RSN_UPDATE_BT_SCBD); 64658e93258fSBjoern A. Zeeb } 64668e93258fSBjoern A. Zeeb 64678e93258fSBjoern A. Zeeb static bool _chk_wl_rfk_request(struct rtw89_dev *rtwdev) 64688e93258fSBjoern A. Zeeb { 64698e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 64708e93258fSBjoern A. Zeeb struct rtw89_btc_cx *cx = &btc->cx; 64718e93258fSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &cx->bt; 64728e93258fSBjoern A. Zeeb 64738e93258fSBjoern A. Zeeb _update_bt_scbd(rtwdev, true); 64748e93258fSBjoern A. Zeeb 64758e93258fSBjoern A. Zeeb cx->cnt_wl[BTC_WCNT_RFK_REQ]++; 64768e93258fSBjoern A. Zeeb 64778e93258fSBjoern A. Zeeb if ((bt->rfk_info.map.run || bt->rfk_info.map.req) && 64788e93258fSBjoern A. Zeeb !bt->rfk_info.map.timeout) { 64798e93258fSBjoern A. Zeeb cx->cnt_wl[BTC_WCNT_RFK_REJECT]++; 64808e93258fSBjoern A. Zeeb } else { 64818e93258fSBjoern A. Zeeb cx->cnt_wl[BTC_WCNT_RFK_GO]++; 64828e93258fSBjoern A. Zeeb return true; 64838e93258fSBjoern A. Zeeb } 64848e93258fSBjoern A. Zeeb return false; 64858e93258fSBjoern A. Zeeb } 64868e93258fSBjoern A. Zeeb 64878e93258fSBjoern A. Zeeb static 64888e93258fSBjoern A. Zeeb void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason) 64898e93258fSBjoern A. Zeeb { 64908e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 6491e2340276SBjoern A. Zeeb const struct rtw89_btc_ver *ver = btc->ver; 64928e93258fSBjoern A. Zeeb struct rtw89_btc_dm *dm = &rtwdev->btc.dm; 64938e93258fSBjoern A. Zeeb struct rtw89_btc_cx *cx = &btc->cx; 64948e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 6495e2340276SBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &btc->cx.bt; 64968e93258fSBjoern A. Zeeb struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; 64978e93258fSBjoern A. Zeeb struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1; 6498e2340276SBjoern A. Zeeb struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2; 6499*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_role_info_v8 *wl_rinfo_v8 = &wl->role_info_v8; 6500*6d67aabdSBjoern A. Zeeb u8 mode, igno_bt, always_freerun; 65018e93258fSBjoern A. Zeeb 65028e93258fSBjoern A. Zeeb lockdep_assert_held(&rtwdev->mutex); 65038e93258fSBjoern A. Zeeb 65048e93258fSBjoern A. Zeeb dm->run_reason = reason; 65058e93258fSBjoern A. Zeeb _update_dm_step(rtwdev, reason); 65068e93258fSBjoern A. Zeeb _update_btc_state_map(rtwdev); 65078e93258fSBjoern A. Zeeb 6508e2340276SBjoern A. Zeeb if (ver->fwlrole == 0) 65098e93258fSBjoern A. Zeeb mode = wl_rinfo->link_mode; 6510e2340276SBjoern A. Zeeb else if (ver->fwlrole == 1) 65118e93258fSBjoern A. Zeeb mode = wl_rinfo_v1->link_mode; 6512e2340276SBjoern A. Zeeb else if (ver->fwlrole == 2) 6513e2340276SBjoern A. Zeeb mode = wl_rinfo_v2->link_mode; 6514*6d67aabdSBjoern A. Zeeb else if (ver->fwlrole == 8) 6515*6d67aabdSBjoern A. Zeeb mode = wl_rinfo_v8->link_mode; 6516e2340276SBjoern A. Zeeb else 6517e2340276SBjoern A. Zeeb return; 65188e93258fSBjoern A. Zeeb 6519*6d67aabdSBjoern A. Zeeb if (ver->fcxctrl == 7) { 6520*6d67aabdSBjoern A. Zeeb igno_bt = btc->ctrl.ctrl_v7.igno_bt; 6521*6d67aabdSBjoern A. Zeeb always_freerun = btc->ctrl.ctrl_v7.always_freerun; 6522*6d67aabdSBjoern A. Zeeb } else { 6523*6d67aabdSBjoern A. Zeeb igno_bt = btc->ctrl.ctrl.igno_bt; 6524*6d67aabdSBjoern A. Zeeb always_freerun = btc->ctrl.ctrl.always_freerun; 6525*6d67aabdSBjoern A. Zeeb } 6526*6d67aabdSBjoern A. Zeeb 65278e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): reason=%d, mode=%d\n", 65288e93258fSBjoern A. Zeeb __func__, reason, mode); 65298e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): wl_only=%d, bt_only=%d\n", 65308e93258fSBjoern A. Zeeb __func__, dm->wl_only, dm->bt_only); 65318e93258fSBjoern A. Zeeb 65328e93258fSBjoern A. Zeeb /* Be careful to change the following function sequence!! */ 6533*6d67aabdSBjoern A. Zeeb if (btc->manual_ctrl) { 65348e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 65358e93258fSBjoern A. Zeeb "[BTC], %s(): return for Manual CTRL!!\n", 65368e93258fSBjoern A. Zeeb __func__); 65378e93258fSBjoern A. Zeeb return; 65388e93258fSBjoern A. Zeeb } 65398e93258fSBjoern A. Zeeb 6540*6d67aabdSBjoern A. Zeeb if (igno_bt && 65418e93258fSBjoern A. Zeeb (reason == BTC_RSN_UPDATE_BT_INFO || 65428e93258fSBjoern A. Zeeb reason == BTC_RSN_UPDATE_BT_SCBD)) { 65438e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 65448e93258fSBjoern A. Zeeb "[BTC], %s(): return for Stop Coex DM!!\n", 65458e93258fSBjoern A. Zeeb __func__); 65468e93258fSBjoern A. Zeeb return; 65478e93258fSBjoern A. Zeeb } 65488e93258fSBjoern A. Zeeb 65498e93258fSBjoern A. Zeeb if (!wl->status.map.init_ok) { 65508e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 65518e93258fSBjoern A. Zeeb "[BTC], %s(): return for WL init fail!!\n", 65528e93258fSBjoern A. Zeeb __func__); 65538e93258fSBjoern A. Zeeb return; 65548e93258fSBjoern A. Zeeb } 65558e93258fSBjoern A. Zeeb 65568e93258fSBjoern A. Zeeb if (wl->status.map.rf_off_pre == wl->status.map.rf_off && 6557*6d67aabdSBjoern A. Zeeb wl->status.map.lps_pre == wl->status.map.lps) { 6558*6d67aabdSBjoern A. Zeeb if (reason == BTC_RSN_NTFY_POWEROFF || 6559*6d67aabdSBjoern A. Zeeb reason == BTC_RSN_NTFY_RADIO_STATE) { 65608e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 65618e93258fSBjoern A. Zeeb "[BTC], %s(): return for WL rf off state no change!!\n", 65628e93258fSBjoern A. Zeeb __func__); 65638e93258fSBjoern A. Zeeb return; 65648e93258fSBjoern A. Zeeb } 6565*6d67aabdSBjoern A. Zeeb if (wl->status.map.rf_off == 1 || 6566*6d67aabdSBjoern A. Zeeb wl->status.map.lps == BTC_LPS_RF_OFF) { 6567*6d67aabdSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 6568*6d67aabdSBjoern A. Zeeb "[BTC], %s(): return for WL rf off state!!\n", 6569*6d67aabdSBjoern A. Zeeb __func__); 6570*6d67aabdSBjoern A. Zeeb return; 6571*6d67aabdSBjoern A. Zeeb } 6572*6d67aabdSBjoern A. Zeeb } 65738e93258fSBjoern A. Zeeb 6574*6d67aabdSBjoern A. Zeeb dm->freerun = false; 65758e93258fSBjoern A. Zeeb dm->cnt_dm[BTC_DCNT_RUN]++; 6576e2340276SBjoern A. Zeeb dm->fddt_train = BTC_FDDT_DISABLE; 6577*6d67aabdSBjoern A. Zeeb bt->scan_rx_low_pri = false; 6578*6d67aabdSBjoern A. Zeeb igno_bt = false; 65798e93258fSBjoern A. Zeeb 6580*6d67aabdSBjoern A. Zeeb if (always_freerun) { 65818e93258fSBjoern A. Zeeb _action_freerun(rtwdev); 6582*6d67aabdSBjoern A. Zeeb igno_bt = true; 65838e93258fSBjoern A. Zeeb goto exit; 65848e93258fSBjoern A. Zeeb } 65858e93258fSBjoern A. Zeeb 65868e93258fSBjoern A. Zeeb if (dm->wl_only) { 65878e93258fSBjoern A. Zeeb _action_wl_only(rtwdev); 6588*6d67aabdSBjoern A. Zeeb igno_bt = true; 65898e93258fSBjoern A. Zeeb goto exit; 65908e93258fSBjoern A. Zeeb } 65918e93258fSBjoern A. Zeeb 65928e93258fSBjoern A. Zeeb if (wl->status.map.rf_off || wl->status.map.lps || dm->bt_only) { 6593*6d67aabdSBjoern A. Zeeb _action_wl_off(rtwdev, mode); 6594*6d67aabdSBjoern A. Zeeb igno_bt = true; 65958e93258fSBjoern A. Zeeb goto exit; 65968e93258fSBjoern A. Zeeb } 65978e93258fSBjoern A. Zeeb 65988e93258fSBjoern A. Zeeb if (reason == BTC_RSN_NTFY_INIT) { 65998e93258fSBjoern A. Zeeb _action_wl_init(rtwdev); 66008e93258fSBjoern A. Zeeb goto exit; 66018e93258fSBjoern A. Zeeb } 66028e93258fSBjoern A. Zeeb 66038e93258fSBjoern A. Zeeb if (!cx->bt.enable.now && !cx->other.type) { 66048e93258fSBjoern A. Zeeb _action_bt_off(rtwdev); 66058e93258fSBjoern A. Zeeb goto exit; 66068e93258fSBjoern A. Zeeb } 66078e93258fSBjoern A. Zeeb 66088e93258fSBjoern A. Zeeb if (cx->bt.whql_test) { 66098e93258fSBjoern A. Zeeb _action_bt_whql(rtwdev); 66108e93258fSBjoern A. Zeeb goto exit; 66118e93258fSBjoern A. Zeeb } 66128e93258fSBjoern A. Zeeb 66138e93258fSBjoern A. Zeeb if (wl->rfk_info.state != BTC_WRFK_STOP) { 66148e93258fSBjoern A. Zeeb _action_wl_rfk(rtwdev); 66158e93258fSBjoern A. Zeeb goto exit; 66168e93258fSBjoern A. Zeeb } 66178e93258fSBjoern A. Zeeb 66188e93258fSBjoern A. Zeeb if (cx->state_map == BTC_WLINKING) { 66198e93258fSBjoern A. Zeeb if (mode == BTC_WLINK_NOLINK || mode == BTC_WLINK_2G_STA || 66208e93258fSBjoern A. Zeeb mode == BTC_WLINK_5G) { 66218e93258fSBjoern A. Zeeb _action_wl_scan(rtwdev); 6622*6d67aabdSBjoern A. Zeeb bt->scan_rx_low_pri = false; 66238e93258fSBjoern A. Zeeb goto exit; 66248e93258fSBjoern A. Zeeb } 66258e93258fSBjoern A. Zeeb } 66268e93258fSBjoern A. Zeeb 66278e93258fSBjoern A. Zeeb if (wl->status.map.scan) { 66288e93258fSBjoern A. Zeeb _action_wl_scan(rtwdev); 6629*6d67aabdSBjoern A. Zeeb bt->scan_rx_low_pri = false; 66308e93258fSBjoern A. Zeeb goto exit; 66318e93258fSBjoern A. Zeeb } 66328e93258fSBjoern A. Zeeb 66338e93258fSBjoern A. Zeeb switch (mode) { 66348e93258fSBjoern A. Zeeb case BTC_WLINK_NOLINK: 66358e93258fSBjoern A. Zeeb _action_wl_nc(rtwdev); 66368e93258fSBjoern A. Zeeb break; 66378e93258fSBjoern A. Zeeb case BTC_WLINK_2G_STA: 6638e2340276SBjoern A. Zeeb if (wl->status.map.traffic_dir & BIT(RTW89_TFC_DL)) 6639e2340276SBjoern A. Zeeb bt->scan_rx_low_pri = true; 66408e93258fSBjoern A. Zeeb _action_wl_2g_sta(rtwdev); 66418e93258fSBjoern A. Zeeb break; 66428e93258fSBjoern A. Zeeb case BTC_WLINK_2G_AP: 6643e2340276SBjoern A. Zeeb bt->scan_rx_low_pri = true; 66448e93258fSBjoern A. Zeeb _action_wl_2g_ap(rtwdev); 66458e93258fSBjoern A. Zeeb break; 66468e93258fSBjoern A. Zeeb case BTC_WLINK_2G_GO: 6647e2340276SBjoern A. Zeeb bt->scan_rx_low_pri = true; 66488e93258fSBjoern A. Zeeb _action_wl_2g_go(rtwdev); 66498e93258fSBjoern A. Zeeb break; 66508e93258fSBjoern A. Zeeb case BTC_WLINK_2G_GC: 6651e2340276SBjoern A. Zeeb bt->scan_rx_low_pri = true; 66528e93258fSBjoern A. Zeeb _action_wl_2g_gc(rtwdev); 66538e93258fSBjoern A. Zeeb break; 66548e93258fSBjoern A. Zeeb case BTC_WLINK_2G_SCC: 6655e2340276SBjoern A. Zeeb bt->scan_rx_low_pri = true; 6656e2340276SBjoern A. Zeeb if (ver->fwlrole == 0) 66578e93258fSBjoern A. Zeeb _action_wl_2g_scc(rtwdev); 6658e2340276SBjoern A. Zeeb else if (ver->fwlrole == 1) 66598e93258fSBjoern A. Zeeb _action_wl_2g_scc_v1(rtwdev); 6660e2340276SBjoern A. Zeeb else if (ver->fwlrole == 2) 6661e2340276SBjoern A. Zeeb _action_wl_2g_scc_v2(rtwdev); 6662*6d67aabdSBjoern A. Zeeb else if (ver->fwlrole == 8) 6663*6d67aabdSBjoern A. Zeeb _action_wl_2g_scc_v8(rtwdev); 66648e93258fSBjoern A. Zeeb break; 66658e93258fSBjoern A. Zeeb case BTC_WLINK_2G_MCC: 6666e2340276SBjoern A. Zeeb bt->scan_rx_low_pri = true; 66678e93258fSBjoern A. Zeeb _action_wl_2g_mcc(rtwdev); 66688e93258fSBjoern A. Zeeb break; 66698e93258fSBjoern A. Zeeb case BTC_WLINK_25G_MCC: 6670e2340276SBjoern A. Zeeb bt->scan_rx_low_pri = true; 66718e93258fSBjoern A. Zeeb _action_wl_25g_mcc(rtwdev); 66728e93258fSBjoern A. Zeeb break; 66738e93258fSBjoern A. Zeeb case BTC_WLINK_5G: 66748e93258fSBjoern A. Zeeb _action_wl_5g(rtwdev); 66758e93258fSBjoern A. Zeeb break; 66768e93258fSBjoern A. Zeeb case BTC_WLINK_2G_NAN: 66778e93258fSBjoern A. Zeeb _action_wl_2g_nan(rtwdev); 66788e93258fSBjoern A. Zeeb break; 66798e93258fSBjoern A. Zeeb default: 66808e93258fSBjoern A. Zeeb _action_wl_other(rtwdev); 66818e93258fSBjoern A. Zeeb break; 66828e93258fSBjoern A. Zeeb } 66838e93258fSBjoern A. Zeeb 66848e93258fSBjoern A. Zeeb exit: 66858e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): exit\n", __func__); 6686*6d67aabdSBjoern A. Zeeb if (ver->fcxctrl == 7) 6687*6d67aabdSBjoern A. Zeeb btc->ctrl.ctrl_v7.igno_bt = igno_bt; 6688*6d67aabdSBjoern A. Zeeb else 6689*6d67aabdSBjoern A. Zeeb btc->ctrl.ctrl.igno_bt = igno_bt; 66908e93258fSBjoern A. Zeeb _action_common(rtwdev); 66918e93258fSBjoern A. Zeeb } 66928e93258fSBjoern A. Zeeb 66938e93258fSBjoern A. Zeeb void rtw89_btc_ntfy_poweron(struct rtw89_dev *rtwdev) 66948e93258fSBjoern A. Zeeb { 66958e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 66968e93258fSBjoern A. Zeeb 66978e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): !!\n", __func__); 66988e93258fSBjoern A. Zeeb btc->dm.cnt_notify[BTC_NCNT_POWER_ON]++; 66998e93258fSBjoern A. Zeeb } 67008e93258fSBjoern A. Zeeb 67018e93258fSBjoern A. Zeeb void rtw89_btc_ntfy_poweroff(struct rtw89_dev *rtwdev) 67028e93258fSBjoern A. Zeeb { 67038e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 67048e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 67058e93258fSBjoern A. Zeeb 67068e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): !!\n", __func__); 67078e93258fSBjoern A. Zeeb btc->dm.cnt_notify[BTC_NCNT_POWER_OFF]++; 67088e93258fSBjoern A. Zeeb 67098e93258fSBjoern A. Zeeb btc->cx.wl.status.map.rf_off = 1; 67108e93258fSBjoern A. Zeeb btc->cx.wl.status.map.busy = 0; 67118e93258fSBjoern A. Zeeb wl->status.map.lps = BTC_LPS_OFF; 67128e93258fSBjoern A. Zeeb 67138e93258fSBjoern A. Zeeb _write_scbd(rtwdev, BTC_WSCB_ALL, false); 67148e93258fSBjoern A. Zeeb _run_coex(rtwdev, BTC_RSN_NTFY_POWEROFF); 67158e93258fSBjoern A. Zeeb 67168e93258fSBjoern A. Zeeb rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_ALL, 0); 67178e93258fSBjoern A. Zeeb 67188e93258fSBjoern A. Zeeb btc->cx.wl.status.map.rf_off_pre = btc->cx.wl.status.map.rf_off; 67198e93258fSBjoern A. Zeeb } 67208e93258fSBjoern A. Zeeb 67218e93258fSBjoern A. Zeeb static void _set_init_info(struct rtw89_dev *rtwdev) 67228e93258fSBjoern A. Zeeb { 67238e93258fSBjoern A. Zeeb const struct rtw89_chip_info *chip = rtwdev->chip; 67248e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 6725*6d67aabdSBjoern A. Zeeb const struct rtw89_btc_ver *ver = btc->ver; 67268e93258fSBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 67278e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 67288e93258fSBjoern A. Zeeb 6729*6d67aabdSBjoern A. Zeeb if (ver->fcxinit == 7) { 6730*6d67aabdSBjoern A. Zeeb dm->init_info.init_v7.wl_only = (u8)dm->wl_only; 6731*6d67aabdSBjoern A. Zeeb dm->init_info.init_v7.bt_only = (u8)dm->bt_only; 6732*6d67aabdSBjoern A. Zeeb dm->init_info.init_v7.wl_init_ok = (u8)wl->status.map.init_ok; 6733*6d67aabdSBjoern A. Zeeb dm->init_info.init_v7.cx_other = btc->cx.other.type; 6734*6d67aabdSBjoern A. Zeeb dm->init_info.init_v7.wl_guard_ch = chip->afh_guard_ch; 6735*6d67aabdSBjoern A. Zeeb dm->init_info.init_v7.module = btc->mdinfo.md_v7; 6736*6d67aabdSBjoern A. Zeeb } else { 6737*6d67aabdSBjoern A. Zeeb dm->init_info.init.wl_only = (u8)dm->wl_only; 6738*6d67aabdSBjoern A. Zeeb dm->init_info.init.bt_only = (u8)dm->bt_only; 6739*6d67aabdSBjoern A. Zeeb dm->init_info.init.wl_init_ok = (u8)wl->status.map.init_ok; 6740*6d67aabdSBjoern A. Zeeb dm->init_info.init.dbcc_en = rtwdev->dbcc_en; 6741*6d67aabdSBjoern A. Zeeb dm->init_info.init.cx_other = btc->cx.other.type; 6742*6d67aabdSBjoern A. Zeeb dm->init_info.init.wl_guard_ch = chip->afh_guard_ch; 6743*6d67aabdSBjoern A. Zeeb dm->init_info.init.module = btc->mdinfo.md; 6744*6d67aabdSBjoern A. Zeeb } 67458e93258fSBjoern A. Zeeb } 67468e93258fSBjoern A. Zeeb 67478e93258fSBjoern A. Zeeb void rtw89_btc_ntfy_init(struct rtw89_dev *rtwdev, u8 mode) 67488e93258fSBjoern A. Zeeb { 67498e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 67508e93258fSBjoern A. Zeeb struct rtw89_btc_dm *dm = &rtwdev->btc.dm; 67518e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 67528e93258fSBjoern A. Zeeb const struct rtw89_chip_info *chip = rtwdev->chip; 6753*6d67aabdSBjoern A. Zeeb const struct rtw89_btc_ver *ver = btc->ver; 67548e93258fSBjoern A. Zeeb 67558e93258fSBjoern A. Zeeb _reset_btc_var(rtwdev, BTC_RESET_ALL); 67568e93258fSBjoern A. Zeeb btc->dm.run_reason = BTC_RSN_NONE; 67578e93258fSBjoern A. Zeeb btc->dm.run_action = BTC_ACT_NONE; 6758*6d67aabdSBjoern A. Zeeb if (ver->fcxctrl == 7) 6759*6d67aabdSBjoern A. Zeeb btc->ctrl.ctrl_v7.igno_bt = true; 6760*6d67aabdSBjoern A. Zeeb else 6761*6d67aabdSBjoern A. Zeeb btc->ctrl.ctrl.igno_bt = true; 67628e93258fSBjoern A. Zeeb 67638e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 67648e93258fSBjoern A. Zeeb "[BTC], %s(): mode=%d\n", __func__, mode); 67658e93258fSBjoern A. Zeeb 6766*6d67aabdSBjoern A. Zeeb wl->coex_mode = mode; 67678e93258fSBjoern A. Zeeb dm->cnt_notify[BTC_NCNT_INIT_COEX]++; 67688e93258fSBjoern A. Zeeb dm->wl_only = mode == BTC_MODE_WL ? 1 : 0; 67698e93258fSBjoern A. Zeeb dm->bt_only = mode == BTC_MODE_BT ? 1 : 0; 67708e93258fSBjoern A. Zeeb wl->status.map.rf_off = mode == BTC_MODE_WLOFF ? 1 : 0; 67718e93258fSBjoern A. Zeeb 67728e93258fSBjoern A. Zeeb chip->ops->btc_set_rfe(rtwdev); 67738e93258fSBjoern A. Zeeb chip->ops->btc_init_cfg(rtwdev); 67748e93258fSBjoern A. Zeeb 67758e93258fSBjoern A. Zeeb if (!wl->status.map.init_ok) { 67768e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 67778e93258fSBjoern A. Zeeb "[BTC], %s(): return for WL init fail!!\n", 67788e93258fSBjoern A. Zeeb __func__); 67798e93258fSBjoern A. Zeeb dm->error.map.init = true; 67808e93258fSBjoern A. Zeeb return; 67818e93258fSBjoern A. Zeeb } 67828e93258fSBjoern A. Zeeb 67838e93258fSBjoern A. Zeeb _write_scbd(rtwdev, 67848e93258fSBjoern A. Zeeb BTC_WSCB_ACTIVE | BTC_WSCB_ON | BTC_WSCB_BTLOG, true); 67858e93258fSBjoern A. Zeeb _update_bt_scbd(rtwdev, true); 67868e93258fSBjoern A. Zeeb if (rtw89_mac_get_ctrl_path(rtwdev)) { 67878e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 67888e93258fSBjoern A. Zeeb "[BTC], %s(): PTA owner warning!!\n", 67898e93258fSBjoern A. Zeeb __func__); 67908e93258fSBjoern A. Zeeb dm->error.map.pta_owner = true; 67918e93258fSBjoern A. Zeeb } 67928e93258fSBjoern A. Zeeb 67938e93258fSBjoern A. Zeeb _set_init_info(rtwdev); 67948e93258fSBjoern A. Zeeb _set_wl_tx_power(rtwdev, RTW89_BTC_WL_DEF_TX_PWR); 67958e93258fSBjoern A. Zeeb btc_fw_set_monreg(rtwdev); 6796*6d67aabdSBjoern A. Zeeb rtw89_btc_fw_set_slots(rtwdev); 67978e93258fSBjoern A. Zeeb _fw_set_drv_info(rtwdev, CXDRVINFO_INIT); 67988e93258fSBjoern A. Zeeb _fw_set_drv_info(rtwdev, CXDRVINFO_CTRL); 67998e93258fSBjoern A. Zeeb 68008e93258fSBjoern A. Zeeb _run_coex(rtwdev, BTC_RSN_NTFY_INIT); 68018e93258fSBjoern A. Zeeb } 68028e93258fSBjoern A. Zeeb 68038e93258fSBjoern A. Zeeb void rtw89_btc_ntfy_scan_start(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band) 68048e93258fSBjoern A. Zeeb { 68058e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 68068e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 68078e93258fSBjoern A. Zeeb 68088e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 68098e93258fSBjoern A. Zeeb "[BTC], %s(): phy_idx=%d, band=%d\n", 68108e93258fSBjoern A. Zeeb __func__, phy_idx, band); 6811*6d67aabdSBjoern A. Zeeb 6812*6d67aabdSBjoern A. Zeeb if (phy_idx >= RTW89_PHY_MAX) 6813*6d67aabdSBjoern A. Zeeb return; 6814*6d67aabdSBjoern A. Zeeb 68158e93258fSBjoern A. Zeeb btc->dm.cnt_notify[BTC_NCNT_SCAN_START]++; 68168e93258fSBjoern A. Zeeb wl->status.map.scan = true; 68178e93258fSBjoern A. Zeeb wl->scan_info.band[phy_idx] = band; 68188e93258fSBjoern A. Zeeb wl->scan_info.phy_map |= BIT(phy_idx); 68198e93258fSBjoern A. Zeeb _fw_set_drv_info(rtwdev, CXDRVINFO_SCAN); 68208e93258fSBjoern A. Zeeb 68218e93258fSBjoern A. Zeeb if (rtwdev->dbcc_en) { 68228e93258fSBjoern A. Zeeb wl->dbcc_info.scan_band[phy_idx] = band; 68238e93258fSBjoern A. Zeeb _update_dbcc_band(rtwdev, phy_idx); 68248e93258fSBjoern A. Zeeb _fw_set_drv_info(rtwdev, CXDRVINFO_DBCC); 68258e93258fSBjoern A. Zeeb } 68268e93258fSBjoern A. Zeeb 68278e93258fSBjoern A. Zeeb _run_coex(rtwdev, BTC_RSN_NTFY_SCAN_START); 68288e93258fSBjoern A. Zeeb } 68298e93258fSBjoern A. Zeeb 68308e93258fSBjoern A. Zeeb void rtw89_btc_ntfy_scan_finish(struct rtw89_dev *rtwdev, u8 phy_idx) 68318e93258fSBjoern A. Zeeb { 68328e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 68338e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 68348e93258fSBjoern A. Zeeb 68358e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 68368e93258fSBjoern A. Zeeb "[BTC], %s(): phy_idx=%d\n", __func__, phy_idx); 68378e93258fSBjoern A. Zeeb btc->dm.cnt_notify[BTC_NCNT_SCAN_FINISH]++; 68388e93258fSBjoern A. Zeeb 68398e93258fSBjoern A. Zeeb wl->status.map.scan = false; 68408e93258fSBjoern A. Zeeb wl->scan_info.phy_map &= ~BIT(phy_idx); 68418e93258fSBjoern A. Zeeb _fw_set_drv_info(rtwdev, CXDRVINFO_SCAN); 68428e93258fSBjoern A. Zeeb 68438e93258fSBjoern A. Zeeb if (rtwdev->dbcc_en) { 68448e93258fSBjoern A. Zeeb _update_dbcc_band(rtwdev, phy_idx); 68458e93258fSBjoern A. Zeeb _fw_set_drv_info(rtwdev, CXDRVINFO_DBCC); 68468e93258fSBjoern A. Zeeb } 68478e93258fSBjoern A. Zeeb 68488e93258fSBjoern A. Zeeb _run_coex(rtwdev, BTC_RSN_NTFY_SCAN_FINISH); 68498e93258fSBjoern A. Zeeb } 68508e93258fSBjoern A. Zeeb 68518e93258fSBjoern A. Zeeb void rtw89_btc_ntfy_switch_band(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band) 68528e93258fSBjoern A. Zeeb { 68538e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 68548e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 68558e93258fSBjoern A. Zeeb 68568e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 68578e93258fSBjoern A. Zeeb "[BTC], %s(): phy_idx=%d, band=%d\n", 68588e93258fSBjoern A. Zeeb __func__, phy_idx, band); 6859*6d67aabdSBjoern A. Zeeb 6860*6d67aabdSBjoern A. Zeeb if (phy_idx >= RTW89_PHY_MAX) 6861*6d67aabdSBjoern A. Zeeb return; 6862*6d67aabdSBjoern A. Zeeb 68638e93258fSBjoern A. Zeeb btc->dm.cnt_notify[BTC_NCNT_SWITCH_BAND]++; 68648e93258fSBjoern A. Zeeb 68658e93258fSBjoern A. Zeeb wl->scan_info.band[phy_idx] = band; 68668e93258fSBjoern A. Zeeb wl->scan_info.phy_map |= BIT(phy_idx); 68678e93258fSBjoern A. Zeeb _fw_set_drv_info(rtwdev, CXDRVINFO_SCAN); 68688e93258fSBjoern A. Zeeb 68698e93258fSBjoern A. Zeeb if (rtwdev->dbcc_en) { 68708e93258fSBjoern A. Zeeb wl->dbcc_info.scan_band[phy_idx] = band; 68718e93258fSBjoern A. Zeeb _update_dbcc_band(rtwdev, phy_idx); 68728e93258fSBjoern A. Zeeb _fw_set_drv_info(rtwdev, CXDRVINFO_DBCC); 68738e93258fSBjoern A. Zeeb } 68748e93258fSBjoern A. Zeeb _run_coex(rtwdev, BTC_RSN_NTFY_SWBAND); 68758e93258fSBjoern A. Zeeb } 68768e93258fSBjoern A. Zeeb 68778e93258fSBjoern A. Zeeb void rtw89_btc_ntfy_specific_packet(struct rtw89_dev *rtwdev, 68788e93258fSBjoern A. Zeeb enum btc_pkt_type pkt_type) 68798e93258fSBjoern A. Zeeb { 68808e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 68818e93258fSBjoern A. Zeeb struct rtw89_btc_cx *cx = &btc->cx; 68828e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &cx->wl; 68838e93258fSBjoern A. Zeeb struct rtw89_btc_bt_link_info *b = &cx->bt.link_info; 68848e93258fSBjoern A. Zeeb struct rtw89_btc_bt_hfp_desc *hfp = &b->hfp_desc; 68858e93258fSBjoern A. Zeeb struct rtw89_btc_bt_hid_desc *hid = &b->hid_desc; 68868e93258fSBjoern A. Zeeb u32 cnt; 68878e93258fSBjoern A. Zeeb u32 delay = RTW89_COEX_ACT1_WORK_PERIOD; 68888e93258fSBjoern A. Zeeb bool delay_work = false; 68898e93258fSBjoern A. Zeeb 68908e93258fSBjoern A. Zeeb switch (pkt_type) { 68918e93258fSBjoern A. Zeeb case PACKET_DHCP: 68928e93258fSBjoern A. Zeeb cnt = ++cx->cnt_wl[BTC_WCNT_DHCP]; 68938e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 68948e93258fSBjoern A. Zeeb "[BTC], %s(): DHCP cnt=%d\n", __func__, cnt); 68958e93258fSBjoern A. Zeeb wl->status.map.connecting = true; 68968e93258fSBjoern A. Zeeb delay_work = true; 68978e93258fSBjoern A. Zeeb break; 68988e93258fSBjoern A. Zeeb case PACKET_EAPOL: 68998e93258fSBjoern A. Zeeb cnt = ++cx->cnt_wl[BTC_WCNT_EAPOL]; 69008e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 69018e93258fSBjoern A. Zeeb "[BTC], %s(): EAPOL cnt=%d\n", __func__, cnt); 69028e93258fSBjoern A. Zeeb wl->status.map._4way = true; 69038e93258fSBjoern A. Zeeb delay_work = true; 69048e93258fSBjoern A. Zeeb if (hfp->exist || hid->exist) 69058e93258fSBjoern A. Zeeb delay /= 2; 69068e93258fSBjoern A. Zeeb break; 69078e93258fSBjoern A. Zeeb case PACKET_EAPOL_END: 69088e93258fSBjoern A. Zeeb cnt = ++cx->cnt_wl[BTC_WCNT_EAPOL]; 69098e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 69108e93258fSBjoern A. Zeeb "[BTC], %s(): EAPOL_End cnt=%d\n", 69118e93258fSBjoern A. Zeeb __func__, cnt); 69128e93258fSBjoern A. Zeeb wl->status.map._4way = false; 69138e93258fSBjoern A. Zeeb cancel_delayed_work(&rtwdev->coex_act1_work); 69148e93258fSBjoern A. Zeeb break; 69158e93258fSBjoern A. Zeeb case PACKET_ARP: 69168e93258fSBjoern A. Zeeb cnt = ++cx->cnt_wl[BTC_WCNT_ARP]; 69178e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 69188e93258fSBjoern A. Zeeb "[BTC], %s(): ARP cnt=%d\n", __func__, cnt); 69198e93258fSBjoern A. Zeeb return; 69208e93258fSBjoern A. Zeeb case PACKET_ICMP: 69218e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 69228e93258fSBjoern A. Zeeb "[BTC], %s(): ICMP pkt\n", __func__); 69238e93258fSBjoern A. Zeeb return; 69248e93258fSBjoern A. Zeeb default: 69258e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 69268e93258fSBjoern A. Zeeb "[BTC], %s(): unknown packet type %d\n", 69278e93258fSBjoern A. Zeeb __func__, pkt_type); 69288e93258fSBjoern A. Zeeb return; 69298e93258fSBjoern A. Zeeb } 69308e93258fSBjoern A. Zeeb 69318e93258fSBjoern A. Zeeb if (delay_work) { 69328e93258fSBjoern A. Zeeb cancel_delayed_work(&rtwdev->coex_act1_work); 69338e93258fSBjoern A. Zeeb ieee80211_queue_delayed_work(rtwdev->hw, 69348e93258fSBjoern A. Zeeb &rtwdev->coex_act1_work, delay); 69358e93258fSBjoern A. Zeeb } 69368e93258fSBjoern A. Zeeb 69378e93258fSBjoern A. Zeeb btc->dm.cnt_notify[BTC_NCNT_SPECIAL_PACKET]++; 69388e93258fSBjoern A. Zeeb _run_coex(rtwdev, BTC_RSN_NTFY_SPECIFIC_PACKET); 69398e93258fSBjoern A. Zeeb } 69408e93258fSBjoern A. Zeeb 69418e93258fSBjoern A. Zeeb void rtw89_btc_ntfy_eapol_packet_work(struct work_struct *work) 69428e93258fSBjoern A. Zeeb { 69438e93258fSBjoern A. Zeeb struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, 69448e93258fSBjoern A. Zeeb btc.eapol_notify_work); 69458e93258fSBjoern A. Zeeb 69468e93258fSBjoern A. Zeeb mutex_lock(&rtwdev->mutex); 69478e93258fSBjoern A. Zeeb rtw89_leave_ps_mode(rtwdev); 69488e93258fSBjoern A. Zeeb rtw89_btc_ntfy_specific_packet(rtwdev, PACKET_EAPOL); 69498e93258fSBjoern A. Zeeb mutex_unlock(&rtwdev->mutex); 69508e93258fSBjoern A. Zeeb } 69518e93258fSBjoern A. Zeeb 69528e93258fSBjoern A. Zeeb void rtw89_btc_ntfy_arp_packet_work(struct work_struct *work) 69538e93258fSBjoern A. Zeeb { 69548e93258fSBjoern A. Zeeb struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, 69558e93258fSBjoern A. Zeeb btc.arp_notify_work); 69568e93258fSBjoern A. Zeeb 69578e93258fSBjoern A. Zeeb mutex_lock(&rtwdev->mutex); 69588e93258fSBjoern A. Zeeb rtw89_btc_ntfy_specific_packet(rtwdev, PACKET_ARP); 69598e93258fSBjoern A. Zeeb mutex_unlock(&rtwdev->mutex); 69608e93258fSBjoern A. Zeeb } 69618e93258fSBjoern A. Zeeb 69628e93258fSBjoern A. Zeeb void rtw89_btc_ntfy_dhcp_packet_work(struct work_struct *work) 69638e93258fSBjoern A. Zeeb { 69648e93258fSBjoern A. Zeeb struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, 69658e93258fSBjoern A. Zeeb btc.dhcp_notify_work); 69668e93258fSBjoern A. Zeeb 69678e93258fSBjoern A. Zeeb mutex_lock(&rtwdev->mutex); 69688e93258fSBjoern A. Zeeb rtw89_leave_ps_mode(rtwdev); 69698e93258fSBjoern A. Zeeb rtw89_btc_ntfy_specific_packet(rtwdev, PACKET_DHCP); 69708e93258fSBjoern A. Zeeb mutex_unlock(&rtwdev->mutex); 69718e93258fSBjoern A. Zeeb } 69728e93258fSBjoern A. Zeeb 69738e93258fSBjoern A. Zeeb void rtw89_btc_ntfy_icmp_packet_work(struct work_struct *work) 69748e93258fSBjoern A. Zeeb { 69758e93258fSBjoern A. Zeeb struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, 69768e93258fSBjoern A. Zeeb btc.icmp_notify_work); 69778e93258fSBjoern A. Zeeb 69788e93258fSBjoern A. Zeeb mutex_lock(&rtwdev->mutex); 69798e93258fSBjoern A. Zeeb rtw89_leave_ps_mode(rtwdev); 69808e93258fSBjoern A. Zeeb rtw89_btc_ntfy_specific_packet(rtwdev, PACKET_ICMP); 69818e93258fSBjoern A. Zeeb mutex_unlock(&rtwdev->mutex); 69828e93258fSBjoern A. Zeeb } 69838e93258fSBjoern A. Zeeb 6984*6d67aabdSBjoern A. Zeeb static u8 _update_bt_rssi_level(struct rtw89_dev *rtwdev, u8 rssi) 6985*6d67aabdSBjoern A. Zeeb { 6986*6d67aabdSBjoern A. Zeeb const struct rtw89_chip_info *chip = rtwdev->chip; 6987*6d67aabdSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 6988*6d67aabdSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &btc->cx.bt; 6989*6d67aabdSBjoern A. Zeeb u8 *rssi_st, rssi_th, rssi_level = 0; 6990*6d67aabdSBjoern A. Zeeb u8 i; 6991*6d67aabdSBjoern A. Zeeb 6992*6d67aabdSBjoern A. Zeeb /* for rssi locate in which {40, 36, 31, 28} 6993*6d67aabdSBjoern A. Zeeb * if rssi >= 40% (-60dBm) --> rssi_level = 4 6994*6d67aabdSBjoern A. Zeeb * if 36% <= rssi < 40% --> rssi_level = 3 6995*6d67aabdSBjoern A. Zeeb * if 31% <= rssi < 36% --> rssi_level = 2 6996*6d67aabdSBjoern A. Zeeb * if 28% <= rssi < 31% --> rssi_level = 1 6997*6d67aabdSBjoern A. Zeeb * if rssi < 28% --> rssi_level = 0 6998*6d67aabdSBjoern A. Zeeb */ 6999*6d67aabdSBjoern A. Zeeb 7000*6d67aabdSBjoern A. Zeeb /* check if rssi across bt_rssi_thres boundary */ 7001*6d67aabdSBjoern A. Zeeb for (i = 0; i < BTC_BT_RSSI_THMAX; i++) { 7002*6d67aabdSBjoern A. Zeeb rssi_th = chip->bt_rssi_thres[i]; 7003*6d67aabdSBjoern A. Zeeb rssi_st = &bt->link_info.rssi_state[i]; 7004*6d67aabdSBjoern A. Zeeb 7005*6d67aabdSBjoern A. Zeeb *rssi_st = _update_rssi_state(rtwdev, *rssi_st, rssi, rssi_th); 7006*6d67aabdSBjoern A. Zeeb 7007*6d67aabdSBjoern A. Zeeb if (BTC_RSSI_HIGH(*rssi_st)) { 7008*6d67aabdSBjoern A. Zeeb rssi_level = BTC_BT_RSSI_THMAX - i; 7009*6d67aabdSBjoern A. Zeeb break; 7010*6d67aabdSBjoern A. Zeeb } 7011*6d67aabdSBjoern A. Zeeb } 7012*6d67aabdSBjoern A. Zeeb return rssi_level; 7013*6d67aabdSBjoern A. Zeeb } 7014*6d67aabdSBjoern A. Zeeb 7015*6d67aabdSBjoern A. Zeeb static void _update_zb_coex_tbl(struct rtw89_dev *rtwdev) 7016*6d67aabdSBjoern A. Zeeb { 7017*6d67aabdSBjoern A. Zeeb u8 mode = rtwdev->btc.cx.wl.role_info.link_mode; 7018*6d67aabdSBjoern A. Zeeb u32 zb_tbl0 = 0xda5a5a5a, zb_tbl1 = 0xda5a5a5a; 7019*6d67aabdSBjoern A. Zeeb 7020*6d67aabdSBjoern A. Zeeb if (mode == BTC_WLINK_5G || rtwdev->btc.dm.freerun) { 7021*6d67aabdSBjoern A. Zeeb zb_tbl0 = 0xffffffff; 7022*6d67aabdSBjoern A. Zeeb zb_tbl1 = 0xffffffff; 7023*6d67aabdSBjoern A. Zeeb } else if (mode == BTC_WLINK_25G_MCC) { 7024*6d67aabdSBjoern A. Zeeb zb_tbl0 = 0xffffffff; /* for E5G slot */ 7025*6d67aabdSBjoern A. Zeeb zb_tbl1 = 0xda5a5a5a; /* for E2G slot */ 7026*6d67aabdSBjoern A. Zeeb } 7027*6d67aabdSBjoern A. Zeeb rtw89_write32(rtwdev, R_BTC_ZB_COEX_TBL_0, zb_tbl0); 7028*6d67aabdSBjoern A. Zeeb rtw89_write32(rtwdev, R_BTC_ZB_COEX_TBL_1, zb_tbl1); 7029*6d67aabdSBjoern A. Zeeb } 7030*6d67aabdSBjoern A. Zeeb 7031e2340276SBjoern A. Zeeb #define BT_PROFILE_PROTOCOL_MASK GENMASK(7, 4) 7032e2340276SBjoern A. Zeeb 70338e93258fSBjoern A. Zeeb static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len) 70348e93258fSBjoern A. Zeeb { 70358e93258fSBjoern A. Zeeb const struct rtw89_chip_info *chip = rtwdev->chip; 70368e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 70378e93258fSBjoern A. Zeeb struct rtw89_btc_cx *cx = &btc->cx; 70388e93258fSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &cx->bt; 70398e93258fSBjoern A. Zeeb struct rtw89_btc_bt_link_info *b = &bt->link_info; 70408e93258fSBjoern A. Zeeb struct rtw89_btc_bt_hfp_desc *hfp = &b->hfp_desc; 70418e93258fSBjoern A. Zeeb struct rtw89_btc_bt_hid_desc *hid = &b->hid_desc; 70428e93258fSBjoern A. Zeeb struct rtw89_btc_bt_a2dp_desc *a2dp = &b->a2dp_desc; 70438e93258fSBjoern A. Zeeb struct rtw89_btc_bt_pan_desc *pan = &b->pan_desc; 70448e93258fSBjoern A. Zeeb union btc_btinfo btinfo; 70458e93258fSBjoern A. Zeeb 70468e93258fSBjoern A. Zeeb if (buf[BTC_BTINFO_L1] != 6) 70478e93258fSBjoern A. Zeeb return; 70488e93258fSBjoern A. Zeeb 70498e93258fSBjoern A. Zeeb if (!memcmp(bt->raw_info, buf, BTC_BTINFO_MAX)) { 70508e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 70518e93258fSBjoern A. Zeeb "[BTC], %s(): return by bt-info duplicate!!\n", 70528e93258fSBjoern A. Zeeb __func__); 70538e93258fSBjoern A. Zeeb cx->cnt_bt[BTC_BCNT_INFOSAME]++; 70548e93258fSBjoern A. Zeeb return; 70558e93258fSBjoern A. Zeeb } 70568e93258fSBjoern A. Zeeb 70578e93258fSBjoern A. Zeeb memcpy(bt->raw_info, buf, BTC_BTINFO_MAX); 70588e93258fSBjoern A. Zeeb 70598e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 70608e93258fSBjoern A. Zeeb "[BTC], %s(): bt_info[2]=0x%02x\n", 70618e93258fSBjoern A. Zeeb __func__, bt->raw_info[2]); 70628e93258fSBjoern A. Zeeb 70638e93258fSBjoern A. Zeeb /* reset to mo-connect before update */ 70648e93258fSBjoern A. Zeeb b->status.val = BTC_BLINK_NOCONNECT; 70658e93258fSBjoern A. Zeeb b->profile_cnt.last = b->profile_cnt.now; 70668e93258fSBjoern A. Zeeb b->relink.last = b->relink.now; 70678e93258fSBjoern A. Zeeb a2dp->exist_last = a2dp->exist; 70688e93258fSBjoern A. Zeeb b->multi_link.last = b->multi_link.now; 70698e93258fSBjoern A. Zeeb bt->inq_pag.last = bt->inq_pag.now; 70708e93258fSBjoern A. Zeeb b->profile_cnt.now = 0; 70718e93258fSBjoern A. Zeeb hid->type = 0; 70728e93258fSBjoern A. Zeeb 70738e93258fSBjoern A. Zeeb /* parse raw info low-Byte2 */ 70748e93258fSBjoern A. Zeeb btinfo.val = bt->raw_info[BTC_BTINFO_L2]; 70758e93258fSBjoern A. Zeeb b->status.map.connect = btinfo.lb2.connect; 70768e93258fSBjoern A. Zeeb b->status.map.sco_busy = btinfo.lb2.sco_busy; 70778e93258fSBjoern A. Zeeb b->status.map.acl_busy = btinfo.lb2.acl_busy; 70788e93258fSBjoern A. Zeeb b->status.map.inq_pag = btinfo.lb2.inq_pag; 70798e93258fSBjoern A. Zeeb bt->inq_pag.now = btinfo.lb2.inq_pag; 70808e93258fSBjoern A. Zeeb cx->cnt_bt[BTC_BCNT_INQPAG] += !!(bt->inq_pag.now && !bt->inq_pag.last); 70818e93258fSBjoern A. Zeeb 70828e93258fSBjoern A. Zeeb hfp->exist = btinfo.lb2.hfp; 70838e93258fSBjoern A. Zeeb b->profile_cnt.now += (u8)hfp->exist; 70848e93258fSBjoern A. Zeeb hid->exist = btinfo.lb2.hid; 70858e93258fSBjoern A. Zeeb b->profile_cnt.now += (u8)hid->exist; 70868e93258fSBjoern A. Zeeb a2dp->exist = btinfo.lb2.a2dp; 70878e93258fSBjoern A. Zeeb b->profile_cnt.now += (u8)a2dp->exist; 70888e93258fSBjoern A. Zeeb pan->active = btinfo.lb2.pan; 7089e2340276SBjoern A. Zeeb btc->dm.trx_info.bt_profile = u32_get_bits(btinfo.val, BT_PROFILE_PROTOCOL_MASK); 70908e93258fSBjoern A. Zeeb 70918e93258fSBjoern A. Zeeb /* parse raw info low-Byte3 */ 70928e93258fSBjoern A. Zeeb btinfo.val = bt->raw_info[BTC_BTINFO_L3]; 70938e93258fSBjoern A. Zeeb if (btinfo.lb3.retry != 0) 70948e93258fSBjoern A. Zeeb cx->cnt_bt[BTC_BCNT_RETRY]++; 70958e93258fSBjoern A. Zeeb b->cqddr = btinfo.lb3.cqddr; 70968e93258fSBjoern A. Zeeb cx->cnt_bt[BTC_BCNT_INQ] += !!(btinfo.lb3.inq && !bt->inq); 70978e93258fSBjoern A. Zeeb bt->inq = btinfo.lb3.inq; 70988e93258fSBjoern A. Zeeb cx->cnt_bt[BTC_BCNT_PAGE] += !!(btinfo.lb3.pag && !bt->pag); 70998e93258fSBjoern A. Zeeb bt->pag = btinfo.lb3.pag; 71008e93258fSBjoern A. Zeeb 71018e93258fSBjoern A. Zeeb b->status.map.mesh_busy = btinfo.lb3.mesh_busy; 71028e93258fSBjoern A. Zeeb /* parse raw info high-Byte0 */ 71038e93258fSBjoern A. Zeeb btinfo.val = bt->raw_info[BTC_BTINFO_H0]; 71048e93258fSBjoern A. Zeeb /* raw val is dBm unit, translate from -100~ 0dBm to 0~100%*/ 71058e93258fSBjoern A. Zeeb b->rssi = chip->ops->btc_get_bt_rssi(rtwdev, btinfo.hb0.rssi); 7106*6d67aabdSBjoern A. Zeeb bt->rssi_level = _update_bt_rssi_level(rtwdev, b->rssi); 7107*6d67aabdSBjoern A. Zeeb btc->dm.trx_info.bt_rssi = bt->rssi_level; 71088e93258fSBjoern A. Zeeb 71098e93258fSBjoern A. Zeeb /* parse raw info high-Byte1 */ 71108e93258fSBjoern A. Zeeb btinfo.val = bt->raw_info[BTC_BTINFO_H1]; 71118e93258fSBjoern A. Zeeb b->status.map.ble_connect = btinfo.hb1.ble_connect; 71128e93258fSBjoern A. Zeeb if (btinfo.hb1.ble_connect) 71138e93258fSBjoern A. Zeeb hid->type |= (hid->exist ? BTC_HID_BLE : BTC_HID_RCU); 71148e93258fSBjoern A. Zeeb 71158e93258fSBjoern A. Zeeb cx->cnt_bt[BTC_BCNT_REINIT] += !!(btinfo.hb1.reinit && !bt->reinit); 71168e93258fSBjoern A. Zeeb bt->reinit = btinfo.hb1.reinit; 71178e93258fSBjoern A. Zeeb cx->cnt_bt[BTC_BCNT_RELINK] += !!(btinfo.hb1.relink && !b->relink.now); 71188e93258fSBjoern A. Zeeb b->relink.now = btinfo.hb1.relink; 71198e93258fSBjoern A. Zeeb cx->cnt_bt[BTC_BCNT_IGNOWL] += !!(btinfo.hb1.igno_wl && !bt->igno_wl); 71208e93258fSBjoern A. Zeeb bt->igno_wl = btinfo.hb1.igno_wl; 71218e93258fSBjoern A. Zeeb 71228e93258fSBjoern A. Zeeb if (bt->igno_wl && !cx->wl.status.map.rf_off) 71238e93258fSBjoern A. Zeeb _set_bt_ignore_wlan_act(rtwdev, false); 71248e93258fSBjoern A. Zeeb 71258e93258fSBjoern A. Zeeb hid->type |= (btinfo.hb1.voice ? BTC_HID_RCU_VOICE : 0); 71268e93258fSBjoern A. Zeeb bt->ble_scan_en = btinfo.hb1.ble_scan; 71278e93258fSBjoern A. Zeeb 71288e93258fSBjoern A. Zeeb cx->cnt_bt[BTC_BCNT_ROLESW] += !!(btinfo.hb1.role_sw && !b->role_sw); 71298e93258fSBjoern A. Zeeb b->role_sw = btinfo.hb1.role_sw; 71308e93258fSBjoern A. Zeeb 71318e93258fSBjoern A. Zeeb b->multi_link.now = btinfo.hb1.multi_link; 71328e93258fSBjoern A. Zeeb 71338e93258fSBjoern A. Zeeb /* parse raw info high-Byte2 */ 71348e93258fSBjoern A. Zeeb btinfo.val = bt->raw_info[BTC_BTINFO_H2]; 71358e93258fSBjoern A. Zeeb pan->exist = btinfo.hb2.pan_active; 71368e93258fSBjoern A. Zeeb b->profile_cnt.now += (u8)pan->exist; 71378e93258fSBjoern A. Zeeb 71388e93258fSBjoern A. Zeeb cx->cnt_bt[BTC_BCNT_AFH] += !!(btinfo.hb2.afh_update && !b->afh_update); 71398e93258fSBjoern A. Zeeb b->afh_update = btinfo.hb2.afh_update; 71408e93258fSBjoern A. Zeeb a2dp->active = btinfo.hb2.a2dp_active; 71418e93258fSBjoern A. Zeeb b->slave_role = btinfo.hb2.slave; 71428e93258fSBjoern A. Zeeb hid->slot_info = btinfo.hb2.hid_slot; 71438e93258fSBjoern A. Zeeb hid->pair_cnt = btinfo.hb2.hid_cnt; 71448e93258fSBjoern A. Zeeb hid->type |= (hid->slot_info == BTC_HID_218 ? 71458e93258fSBjoern A. Zeeb BTC_HID_218 : BTC_HID_418); 71468e93258fSBjoern A. Zeeb /* parse raw info high-Byte3 */ 71478e93258fSBjoern A. Zeeb btinfo.val = bt->raw_info[BTC_BTINFO_H3]; 71488e93258fSBjoern A. Zeeb a2dp->bitpool = btinfo.hb3.a2dp_bitpool; 71498e93258fSBjoern A. Zeeb 71508e93258fSBjoern A. Zeeb if (b->tx_3m != (u32)btinfo.hb3.tx_3m) 71518e93258fSBjoern A. Zeeb cx->cnt_bt[BTC_BCNT_RATECHG]++; 71528e93258fSBjoern A. Zeeb b->tx_3m = (u32)btinfo.hb3.tx_3m; 71538e93258fSBjoern A. Zeeb 71548e93258fSBjoern A. Zeeb a2dp->sink = btinfo.hb3.a2dp_sink; 71558e93258fSBjoern A. Zeeb 71568e93258fSBjoern A. Zeeb if (!a2dp->exist_last && a2dp->exist) { 71578e93258fSBjoern A. Zeeb a2dp->vendor_id = 0; 71588e93258fSBjoern A. Zeeb a2dp->flush_time = 0; 71598e93258fSBjoern A. Zeeb a2dp->play_latency = 1; 71608e93258fSBjoern A. Zeeb ieee80211_queue_delayed_work(rtwdev->hw, 71618e93258fSBjoern A. Zeeb &rtwdev->coex_bt_devinfo_work, 71628e93258fSBjoern A. Zeeb RTW89_COEX_BT_DEVINFO_WORK_PERIOD); 71638e93258fSBjoern A. Zeeb } 71648e93258fSBjoern A. Zeeb 71658e93258fSBjoern A. Zeeb _run_coex(rtwdev, BTC_RSN_UPDATE_BT_INFO); 71668e93258fSBjoern A. Zeeb } 71678e93258fSBjoern A. Zeeb 71688e93258fSBjoern A. Zeeb void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, 71698e93258fSBjoern A. Zeeb struct rtw89_sta *rtwsta, enum btc_role_state state) 71708e93258fSBjoern A. Zeeb { 7171*6d67aabdSBjoern A. Zeeb const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, 7172*6d67aabdSBjoern A. Zeeb rtwvif->sub_entity_idx); 71738e93258fSBjoern A. Zeeb struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); 71748e93258fSBjoern A. Zeeb struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta); 71758e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 7176e2340276SBjoern A. Zeeb const struct rtw89_btc_ver *ver = btc->ver; 71778e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 71788e93258fSBjoern A. Zeeb struct rtw89_btc_wl_link_info r = {0}; 71798e93258fSBjoern A. Zeeb struct rtw89_btc_wl_link_info *wlinfo = NULL; 7180*6d67aabdSBjoern A. Zeeb u8 mode = 0, rlink_id, link_mode_ori, pta_req_mac_ori, wa_type; 71818e93258fSBjoern A. Zeeb 71828e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], state=%d\n", state); 71838e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 71848e93258fSBjoern A. Zeeb "[BTC], role is STA=%d\n", 71858e93258fSBjoern A. Zeeb vif->type == NL80211_IFTYPE_STATION); 71868e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], port=%d\n", rtwvif->port); 71878e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], band=%d ch=%d bw=%d\n", 71888e93258fSBjoern A. Zeeb chan->band_type, chan->channel, chan->band_width); 71898e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], associated=%d\n", 71908e93258fSBjoern A. Zeeb state == BTC_ROLE_MSTS_STA_CONN_END); 71918e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 71928e93258fSBjoern A. Zeeb "[BTC], bcn_period=%d dtim_period=%d\n", 71938e93258fSBjoern A. Zeeb vif->bss_conf.beacon_int, vif->bss_conf.dtim_period); 71948e93258fSBjoern A. Zeeb 71958e93258fSBjoern A. Zeeb if (rtwsta) { 71968e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], STA mac_id=%d\n", 71978e93258fSBjoern A. Zeeb rtwsta->mac_id); 71988e93258fSBjoern A. Zeeb 71998e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 72008e93258fSBjoern A. Zeeb "[BTC], STA support HE=%d VHT=%d HT=%d\n", 72018e93258fSBjoern A. Zeeb sta->deflink.he_cap.has_he, 72028e93258fSBjoern A. Zeeb sta->deflink.vht_cap.vht_supported, 72038e93258fSBjoern A. Zeeb sta->deflink.ht_cap.ht_supported); 72048e93258fSBjoern A. Zeeb if (sta->deflink.he_cap.has_he) 72058e93258fSBjoern A. Zeeb mode |= BIT(BTC_WL_MODE_HE); 72068e93258fSBjoern A. Zeeb if (sta->deflink.vht_cap.vht_supported) 72078e93258fSBjoern A. Zeeb mode |= BIT(BTC_WL_MODE_VHT); 72088e93258fSBjoern A. Zeeb if (sta->deflink.ht_cap.ht_supported) 72098e93258fSBjoern A. Zeeb mode |= BIT(BTC_WL_MODE_HT); 72108e93258fSBjoern A. Zeeb 72118e93258fSBjoern A. Zeeb r.mode = mode; 72128e93258fSBjoern A. Zeeb } 72138e93258fSBjoern A. Zeeb 72148e93258fSBjoern A. Zeeb if (rtwvif->wifi_role >= RTW89_WIFI_ROLE_MLME_MAX) 72158e93258fSBjoern A. Zeeb return; 72168e93258fSBjoern A. Zeeb 72178e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 72188e93258fSBjoern A. Zeeb "[BTC], wifi_role=%d\n", rtwvif->wifi_role); 72198e93258fSBjoern A. Zeeb 72208e93258fSBjoern A. Zeeb r.role = rtwvif->wifi_role; 72218e93258fSBjoern A. Zeeb r.phy = rtwvif->phy_idx; 72228e93258fSBjoern A. Zeeb r.pid = rtwvif->port; 72238e93258fSBjoern A. Zeeb r.active = true; 72248e93258fSBjoern A. Zeeb r.connected = MLME_LINKED; 72258e93258fSBjoern A. Zeeb r.bcn_period = vif->bss_conf.beacon_int; 72268e93258fSBjoern A. Zeeb r.dtim_period = vif->bss_conf.dtim_period; 72278e93258fSBjoern A. Zeeb r.band = chan->band_type; 72288e93258fSBjoern A. Zeeb r.ch = chan->channel; 72298e93258fSBjoern A. Zeeb r.bw = chan->band_width; 7230*6d67aabdSBjoern A. Zeeb r.chdef.band = chan->band_type; 7231*6d67aabdSBjoern A. Zeeb r.chdef.center_ch = chan->channel; 7232*6d67aabdSBjoern A. Zeeb r.chdef.bw = chan->band_width; 7233*6d67aabdSBjoern A. Zeeb r.chdef.chan = chan->primary_channel; 72348e93258fSBjoern A. Zeeb ether_addr_copy(r.mac_addr, rtwvif->mac_addr); 72358e93258fSBjoern A. Zeeb 72368e93258fSBjoern A. Zeeb if (rtwsta && vif->type == NL80211_IFTYPE_STATION) 72378e93258fSBjoern A. Zeeb r.mac_id = rtwsta->mac_id; 72388e93258fSBjoern A. Zeeb 72398e93258fSBjoern A. Zeeb btc->dm.cnt_notify[BTC_NCNT_ROLE_INFO]++; 72408e93258fSBjoern A. Zeeb 72418e93258fSBjoern A. Zeeb wlinfo = &wl->link_info[r.pid]; 72428e93258fSBjoern A. Zeeb 7243*6d67aabdSBjoern A. Zeeb rlink_id = 0; /* to do */ 7244*6d67aabdSBjoern A. Zeeb if (ver->fwlrole == 0) { 7245*6d67aabdSBjoern A. Zeeb *wlinfo = r; 72468e93258fSBjoern A. Zeeb _update_wl_info(rtwdev); 7247*6d67aabdSBjoern A. Zeeb } else if (ver->fwlrole == 1) { 7248*6d67aabdSBjoern A. Zeeb *wlinfo = r; 72498e93258fSBjoern A. Zeeb _update_wl_info_v1(rtwdev); 7250*6d67aabdSBjoern A. Zeeb } else if (ver->fwlrole == 2) { 7251*6d67aabdSBjoern A. Zeeb *wlinfo = r; 7252e2340276SBjoern A. Zeeb _update_wl_info_v2(rtwdev); 7253*6d67aabdSBjoern A. Zeeb } else if (ver->fwlrole == 8) { 7254*6d67aabdSBjoern A. Zeeb wlinfo = &wl->rlink_info[r.pid][rlink_id]; 7255*6d67aabdSBjoern A. Zeeb *wlinfo = r; 7256*6d67aabdSBjoern A. Zeeb link_mode_ori = wl->role_info_v8.link_mode; 7257*6d67aabdSBjoern A. Zeeb pta_req_mac_ori = wl->pta_req_mac; 7258*6d67aabdSBjoern A. Zeeb _update_wl_info_v8(rtwdev, r.pid, rlink_id, state); 7259*6d67aabdSBjoern A. Zeeb 7260*6d67aabdSBjoern A. Zeeb if (wl->role_info_v8.link_mode != link_mode_ori) { 7261*6d67aabdSBjoern A. Zeeb wl->role_info_v8.link_mode_chg = 1; 7262*6d67aabdSBjoern A. Zeeb if (ver->fcxinit == 7) 7263*6d67aabdSBjoern A. Zeeb wa_type = btc->mdinfo.md_v7.wa_type; 7264*6d67aabdSBjoern A. Zeeb else 7265*6d67aabdSBjoern A. Zeeb wa_type = btc->mdinfo.md.wa_type; 7266*6d67aabdSBjoern A. Zeeb 7267*6d67aabdSBjoern A. Zeeb if (wa_type & BTC_WA_HFP_ZB) 7268*6d67aabdSBjoern A. Zeeb _update_zb_coex_tbl(rtwdev); 7269*6d67aabdSBjoern A. Zeeb } 7270*6d67aabdSBjoern A. Zeeb 7271*6d67aabdSBjoern A. Zeeb if (wl->pta_req_mac != pta_req_mac_ori) 7272*6d67aabdSBjoern A. Zeeb wl->pta_reg_mac_chg = 1; 7273*6d67aabdSBjoern A. Zeeb } 72748e93258fSBjoern A. Zeeb 72758e93258fSBjoern A. Zeeb if (wlinfo->role == RTW89_WIFI_ROLE_STATION && 72768e93258fSBjoern A. Zeeb wlinfo->connected == MLME_NO_LINK) 72778e93258fSBjoern A. Zeeb btc->dm.leak_ap = 0; 72788e93258fSBjoern A. Zeeb 72798e93258fSBjoern A. Zeeb if (state == BTC_ROLE_MSTS_STA_CONN_START) 72808e93258fSBjoern A. Zeeb wl->status.map.connecting = 1; 72818e93258fSBjoern A. Zeeb else 72828e93258fSBjoern A. Zeeb wl->status.map.connecting = 0; 72838e93258fSBjoern A. Zeeb 72848e93258fSBjoern A. Zeeb if (state == BTC_ROLE_MSTS_STA_DIS_CONN) 72858e93258fSBjoern A. Zeeb wl->status.map._4way = false; 72868e93258fSBjoern A. Zeeb 72878e93258fSBjoern A. Zeeb _run_coex(rtwdev, BTC_RSN_NTFY_ROLE_INFO); 72888e93258fSBjoern A. Zeeb } 72898e93258fSBjoern A. Zeeb 72908e93258fSBjoern A. Zeeb void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_state) 72918e93258fSBjoern A. Zeeb { 72928e93258fSBjoern A. Zeeb const struct rtw89_chip_info *chip = rtwdev->chip; 72938e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 72948e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 72958e93258fSBjoern A. Zeeb u32 val; 72968e93258fSBjoern A. Zeeb 72978e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): rf_state = %d\n", 72988e93258fSBjoern A. Zeeb __func__, rf_state); 72998e93258fSBjoern A. Zeeb btc->dm.cnt_notify[BTC_NCNT_RADIO_STATE]++; 73008e93258fSBjoern A. Zeeb 73018e93258fSBjoern A. Zeeb switch (rf_state) { 73028e93258fSBjoern A. Zeeb case BTC_RFCTRL_WL_OFF: 73038e93258fSBjoern A. Zeeb wl->status.map.rf_off = 1; 73048e93258fSBjoern A. Zeeb wl->status.map.lps = BTC_LPS_OFF; 73058e93258fSBjoern A. Zeeb wl->status.map.busy = 0; 73068e93258fSBjoern A. Zeeb break; 73078e93258fSBjoern A. Zeeb case BTC_RFCTRL_FW_CTRL: 73088e93258fSBjoern A. Zeeb wl->status.map.rf_off = 0; 73098e93258fSBjoern A. Zeeb wl->status.map.lps = BTC_LPS_RF_OFF; 73108e93258fSBjoern A. Zeeb wl->status.map.busy = 0; 73118e93258fSBjoern A. Zeeb break; 7312e2340276SBjoern A. Zeeb case BTC_RFCTRL_LPS_WL_ON: /* LPS-Protocol (RFon) */ 7313e2340276SBjoern A. Zeeb wl->status.map.rf_off = 0; 7314e2340276SBjoern A. Zeeb wl->status.map.lps = BTC_LPS_RF_ON; 7315e2340276SBjoern A. Zeeb wl->status.map.busy = 0; 7316e2340276SBjoern A. Zeeb break; 73178e93258fSBjoern A. Zeeb case BTC_RFCTRL_WL_ON: 73188e93258fSBjoern A. Zeeb default: 73198e93258fSBjoern A. Zeeb wl->status.map.rf_off = 0; 73208e93258fSBjoern A. Zeeb wl->status.map.lps = BTC_LPS_OFF; 73218e93258fSBjoern A. Zeeb break; 73228e93258fSBjoern A. Zeeb } 73238e93258fSBjoern A. Zeeb 73248e93258fSBjoern A. Zeeb if (rf_state == BTC_RFCTRL_WL_ON) { 7325e2340276SBjoern A. Zeeb rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_MREG, true); 73268e93258fSBjoern A. Zeeb val = BTC_WSCB_ACTIVE | BTC_WSCB_ON | BTC_WSCB_BTLOG; 73278e93258fSBjoern A. Zeeb _write_scbd(rtwdev, val, true); 73288e93258fSBjoern A. Zeeb _update_bt_scbd(rtwdev, true); 73298e93258fSBjoern A. Zeeb chip->ops->btc_init_cfg(rtwdev); 73308e93258fSBjoern A. Zeeb } else { 73318e93258fSBjoern A. Zeeb rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_ALL, false); 7332*6d67aabdSBjoern A. Zeeb if (rf_state == BTC_RFCTRL_FW_CTRL) 7333*6d67aabdSBjoern A. Zeeb _write_scbd(rtwdev, BTC_WSCB_ACTIVE, false); 7334*6d67aabdSBjoern A. Zeeb else if (rf_state == BTC_RFCTRL_WL_OFF) 73358e93258fSBjoern A. Zeeb _write_scbd(rtwdev, BTC_WSCB_ALL, false); 7336*6d67aabdSBjoern A. Zeeb else 7337*6d67aabdSBjoern A. Zeeb _write_scbd(rtwdev, BTC_WSCB_ACTIVE, false); 7338*6d67aabdSBjoern A. Zeeb 7339*6d67aabdSBjoern A. Zeeb if (rf_state == BTC_RFCTRL_LPS_WL_ON && 7340e2340276SBjoern A. Zeeb wl->status.map.lps_pre != BTC_LPS_OFF) 7341e2340276SBjoern A. Zeeb _update_bt_scbd(rtwdev, true); 73428e93258fSBjoern A. Zeeb } 73438e93258fSBjoern A. Zeeb 7344e2340276SBjoern A. Zeeb btc->dm.cnt_dm[BTC_DCNT_BTCNT_HANG] = 0; 7345e2340276SBjoern A. Zeeb btc->dm.tdma_instant_excute = 1; 73468e93258fSBjoern A. Zeeb 7347e2340276SBjoern A. Zeeb _run_coex(rtwdev, BTC_RSN_NTFY_RADIO_STATE); 73488e93258fSBjoern A. Zeeb wl->status.map.rf_off_pre = wl->status.map.rf_off; 73498e93258fSBjoern A. Zeeb wl->status.map.lps_pre = wl->status.map.lps; 73508e93258fSBjoern A. Zeeb } 73518e93258fSBjoern A. Zeeb 73528e93258fSBjoern A. Zeeb static bool _ntfy_wl_rfk(struct rtw89_dev *rtwdev, u8 phy_path, 73538e93258fSBjoern A. Zeeb enum btc_wl_rfk_type type, 73548e93258fSBjoern A. Zeeb enum btc_wl_rfk_state state) 73558e93258fSBjoern A. Zeeb { 73568e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 73578e93258fSBjoern A. Zeeb struct rtw89_btc_cx *cx = &btc->cx; 73588e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &cx->wl; 73598e93258fSBjoern A. Zeeb bool result = BTC_WRFK_REJECT; 73608e93258fSBjoern A. Zeeb 73618e93258fSBjoern A. Zeeb wl->rfk_info.type = type; 73628e93258fSBjoern A. Zeeb wl->rfk_info.path_map = FIELD_GET(BTC_RFK_PATH_MAP, phy_path); 73638e93258fSBjoern A. Zeeb wl->rfk_info.phy_map = FIELD_GET(BTC_RFK_PHY_MAP, phy_path); 73648e93258fSBjoern A. Zeeb wl->rfk_info.band = FIELD_GET(BTC_RFK_BAND_MAP, phy_path); 73658e93258fSBjoern A. Zeeb 73668e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 73678e93258fSBjoern A. Zeeb "[BTC], %s()_start: phy=0x%x, path=0x%x, type=%d, state=%d\n", 73688e93258fSBjoern A. Zeeb __func__, wl->rfk_info.phy_map, wl->rfk_info.path_map, 73698e93258fSBjoern A. Zeeb type, state); 73708e93258fSBjoern A. Zeeb 73718e93258fSBjoern A. Zeeb switch (state) { 73728e93258fSBjoern A. Zeeb case BTC_WRFK_START: 73738e93258fSBjoern A. Zeeb result = _chk_wl_rfk_request(rtwdev); 73748e93258fSBjoern A. Zeeb wl->rfk_info.state = result ? BTC_WRFK_START : BTC_WRFK_STOP; 73758e93258fSBjoern A. Zeeb 73768e93258fSBjoern A. Zeeb _write_scbd(rtwdev, BTC_WSCB_WLRFK, result); 73778e93258fSBjoern A. Zeeb 73788e93258fSBjoern A. Zeeb btc->dm.cnt_notify[BTC_NCNT_WL_RFK]++; 73798e93258fSBjoern A. Zeeb break; 73808e93258fSBjoern A. Zeeb case BTC_WRFK_ONESHOT_START: 73818e93258fSBjoern A. Zeeb case BTC_WRFK_ONESHOT_STOP: 73828e93258fSBjoern A. Zeeb if (wl->rfk_info.state == BTC_WRFK_STOP) { 73838e93258fSBjoern A. Zeeb result = BTC_WRFK_REJECT; 73848e93258fSBjoern A. Zeeb } else { 73858e93258fSBjoern A. Zeeb result = BTC_WRFK_ALLOW; 73868e93258fSBjoern A. Zeeb wl->rfk_info.state = state; 73878e93258fSBjoern A. Zeeb } 73888e93258fSBjoern A. Zeeb break; 73898e93258fSBjoern A. Zeeb case BTC_WRFK_STOP: 73908e93258fSBjoern A. Zeeb result = BTC_WRFK_ALLOW; 73918e93258fSBjoern A. Zeeb wl->rfk_info.state = BTC_WRFK_STOP; 73928e93258fSBjoern A. Zeeb 73938e93258fSBjoern A. Zeeb _write_scbd(rtwdev, BTC_WSCB_WLRFK, false); 73948e93258fSBjoern A. Zeeb cancel_delayed_work(&rtwdev->coex_rfk_chk_work); 73958e93258fSBjoern A. Zeeb break; 73968e93258fSBjoern A. Zeeb default: 73978e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 73988e93258fSBjoern A. Zeeb "[BTC], %s() warning state=%d\n", __func__, state); 73998e93258fSBjoern A. Zeeb break; 74008e93258fSBjoern A. Zeeb } 74018e93258fSBjoern A. Zeeb 74028e93258fSBjoern A. Zeeb if (result == BTC_WRFK_ALLOW) { 74038e93258fSBjoern A. Zeeb if (wl->rfk_info.state == BTC_WRFK_START || 74048e93258fSBjoern A. Zeeb wl->rfk_info.state == BTC_WRFK_STOP) 74058e93258fSBjoern A. Zeeb _run_coex(rtwdev, BTC_RSN_NTFY_WL_RFK); 74068e93258fSBjoern A. Zeeb 74078e93258fSBjoern A. Zeeb if (wl->rfk_info.state == BTC_WRFK_START) 74088e93258fSBjoern A. Zeeb ieee80211_queue_delayed_work(rtwdev->hw, 74098e93258fSBjoern A. Zeeb &rtwdev->coex_rfk_chk_work, 74108e93258fSBjoern A. Zeeb RTW89_COEX_RFK_CHK_WORK_PERIOD); 74118e93258fSBjoern A. Zeeb } 74128e93258fSBjoern A. Zeeb 74138e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 74148e93258fSBjoern A. Zeeb "[BTC], %s()_finish: rfk_cnt=%d, result=%d\n", 74158e93258fSBjoern A. Zeeb __func__, btc->dm.cnt_notify[BTC_NCNT_WL_RFK], result); 74168e93258fSBjoern A. Zeeb 74178e93258fSBjoern A. Zeeb return result == BTC_WRFK_ALLOW; 74188e93258fSBjoern A. Zeeb } 74198e93258fSBjoern A. Zeeb 74208e93258fSBjoern A. Zeeb void rtw89_btc_ntfy_wl_rfk(struct rtw89_dev *rtwdev, u8 phy_map, 74218e93258fSBjoern A. Zeeb enum btc_wl_rfk_type type, 74228e93258fSBjoern A. Zeeb enum btc_wl_rfk_state state) 74238e93258fSBjoern A. Zeeb { 74248e93258fSBjoern A. Zeeb u8 band; 74258e93258fSBjoern A. Zeeb bool allow; 74268e93258fSBjoern A. Zeeb int ret; 74278e93258fSBjoern A. Zeeb 74288e93258fSBjoern A. Zeeb band = FIELD_GET(BTC_RFK_BAND_MAP, phy_map); 74298e93258fSBjoern A. Zeeb 74308e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 74318e93258fSBjoern A. Zeeb "[RFK] RFK notify (%s / PHY%u / K_type = %u / path_idx = %lu / process = %s)\n", 74328e93258fSBjoern A. Zeeb band == RTW89_BAND_2G ? "2G" : 74338e93258fSBjoern A. Zeeb band == RTW89_BAND_5G ? "5G" : "6G", 74348e93258fSBjoern A. Zeeb !!(FIELD_GET(BTC_RFK_PHY_MAP, phy_map) & BIT(RTW89_PHY_1)), 74358e93258fSBjoern A. Zeeb type, 74368e93258fSBjoern A. Zeeb FIELD_GET(BTC_RFK_PATH_MAP, phy_map), 74378e93258fSBjoern A. Zeeb state == BTC_WRFK_STOP ? "RFK_STOP" : 74388e93258fSBjoern A. Zeeb state == BTC_WRFK_START ? "RFK_START" : 74398e93258fSBjoern A. Zeeb state == BTC_WRFK_ONESHOT_START ? "ONE-SHOT_START" : 74408e93258fSBjoern A. Zeeb "ONE-SHOT_STOP"); 74418e93258fSBjoern A. Zeeb 74428e93258fSBjoern A. Zeeb if (state != BTC_WRFK_START || rtwdev->is_bt_iqk_timeout) { 74438e93258fSBjoern A. Zeeb _ntfy_wl_rfk(rtwdev, phy_map, type, state); 74448e93258fSBjoern A. Zeeb return; 74458e93258fSBjoern A. Zeeb } 74468e93258fSBjoern A. Zeeb 74478e93258fSBjoern A. Zeeb ret = read_poll_timeout(_ntfy_wl_rfk, allow, allow, 40, 100000, false, 74488e93258fSBjoern A. Zeeb rtwdev, phy_map, type, state); 74498e93258fSBjoern A. Zeeb if (ret) { 74508e93258fSBjoern A. Zeeb rtw89_warn(rtwdev, "RFK notify timeout\n"); 74518e93258fSBjoern A. Zeeb rtwdev->is_bt_iqk_timeout = true; 74528e93258fSBjoern A. Zeeb } 74538e93258fSBjoern A. Zeeb } 74548e93258fSBjoern A. Zeeb EXPORT_SYMBOL(rtw89_btc_ntfy_wl_rfk); 74558e93258fSBjoern A. Zeeb 74568e93258fSBjoern A. Zeeb struct rtw89_btc_wl_sta_iter_data { 74578e93258fSBjoern A. Zeeb struct rtw89_dev *rtwdev; 74588e93258fSBjoern A. Zeeb u8 busy_all; 74598e93258fSBjoern A. Zeeb u8 dir_all; 74608e93258fSBjoern A. Zeeb u8 rssi_map_all; 74618e93258fSBjoern A. Zeeb bool is_sta_change; 74628e93258fSBjoern A. Zeeb bool is_traffic_change; 74638e93258fSBjoern A. Zeeb }; 74648e93258fSBjoern A. Zeeb 74658e93258fSBjoern A. Zeeb static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta) 74668e93258fSBjoern A. Zeeb { 74678e93258fSBjoern A. Zeeb struct rtw89_btc_wl_sta_iter_data *iter_data = 74688e93258fSBjoern A. Zeeb (struct rtw89_btc_wl_sta_iter_data *)data; 74698e93258fSBjoern A. Zeeb struct rtw89_dev *rtwdev = iter_data->rtwdev; 74708e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 7471e2340276SBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 7472e2340276SBjoern A. Zeeb const struct rtw89_btc_ver *ver = btc->ver; 74738e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 74748e93258fSBjoern A. Zeeb struct rtw89_btc_wl_link_info *link_info = NULL; 74758e93258fSBjoern A. Zeeb struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; 74768e93258fSBjoern A. Zeeb struct rtw89_traffic_stats *link_info_t = NULL; 74778e93258fSBjoern A. Zeeb struct rtw89_vif *rtwvif = rtwsta->rtwvif; 74788e93258fSBjoern A. Zeeb struct rtw89_traffic_stats *stats = &rtwvif->stats; 74798e93258fSBjoern A. Zeeb const struct rtw89_chip_info *chip = rtwdev->chip; 7480e2340276SBjoern A. Zeeb struct rtw89_btc_wl_role_info *r; 7481e2340276SBjoern A. Zeeb struct rtw89_btc_wl_role_info_v1 *r1; 74828e93258fSBjoern A. Zeeb u32 last_tx_rate, last_rx_rate; 74838e93258fSBjoern A. Zeeb u16 last_tx_lvl, last_rx_lvl; 74848e93258fSBjoern A. Zeeb u8 port = rtwvif->port; 74858e93258fSBjoern A. Zeeb u8 rssi; 74868e93258fSBjoern A. Zeeb u8 busy = 0; 74878e93258fSBjoern A. Zeeb u8 dir = 0; 74888e93258fSBjoern A. Zeeb u8 rssi_map = 0; 74898e93258fSBjoern A. Zeeb u8 i = 0; 74908e93258fSBjoern A. Zeeb bool is_sta_change = false, is_traffic_change = false; 74918e93258fSBjoern A. Zeeb 74928e93258fSBjoern A. Zeeb rssi = ewma_rssi_read(&rtwsta->avg_rssi) >> RSSI_FACTOR; 74938e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], rssi=%d\n", rssi); 74948e93258fSBjoern A. Zeeb 74958e93258fSBjoern A. Zeeb link_info = &wl->link_info[port]; 74968e93258fSBjoern A. Zeeb link_info->stat.traffic = rtwvif->stats; 74978e93258fSBjoern A. Zeeb link_info_t = &link_info->stat.traffic; 74988e93258fSBjoern A. Zeeb 74998e93258fSBjoern A. Zeeb if (link_info->connected == MLME_NO_LINK) { 75008e93258fSBjoern A. Zeeb link_info->rx_rate_drop_cnt = 0; 75018e93258fSBjoern A. Zeeb return; 75028e93258fSBjoern A. Zeeb } 75038e93258fSBjoern A. Zeeb 75048e93258fSBjoern A. Zeeb link_info->stat.rssi = rssi; 75058e93258fSBjoern A. Zeeb for (i = 0; i < BTC_WL_RSSI_THMAX; i++) { 75068e93258fSBjoern A. Zeeb link_info->rssi_state[i] = 75078e93258fSBjoern A. Zeeb _update_rssi_state(rtwdev, 75088e93258fSBjoern A. Zeeb link_info->rssi_state[i], 75098e93258fSBjoern A. Zeeb link_info->stat.rssi, 75108e93258fSBjoern A. Zeeb chip->wl_rssi_thres[i]); 75118e93258fSBjoern A. Zeeb if (BTC_RSSI_LOW(link_info->rssi_state[i])) 75128e93258fSBjoern A. Zeeb rssi_map |= BIT(i); 75138e93258fSBjoern A. Zeeb 7514*6d67aabdSBjoern A. Zeeb if (btc->ant_type == BTC_ANT_DEDICATED && 75158e93258fSBjoern A. Zeeb BTC_RSSI_CHANGE(link_info->rssi_state[i])) 75168e93258fSBjoern A. Zeeb is_sta_change = true; 75178e93258fSBjoern A. Zeeb } 75188e93258fSBjoern A. Zeeb iter_data->rssi_map_all |= rssi_map; 75198e93258fSBjoern A. Zeeb 75208e93258fSBjoern A. Zeeb last_tx_rate = link_info_t->tx_rate; 75218e93258fSBjoern A. Zeeb last_rx_rate = link_info_t->rx_rate; 75228e93258fSBjoern A. Zeeb last_tx_lvl = (u16)link_info_t->tx_tfc_lv; 75238e93258fSBjoern A. Zeeb last_rx_lvl = (u16)link_info_t->rx_tfc_lv; 75248e93258fSBjoern A. Zeeb 75258e93258fSBjoern A. Zeeb if (stats->tx_tfc_lv != RTW89_TFC_IDLE || 75268e93258fSBjoern A. Zeeb stats->rx_tfc_lv != RTW89_TFC_IDLE) 75278e93258fSBjoern A. Zeeb busy = 1; 75288e93258fSBjoern A. Zeeb 75298e93258fSBjoern A. Zeeb if (stats->tx_tfc_lv > stats->rx_tfc_lv) 75308e93258fSBjoern A. Zeeb dir = RTW89_TFC_UL; 75318e93258fSBjoern A. Zeeb else 75328e93258fSBjoern A. Zeeb dir = RTW89_TFC_DL; 75338e93258fSBjoern A. Zeeb 75348e93258fSBjoern A. Zeeb link_info = &wl->link_info[port]; 75358e93258fSBjoern A. Zeeb if (link_info->busy != busy || link_info->dir != dir) { 75368e93258fSBjoern A. Zeeb is_sta_change = true; 75378e93258fSBjoern A. Zeeb link_info->busy = busy; 75388e93258fSBjoern A. Zeeb link_info->dir = dir; 75398e93258fSBjoern A. Zeeb } 75408e93258fSBjoern A. Zeeb 75418e93258fSBjoern A. Zeeb iter_data->busy_all |= busy; 75428e93258fSBjoern A. Zeeb iter_data->dir_all |= BIT(dir); 75438e93258fSBjoern A. Zeeb 75448e93258fSBjoern A. Zeeb if (rtwsta->rx_hw_rate <= RTW89_HW_RATE_CCK2 && 75458e93258fSBjoern A. Zeeb last_rx_rate > RTW89_HW_RATE_CCK2 && 75468e93258fSBjoern A. Zeeb link_info_t->rx_tfc_lv > RTW89_TFC_IDLE) 75478e93258fSBjoern A. Zeeb link_info->rx_rate_drop_cnt++; 75488e93258fSBjoern A. Zeeb 75498e93258fSBjoern A. Zeeb if (last_tx_rate != rtwsta->ra_report.hw_rate || 75508e93258fSBjoern A. Zeeb last_rx_rate != rtwsta->rx_hw_rate || 75518e93258fSBjoern A. Zeeb last_tx_lvl != link_info_t->tx_tfc_lv || 75528e93258fSBjoern A. Zeeb last_rx_lvl != link_info_t->rx_tfc_lv) 75538e93258fSBjoern A. Zeeb is_traffic_change = true; 75548e93258fSBjoern A. Zeeb 75558e93258fSBjoern A. Zeeb link_info_t->tx_rate = rtwsta->ra_report.hw_rate; 75568e93258fSBjoern A. Zeeb link_info_t->rx_rate = rtwsta->rx_hw_rate; 75578e93258fSBjoern A. Zeeb 7558e2340276SBjoern A. Zeeb if (link_info->role == RTW89_WIFI_ROLE_STATION || 7559e2340276SBjoern A. Zeeb link_info->role == RTW89_WIFI_ROLE_P2P_CLIENT) { 7560e2340276SBjoern A. Zeeb dm->trx_info.tx_rate = link_info_t->tx_rate; 7561e2340276SBjoern A. Zeeb dm->trx_info.rx_rate = link_info_t->rx_rate; 7562e2340276SBjoern A. Zeeb } 7563e2340276SBjoern A. Zeeb 7564e2340276SBjoern A. Zeeb if (ver->fwlrole == 0) { 7565e2340276SBjoern A. Zeeb r = &wl->role_info; 7566e2340276SBjoern A. Zeeb r->active_role[port].tx_lvl = stats->tx_tfc_lv; 7567e2340276SBjoern A. Zeeb r->active_role[port].rx_lvl = stats->rx_tfc_lv; 7568e2340276SBjoern A. Zeeb r->active_role[port].tx_rate = rtwsta->ra_report.hw_rate; 7569e2340276SBjoern A. Zeeb r->active_role[port].rx_rate = rtwsta->rx_hw_rate; 7570e2340276SBjoern A. Zeeb } else if (ver->fwlrole == 1) { 7571e2340276SBjoern A. Zeeb r1 = &wl->role_info_v1; 7572e2340276SBjoern A. Zeeb r1->active_role_v1[port].tx_lvl = stats->tx_tfc_lv; 7573e2340276SBjoern A. Zeeb r1->active_role_v1[port].rx_lvl = stats->rx_tfc_lv; 7574e2340276SBjoern A. Zeeb r1->active_role_v1[port].tx_rate = rtwsta->ra_report.hw_rate; 7575e2340276SBjoern A. Zeeb r1->active_role_v1[port].rx_rate = rtwsta->rx_hw_rate; 7576e2340276SBjoern A. Zeeb } else if (ver->fwlrole == 2) { 7577e2340276SBjoern A. Zeeb dm->trx_info.tx_lvl = stats->tx_tfc_lv; 7578e2340276SBjoern A. Zeeb dm->trx_info.rx_lvl = stats->rx_tfc_lv; 7579e2340276SBjoern A. Zeeb dm->trx_info.tx_rate = rtwsta->ra_report.hw_rate; 7580e2340276SBjoern A. Zeeb dm->trx_info.rx_rate = rtwsta->rx_hw_rate; 7581e2340276SBjoern A. Zeeb } 7582e2340276SBjoern A. Zeeb 7583e2340276SBjoern A. Zeeb dm->trx_info.tx_tp = link_info_t->tx_throughput; 7584e2340276SBjoern A. Zeeb dm->trx_info.rx_tp = link_info_t->rx_throughput; 75858e93258fSBjoern A. Zeeb 7586*6d67aabdSBjoern A. Zeeb /* Trigger coex-run if 0x10980 reg-value is diff with coex setup */ 7587*6d67aabdSBjoern A. Zeeb if ((dm->wl_btg_rx_rb != dm->wl_btg_rx && 7588*6d67aabdSBjoern A. Zeeb dm->wl_btg_rx_rb != BTC_BTGCTRL_BB_GNT_NOTFOUND) || 7589*6d67aabdSBjoern A. Zeeb (dm->wl_pre_agc_rb != dm->wl_pre_agc && 7590*6d67aabdSBjoern A. Zeeb dm->wl_pre_agc_rb != BTC_PREAGC_NOTFOUND)) 7591*6d67aabdSBjoern A. Zeeb iter_data->is_sta_change = true; 7592*6d67aabdSBjoern A. Zeeb 75938e93258fSBjoern A. Zeeb if (is_sta_change) 75948e93258fSBjoern A. Zeeb iter_data->is_sta_change = true; 75958e93258fSBjoern A. Zeeb 75968e93258fSBjoern A. Zeeb if (is_traffic_change) 75978e93258fSBjoern A. Zeeb iter_data->is_traffic_change = true; 75988e93258fSBjoern A. Zeeb } 75998e93258fSBjoern A. Zeeb 76008e93258fSBjoern A. Zeeb #define BTC_NHM_CHK_INTVL 20 76018e93258fSBjoern A. Zeeb 76028e93258fSBjoern A. Zeeb void rtw89_btc_ntfy_wl_sta(struct rtw89_dev *rtwdev) 76038e93258fSBjoern A. Zeeb { 76048e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 7605e2340276SBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 76068e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 76078e93258fSBjoern A. Zeeb struct rtw89_btc_wl_sta_iter_data data = {.rtwdev = rtwdev}; 76088e93258fSBjoern A. Zeeb u8 i; 76098e93258fSBjoern A. Zeeb 76108e93258fSBjoern A. Zeeb ieee80211_iterate_stations_atomic(rtwdev->hw, 76118e93258fSBjoern A. Zeeb rtw89_btc_ntfy_wl_sta_iter, 76128e93258fSBjoern A. Zeeb &data); 76138e93258fSBjoern A. Zeeb 76148e93258fSBjoern A. Zeeb wl->rssi_level = 0; 76158e93258fSBjoern A. Zeeb btc->dm.cnt_notify[BTC_NCNT_WL_STA]++; 76168e93258fSBjoern A. Zeeb for (i = BTC_WL_RSSI_THMAX; i > 0; i--) { 76178e93258fSBjoern A. Zeeb /* set RSSI level 4 ~ 0 if rssi bit map match */ 76188e93258fSBjoern A. Zeeb if (data.rssi_map_all & BIT(i - 1)) { 76198e93258fSBjoern A. Zeeb wl->rssi_level = i; 76208e93258fSBjoern A. Zeeb break; 76218e93258fSBjoern A. Zeeb } 76228e93258fSBjoern A. Zeeb } 76238e93258fSBjoern A. Zeeb 7624e2340276SBjoern A. Zeeb if (dm->trx_info.wl_rssi != wl->rssi_level) 7625e2340276SBjoern A. Zeeb dm->trx_info.wl_rssi = wl->rssi_level; 7626e2340276SBjoern A. Zeeb 76278e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): busy=%d\n", 76288e93258fSBjoern A. Zeeb __func__, !!wl->status.map.busy); 76298e93258fSBjoern A. Zeeb 76308e93258fSBjoern A. Zeeb _write_scbd(rtwdev, BTC_WSCB_WLBUSY, (!!wl->status.map.busy)); 76318e93258fSBjoern A. Zeeb 76328e93258fSBjoern A. Zeeb if (data.is_traffic_change) 76338e93258fSBjoern A. Zeeb _fw_set_drv_info(rtwdev, CXDRVINFO_ROLE); 76348e93258fSBjoern A. Zeeb if (data.is_sta_change) { 76358e93258fSBjoern A. Zeeb wl->status.map.busy = data.busy_all; 76368e93258fSBjoern A. Zeeb wl->status.map.traffic_dir = data.dir_all; 76378e93258fSBjoern A. Zeeb _run_coex(rtwdev, BTC_RSN_NTFY_WL_STA); 76388e93258fSBjoern A. Zeeb } else if (btc->dm.cnt_notify[BTC_NCNT_WL_STA] >= 76398e93258fSBjoern A. Zeeb btc->dm.cnt_dm[BTC_DCNT_WL_STA_LAST] + BTC_NHM_CHK_INTVL) { 76408e93258fSBjoern A. Zeeb btc->dm.cnt_dm[BTC_DCNT_WL_STA_LAST] = 76418e93258fSBjoern A. Zeeb btc->dm.cnt_notify[BTC_NCNT_WL_STA]; 76428e93258fSBjoern A. Zeeb } else if (btc->dm.cnt_notify[BTC_NCNT_WL_STA] < 76438e93258fSBjoern A. Zeeb btc->dm.cnt_dm[BTC_DCNT_WL_STA_LAST]) { 76448e93258fSBjoern A. Zeeb btc->dm.cnt_dm[BTC_DCNT_WL_STA_LAST] = 76458e93258fSBjoern A. Zeeb btc->dm.cnt_notify[BTC_NCNT_WL_STA]; 76468e93258fSBjoern A. Zeeb } 76478e93258fSBjoern A. Zeeb } 76488e93258fSBjoern A. Zeeb 76498e93258fSBjoern A. Zeeb void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb, 76508e93258fSBjoern A. Zeeb u32 len, u8 class, u8 func) 76518e93258fSBjoern A. Zeeb { 76528e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 76538e93258fSBjoern A. Zeeb struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; 76548e93258fSBjoern A. Zeeb u8 *buf = &skb->data[RTW89_C2H_HEADER_LEN]; 76558e93258fSBjoern A. Zeeb 76568e93258fSBjoern A. Zeeb len -= RTW89_C2H_HEADER_LEN; 76578e93258fSBjoern A. Zeeb 76588e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 76598e93258fSBjoern A. Zeeb "[BTC], %s(): C2H BT len:%d class:%d fun:%d\n", 76608e93258fSBjoern A. Zeeb __func__, len, class, func); 76618e93258fSBjoern A. Zeeb 76628e93258fSBjoern A. Zeeb if (class != BTFC_FW_EVENT) 76638e93258fSBjoern A. Zeeb return; 76648e93258fSBjoern A. Zeeb 76658e93258fSBjoern A. Zeeb switch (func) { 76668e93258fSBjoern A. Zeeb case BTF_EVNT_RPT: 76678e93258fSBjoern A. Zeeb case BTF_EVNT_BUF_OVERFLOW: 76688e93258fSBjoern A. Zeeb pfwinfo->event[func]++; 76698e93258fSBjoern A. Zeeb /* Don't need rtw89_leave_ps_mode() */ 76708e93258fSBjoern A. Zeeb btc_fw_event(rtwdev, func, buf, len); 76718e93258fSBjoern A. Zeeb break; 76728e93258fSBjoern A. Zeeb case BTF_EVNT_BT_INFO: 76738e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 76748e93258fSBjoern A. Zeeb "[BTC], handle C2H BT INFO with data %8ph\n", buf); 76758e93258fSBjoern A. Zeeb btc->cx.cnt_bt[BTC_BCNT_INFOUPDATE]++; 76768e93258fSBjoern A. Zeeb _update_bt_info(rtwdev, buf, len); 76778e93258fSBjoern A. Zeeb break; 76788e93258fSBjoern A. Zeeb case BTF_EVNT_BT_SCBD: 76798e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 76808e93258fSBjoern A. Zeeb "[BTC], handle C2H BT SCBD with data %8ph\n", buf); 76818e93258fSBjoern A. Zeeb btc->cx.cnt_bt[BTC_BCNT_SCBDUPDATE]++; 76828e93258fSBjoern A. Zeeb _update_bt_scbd(rtwdev, false); 76838e93258fSBjoern A. Zeeb break; 76848e93258fSBjoern A. Zeeb case BTF_EVNT_BT_PSD: 76858e93258fSBjoern A. Zeeb break; 76868e93258fSBjoern A. Zeeb case BTF_EVNT_BT_REG: 76878e93258fSBjoern A. Zeeb btc->dbg.rb_done = true; 76888e93258fSBjoern A. Zeeb btc->dbg.rb_val = le32_to_cpu(*((__le32 *)buf)); 76898e93258fSBjoern A. Zeeb 76908e93258fSBjoern A. Zeeb break; 76918e93258fSBjoern A. Zeeb case BTF_EVNT_C2H_LOOPBACK: 76928e93258fSBjoern A. Zeeb btc->dbg.rb_done = true; 76938e93258fSBjoern A. Zeeb btc->dbg.rb_val = buf[0]; 76948e93258fSBjoern A. Zeeb break; 76958e93258fSBjoern A. Zeeb case BTF_EVNT_CX_RUNINFO: 76968e93258fSBjoern A. Zeeb btc->dm.cnt_dm[BTC_DCNT_CX_RUNINFO]++; 76978e93258fSBjoern A. Zeeb break; 76988e93258fSBjoern A. Zeeb } 76998e93258fSBjoern A. Zeeb } 77008e93258fSBjoern A. Zeeb 77018e93258fSBjoern A. Zeeb #define BTC_CX_FW_OFFLOAD 0 77028e93258fSBjoern A. Zeeb 77038e93258fSBjoern A. Zeeb static void _show_cx_info(struct rtw89_dev *rtwdev, struct seq_file *m) 77048e93258fSBjoern A. Zeeb { 7705*6d67aabdSBjoern A. Zeeb union rtw89_btc_module_info *md = &rtwdev->btc.mdinfo; 77068e93258fSBjoern A. Zeeb const struct rtw89_chip_info *chip = rtwdev->chip; 7707*6d67aabdSBjoern A. Zeeb const struct rtw89_btc_ver *ver = rtwdev->btc.ver; 77088e93258fSBjoern A. Zeeb struct rtw89_hal *hal = &rtwdev->hal; 77098e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 77108e93258fSBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 77118e93258fSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &btc->cx.bt; 77128e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 77138e93258fSBjoern A. Zeeb u32 ver_main = 0, ver_sub = 0, ver_hotfix = 0, id_branch = 0; 7714*6d67aabdSBjoern A. Zeeb u8 cv, rfe, iso, ant_num, ant_single_pos; 77158e93258fSBjoern A. Zeeb 77168e93258fSBjoern A. Zeeb if (!(dm->coex_info_map & BTC_COEX_INFO_CX)) 77178e93258fSBjoern A. Zeeb return; 77188e93258fSBjoern A. Zeeb 77198e93258fSBjoern A. Zeeb dm->cnt_notify[BTC_NCNT_SHOW_COEX_INFO]++; 77208e93258fSBjoern A. Zeeb 77218e93258fSBjoern A. Zeeb seq_printf(m, "========== [BTC COEX INFO (%d)] ==========\n", 77228e93258fSBjoern A. Zeeb chip->chip_id); 77238e93258fSBjoern A. Zeeb 7724e2340276SBjoern A. Zeeb ver_main = FIELD_GET(GENMASK(31, 24), RTW89_COEX_VERSION); 7725e2340276SBjoern A. Zeeb ver_sub = FIELD_GET(GENMASK(23, 16), RTW89_COEX_VERSION); 7726e2340276SBjoern A. Zeeb ver_hotfix = FIELD_GET(GENMASK(15, 8), RTW89_COEX_VERSION); 7727e2340276SBjoern A. Zeeb id_branch = FIELD_GET(GENMASK(7, 0), RTW89_COEX_VERSION); 77288e93258fSBjoern A. Zeeb seq_printf(m, " %-15s : Coex:%d.%d.%d(branch:%d), ", 77298e93258fSBjoern A. Zeeb "[coex_version]", ver_main, ver_sub, ver_hotfix, id_branch); 77308e93258fSBjoern A. Zeeb 77318e93258fSBjoern A. Zeeb ver_main = FIELD_GET(GENMASK(31, 24), wl->ver_info.fw_coex); 77328e93258fSBjoern A. Zeeb ver_sub = FIELD_GET(GENMASK(23, 16), wl->ver_info.fw_coex); 77338e93258fSBjoern A. Zeeb ver_hotfix = FIELD_GET(GENMASK(15, 8), wl->ver_info.fw_coex); 77348e93258fSBjoern A. Zeeb id_branch = FIELD_GET(GENMASK(7, 0), wl->ver_info.fw_coex); 77358e93258fSBjoern A. Zeeb seq_printf(m, "WL_FW_coex:%d.%d.%d(branch:%d)", 77368e93258fSBjoern A. Zeeb ver_main, ver_sub, ver_hotfix, id_branch); 77378e93258fSBjoern A. Zeeb 77388e93258fSBjoern A. Zeeb ver_main = FIELD_GET(GENMASK(31, 24), chip->wlcx_desired); 77398e93258fSBjoern A. Zeeb ver_sub = FIELD_GET(GENMASK(23, 16), chip->wlcx_desired); 77408e93258fSBjoern A. Zeeb ver_hotfix = FIELD_GET(GENMASK(15, 8), chip->wlcx_desired); 77418e93258fSBjoern A. Zeeb seq_printf(m, "(%s, desired:%d.%d.%d), ", 77428e93258fSBjoern A. Zeeb (wl->ver_info.fw_coex >= chip->wlcx_desired ? 77438e93258fSBjoern A. Zeeb "Match" : "Mismatch"), ver_main, ver_sub, ver_hotfix); 77448e93258fSBjoern A. Zeeb 77458e93258fSBjoern A. Zeeb seq_printf(m, "BT_FW_coex:%d(%s, desired:%d)\n", 77468e93258fSBjoern A. Zeeb bt->ver_info.fw_coex, 77478e93258fSBjoern A. Zeeb (bt->ver_info.fw_coex >= chip->btcx_desired ? 77488e93258fSBjoern A. Zeeb "Match" : "Mismatch"), chip->btcx_desired); 77498e93258fSBjoern A. Zeeb 77508e93258fSBjoern A. Zeeb if (bt->enable.now && bt->ver_info.fw == 0) 77518e93258fSBjoern A. Zeeb rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_VER_INFO, true); 77528e93258fSBjoern A. Zeeb else 77538e93258fSBjoern A. Zeeb rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_VER_INFO, false); 77548e93258fSBjoern A. Zeeb 77558e93258fSBjoern A. Zeeb ver_main = FIELD_GET(GENMASK(31, 24), wl->ver_info.fw); 77568e93258fSBjoern A. Zeeb ver_sub = FIELD_GET(GENMASK(23, 16), wl->ver_info.fw); 77578e93258fSBjoern A. Zeeb ver_hotfix = FIELD_GET(GENMASK(15, 8), wl->ver_info.fw); 77588e93258fSBjoern A. Zeeb id_branch = FIELD_GET(GENMASK(7, 0), wl->ver_info.fw); 77598e93258fSBjoern A. Zeeb seq_printf(m, " %-15s : WL_FW:%d.%d.%d.%d, BT_FW:0x%x(%s)\n", 77608e93258fSBjoern A. Zeeb "[sub_module]", 77618e93258fSBjoern A. Zeeb ver_main, ver_sub, ver_hotfix, id_branch, 77628e93258fSBjoern A. Zeeb bt->ver_info.fw, bt->run_patch_code ? "patch" : "ROM"); 77638e93258fSBjoern A. Zeeb 7764*6d67aabdSBjoern A. Zeeb if (ver->fcxinit == 7) { 7765*6d67aabdSBjoern A. Zeeb cv = md->md_v7.kt_ver; 7766*6d67aabdSBjoern A. Zeeb rfe = md->md_v7.rfe_type; 7767*6d67aabdSBjoern A. Zeeb iso = md->md_v7.ant.isolation; 7768*6d67aabdSBjoern A. Zeeb ant_num = md->md_v7.ant.num; 7769*6d67aabdSBjoern A. Zeeb ant_single_pos = md->md_v7.ant.single_pos; 7770*6d67aabdSBjoern A. Zeeb } else { 7771*6d67aabdSBjoern A. Zeeb cv = md->md.cv; 7772*6d67aabdSBjoern A. Zeeb rfe = md->md.rfe_type; 7773*6d67aabdSBjoern A. Zeeb iso = md->md.ant.isolation; 7774*6d67aabdSBjoern A. Zeeb ant_num = md->md.ant.num; 7775*6d67aabdSBjoern A. Zeeb ant_single_pos = md->md.ant.single_pos; 7776*6d67aabdSBjoern A. Zeeb } 7777*6d67aabdSBjoern A. Zeeb 77788e93258fSBjoern A. Zeeb seq_printf(m, " %-15s : cv:%x, rfe_type:0x%x, ant_iso:%d, ant_pg:%d, %s", 7779*6d67aabdSBjoern A. Zeeb "[hw_info]", cv, rfe, iso, ant_num, 7780*6d67aabdSBjoern A. Zeeb ant_num > 1 ? "" : 7781*6d67aabdSBjoern A. Zeeb ant_single_pos ? "1Ant_Pos:S1, " : "1Ant_Pos:S0, "); 77828e93258fSBjoern A. Zeeb 77838e93258fSBjoern A. Zeeb seq_printf(m, "3rd_coex:%d, dbcc:%d, tx_num:%d, rx_num:%d\n", 77848e93258fSBjoern A. Zeeb btc->cx.other.type, rtwdev->dbcc_en, hal->tx_nss, 77858e93258fSBjoern A. Zeeb hal->rx_nss); 77868e93258fSBjoern A. Zeeb } 77878e93258fSBjoern A. Zeeb 77888e93258fSBjoern A. Zeeb static void _show_wl_role_info(struct rtw89_dev *rtwdev, struct seq_file *m) 77898e93258fSBjoern A. Zeeb { 77908e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 77918e93258fSBjoern A. Zeeb struct rtw89_btc_wl_link_info *plink = NULL; 77928e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 77938e93258fSBjoern A. Zeeb struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info; 77948e93258fSBjoern A. Zeeb struct rtw89_traffic_stats *t; 77958e93258fSBjoern A. Zeeb u8 i; 77968e93258fSBjoern A. Zeeb 77978e93258fSBjoern A. Zeeb if (rtwdev->dbcc_en) { 77988e93258fSBjoern A. Zeeb seq_printf(m, 77998e93258fSBjoern A. Zeeb " %-15s : PHY0_band(op:%d/scan:%d/real:%d), ", 78008e93258fSBjoern A. Zeeb "[dbcc_info]", wl_dinfo->op_band[RTW89_PHY_0], 78018e93258fSBjoern A. Zeeb wl_dinfo->scan_band[RTW89_PHY_0], 78028e93258fSBjoern A. Zeeb wl_dinfo->real_band[RTW89_PHY_0]); 78038e93258fSBjoern A. Zeeb seq_printf(m, 78048e93258fSBjoern A. Zeeb "PHY1_band(op:%d/scan:%d/real:%d)\n", 78058e93258fSBjoern A. Zeeb wl_dinfo->op_band[RTW89_PHY_1], 78068e93258fSBjoern A. Zeeb wl_dinfo->scan_band[RTW89_PHY_1], 78078e93258fSBjoern A. Zeeb wl_dinfo->real_band[RTW89_PHY_1]); 78088e93258fSBjoern A. Zeeb } 78098e93258fSBjoern A. Zeeb 78108e93258fSBjoern A. Zeeb for (i = 0; i < RTW89_PORT_NUM; i++) { 7811*6d67aabdSBjoern A. Zeeb if (btc->ver->fwlrole == 8) 7812*6d67aabdSBjoern A. Zeeb plink = &btc->cx.wl.rlink_info[i][0]; 7813*6d67aabdSBjoern A. Zeeb else 78148e93258fSBjoern A. Zeeb plink = &btc->cx.wl.link_info[i]; 78158e93258fSBjoern A. Zeeb 78168e93258fSBjoern A. Zeeb if (!plink->active) 78178e93258fSBjoern A. Zeeb continue; 78188e93258fSBjoern A. Zeeb 78198e93258fSBjoern A. Zeeb seq_printf(m, 78208e93258fSBjoern A. Zeeb " [port_%d] : role=%d(phy-%d), connect=%d(client_cnt=%d), mode=%d, center_ch=%d, bw=%d", 78218e93258fSBjoern A. Zeeb plink->pid, (u32)plink->role, plink->phy, 78228e93258fSBjoern A. Zeeb (u32)plink->connected, plink->client_cnt - 1, 78238e93258fSBjoern A. Zeeb (u32)plink->mode, plink->ch, (u32)plink->bw); 78248e93258fSBjoern A. Zeeb 78258e93258fSBjoern A. Zeeb if (plink->connected == MLME_NO_LINK) 78268e93258fSBjoern A. Zeeb continue; 78278e93258fSBjoern A. Zeeb 78288e93258fSBjoern A. Zeeb seq_printf(m, 78298e93258fSBjoern A. Zeeb ", mac_id=%d, max_tx_time=%dus, max_tx_retry=%d\n", 78308e93258fSBjoern A. Zeeb plink->mac_id, plink->tx_time, plink->tx_retry); 78318e93258fSBjoern A. Zeeb 78328e93258fSBjoern A. Zeeb seq_printf(m, 78338e93258fSBjoern A. Zeeb " [port_%d] : rssi=-%ddBm(%d), busy=%d, dir=%s, ", 78348e93258fSBjoern A. Zeeb plink->pid, 110 - plink->stat.rssi, 78358e93258fSBjoern A. Zeeb plink->stat.rssi, plink->busy, 78368e93258fSBjoern A. Zeeb plink->dir == RTW89_TFC_UL ? "UL" : "DL"); 78378e93258fSBjoern A. Zeeb 78388e93258fSBjoern A. Zeeb t = &plink->stat.traffic; 78398e93258fSBjoern A. Zeeb 78408e93258fSBjoern A. Zeeb seq_printf(m, 78418e93258fSBjoern A. Zeeb "tx[rate:%d/busy_level:%d], ", 78428e93258fSBjoern A. Zeeb (u32)t->tx_rate, t->tx_tfc_lv); 78438e93258fSBjoern A. Zeeb 78448e93258fSBjoern A. Zeeb seq_printf(m, "rx[rate:%d/busy_level:%d/drop:%d]\n", 78458e93258fSBjoern A. Zeeb (u32)t->rx_rate, 78468e93258fSBjoern A. Zeeb t->rx_tfc_lv, plink->rx_rate_drop_cnt); 78478e93258fSBjoern A. Zeeb } 78488e93258fSBjoern A. Zeeb } 78498e93258fSBjoern A. Zeeb 78508e93258fSBjoern A. Zeeb static void _show_wl_info(struct rtw89_dev *rtwdev, struct seq_file *m) 78518e93258fSBjoern A. Zeeb { 78528e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 7853e2340276SBjoern A. Zeeb const struct rtw89_btc_ver *ver = btc->ver; 78548e93258fSBjoern A. Zeeb struct rtw89_btc_cx *cx = &btc->cx; 78558e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &cx->wl; 78568e93258fSBjoern A. Zeeb struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; 78578e93258fSBjoern A. Zeeb struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1; 7858e2340276SBjoern A. Zeeb struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2; 7859*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_role_info_v8 *wl_rinfo_v8 = &wl->role_info_v8; 78608e93258fSBjoern A. Zeeb u8 mode; 78618e93258fSBjoern A. Zeeb 78628e93258fSBjoern A. Zeeb if (!(btc->dm.coex_info_map & BTC_COEX_INFO_WL)) 78638e93258fSBjoern A. Zeeb return; 78648e93258fSBjoern A. Zeeb 78658e93258fSBjoern A. Zeeb seq_puts(m, "========== [WL Status] ==========\n"); 78668e93258fSBjoern A. Zeeb 7867e2340276SBjoern A. Zeeb if (ver->fwlrole == 0) 78688e93258fSBjoern A. Zeeb mode = wl_rinfo->link_mode; 7869e2340276SBjoern A. Zeeb else if (ver->fwlrole == 1) 78708e93258fSBjoern A. Zeeb mode = wl_rinfo_v1->link_mode; 7871e2340276SBjoern A. Zeeb else if (ver->fwlrole == 2) 7872e2340276SBjoern A. Zeeb mode = wl_rinfo_v2->link_mode; 7873*6d67aabdSBjoern A. Zeeb else if (ver->fwlrole == 8) 7874*6d67aabdSBjoern A. Zeeb mode = wl_rinfo_v8->link_mode; 7875e2340276SBjoern A. Zeeb else 7876e2340276SBjoern A. Zeeb return; 78778e93258fSBjoern A. Zeeb 78788e93258fSBjoern A. Zeeb seq_printf(m, " %-15s : link_mode:%d, ", "[status]", mode); 78798e93258fSBjoern A. Zeeb 78808e93258fSBjoern A. Zeeb seq_printf(m, 78818e93258fSBjoern A. Zeeb "rf_off:%d, power_save:%d, scan:%s(band:%d/phy_map:0x%x), ", 78828e93258fSBjoern A. Zeeb wl->status.map.rf_off, wl->status.map.lps, 78838e93258fSBjoern A. Zeeb wl->status.map.scan ? "Y" : "N", 78848e93258fSBjoern A. Zeeb wl->scan_info.band[RTW89_PHY_0], wl->scan_info.phy_map); 78858e93258fSBjoern A. Zeeb 78868e93258fSBjoern A. Zeeb seq_printf(m, 78878e93258fSBjoern A. Zeeb "connecting:%s, roam:%s, 4way:%s, init_ok:%s\n", 78888e93258fSBjoern A. Zeeb wl->status.map.connecting ? "Y" : "N", 78898e93258fSBjoern A. Zeeb wl->status.map.roaming ? "Y" : "N", 78908e93258fSBjoern A. Zeeb wl->status.map._4way ? "Y" : "N", 78918e93258fSBjoern A. Zeeb wl->status.map.init_ok ? "Y" : "N"); 78928e93258fSBjoern A. Zeeb 78938e93258fSBjoern A. Zeeb _show_wl_role_info(rtwdev, m); 78948e93258fSBjoern A. Zeeb } 78958e93258fSBjoern A. Zeeb 78968e93258fSBjoern A. Zeeb enum btc_bt_a2dp_type { 78978e93258fSBjoern A. Zeeb BTC_A2DP_LEGACY = 0, 78988e93258fSBjoern A. Zeeb BTC_A2DP_TWS_SNIFF = 1, 78998e93258fSBjoern A. Zeeb BTC_A2DP_TWS_RELAY = 2, 79008e93258fSBjoern A. Zeeb }; 79018e93258fSBjoern A. Zeeb 79028e93258fSBjoern A. Zeeb static void _show_bt_profile_info(struct rtw89_dev *rtwdev, struct seq_file *m) 79038e93258fSBjoern A. Zeeb { 79048e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 79058e93258fSBjoern A. Zeeb struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt.link_info; 79068e93258fSBjoern A. Zeeb struct rtw89_btc_bt_hfp_desc hfp = bt_linfo->hfp_desc; 79078e93258fSBjoern A. Zeeb struct rtw89_btc_bt_hid_desc hid = bt_linfo->hid_desc; 79088e93258fSBjoern A. Zeeb struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc; 79098e93258fSBjoern A. Zeeb struct rtw89_btc_bt_pan_desc pan = bt_linfo->pan_desc; 79108e93258fSBjoern A. Zeeb 79118e93258fSBjoern A. Zeeb if (hfp.exist) { 79128e93258fSBjoern A. Zeeb seq_printf(m, " %-15s : type:%s, sut_pwr:%d, golden-rx:%d", 79138e93258fSBjoern A. Zeeb "[HFP]", (hfp.type == 0 ? "SCO" : "eSCO"), 79148e93258fSBjoern A. Zeeb bt_linfo->sut_pwr_level[0], 79158e93258fSBjoern A. Zeeb bt_linfo->golden_rx_shift[0]); 79168e93258fSBjoern A. Zeeb } 79178e93258fSBjoern A. Zeeb 79188e93258fSBjoern A. Zeeb if (hid.exist) { 79198e93258fSBjoern A. Zeeb seq_printf(m, 79208e93258fSBjoern A. Zeeb "\n\r %-15s : type:%s%s%s%s%s pair-cnt:%d, sut_pwr:%d, golden-rx:%d\n", 79218e93258fSBjoern A. Zeeb "[HID]", 79228e93258fSBjoern A. Zeeb hid.type & BTC_HID_218 ? "2/18," : "", 79238e93258fSBjoern A. Zeeb hid.type & BTC_HID_418 ? "4/18," : "", 79248e93258fSBjoern A. Zeeb hid.type & BTC_HID_BLE ? "BLE," : "", 79258e93258fSBjoern A. Zeeb hid.type & BTC_HID_RCU ? "RCU," : "", 79268e93258fSBjoern A. Zeeb hid.type & BTC_HID_RCU_VOICE ? "RCU-Voice," : "", 79278e93258fSBjoern A. Zeeb hid.pair_cnt, bt_linfo->sut_pwr_level[1], 79288e93258fSBjoern A. Zeeb bt_linfo->golden_rx_shift[1]); 79298e93258fSBjoern A. Zeeb } 79308e93258fSBjoern A. Zeeb 79318e93258fSBjoern A. Zeeb if (a2dp.exist) { 79328e93258fSBjoern A. Zeeb seq_printf(m, 79338e93258fSBjoern A. Zeeb " %-15s : type:%s, bit-pool:%d, flush-time:%d, ", 79348e93258fSBjoern A. Zeeb "[A2DP]", 79358e93258fSBjoern A. Zeeb a2dp.type == BTC_A2DP_LEGACY ? "Legacy" : "TWS", 79368e93258fSBjoern A. Zeeb a2dp.bitpool, a2dp.flush_time); 79378e93258fSBjoern A. Zeeb 79388e93258fSBjoern A. Zeeb seq_printf(m, 79398e93258fSBjoern A. Zeeb "vid:0x%x, Dev-name:0x%x, sut_pwr:%d, golden-rx:%d\n", 79408e93258fSBjoern A. Zeeb a2dp.vendor_id, a2dp.device_name, 79418e93258fSBjoern A. Zeeb bt_linfo->sut_pwr_level[2], 79428e93258fSBjoern A. Zeeb bt_linfo->golden_rx_shift[2]); 79438e93258fSBjoern A. Zeeb } 79448e93258fSBjoern A. Zeeb 79458e93258fSBjoern A. Zeeb if (pan.exist) { 79468e93258fSBjoern A. Zeeb seq_printf(m, " %-15s : sut_pwr:%d, golden-rx:%d\n", 79478e93258fSBjoern A. Zeeb "[PAN]", 79488e93258fSBjoern A. Zeeb bt_linfo->sut_pwr_level[3], 79498e93258fSBjoern A. Zeeb bt_linfo->golden_rx_shift[3]); 79508e93258fSBjoern A. Zeeb } 79518e93258fSBjoern A. Zeeb } 79528e93258fSBjoern A. Zeeb 79538e93258fSBjoern A. Zeeb static void _show_bt_info(struct rtw89_dev *rtwdev, struct seq_file *m) 79548e93258fSBjoern A. Zeeb { 79558e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 7956e2340276SBjoern A. Zeeb const struct rtw89_btc_ver *ver = btc->ver; 79578e93258fSBjoern A. Zeeb struct rtw89_btc_cx *cx = &btc->cx; 79588e93258fSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &cx->bt; 79598e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &cx->wl; 79608e93258fSBjoern A. Zeeb struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info; 7961*6d67aabdSBjoern A. Zeeb union rtw89_btc_module_info *md = &btc->mdinfo; 79628e93258fSBjoern A. Zeeb u8 *afh = bt_linfo->afh_map; 7963e2340276SBjoern A. Zeeb u8 *afh_le = bt_linfo->afh_map_le; 7964*6d67aabdSBjoern A. Zeeb u8 bt_pos; 79658e93258fSBjoern A. Zeeb 79668e93258fSBjoern A. Zeeb if (!(btc->dm.coex_info_map & BTC_COEX_INFO_BT)) 79678e93258fSBjoern A. Zeeb return; 79688e93258fSBjoern A. Zeeb 7969*6d67aabdSBjoern A. Zeeb if (ver->fcxinit == 7) 7970*6d67aabdSBjoern A. Zeeb bt_pos = md->md_v7.bt_pos; 7971*6d67aabdSBjoern A. Zeeb else 7972*6d67aabdSBjoern A. Zeeb bt_pos = md->md.bt_pos; 7973*6d67aabdSBjoern A. Zeeb 79748e93258fSBjoern A. Zeeb seq_puts(m, "========== [BT Status] ==========\n"); 79758e93258fSBjoern A. Zeeb 79768e93258fSBjoern A. Zeeb seq_printf(m, " %-15s : enable:%s, btg:%s%s, connect:%s, ", 79778e93258fSBjoern A. Zeeb "[status]", bt->enable.now ? "Y" : "N", 79788e93258fSBjoern A. Zeeb bt->btg_type ? "Y" : "N", 7979*6d67aabdSBjoern A. Zeeb (bt->enable.now && (bt->btg_type != bt_pos) ? 79808e93258fSBjoern A. Zeeb "(efuse-mismatch!!)" : ""), 79818e93258fSBjoern A. Zeeb (bt_linfo->status.map.connect ? "Y" : "N")); 79828e93258fSBjoern A. Zeeb 79838e93258fSBjoern A. Zeeb seq_printf(m, "igno_wl:%s, mailbox_avl:%s, rfk_state:0x%x\n", 79848e93258fSBjoern A. Zeeb bt->igno_wl ? "Y" : "N", 79858e93258fSBjoern A. Zeeb bt->mbx_avl ? "Y" : "N", bt->rfk_info.val); 79868e93258fSBjoern A. Zeeb 79878e93258fSBjoern A. Zeeb seq_printf(m, " %-15s : profile:%s%s%s%s%s ", 79888e93258fSBjoern A. Zeeb "[profile]", 79898e93258fSBjoern A. Zeeb (bt_linfo->profile_cnt.now == 0) ? "None," : "", 79908e93258fSBjoern A. Zeeb bt_linfo->hfp_desc.exist ? "HFP," : "", 79918e93258fSBjoern A. Zeeb bt_linfo->hid_desc.exist ? "HID," : "", 79928e93258fSBjoern A. Zeeb bt_linfo->a2dp_desc.exist ? 79938e93258fSBjoern A. Zeeb (bt_linfo->a2dp_desc.sink ? "A2DP_sink," : "A2DP,") : "", 79948e93258fSBjoern A. Zeeb bt_linfo->pan_desc.exist ? "PAN," : ""); 79958e93258fSBjoern A. Zeeb 79968e93258fSBjoern A. Zeeb seq_printf(m, 79978e93258fSBjoern A. Zeeb "multi-link:%s, role:%s, ble-connect:%s, CQDDR:%s, A2DP_active:%s, PAN_active:%s\n", 79988e93258fSBjoern A. Zeeb bt_linfo->multi_link.now ? "Y" : "N", 79998e93258fSBjoern A. Zeeb bt_linfo->slave_role ? "Slave" : "Master", 80008e93258fSBjoern A. Zeeb bt_linfo->status.map.ble_connect ? "Y" : "N", 80018e93258fSBjoern A. Zeeb bt_linfo->cqddr ? "Y" : "N", 80028e93258fSBjoern A. Zeeb bt_linfo->a2dp_desc.active ? "Y" : "N", 80038e93258fSBjoern A. Zeeb bt_linfo->pan_desc.active ? "Y" : "N"); 80048e93258fSBjoern A. Zeeb 80058e93258fSBjoern A. Zeeb seq_printf(m, 8006*6d67aabdSBjoern A. Zeeb " %-15s : rssi:%ddBm(lvl:%d), tx_rate:%dM, %s%s%s", 80078e93258fSBjoern A. Zeeb "[link]", bt_linfo->rssi - 100, 8008*6d67aabdSBjoern A. Zeeb bt->rssi_level, 80098e93258fSBjoern A. Zeeb bt_linfo->tx_3m ? 3 : 2, 80108e93258fSBjoern A. Zeeb bt_linfo->status.map.inq_pag ? " inq-page!!" : "", 80118e93258fSBjoern A. Zeeb bt_linfo->status.map.acl_busy ? " acl_busy!!" : "", 80128e93258fSBjoern A. Zeeb bt_linfo->status.map.mesh_busy ? " mesh_busy!!" : ""); 80138e93258fSBjoern A. Zeeb 80148e93258fSBjoern A. Zeeb seq_printf(m, 80158e93258fSBjoern A. Zeeb "%s afh_map[%02x%02x_%02x%02x_%02x%02x_%02x%02x_%02x%02x], ", 80168e93258fSBjoern A. Zeeb bt_linfo->relink.now ? " ReLink!!" : "", 80178e93258fSBjoern A. Zeeb afh[0], afh[1], afh[2], afh[3], afh[4], 80188e93258fSBjoern A. Zeeb afh[5], afh[6], afh[7], afh[8], afh[9]); 80198e93258fSBjoern A. Zeeb 8020e2340276SBjoern A. Zeeb if (ver->fcxbtafh == 2 && bt_linfo->status.map.ble_connect) 8021e2340276SBjoern A. Zeeb seq_printf(m, 8022e2340276SBjoern A. Zeeb "LE[%02x%02x_%02x_%02x%02x]", 8023e2340276SBjoern A. Zeeb afh_le[0], afh_le[1], afh_le[2], 8024e2340276SBjoern A. Zeeb afh_le[3], afh_le[4]); 8025e2340276SBjoern A. Zeeb 80268e93258fSBjoern A. Zeeb seq_printf(m, "wl_ch_map[en:%d/ch:%d/bw:%d]\n", 80278e93258fSBjoern A. Zeeb wl->afh_info.en, wl->afh_info.ch, wl->afh_info.bw); 80288e93258fSBjoern A. Zeeb 80298e93258fSBjoern A. Zeeb seq_printf(m, 80308e93258fSBjoern A. Zeeb " %-15s : retry:%d, relink:%d, rate_chg:%d, reinit:%d, reenable:%d, ", 80318e93258fSBjoern A. Zeeb "[stat_cnt]", cx->cnt_bt[BTC_BCNT_RETRY], 80328e93258fSBjoern A. Zeeb cx->cnt_bt[BTC_BCNT_RELINK], cx->cnt_bt[BTC_BCNT_RATECHG], 80338e93258fSBjoern A. Zeeb cx->cnt_bt[BTC_BCNT_REINIT], cx->cnt_bt[BTC_BCNT_REENABLE]); 80348e93258fSBjoern A. Zeeb 80358e93258fSBjoern A. Zeeb seq_printf(m, 80368e93258fSBjoern A. Zeeb "role-switch:%d, afh:%d, inq_page:%d(inq:%d/page:%d), igno_wl:%d\n", 80378e93258fSBjoern A. Zeeb cx->cnt_bt[BTC_BCNT_ROLESW], cx->cnt_bt[BTC_BCNT_AFH], 80388e93258fSBjoern A. Zeeb cx->cnt_bt[BTC_BCNT_INQPAG], cx->cnt_bt[BTC_BCNT_INQ], 80398e93258fSBjoern A. Zeeb cx->cnt_bt[BTC_BCNT_PAGE], cx->cnt_bt[BTC_BCNT_IGNOWL]); 80408e93258fSBjoern A. Zeeb 80418e93258fSBjoern A. Zeeb _show_bt_profile_info(rtwdev, m); 80428e93258fSBjoern A. Zeeb 80438e93258fSBjoern A. Zeeb seq_printf(m, 80448e93258fSBjoern A. Zeeb " %-15s : raw_data[%02x %02x %02x %02x %02x %02x] (type:%s/cnt:%d/same:%d)\n", 80458e93258fSBjoern A. Zeeb "[bt_info]", bt->raw_info[2], bt->raw_info[3], 80468e93258fSBjoern A. Zeeb bt->raw_info[4], bt->raw_info[5], bt->raw_info[6], 80478e93258fSBjoern A. Zeeb bt->raw_info[7], 80488e93258fSBjoern A. Zeeb bt->raw_info[0] == BTC_BTINFO_AUTO ? "auto" : "reply", 80498e93258fSBjoern A. Zeeb cx->cnt_bt[BTC_BCNT_INFOUPDATE], 80508e93258fSBjoern A. Zeeb cx->cnt_bt[BTC_BCNT_INFOSAME]); 80518e93258fSBjoern A. Zeeb 80528e93258fSBjoern A. Zeeb seq_printf(m, 8053e2340276SBjoern A. Zeeb " %-15s : Hi-rx = %d, Hi-tx = %d, Lo-rx = %d, Lo-tx = %d (bt_polut_wl_tx = %d)", 80548e93258fSBjoern A. Zeeb "[trx_req_cnt]", cx->cnt_bt[BTC_BCNT_HIPRI_RX], 80558e93258fSBjoern A. Zeeb cx->cnt_bt[BTC_BCNT_HIPRI_TX], cx->cnt_bt[BTC_BCNT_LOPRI_RX], 80568e93258fSBjoern A. Zeeb cx->cnt_bt[BTC_BCNT_LOPRI_TX], cx->cnt_bt[BTC_BCNT_POLUT]); 8057e2340276SBjoern A. Zeeb 8058e2340276SBjoern A. Zeeb if (!bt->scan_info_update) { 8059e2340276SBjoern A. Zeeb rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_SCAN_INFO, true); 8060e2340276SBjoern A. Zeeb seq_puts(m, "\n"); 8061e2340276SBjoern A. Zeeb } else { 8062e2340276SBjoern A. Zeeb rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_SCAN_INFO, false); 8063e2340276SBjoern A. Zeeb if (ver->fcxbtscan == 1) { 8064e2340276SBjoern A. Zeeb seq_printf(m, 8065e2340276SBjoern A. Zeeb "(INQ:%d-%d/PAGE:%d-%d/LE:%d-%d/INIT:%d-%d)", 8066e2340276SBjoern A. Zeeb le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INQ].win), 8067e2340276SBjoern A. Zeeb le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INQ].intvl), 8068e2340276SBjoern A. Zeeb le16_to_cpu(bt->scan_info_v1[BTC_SCAN_PAGE].win), 8069e2340276SBjoern A. Zeeb le16_to_cpu(bt->scan_info_v1[BTC_SCAN_PAGE].intvl), 8070e2340276SBjoern A. Zeeb le16_to_cpu(bt->scan_info_v1[BTC_SCAN_BLE].win), 8071e2340276SBjoern A. Zeeb le16_to_cpu(bt->scan_info_v1[BTC_SCAN_BLE].intvl), 8072e2340276SBjoern A. Zeeb le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INIT].win), 8073e2340276SBjoern A. Zeeb le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INIT].intvl)); 8074e2340276SBjoern A. Zeeb } else if (ver->fcxbtscan == 2) { 8075e2340276SBjoern A. Zeeb seq_printf(m, 8076e2340276SBjoern A. Zeeb "(BG:%d-%d/INIT:%d-%d/LE:%d-%d)", 8077e2340276SBjoern A. Zeeb le16_to_cpu(bt->scan_info_v2[CXSCAN_BG].win), 8078e2340276SBjoern A. Zeeb le16_to_cpu(bt->scan_info_v2[CXSCAN_BG].intvl), 8079e2340276SBjoern A. Zeeb le16_to_cpu(bt->scan_info_v2[CXSCAN_INIT].win), 8080e2340276SBjoern A. Zeeb le16_to_cpu(bt->scan_info_v2[CXSCAN_INIT].intvl), 8081e2340276SBjoern A. Zeeb le16_to_cpu(bt->scan_info_v2[CXSCAN_LE].win), 8082e2340276SBjoern A. Zeeb le16_to_cpu(bt->scan_info_v2[CXSCAN_LE].intvl)); 8083e2340276SBjoern A. Zeeb } 8084e2340276SBjoern A. Zeeb seq_puts(m, "\n"); 8085e2340276SBjoern A. Zeeb } 8086e2340276SBjoern A. Zeeb 8087e2340276SBjoern A. Zeeb if (bt_linfo->profile_cnt.now || bt_linfo->status.map.ble_connect) 8088e2340276SBjoern A. Zeeb rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_AFH_MAP, true); 8089e2340276SBjoern A. Zeeb else 8090e2340276SBjoern A. Zeeb rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_AFH_MAP, false); 8091e2340276SBjoern A. Zeeb 8092e2340276SBjoern A. Zeeb if (ver->fcxbtafh == 2 && bt_linfo->status.map.ble_connect) 8093e2340276SBjoern A. Zeeb rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_AFH_MAP_LE, true); 8094e2340276SBjoern A. Zeeb else 8095e2340276SBjoern A. Zeeb rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_AFH_MAP_LE, false); 8096e2340276SBjoern A. Zeeb 8097e2340276SBjoern A. Zeeb if (bt_linfo->a2dp_desc.exist && 8098e2340276SBjoern A. Zeeb (bt_linfo->a2dp_desc.flush_time == 0 || 8099e2340276SBjoern A. Zeeb bt_linfo->a2dp_desc.vendor_id == 0 || 8100e2340276SBjoern A. Zeeb bt_linfo->a2dp_desc.play_latency == 1)) 8101e2340276SBjoern A. Zeeb rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_DEVICE_INFO, true); 8102e2340276SBjoern A. Zeeb else 8103e2340276SBjoern A. Zeeb rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_DEVICE_INFO, false); 81048e93258fSBjoern A. Zeeb } 81058e93258fSBjoern A. Zeeb 81068e93258fSBjoern A. Zeeb #define CASE_BTC_RSN_STR(e) case BTC_RSN_ ## e: return #e 81078e93258fSBjoern A. Zeeb #define CASE_BTC_ACT_STR(e) case BTC_ACT_ ## e | BTC_ACT_EXT_BIT: return #e 81088e93258fSBjoern A. Zeeb #define CASE_BTC_POLICY_STR(e) \ 81098e93258fSBjoern A. Zeeb case BTC_CXP_ ## e | BTC_POLICY_EXT_BIT: return #e 8110e2340276SBjoern A. Zeeb #define CASE_BTC_SLOT_STR(e) case CXST_ ## e: return #e 8111e2340276SBjoern A. Zeeb #define CASE_BTC_EVT_STR(e) case CXEVNT_## e: return #e 8112*6d67aabdSBjoern A. Zeeb #define CASE_BTC_INIT(e) case BTC_MODE_## e: return #e 8113*6d67aabdSBjoern A. Zeeb #define CASE_BTC_ANTPATH_STR(e) case BTC_ANT_##e: return #e 8114*6d67aabdSBjoern A. Zeeb #define CASE_BTC_POLUT_STR(e) case BTC_PLT_## e: return #e 8115*6d67aabdSBjoern A. Zeeb #define CASE_BTC_REGTYPE_STR(e) case REG_## e: return #e 8116*6d67aabdSBjoern A. Zeeb #define CASE_BTC_GDBG_STR(e) case BTC_DBG_## e: return #e 8117*6d67aabdSBjoern A. Zeeb 8118*6d67aabdSBjoern A. Zeeb static const char *id_to_polut(u32 id) 8119*6d67aabdSBjoern A. Zeeb { 8120*6d67aabdSBjoern A. Zeeb switch (id) { 8121*6d67aabdSBjoern A. Zeeb CASE_BTC_POLUT_STR(NONE); 8122*6d67aabdSBjoern A. Zeeb CASE_BTC_POLUT_STR(GNT_BT_TX); 8123*6d67aabdSBjoern A. Zeeb CASE_BTC_POLUT_STR(GNT_BT_RX); 8124*6d67aabdSBjoern A. Zeeb CASE_BTC_POLUT_STR(GNT_WL); 8125*6d67aabdSBjoern A. Zeeb CASE_BTC_POLUT_STR(BT); 8126*6d67aabdSBjoern A. Zeeb CASE_BTC_POLUT_STR(ALL); 8127*6d67aabdSBjoern A. Zeeb default: 8128*6d67aabdSBjoern A. Zeeb return "unknown"; 8129*6d67aabdSBjoern A. Zeeb } 8130*6d67aabdSBjoern A. Zeeb } 8131*6d67aabdSBjoern A. Zeeb 8132*6d67aabdSBjoern A. Zeeb static const char *id_to_regtype(u32 id) 8133*6d67aabdSBjoern A. Zeeb { 8134*6d67aabdSBjoern A. Zeeb switch (id) { 8135*6d67aabdSBjoern A. Zeeb CASE_BTC_REGTYPE_STR(MAC); 8136*6d67aabdSBjoern A. Zeeb CASE_BTC_REGTYPE_STR(BB); 8137*6d67aabdSBjoern A. Zeeb CASE_BTC_REGTYPE_STR(RF); 8138*6d67aabdSBjoern A. Zeeb CASE_BTC_REGTYPE_STR(BT_RF); 8139*6d67aabdSBjoern A. Zeeb CASE_BTC_REGTYPE_STR(BT_MODEM); 8140*6d67aabdSBjoern A. Zeeb CASE_BTC_REGTYPE_STR(BT_BLUEWIZE); 8141*6d67aabdSBjoern A. Zeeb CASE_BTC_REGTYPE_STR(BT_VENDOR); 8142*6d67aabdSBjoern A. Zeeb CASE_BTC_REGTYPE_STR(BT_LE); 8143*6d67aabdSBjoern A. Zeeb default: 8144*6d67aabdSBjoern A. Zeeb return "unknown"; 8145*6d67aabdSBjoern A. Zeeb } 8146*6d67aabdSBjoern A. Zeeb } 8147*6d67aabdSBjoern A. Zeeb 8148*6d67aabdSBjoern A. Zeeb static const char *id_to_gdbg(u32 id) 8149*6d67aabdSBjoern A. Zeeb { 8150*6d67aabdSBjoern A. Zeeb switch (id) { 8151*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(GNT_BT); 8152*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(GNT_WL); 8153*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(BCN_EARLY); 8154*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(WL_NULL0); 8155*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(WL_NULL1); 8156*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(WL_RXISR); 8157*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(TDMA_ENTRY); 8158*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(A2DP_EMPTY); 8159*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(BT_RETRY); 8160*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(BT_RELINK); 8161*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(SLOT_WL); 8162*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(SLOT_BT); 8163*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(WL_ERR); 8164*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(WL_OK); 8165*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(SLOT_B2W); 8166*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(SLOT_W1); 8167*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(SLOT_W2); 8168*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(SLOT_W2B); 8169*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(SLOT_B1); 8170*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(SLOT_B2); 8171*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(SLOT_B3); 8172*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(SLOT_B4); 8173*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(SLOT_LK); 8174*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(SLOT_E2G); 8175*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(SLOT_E5G); 8176*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(SLOT_EBT); 8177*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(SLOT_WLK); 8178*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(SLOT_B1FDD); 8179*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(BT_CHANGE); 8180*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(WL_CCA); 8181*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(BT_LEAUDIO); 8182*6d67aabdSBjoern A. Zeeb CASE_BTC_GDBG_STR(USER_DEF); 8183*6d67aabdSBjoern A. Zeeb default: 8184*6d67aabdSBjoern A. Zeeb return "unknown"; 8185*6d67aabdSBjoern A. Zeeb } 8186*6d67aabdSBjoern A. Zeeb } 81878e93258fSBjoern A. Zeeb 81888e93258fSBjoern A. Zeeb static const char *steps_to_str(u16 step) 81898e93258fSBjoern A. Zeeb { 81908e93258fSBjoern A. Zeeb switch (step) { 81918e93258fSBjoern A. Zeeb CASE_BTC_RSN_STR(NONE); 81928e93258fSBjoern A. Zeeb CASE_BTC_RSN_STR(NTFY_INIT); 81938e93258fSBjoern A. Zeeb CASE_BTC_RSN_STR(NTFY_SWBAND); 81948e93258fSBjoern A. Zeeb CASE_BTC_RSN_STR(NTFY_WL_STA); 81958e93258fSBjoern A. Zeeb CASE_BTC_RSN_STR(NTFY_RADIO_STATE); 81968e93258fSBjoern A. Zeeb CASE_BTC_RSN_STR(UPDATE_BT_SCBD); 81978e93258fSBjoern A. Zeeb CASE_BTC_RSN_STR(NTFY_WL_RFK); 81988e93258fSBjoern A. Zeeb CASE_BTC_RSN_STR(UPDATE_BT_INFO); 81998e93258fSBjoern A. Zeeb CASE_BTC_RSN_STR(NTFY_SCAN_START); 82008e93258fSBjoern A. Zeeb CASE_BTC_RSN_STR(NTFY_SCAN_FINISH); 82018e93258fSBjoern A. Zeeb CASE_BTC_RSN_STR(NTFY_SPECIFIC_PACKET); 82028e93258fSBjoern A. Zeeb CASE_BTC_RSN_STR(NTFY_POWEROFF); 82038e93258fSBjoern A. Zeeb CASE_BTC_RSN_STR(NTFY_ROLE_INFO); 82048e93258fSBjoern A. Zeeb CASE_BTC_RSN_STR(CMD_SET_COEX); 82058e93258fSBjoern A. Zeeb CASE_BTC_RSN_STR(ACT1_WORK); 82068e93258fSBjoern A. Zeeb CASE_BTC_RSN_STR(BT_DEVINFO_WORK); 82078e93258fSBjoern A. Zeeb CASE_BTC_RSN_STR(RFK_CHK_WORK); 82088e93258fSBjoern A. Zeeb 82098e93258fSBjoern A. Zeeb CASE_BTC_ACT_STR(NONE); 82108e93258fSBjoern A. Zeeb CASE_BTC_ACT_STR(WL_ONLY); 82118e93258fSBjoern A. Zeeb CASE_BTC_ACT_STR(WL_5G); 82128e93258fSBjoern A. Zeeb CASE_BTC_ACT_STR(WL_OTHER); 82138e93258fSBjoern A. Zeeb CASE_BTC_ACT_STR(WL_IDLE); 82148e93258fSBjoern A. Zeeb CASE_BTC_ACT_STR(WL_NC); 82158e93258fSBjoern A. Zeeb CASE_BTC_ACT_STR(WL_RFK); 82168e93258fSBjoern A. Zeeb CASE_BTC_ACT_STR(WL_INIT); 82178e93258fSBjoern A. Zeeb CASE_BTC_ACT_STR(WL_OFF); 82188e93258fSBjoern A. Zeeb CASE_BTC_ACT_STR(FREERUN); 82198e93258fSBjoern A. Zeeb CASE_BTC_ACT_STR(BT_WHQL); 82208e93258fSBjoern A. Zeeb CASE_BTC_ACT_STR(BT_RFK); 82218e93258fSBjoern A. Zeeb CASE_BTC_ACT_STR(BT_OFF); 82228e93258fSBjoern A. Zeeb CASE_BTC_ACT_STR(BT_IDLE); 82238e93258fSBjoern A. Zeeb CASE_BTC_ACT_STR(BT_HFP); 82248e93258fSBjoern A. Zeeb CASE_BTC_ACT_STR(BT_HID); 82258e93258fSBjoern A. Zeeb CASE_BTC_ACT_STR(BT_A2DP); 82268e93258fSBjoern A. Zeeb CASE_BTC_ACT_STR(BT_A2DPSINK); 82278e93258fSBjoern A. Zeeb CASE_BTC_ACT_STR(BT_PAN); 82288e93258fSBjoern A. Zeeb CASE_BTC_ACT_STR(BT_A2DP_HID); 82298e93258fSBjoern A. Zeeb CASE_BTC_ACT_STR(BT_A2DP_PAN); 82308e93258fSBjoern A. Zeeb CASE_BTC_ACT_STR(BT_PAN_HID); 82318e93258fSBjoern A. Zeeb CASE_BTC_ACT_STR(BT_A2DP_PAN_HID); 82328e93258fSBjoern A. Zeeb CASE_BTC_ACT_STR(WL_25G_MCC); 82338e93258fSBjoern A. Zeeb CASE_BTC_ACT_STR(WL_2G_MCC); 82348e93258fSBjoern A. Zeeb CASE_BTC_ACT_STR(WL_2G_SCC); 82358e93258fSBjoern A. Zeeb CASE_BTC_ACT_STR(WL_2G_AP); 82368e93258fSBjoern A. Zeeb CASE_BTC_ACT_STR(WL_2G_GO); 82378e93258fSBjoern A. Zeeb CASE_BTC_ACT_STR(WL_2G_GC); 82388e93258fSBjoern A. Zeeb CASE_BTC_ACT_STR(WL_2G_NAN); 82398e93258fSBjoern A. Zeeb 82408e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(OFF_BT); 82418e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(OFF_WL); 82428e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(OFF_EQ0); 82438e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(OFF_EQ1); 82448e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(OFF_EQ2); 82458e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(OFF_EQ3); 8246*6d67aabdSBjoern A. Zeeb CASE_BTC_POLICY_STR(OFF_EQ4); 8247*6d67aabdSBjoern A. Zeeb CASE_BTC_POLICY_STR(OFF_EQ5); 82488e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(OFF_BWB0); 82498e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(OFF_BWB1); 82508e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(OFF_BWB2); 8251e2340276SBjoern A. Zeeb CASE_BTC_POLICY_STR(OFF_BWB3); 8252*6d67aabdSBjoern A. Zeeb CASE_BTC_POLICY_STR(OFF_WL2); 82538e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(OFFB_BWB0); 82548e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(OFFE_DEF); 82558e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(OFFE_DEF2); 82568e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(OFFE_2GBWISOB); 82578e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(OFFE_2GISOB); 82588e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(OFFE_2GBWMIXB); 82598e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(OFFE_WL); 82608e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(OFFE_2GBWMIXB2); 82618e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(FIX_TD3030); 82628e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(FIX_TD5050); 82638e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(FIX_TD2030); 82648e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(FIX_TD4010); 82658e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(FIX_TD7010); 82668e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(FIX_TD2060); 82678e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(FIX_TD3060); 82688e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(FIX_TD2080); 82698e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(FIX_TDW1B1); 82708e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(FIX_TD4010ISO); 8271*6d67aabdSBjoern A. Zeeb CASE_BTC_POLICY_STR(FIX_TD4010ISO_DL); 8272*6d67aabdSBjoern A. Zeeb CASE_BTC_POLICY_STR(FIX_TD4010ISO_UL); 82738e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(PFIX_TD3030); 82748e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(PFIX_TD5050); 82758e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(PFIX_TD2030); 82768e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(PFIX_TD2060); 82778e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(PFIX_TD3070); 82788e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(PFIX_TD2080); 82798e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(PFIX_TDW1B1); 82808e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(AUTO_TD50B1); 82818e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(AUTO_TD60B1); 82828e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(AUTO_TD20B1); 82838e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(AUTO_TDW1B1); 82848e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(PAUTO_TD50B1); 82858e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(PAUTO_TD60B1); 82868e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(PAUTO_TD20B1); 82878e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(PAUTO_TDW1B1); 82888e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(AUTO2_TD3050); 82898e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(AUTO2_TD3070); 82908e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(AUTO2_TD5050); 82918e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(AUTO2_TD6060); 82928e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(AUTO2_TD2080); 82938e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(AUTO2_TDW1B4); 82948e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(PAUTO2_TD3050); 82958e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(PAUTO2_TD3070); 82968e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(PAUTO2_TD5050); 82978e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(PAUTO2_TD6060); 82988e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(PAUTO2_TD2080); 82998e93258fSBjoern A. Zeeb CASE_BTC_POLICY_STR(PAUTO2_TDW1B4); 83008e93258fSBjoern A. Zeeb default: 83018e93258fSBjoern A. Zeeb return "unknown step"; 83028e93258fSBjoern A. Zeeb } 83038e93258fSBjoern A. Zeeb } 83048e93258fSBjoern A. Zeeb 8305e2340276SBjoern A. Zeeb static const char *id_to_slot(u32 id) 8306e2340276SBjoern A. Zeeb { 8307e2340276SBjoern A. Zeeb switch (id) { 8308e2340276SBjoern A. Zeeb CASE_BTC_SLOT_STR(OFF); 8309e2340276SBjoern A. Zeeb CASE_BTC_SLOT_STR(B2W); 8310e2340276SBjoern A. Zeeb CASE_BTC_SLOT_STR(W1); 8311e2340276SBjoern A. Zeeb CASE_BTC_SLOT_STR(W2); 8312e2340276SBjoern A. Zeeb CASE_BTC_SLOT_STR(W2B); 8313e2340276SBjoern A. Zeeb CASE_BTC_SLOT_STR(B1); 8314e2340276SBjoern A. Zeeb CASE_BTC_SLOT_STR(B2); 8315e2340276SBjoern A. Zeeb CASE_BTC_SLOT_STR(B3); 8316e2340276SBjoern A. Zeeb CASE_BTC_SLOT_STR(B4); 8317e2340276SBjoern A. Zeeb CASE_BTC_SLOT_STR(LK); 8318e2340276SBjoern A. Zeeb CASE_BTC_SLOT_STR(BLK); 8319e2340276SBjoern A. Zeeb CASE_BTC_SLOT_STR(E2G); 8320e2340276SBjoern A. Zeeb CASE_BTC_SLOT_STR(E5G); 8321e2340276SBjoern A. Zeeb CASE_BTC_SLOT_STR(EBT); 8322e2340276SBjoern A. Zeeb CASE_BTC_SLOT_STR(ENULL); 8323e2340276SBjoern A. Zeeb CASE_BTC_SLOT_STR(WLK); 8324e2340276SBjoern A. Zeeb CASE_BTC_SLOT_STR(W1FDD); 8325e2340276SBjoern A. Zeeb CASE_BTC_SLOT_STR(B1FDD); 8326e2340276SBjoern A. Zeeb default: 8327e2340276SBjoern A. Zeeb return "unknown"; 8328e2340276SBjoern A. Zeeb } 8329e2340276SBjoern A. Zeeb } 8330e2340276SBjoern A. Zeeb 8331e2340276SBjoern A. Zeeb static const char *id_to_evt(u32 id) 8332e2340276SBjoern A. Zeeb { 8333e2340276SBjoern A. Zeeb switch (id) { 8334e2340276SBjoern A. Zeeb CASE_BTC_EVT_STR(TDMA_ENTRY); 8335e2340276SBjoern A. Zeeb CASE_BTC_EVT_STR(WL_TMR); 8336e2340276SBjoern A. Zeeb CASE_BTC_EVT_STR(B1_TMR); 8337e2340276SBjoern A. Zeeb CASE_BTC_EVT_STR(B2_TMR); 8338e2340276SBjoern A. Zeeb CASE_BTC_EVT_STR(B3_TMR); 8339e2340276SBjoern A. Zeeb CASE_BTC_EVT_STR(B4_TMR); 8340e2340276SBjoern A. Zeeb CASE_BTC_EVT_STR(W2B_TMR); 8341e2340276SBjoern A. Zeeb CASE_BTC_EVT_STR(B2W_TMR); 8342e2340276SBjoern A. Zeeb CASE_BTC_EVT_STR(BCN_EARLY); 8343e2340276SBjoern A. Zeeb CASE_BTC_EVT_STR(A2DP_EMPTY); 8344e2340276SBjoern A. Zeeb CASE_BTC_EVT_STR(LK_END); 8345e2340276SBjoern A. Zeeb CASE_BTC_EVT_STR(RX_ISR); 8346e2340276SBjoern A. Zeeb CASE_BTC_EVT_STR(RX_FC0); 8347e2340276SBjoern A. Zeeb CASE_BTC_EVT_STR(RX_FC1); 8348e2340276SBjoern A. Zeeb CASE_BTC_EVT_STR(BT_RELINK); 8349e2340276SBjoern A. Zeeb CASE_BTC_EVT_STR(BT_RETRY); 8350e2340276SBjoern A. Zeeb CASE_BTC_EVT_STR(E2G); 8351e2340276SBjoern A. Zeeb CASE_BTC_EVT_STR(E5G); 8352e2340276SBjoern A. Zeeb CASE_BTC_EVT_STR(EBT); 8353e2340276SBjoern A. Zeeb CASE_BTC_EVT_STR(ENULL); 8354e2340276SBjoern A. Zeeb CASE_BTC_EVT_STR(DRV_WLK); 8355e2340276SBjoern A. Zeeb CASE_BTC_EVT_STR(BCN_OK); 8356e2340276SBjoern A. Zeeb CASE_BTC_EVT_STR(BT_CHANGE); 8357e2340276SBjoern A. Zeeb CASE_BTC_EVT_STR(EBT_EXTEND); 8358e2340276SBjoern A. Zeeb CASE_BTC_EVT_STR(E2G_NULL1); 8359e2340276SBjoern A. Zeeb CASE_BTC_EVT_STR(B1FDD_TMR); 8360e2340276SBjoern A. Zeeb default: 8361e2340276SBjoern A. Zeeb return "unknown"; 8362e2340276SBjoern A. Zeeb } 8363e2340276SBjoern A. Zeeb } 8364e2340276SBjoern A. Zeeb 8365*6d67aabdSBjoern A. Zeeb static const char *id_to_mode(u8 id) 8366*6d67aabdSBjoern A. Zeeb { 8367*6d67aabdSBjoern A. Zeeb switch (id) { 8368*6d67aabdSBjoern A. Zeeb CASE_BTC_INIT(NORMAL); 8369*6d67aabdSBjoern A. Zeeb CASE_BTC_INIT(WL); 8370*6d67aabdSBjoern A. Zeeb CASE_BTC_INIT(BT); 8371*6d67aabdSBjoern A. Zeeb CASE_BTC_INIT(WLOFF); 8372*6d67aabdSBjoern A. Zeeb default: 8373*6d67aabdSBjoern A. Zeeb return "unknown"; 8374*6d67aabdSBjoern A. Zeeb } 8375*6d67aabdSBjoern A. Zeeb } 8376*6d67aabdSBjoern A. Zeeb 8377*6d67aabdSBjoern A. Zeeb static const char *id_to_ant(u32 id) 8378*6d67aabdSBjoern A. Zeeb { 8379*6d67aabdSBjoern A. Zeeb switch (id) { 8380*6d67aabdSBjoern A. Zeeb CASE_BTC_ANTPATH_STR(WPOWERON); 8381*6d67aabdSBjoern A. Zeeb CASE_BTC_ANTPATH_STR(WINIT); 8382*6d67aabdSBjoern A. Zeeb CASE_BTC_ANTPATH_STR(WONLY); 8383*6d67aabdSBjoern A. Zeeb CASE_BTC_ANTPATH_STR(WOFF); 8384*6d67aabdSBjoern A. Zeeb CASE_BTC_ANTPATH_STR(W2G); 8385*6d67aabdSBjoern A. Zeeb CASE_BTC_ANTPATH_STR(W5G); 8386*6d67aabdSBjoern A. Zeeb CASE_BTC_ANTPATH_STR(W25G); 8387*6d67aabdSBjoern A. Zeeb CASE_BTC_ANTPATH_STR(FREERUN); 8388*6d67aabdSBjoern A. Zeeb CASE_BTC_ANTPATH_STR(WRFK); 8389*6d67aabdSBjoern A. Zeeb CASE_BTC_ANTPATH_STR(BRFK); 8390*6d67aabdSBjoern A. Zeeb CASE_BTC_ANTPATH_STR(MAX); 8391*6d67aabdSBjoern A. Zeeb default: 8392*6d67aabdSBjoern A. Zeeb return "unknown"; 8393*6d67aabdSBjoern A. Zeeb } 8394*6d67aabdSBjoern A. Zeeb } 8395*6d67aabdSBjoern A. Zeeb 83968e93258fSBjoern A. Zeeb static 83978e93258fSBjoern A. Zeeb void seq_print_segment(struct seq_file *m, const char *prefix, u16 *data, 83988e93258fSBjoern A. Zeeb u8 len, u8 seg_len, u8 start_idx, u8 ring_len) 83998e93258fSBjoern A. Zeeb { 84008e93258fSBjoern A. Zeeb u8 i; 84018e93258fSBjoern A. Zeeb u8 cur_index; 84028e93258fSBjoern A. Zeeb 84038e93258fSBjoern A. Zeeb for (i = 0; i < len ; i++) { 84048e93258fSBjoern A. Zeeb if ((i % seg_len) == 0) 84058e93258fSBjoern A. Zeeb seq_printf(m, " %-15s : ", prefix); 84068e93258fSBjoern A. Zeeb cur_index = (start_idx + i) % ring_len; 84078e93258fSBjoern A. Zeeb if (i % 3 == 0) 84088e93258fSBjoern A. Zeeb seq_printf(m, "-> %-20s", 84098e93258fSBjoern A. Zeeb steps_to_str(*(data + cur_index))); 84108e93258fSBjoern A. Zeeb else if (i % 3 == 1) 84118e93258fSBjoern A. Zeeb seq_printf(m, "-> %-15s", 84128e93258fSBjoern A. Zeeb steps_to_str(*(data + cur_index))); 84138e93258fSBjoern A. Zeeb else 84148e93258fSBjoern A. Zeeb seq_printf(m, "-> %-13s", 84158e93258fSBjoern A. Zeeb steps_to_str(*(data + cur_index))); 84168e93258fSBjoern A. Zeeb if (i == (len - 1) || (i % seg_len) == (seg_len - 1)) 84178e93258fSBjoern A. Zeeb seq_puts(m, "\n"); 84188e93258fSBjoern A. Zeeb } 84198e93258fSBjoern A. Zeeb } 84208e93258fSBjoern A. Zeeb 84218e93258fSBjoern A. Zeeb static void _show_dm_step(struct rtw89_dev *rtwdev, struct seq_file *m) 84228e93258fSBjoern A. Zeeb { 84238e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 84248e93258fSBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 84258e93258fSBjoern A. Zeeb u8 start_idx; 84268e93258fSBjoern A. Zeeb u8 len; 84278e93258fSBjoern A. Zeeb 84288e93258fSBjoern A. Zeeb len = dm->dm_step.step_ov ? RTW89_BTC_DM_MAXSTEP : dm->dm_step.step_pos; 84298e93258fSBjoern A. Zeeb start_idx = dm->dm_step.step_ov ? dm->dm_step.step_pos : 0; 84308e93258fSBjoern A. Zeeb 84318e93258fSBjoern A. Zeeb seq_print_segment(m, "[dm_steps]", dm->dm_step.step, len, 6, start_idx, 84328e93258fSBjoern A. Zeeb ARRAY_SIZE(dm->dm_step.step)); 84338e93258fSBjoern A. Zeeb } 84348e93258fSBjoern A. Zeeb 84358e93258fSBjoern A. Zeeb static void _show_dm_info(struct rtw89_dev *rtwdev, struct seq_file *m) 84368e93258fSBjoern A. Zeeb { 84378e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 8438*6d67aabdSBjoern A. Zeeb const struct rtw89_btc_ver *ver = btc->ver; 84398e93258fSBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 84408e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 84418e93258fSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &btc->cx.bt; 8442*6d67aabdSBjoern A. Zeeb u8 igno_bt; 84438e93258fSBjoern A. Zeeb 84448e93258fSBjoern A. Zeeb if (!(dm->coex_info_map & BTC_COEX_INFO_DM)) 84458e93258fSBjoern A. Zeeb return; 84468e93258fSBjoern A. Zeeb 84478e93258fSBjoern A. Zeeb seq_printf(m, "========== [Mechanism Status %s] ==========\n", 8448*6d67aabdSBjoern A. Zeeb (btc->manual_ctrl ? "(Manual)" : "(Auto)")); 84498e93258fSBjoern A. Zeeb 84508e93258fSBjoern A. Zeeb seq_printf(m, 8451*6d67aabdSBjoern A. Zeeb " %-15s : type:%s, reason:%s(), action:%s(), ant_path:%s, init_mode:%s, run_cnt:%d\n", 84528e93258fSBjoern A. Zeeb "[status]", 8453*6d67aabdSBjoern A. Zeeb btc->ant_type == BTC_ANT_SHARED ? "shared" : "dedicated", 84548e93258fSBjoern A. Zeeb steps_to_str(dm->run_reason), 84558e93258fSBjoern A. Zeeb steps_to_str(dm->run_action | BTC_ACT_EXT_BIT), 8456*6d67aabdSBjoern A. Zeeb id_to_ant(FIELD_GET(GENMASK(7, 0), dm->set_ant_path)), 8457*6d67aabdSBjoern A. Zeeb id_to_mode(wl->coex_mode), 84588e93258fSBjoern A. Zeeb dm->cnt_dm[BTC_DCNT_RUN]); 84598e93258fSBjoern A. Zeeb 84608e93258fSBjoern A. Zeeb _show_dm_step(rtwdev, m); 84618e93258fSBjoern A. Zeeb 8462*6d67aabdSBjoern A. Zeeb if (ver->fcxctrl == 7) 8463*6d67aabdSBjoern A. Zeeb igno_bt = btc->ctrl.ctrl_v7.igno_bt; 8464*6d67aabdSBjoern A. Zeeb else 8465*6d67aabdSBjoern A. Zeeb igno_bt = btc->ctrl.ctrl.igno_bt; 8466*6d67aabdSBjoern A. Zeeb 84678e93258fSBjoern A. Zeeb seq_printf(m, " %-15s : wl_only:%d, bt_only:%d, igno_bt:%d, free_run:%d, wl_ps_ctrl:%d, wl_mimo_ps:%d, ", 8468*6d67aabdSBjoern A. Zeeb "[dm_flag]", dm->wl_only, dm->bt_only, igno_bt, 84698e93258fSBjoern A. Zeeb dm->freerun, btc->lps, dm->wl_mimo_ps); 84708e93258fSBjoern A. Zeeb 84718e93258fSBjoern A. Zeeb seq_printf(m, "leak_ap:%d, fw_offload:%s%s\n", dm->leak_ap, 84728e93258fSBjoern A. Zeeb (BTC_CX_FW_OFFLOAD ? "Y" : "N"), 84738e93258fSBjoern A. Zeeb (dm->wl_fw_cx_offload == BTC_CX_FW_OFFLOAD ? 84748e93258fSBjoern A. Zeeb "" : "(Mismatch!!)")); 84758e93258fSBjoern A. Zeeb 84768e93258fSBjoern A. Zeeb if (dm->rf_trx_para.wl_tx_power == 0xff) 84778e93258fSBjoern A. Zeeb seq_printf(m, 84788e93258fSBjoern A. Zeeb " %-15s : wl_rssi_lvl:%d, para_lvl:%d, wl_tx_pwr:orig, ", 84798e93258fSBjoern A. Zeeb "[trx_ctrl]", wl->rssi_level, dm->trx_para_level); 84808e93258fSBjoern A. Zeeb 84818e93258fSBjoern A. Zeeb else 84828e93258fSBjoern A. Zeeb seq_printf(m, 84838e93258fSBjoern A. Zeeb " %-15s : wl_rssi_lvl:%d, para_lvl:%d, wl_tx_pwr:%d, ", 84848e93258fSBjoern A. Zeeb "[trx_ctrl]", wl->rssi_level, dm->trx_para_level, 84858e93258fSBjoern A. Zeeb dm->rf_trx_para.wl_tx_power); 84868e93258fSBjoern A. Zeeb 84878e93258fSBjoern A. Zeeb seq_printf(m, 84888e93258fSBjoern A. Zeeb "wl_rx_lvl:%d, bt_tx_pwr_dec:%d, bt_rx_lna:%d(%s-tbl), wl_btg_rx:%d\n", 84898e93258fSBjoern A. Zeeb dm->rf_trx_para.wl_rx_gain, dm->rf_trx_para.bt_tx_power, 84908e93258fSBjoern A. Zeeb dm->rf_trx_para.bt_rx_gain, 84918e93258fSBjoern A. Zeeb (bt->hi_lna_rx ? "Hi" : "Ori"), dm->wl_btg_rx); 84928e93258fSBjoern A. Zeeb 84938e93258fSBjoern A. Zeeb seq_printf(m, 8494e2340276SBjoern A. Zeeb " %-15s : wl_tx_limit[en:%d/max_t:%dus/max_retry:%d], bt_slot_reg:%d-TU, bt_scan_rx_low_pri:%d\n", 84958e93258fSBjoern A. Zeeb "[dm_ctrl]", dm->wl_tx_limit.enable, dm->wl_tx_limit.tx_time, 8496e2340276SBjoern A. Zeeb dm->wl_tx_limit.tx_retry, btc->bt_req_len, bt->scan_rx_low_pri); 84978e93258fSBjoern A. Zeeb } 84988e93258fSBjoern A. Zeeb 84998e93258fSBjoern A. Zeeb static void _show_error(struct rtw89_dev *rtwdev, struct seq_file *m) 85008e93258fSBjoern A. Zeeb { 85018e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 8502e2340276SBjoern A. Zeeb const struct rtw89_btc_ver *ver = btc->ver; 85038e93258fSBjoern A. Zeeb struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; 8504e2340276SBjoern A. Zeeb union rtw89_btc_fbtc_cysta_info *pcysta; 8505e2340276SBjoern A. Zeeb u32 except_cnt, exception_map; 85068e93258fSBjoern A. Zeeb 85078e93258fSBjoern A. Zeeb pcysta = &pfwinfo->rpt_fbtc_cysta.finfo; 8508e2340276SBjoern A. Zeeb if (ver->fcxcysta == 2) { 8509e2340276SBjoern A. Zeeb pcysta->v2 = pfwinfo->rpt_fbtc_cysta.finfo.v2; 8510e2340276SBjoern A. Zeeb except_cnt = le32_to_cpu(pcysta->v2.except_cnt); 8511e2340276SBjoern A. Zeeb exception_map = le32_to_cpu(pcysta->v2.exception); 8512e2340276SBjoern A. Zeeb } else if (ver->fcxcysta == 3) { 8513e2340276SBjoern A. Zeeb pcysta->v3 = pfwinfo->rpt_fbtc_cysta.finfo.v3; 8514e2340276SBjoern A. Zeeb except_cnt = le32_to_cpu(pcysta->v3.except_cnt); 8515e2340276SBjoern A. Zeeb exception_map = le32_to_cpu(pcysta->v3.except_map); 8516e2340276SBjoern A. Zeeb } else if (ver->fcxcysta == 4) { 8517e2340276SBjoern A. Zeeb pcysta->v4 = pfwinfo->rpt_fbtc_cysta.finfo.v4; 8518e2340276SBjoern A. Zeeb except_cnt = pcysta->v4.except_cnt; 8519e2340276SBjoern A. Zeeb exception_map = le32_to_cpu(pcysta->v4.except_map); 8520e2340276SBjoern A. Zeeb } else if (ver->fcxcysta == 5) { 8521e2340276SBjoern A. Zeeb pcysta->v5 = pfwinfo->rpt_fbtc_cysta.finfo.v5; 8522e2340276SBjoern A. Zeeb except_cnt = pcysta->v5.except_cnt; 8523e2340276SBjoern A. Zeeb exception_map = le32_to_cpu(pcysta->v5.except_map); 8524*6d67aabdSBjoern A. Zeeb } else if (ver->fcxcysta == 7) { 8525*6d67aabdSBjoern A. Zeeb pcysta->v7 = pfwinfo->rpt_fbtc_cysta.finfo.v7; 8526*6d67aabdSBjoern A. Zeeb except_cnt = pcysta->v7.except_cnt; 8527*6d67aabdSBjoern A. Zeeb exception_map = le32_to_cpu(pcysta->v7.except_map); 8528e2340276SBjoern A. Zeeb } else { 8529e2340276SBjoern A. Zeeb return; 8530e2340276SBjoern A. Zeeb } 85318e93258fSBjoern A. Zeeb 8532e2340276SBjoern A. Zeeb if (pfwinfo->event[BTF_EVNT_BUF_OVERFLOW] == 0 && except_cnt == 0 && 85338e93258fSBjoern A. Zeeb !pfwinfo->len_mismch && !pfwinfo->fver_mismch) 85348e93258fSBjoern A. Zeeb return; 85358e93258fSBjoern A. Zeeb 85368e93258fSBjoern A. Zeeb seq_printf(m, " %-15s : ", "[error]"); 85378e93258fSBjoern A. Zeeb 85388e93258fSBjoern A. Zeeb if (pfwinfo->event[BTF_EVNT_BUF_OVERFLOW]) { 85398e93258fSBjoern A. Zeeb seq_printf(m, 85408e93258fSBjoern A. Zeeb "overflow-cnt: %d, ", 85418e93258fSBjoern A. Zeeb pfwinfo->event[BTF_EVNT_BUF_OVERFLOW]); 85428e93258fSBjoern A. Zeeb } 85438e93258fSBjoern A. Zeeb 85448e93258fSBjoern A. Zeeb if (pfwinfo->len_mismch) { 85458e93258fSBjoern A. Zeeb seq_printf(m, 85468e93258fSBjoern A. Zeeb "len-mismatch: 0x%x, ", 85478e93258fSBjoern A. Zeeb pfwinfo->len_mismch); 85488e93258fSBjoern A. Zeeb } 85498e93258fSBjoern A. Zeeb 85508e93258fSBjoern A. Zeeb if (pfwinfo->fver_mismch) { 85518e93258fSBjoern A. Zeeb seq_printf(m, 85528e93258fSBjoern A. Zeeb "fver-mismatch: 0x%x, ", 85538e93258fSBjoern A. Zeeb pfwinfo->fver_mismch); 85548e93258fSBjoern A. Zeeb } 85558e93258fSBjoern A. Zeeb 85568e93258fSBjoern A. Zeeb /* cycle statistics exceptions */ 8557e2340276SBjoern A. Zeeb if (exception_map || except_cnt) { 85588e93258fSBjoern A. Zeeb seq_printf(m, 85598e93258fSBjoern A. Zeeb "exception-type: 0x%x, exception-cnt = %d", 8560e2340276SBjoern A. Zeeb exception_map, except_cnt); 85618e93258fSBjoern A. Zeeb } 85628e93258fSBjoern A. Zeeb seq_puts(m, "\n"); 85638e93258fSBjoern A. Zeeb } 85648e93258fSBjoern A. Zeeb 85658e93258fSBjoern A. Zeeb static void _show_fbtc_tdma(struct rtw89_dev *rtwdev, struct seq_file *m) 85668e93258fSBjoern A. Zeeb { 85678e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 8568e2340276SBjoern A. Zeeb const struct rtw89_btc_ver *ver = btc->ver; 85698e93258fSBjoern A. Zeeb struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; 85708e93258fSBjoern A. Zeeb struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; 85718e93258fSBjoern A. Zeeb struct rtw89_btc_fbtc_tdma *t = NULL; 85728e93258fSBjoern A. Zeeb 85738e93258fSBjoern A. Zeeb pcinfo = &pfwinfo->rpt_fbtc_tdma.cinfo; 85748e93258fSBjoern A. Zeeb if (!pcinfo->valid) 85758e93258fSBjoern A. Zeeb return; 85768e93258fSBjoern A. Zeeb 8577e2340276SBjoern A. Zeeb if (ver->fcxtdma == 1) 8578e2340276SBjoern A. Zeeb t = &pfwinfo->rpt_fbtc_tdma.finfo.v1; 8579e2340276SBjoern A. Zeeb else 8580e2340276SBjoern A. Zeeb t = &pfwinfo->rpt_fbtc_tdma.finfo.v3.tdma; 85818e93258fSBjoern A. Zeeb 85828e93258fSBjoern A. Zeeb seq_printf(m, 85838e93258fSBjoern A. Zeeb " %-15s : ", "[tdma_policy]"); 85848e93258fSBjoern A. Zeeb seq_printf(m, 85858e93258fSBjoern A. Zeeb "type:%d, rx_flow_ctrl:%d, tx_pause:%d, ", 85868e93258fSBjoern A. Zeeb (u32)t->type, 85878e93258fSBjoern A. Zeeb t->rxflctrl, t->txpause); 85888e93258fSBjoern A. Zeeb 85898e93258fSBjoern A. Zeeb seq_printf(m, 85908e93258fSBjoern A. Zeeb "wl_toggle_n:%d, leak_n:%d, ext_ctrl:%d, ", 85918e93258fSBjoern A. Zeeb t->wtgle_n, t->leak_n, t->ext_ctrl); 85928e93258fSBjoern A. Zeeb 85938e93258fSBjoern A. Zeeb seq_printf(m, 85948e93258fSBjoern A. Zeeb "policy_type:%d", 85958e93258fSBjoern A. Zeeb (u32)btc->policy_type); 85968e93258fSBjoern A. Zeeb 85978e93258fSBjoern A. Zeeb seq_puts(m, "\n"); 85988e93258fSBjoern A. Zeeb } 85998e93258fSBjoern A. Zeeb 86008e93258fSBjoern A. Zeeb static void _show_fbtc_slots(struct rtw89_dev *rtwdev, struct seq_file *m) 86018e93258fSBjoern A. Zeeb { 86028e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 8603e2340276SBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 8604*6d67aabdSBjoern A. Zeeb u16 dur, cxtype; 8605*6d67aabdSBjoern A. Zeeb u32 tbl; 86068e93258fSBjoern A. Zeeb u8 i = 0; 86078e93258fSBjoern A. Zeeb 86088e93258fSBjoern A. Zeeb for (i = 0; i < CXST_MAX; i++) { 8609*6d67aabdSBjoern A. Zeeb if (btc->ver->fcxslots == 1) { 8610*6d67aabdSBjoern A. Zeeb dur = le16_to_cpu(dm->slot_now.v1[i].dur); 8611*6d67aabdSBjoern A. Zeeb tbl = le32_to_cpu(dm->slot_now.v1[i].cxtbl); 8612*6d67aabdSBjoern A. Zeeb cxtype = le16_to_cpu(dm->slot_now.v1[i].cxtype); 8613*6d67aabdSBjoern A. Zeeb } else if (btc->ver->fcxslots == 7) { 8614*6d67aabdSBjoern A. Zeeb dur = le16_to_cpu(dm->slot_now.v7[i].dur); 8615*6d67aabdSBjoern A. Zeeb tbl = le32_to_cpu(dm->slot_now.v7[i].cxtbl); 8616*6d67aabdSBjoern A. Zeeb cxtype = le16_to_cpu(dm->slot_now.v7[i].cxtype); 8617*6d67aabdSBjoern A. Zeeb } else { 8618*6d67aabdSBjoern A. Zeeb return; 8619*6d67aabdSBjoern A. Zeeb } 8620*6d67aabdSBjoern A. Zeeb 8621e2340276SBjoern A. Zeeb if (i % 5 == 0) 86228e93258fSBjoern A. Zeeb seq_printf(m, 8623e2340276SBjoern A. Zeeb " %-15s : %5s[%03d/0x%x/%d]", 86248e93258fSBjoern A. Zeeb "[slot_list]", 8625e2340276SBjoern A. Zeeb id_to_slot((u32)i), 8626*6d67aabdSBjoern A. Zeeb dur, tbl, cxtype); 86278e93258fSBjoern A. Zeeb else 86288e93258fSBjoern A. Zeeb seq_printf(m, 8629e2340276SBjoern A. Zeeb ", %5s[%03d/0x%x/%d]", 8630e2340276SBjoern A. Zeeb id_to_slot((u32)i), 8631*6d67aabdSBjoern A. Zeeb dur, tbl, cxtype); 8632*6d67aabdSBjoern A. Zeeb 8633e2340276SBjoern A. Zeeb if (i % 5 == 4) 86348e93258fSBjoern A. Zeeb seq_puts(m, "\n"); 86358e93258fSBjoern A. Zeeb } 8636e2340276SBjoern A. Zeeb seq_puts(m, "\n"); 86378e93258fSBjoern A. Zeeb } 86388e93258fSBjoern A. Zeeb 8639e2340276SBjoern A. Zeeb static void _show_fbtc_cysta_v2(struct rtw89_dev *rtwdev, struct seq_file *m) 86408e93258fSBjoern A. Zeeb { 86418e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 86428e93258fSBjoern A. Zeeb struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; 86438e93258fSBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 86448e93258fSBjoern A. Zeeb struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc; 86458e93258fSBjoern A. Zeeb struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; 8646e2340276SBjoern A. Zeeb struct rtw89_btc_fbtc_cysta_v2 *pcysta_le32 = NULL; 86478e93258fSBjoern A. Zeeb union rtw89_btc_fbtc_rxflct r; 86488e93258fSBjoern A. Zeeb u8 i, cnt = 0, slot_pair; 86498e93258fSBjoern A. Zeeb u16 cycle, c_begin, c_end, store_index; 86508e93258fSBjoern A. Zeeb 86518e93258fSBjoern A. Zeeb pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; 86528e93258fSBjoern A. Zeeb if (!pcinfo->valid) 86538e93258fSBjoern A. Zeeb return; 86548e93258fSBjoern A. Zeeb 8655e2340276SBjoern A. Zeeb pcysta_le32 = &pfwinfo->rpt_fbtc_cysta.finfo.v2; 86568e93258fSBjoern A. Zeeb seq_printf(m, 86578e93258fSBjoern A. Zeeb " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]", 8658e2340276SBjoern A. Zeeb "[cycle_cnt]", 8659e2340276SBjoern A. Zeeb le16_to_cpu(pcysta_le32->cycles), 8660e2340276SBjoern A. Zeeb le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_ALL]), 8661e2340276SBjoern A. Zeeb le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_ALL_OK]), 8662e2340276SBjoern A. Zeeb le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_BT_SLOT]), 8663e2340276SBjoern A. Zeeb le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_BT_OK])); 86648e93258fSBjoern A. Zeeb 86658e93258fSBjoern A. Zeeb for (i = 0; i < CXST_MAX; i++) { 8666e2340276SBjoern A. Zeeb if (!le32_to_cpu(pcysta_le32->slot_cnt[i])) 86678e93258fSBjoern A. Zeeb continue; 8668e2340276SBjoern A. Zeeb seq_printf(m, ", %s:%d", id_to_slot((u32)i), 8669e2340276SBjoern A. Zeeb le32_to_cpu(pcysta_le32->slot_cnt[i])); 86708e93258fSBjoern A. Zeeb } 86718e93258fSBjoern A. Zeeb 86728e93258fSBjoern A. Zeeb if (dm->tdma_now.rxflctrl) { 8673e2340276SBjoern A. Zeeb seq_printf(m, ", leak_rx:%d", 8674e2340276SBjoern A. Zeeb le32_to_cpu(pcysta_le32->leakrx_cnt)); 86758e93258fSBjoern A. Zeeb } 86768e93258fSBjoern A. Zeeb 8677e2340276SBjoern A. Zeeb if (le32_to_cpu(pcysta_le32->collision_cnt)) { 8678e2340276SBjoern A. Zeeb seq_printf(m, ", collision:%d", 8679e2340276SBjoern A. Zeeb le32_to_cpu(pcysta_le32->collision_cnt)); 86808e93258fSBjoern A. Zeeb } 86818e93258fSBjoern A. Zeeb 8682e2340276SBjoern A. Zeeb if (le32_to_cpu(pcysta_le32->skip_cnt)) { 8683e2340276SBjoern A. Zeeb seq_printf(m, ", skip:%d", 8684e2340276SBjoern A. Zeeb le32_to_cpu(pcysta_le32->skip_cnt)); 86858e93258fSBjoern A. Zeeb } 86868e93258fSBjoern A. Zeeb seq_puts(m, "\n"); 86878e93258fSBjoern A. Zeeb 86888e93258fSBjoern A. Zeeb seq_printf(m, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]", 86898e93258fSBjoern A. Zeeb "[cycle_time]", 8690e2340276SBjoern A. Zeeb le16_to_cpu(pcysta_le32->tavg_cycle[CXT_WL]), 8691e2340276SBjoern A. Zeeb le16_to_cpu(pcysta_le32->tavg_cycle[CXT_BT]), 8692e2340276SBjoern A. Zeeb le16_to_cpu(pcysta_le32->tavg_lk) / 1000, 8693e2340276SBjoern A. Zeeb le16_to_cpu(pcysta_le32->tavg_lk) % 1000); 8694e2340276SBjoern A. Zeeb seq_printf(m, ", max_t[wl:%d/bt:%d/lk:%d.%03d]", 8695e2340276SBjoern A. Zeeb le16_to_cpu(pcysta_le32->tmax_cycle[CXT_WL]), 8696e2340276SBjoern A. Zeeb le16_to_cpu(pcysta_le32->tmax_cycle[CXT_BT]), 8697e2340276SBjoern A. Zeeb le16_to_cpu(pcysta_le32->tmax_lk) / 1000, 8698e2340276SBjoern A. Zeeb le16_to_cpu(pcysta_le32->tmax_lk) % 1000); 8699e2340276SBjoern A. Zeeb seq_printf(m, ", maxdiff_t[wl:%d/bt:%d]\n", 8700e2340276SBjoern A. Zeeb le16_to_cpu(pcysta_le32->tmaxdiff_cycle[CXT_WL]), 8701e2340276SBjoern A. Zeeb le16_to_cpu(pcysta_le32->tmaxdiff_cycle[CXT_BT])); 87028e93258fSBjoern A. Zeeb 8703e2340276SBjoern A. Zeeb if (le16_to_cpu(pcysta_le32->cycles) <= 1) 87048e93258fSBjoern A. Zeeb return; 87058e93258fSBjoern A. Zeeb 87068e93258fSBjoern A. Zeeb /* 1 cycle record 1 wl-slot and 1 bt-slot */ 87078e93258fSBjoern A. Zeeb slot_pair = BTC_CYCLE_SLOT_MAX / 2; 87088e93258fSBjoern A. Zeeb 8709e2340276SBjoern A. Zeeb if (le16_to_cpu(pcysta_le32->cycles) <= slot_pair) 87108e93258fSBjoern A. Zeeb c_begin = 1; 87118e93258fSBjoern A. Zeeb else 8712e2340276SBjoern A. Zeeb c_begin = le16_to_cpu(pcysta_le32->cycles) - slot_pair + 1; 87138e93258fSBjoern A. Zeeb 8714e2340276SBjoern A. Zeeb c_end = le16_to_cpu(pcysta_le32->cycles); 87158e93258fSBjoern A. Zeeb 87168e93258fSBjoern A. Zeeb for (cycle = c_begin; cycle <= c_end; cycle++) { 87178e93258fSBjoern A. Zeeb cnt++; 87188e93258fSBjoern A. Zeeb store_index = ((cycle - 1) % slot_pair) * 2; 87198e93258fSBjoern A. Zeeb 87208e93258fSBjoern A. Zeeb if (cnt % (BTC_CYCLE_SLOT_MAX / 4) == 1) 87218e93258fSBjoern A. Zeeb seq_printf(m, 87228e93258fSBjoern A. Zeeb " %-15s : ->b%02d->w%02d", "[cycle_step]", 8723e2340276SBjoern A. Zeeb le16_to_cpu(pcysta_le32->tslot_cycle[store_index]), 8724e2340276SBjoern A. Zeeb le16_to_cpu(pcysta_le32->tslot_cycle[store_index + 1])); 87258e93258fSBjoern A. Zeeb else 87268e93258fSBjoern A. Zeeb seq_printf(m, 87278e93258fSBjoern A. Zeeb "->b%02d->w%02d", 8728e2340276SBjoern A. Zeeb le16_to_cpu(pcysta_le32->tslot_cycle[store_index]), 8729e2340276SBjoern A. Zeeb le16_to_cpu(pcysta_le32->tslot_cycle[store_index + 1])); 87308e93258fSBjoern A. Zeeb if (cnt % (BTC_CYCLE_SLOT_MAX / 4) == 0 || cnt == c_end) 87318e93258fSBjoern A. Zeeb seq_puts(m, "\n"); 87328e93258fSBjoern A. Zeeb } 87338e93258fSBjoern A. Zeeb 87348e93258fSBjoern A. Zeeb if (a2dp->exist) { 87358e93258fSBjoern A. Zeeb seq_printf(m, 87368e93258fSBjoern A. Zeeb " %-15s : a2dp_ept:%d, a2dp_late:%d", 87378e93258fSBjoern A. Zeeb "[a2dp_t_sta]", 8738e2340276SBjoern A. Zeeb le16_to_cpu(pcysta_le32->a2dpept), 8739e2340276SBjoern A. Zeeb le16_to_cpu(pcysta_le32->a2dpeptto)); 87408e93258fSBjoern A. Zeeb 87418e93258fSBjoern A. Zeeb seq_printf(m, 87428e93258fSBjoern A. Zeeb ", avg_t:%d, max_t:%d", 8743e2340276SBjoern A. Zeeb le16_to_cpu(pcysta_le32->tavg_a2dpept), 8744e2340276SBjoern A. Zeeb le16_to_cpu(pcysta_le32->tmax_a2dpept)); 87458e93258fSBjoern A. Zeeb r.val = dm->tdma_now.rxflctrl; 87468e93258fSBjoern A. Zeeb 87478e93258fSBjoern A. Zeeb if (r.type && r.tgln_n) { 87488e93258fSBjoern A. Zeeb seq_printf(m, 87498e93258fSBjoern A. Zeeb ", cycle[PSTDMA:%d/TDMA:%d], ", 8750e2340276SBjoern A. Zeeb le16_to_cpu(pcysta_le32->cycles_a2dp[CXT_FLCTRL_ON]), 8751e2340276SBjoern A. Zeeb le16_to_cpu(pcysta_le32->cycles_a2dp[CXT_FLCTRL_OFF])); 87528e93258fSBjoern A. Zeeb 87538e93258fSBjoern A. Zeeb seq_printf(m, 87548e93258fSBjoern A. Zeeb "avg_t[PSTDMA:%d/TDMA:%d], ", 8755e2340276SBjoern A. Zeeb le16_to_cpu(pcysta_le32->tavg_a2dp[CXT_FLCTRL_ON]), 8756e2340276SBjoern A. Zeeb le16_to_cpu(pcysta_le32->tavg_a2dp[CXT_FLCTRL_OFF])); 87578e93258fSBjoern A. Zeeb 87588e93258fSBjoern A. Zeeb seq_printf(m, 87598e93258fSBjoern A. Zeeb "max_t[PSTDMA:%d/TDMA:%d]", 8760e2340276SBjoern A. Zeeb le16_to_cpu(pcysta_le32->tmax_a2dp[CXT_FLCTRL_ON]), 8761e2340276SBjoern A. Zeeb le16_to_cpu(pcysta_le32->tmax_a2dp[CXT_FLCTRL_OFF])); 87628e93258fSBjoern A. Zeeb } 87638e93258fSBjoern A. Zeeb seq_puts(m, "\n"); 87648e93258fSBjoern A. Zeeb } 87658e93258fSBjoern A. Zeeb } 87668e93258fSBjoern A. Zeeb 8767e2340276SBjoern A. Zeeb static void _show_fbtc_cysta_v3(struct rtw89_dev *rtwdev, struct seq_file *m) 8768e2340276SBjoern A. Zeeb { 8769e2340276SBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 8770e2340276SBjoern A. Zeeb struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc; 8771e2340276SBjoern A. Zeeb struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; 8772e2340276SBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 8773e2340276SBjoern A. Zeeb struct rtw89_btc_fbtc_a2dp_trx_stat *a2dp_trx; 8774e2340276SBjoern A. Zeeb struct rtw89_btc_fbtc_cysta_v3 *pcysta; 8775e2340276SBjoern A. Zeeb struct rtw89_btc_rpt_cmn_info *pcinfo; 8776e2340276SBjoern A. Zeeb u8 i, cnt = 0, slot_pair, divide_cnt; 8777e2340276SBjoern A. Zeeb u16 cycle, c_begin, c_end, store_index; 8778e2340276SBjoern A. Zeeb 8779e2340276SBjoern A. Zeeb pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; 8780e2340276SBjoern A. Zeeb if (!pcinfo->valid) 8781e2340276SBjoern A. Zeeb return; 8782e2340276SBjoern A. Zeeb 8783e2340276SBjoern A. Zeeb pcysta = &pfwinfo->rpt_fbtc_cysta.finfo.v3; 8784e2340276SBjoern A. Zeeb seq_printf(m, 8785e2340276SBjoern A. Zeeb " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]", 8786e2340276SBjoern A. Zeeb "[cycle_cnt]", 8787e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->cycles), 8788e2340276SBjoern A. Zeeb le32_to_cpu(pcysta->bcn_cnt[CXBCN_ALL]), 8789e2340276SBjoern A. Zeeb le32_to_cpu(pcysta->bcn_cnt[CXBCN_ALL_OK]), 8790e2340276SBjoern A. Zeeb le32_to_cpu(pcysta->bcn_cnt[CXBCN_BT_SLOT]), 8791e2340276SBjoern A. Zeeb le32_to_cpu(pcysta->bcn_cnt[CXBCN_BT_OK])); 8792e2340276SBjoern A. Zeeb 8793e2340276SBjoern A. Zeeb for (i = 0; i < CXST_MAX; i++) { 8794e2340276SBjoern A. Zeeb if (!le32_to_cpu(pcysta->slot_cnt[i])) 8795e2340276SBjoern A. Zeeb continue; 8796e2340276SBjoern A. Zeeb 8797e2340276SBjoern A. Zeeb seq_printf(m, ", %s:%d", id_to_slot(i), 8798e2340276SBjoern A. Zeeb le32_to_cpu(pcysta->slot_cnt[i])); 8799e2340276SBjoern A. Zeeb } 8800e2340276SBjoern A. Zeeb 8801e2340276SBjoern A. Zeeb if (dm->tdma_now.rxflctrl) 8802e2340276SBjoern A. Zeeb seq_printf(m, ", leak_rx:%d", le32_to_cpu(pcysta->leak_slot.cnt_rximr)); 8803e2340276SBjoern A. Zeeb 8804e2340276SBjoern A. Zeeb if (le32_to_cpu(pcysta->collision_cnt)) 8805e2340276SBjoern A. Zeeb seq_printf(m, ", collision:%d", le32_to_cpu(pcysta->collision_cnt)); 8806e2340276SBjoern A. Zeeb 8807e2340276SBjoern A. Zeeb if (le32_to_cpu(pcysta->skip_cnt)) 8808e2340276SBjoern A. Zeeb seq_printf(m, ", skip:%d", le32_to_cpu(pcysta->skip_cnt)); 8809e2340276SBjoern A. Zeeb 8810e2340276SBjoern A. Zeeb seq_puts(m, "\n"); 8811e2340276SBjoern A. Zeeb 8812e2340276SBjoern A. Zeeb seq_printf(m, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]", 8813e2340276SBjoern A. Zeeb "[cycle_time]", 8814e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->cycle_time.tavg[CXT_WL]), 8815e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->cycle_time.tavg[CXT_BT]), 8816e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->leak_slot.tavg) / 1000, 8817e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->leak_slot.tavg) % 1000); 8818e2340276SBjoern A. Zeeb seq_printf(m, 8819e2340276SBjoern A. Zeeb ", max_t[wl:%d/bt:%d/lk:%d.%03d]", 8820e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->cycle_time.tmax[CXT_WL]), 8821e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->cycle_time.tmax[CXT_BT]), 8822e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->leak_slot.tmax) / 1000, 8823e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->leak_slot.tmax) % 1000); 8824e2340276SBjoern A. Zeeb seq_printf(m, 8825e2340276SBjoern A. Zeeb ", maxdiff_t[wl:%d/bt:%d]\n", 8826e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_WL]), 8827e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_BT])); 8828e2340276SBjoern A. Zeeb 8829e2340276SBjoern A. Zeeb cycle = le16_to_cpu(pcysta->cycles); 8830e2340276SBjoern A. Zeeb if (cycle <= 1) 8831e2340276SBjoern A. Zeeb return; 8832e2340276SBjoern A. Zeeb 8833e2340276SBjoern A. Zeeb /* 1 cycle record 1 wl-slot and 1 bt-slot */ 8834e2340276SBjoern A. Zeeb slot_pair = BTC_CYCLE_SLOT_MAX / 2; 8835e2340276SBjoern A. Zeeb 8836e2340276SBjoern A. Zeeb if (cycle <= slot_pair) 8837e2340276SBjoern A. Zeeb c_begin = 1; 8838e2340276SBjoern A. Zeeb else 8839e2340276SBjoern A. Zeeb c_begin = cycle - slot_pair + 1; 8840e2340276SBjoern A. Zeeb 8841e2340276SBjoern A. Zeeb c_end = cycle; 8842e2340276SBjoern A. Zeeb 8843e2340276SBjoern A. Zeeb if (a2dp->exist) 8844e2340276SBjoern A. Zeeb divide_cnt = 3; 8845e2340276SBjoern A. Zeeb else 8846e2340276SBjoern A. Zeeb divide_cnt = BTC_CYCLE_SLOT_MAX / 4; 8847e2340276SBjoern A. Zeeb 8848e2340276SBjoern A. Zeeb for (cycle = c_begin; cycle <= c_end; cycle++) { 8849e2340276SBjoern A. Zeeb cnt++; 8850e2340276SBjoern A. Zeeb store_index = ((cycle - 1) % slot_pair) * 2; 8851e2340276SBjoern A. Zeeb 8852e2340276SBjoern A. Zeeb if (cnt % divide_cnt == 1) 8853e2340276SBjoern A. Zeeb seq_printf(m, " %-15s : ", "[cycle_step]"); 8854e2340276SBjoern A. Zeeb 8855e2340276SBjoern A. Zeeb seq_printf(m, "->b%02d", 8856e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->slot_step_time[store_index])); 8857e2340276SBjoern A. Zeeb if (a2dp->exist) { 8858e2340276SBjoern A. Zeeb a2dp_trx = &pcysta->a2dp_trx[store_index]; 8859e2340276SBjoern A. Zeeb seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", 8860e2340276SBjoern A. Zeeb a2dp_trx->empty_cnt, 8861e2340276SBjoern A. Zeeb a2dp_trx->retry_cnt, 8862e2340276SBjoern A. Zeeb a2dp_trx->tx_rate ? 3 : 2, 8863e2340276SBjoern A. Zeeb a2dp_trx->tx_cnt, 8864e2340276SBjoern A. Zeeb a2dp_trx->ack_cnt, 8865e2340276SBjoern A. Zeeb a2dp_trx->nack_cnt); 8866e2340276SBjoern A. Zeeb } 8867e2340276SBjoern A. Zeeb seq_printf(m, "->w%02d", 8868e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->slot_step_time[store_index + 1])); 8869e2340276SBjoern A. Zeeb if (a2dp->exist) { 8870e2340276SBjoern A. Zeeb a2dp_trx = &pcysta->a2dp_trx[store_index + 1]; 8871e2340276SBjoern A. Zeeb seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", 8872e2340276SBjoern A. Zeeb a2dp_trx->empty_cnt, 8873e2340276SBjoern A. Zeeb a2dp_trx->retry_cnt, 8874e2340276SBjoern A. Zeeb a2dp_trx->tx_rate ? 3 : 2, 8875e2340276SBjoern A. Zeeb a2dp_trx->tx_cnt, 8876e2340276SBjoern A. Zeeb a2dp_trx->ack_cnt, 8877e2340276SBjoern A. Zeeb a2dp_trx->nack_cnt); 8878e2340276SBjoern A. Zeeb } 8879e2340276SBjoern A. Zeeb if (cnt % divide_cnt == 0 || cnt == c_end) 8880e2340276SBjoern A. Zeeb seq_puts(m, "\n"); 8881e2340276SBjoern A. Zeeb } 8882e2340276SBjoern A. Zeeb 8883e2340276SBjoern A. Zeeb if (a2dp->exist) { 8884e2340276SBjoern A. Zeeb seq_printf(m, " %-15s : a2dp_ept:%d, a2dp_late:%d", 8885e2340276SBjoern A. Zeeb "[a2dp_t_sta]", 8886e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->a2dp_ept.cnt), 8887e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->a2dp_ept.cnt_timeout)); 8888e2340276SBjoern A. Zeeb 8889e2340276SBjoern A. Zeeb seq_printf(m, ", avg_t:%d, max_t:%d", 8890e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->a2dp_ept.tavg), 8891e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->a2dp_ept.tmax)); 8892e2340276SBjoern A. Zeeb 8893e2340276SBjoern A. Zeeb seq_puts(m, "\n"); 8894e2340276SBjoern A. Zeeb } 8895e2340276SBjoern A. Zeeb } 8896e2340276SBjoern A. Zeeb 8897e2340276SBjoern A. Zeeb static void _show_fbtc_cysta_v4(struct rtw89_dev *rtwdev, struct seq_file *m) 8898e2340276SBjoern A. Zeeb { 8899e2340276SBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 8900e2340276SBjoern A. Zeeb struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc; 8901e2340276SBjoern A. Zeeb struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; 8902e2340276SBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 8903e2340276SBjoern A. Zeeb struct rtw89_btc_fbtc_a2dp_trx_stat_v4 *a2dp_trx; 8904e2340276SBjoern A. Zeeb struct rtw89_btc_fbtc_cysta_v4 *pcysta; 8905e2340276SBjoern A. Zeeb struct rtw89_btc_rpt_cmn_info *pcinfo; 8906e2340276SBjoern A. Zeeb u8 i, cnt = 0, slot_pair, divide_cnt; 8907e2340276SBjoern A. Zeeb u16 cycle, c_begin, c_end, store_index; 8908e2340276SBjoern A. Zeeb 8909e2340276SBjoern A. Zeeb pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; 8910e2340276SBjoern A. Zeeb if (!pcinfo->valid) 8911e2340276SBjoern A. Zeeb return; 8912e2340276SBjoern A. Zeeb 8913e2340276SBjoern A. Zeeb pcysta = &pfwinfo->rpt_fbtc_cysta.finfo.v4; 8914e2340276SBjoern A. Zeeb seq_printf(m, 8915e2340276SBjoern A. Zeeb " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]", 8916e2340276SBjoern A. Zeeb "[cycle_cnt]", 8917e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->cycles), 8918e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL]), 8919e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL_OK]), 8920e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_SLOT]), 8921e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_OK])); 8922e2340276SBjoern A. Zeeb 8923e2340276SBjoern A. Zeeb for (i = 0; i < CXST_MAX; i++) { 8924e2340276SBjoern A. Zeeb if (!le16_to_cpu(pcysta->slot_cnt[i])) 8925e2340276SBjoern A. Zeeb continue; 8926e2340276SBjoern A. Zeeb 8927e2340276SBjoern A. Zeeb seq_printf(m, ", %s:%d", id_to_slot(i), 8928e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->slot_cnt[i])); 8929e2340276SBjoern A. Zeeb } 8930e2340276SBjoern A. Zeeb 8931e2340276SBjoern A. Zeeb if (dm->tdma_now.rxflctrl) 8932e2340276SBjoern A. Zeeb seq_printf(m, ", leak_rx:%d", 8933e2340276SBjoern A. Zeeb le32_to_cpu(pcysta->leak_slot.cnt_rximr)); 8934e2340276SBjoern A. Zeeb 8935e2340276SBjoern A. Zeeb if (pcysta->collision_cnt) 8936e2340276SBjoern A. Zeeb seq_printf(m, ", collision:%d", pcysta->collision_cnt); 8937e2340276SBjoern A. Zeeb 8938e2340276SBjoern A. Zeeb if (le16_to_cpu(pcysta->skip_cnt)) 8939e2340276SBjoern A. Zeeb seq_printf(m, ", skip:%d", 8940e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->skip_cnt)); 8941e2340276SBjoern A. Zeeb 8942e2340276SBjoern A. Zeeb seq_puts(m, "\n"); 8943e2340276SBjoern A. Zeeb 8944e2340276SBjoern A. Zeeb seq_printf(m, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]", 8945e2340276SBjoern A. Zeeb "[cycle_time]", 8946e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->cycle_time.tavg[CXT_WL]), 8947e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->cycle_time.tavg[CXT_BT]), 8948e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->leak_slot.tavg) / 1000, 8949e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->leak_slot.tavg) % 1000); 8950e2340276SBjoern A. Zeeb seq_printf(m, 8951e2340276SBjoern A. Zeeb ", max_t[wl:%d/bt:%d/lk:%d.%03d]", 8952e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->cycle_time.tmax[CXT_WL]), 8953e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->cycle_time.tmax[CXT_BT]), 8954e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->leak_slot.tmax) / 1000, 8955e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->leak_slot.tmax) % 1000); 8956e2340276SBjoern A. Zeeb seq_printf(m, 8957e2340276SBjoern A. Zeeb ", maxdiff_t[wl:%d/bt:%d]\n", 8958e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_WL]), 8959e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_BT])); 8960e2340276SBjoern A. Zeeb 8961e2340276SBjoern A. Zeeb cycle = le16_to_cpu(pcysta->cycles); 8962e2340276SBjoern A. Zeeb if (cycle <= 1) 8963e2340276SBjoern A. Zeeb return; 8964e2340276SBjoern A. Zeeb 8965e2340276SBjoern A. Zeeb /* 1 cycle record 1 wl-slot and 1 bt-slot */ 8966e2340276SBjoern A. Zeeb slot_pair = BTC_CYCLE_SLOT_MAX / 2; 8967e2340276SBjoern A. Zeeb 8968e2340276SBjoern A. Zeeb if (cycle <= slot_pair) 8969e2340276SBjoern A. Zeeb c_begin = 1; 8970e2340276SBjoern A. Zeeb else 8971e2340276SBjoern A. Zeeb c_begin = cycle - slot_pair + 1; 8972e2340276SBjoern A. Zeeb 8973e2340276SBjoern A. Zeeb c_end = cycle; 8974e2340276SBjoern A. Zeeb 8975e2340276SBjoern A. Zeeb if (a2dp->exist) 8976e2340276SBjoern A. Zeeb divide_cnt = 3; 8977e2340276SBjoern A. Zeeb else 8978e2340276SBjoern A. Zeeb divide_cnt = BTC_CYCLE_SLOT_MAX / 4; 8979e2340276SBjoern A. Zeeb 8980e2340276SBjoern A. Zeeb for (cycle = c_begin; cycle <= c_end; cycle++) { 8981e2340276SBjoern A. Zeeb cnt++; 8982e2340276SBjoern A. Zeeb store_index = ((cycle - 1) % slot_pair) * 2; 8983e2340276SBjoern A. Zeeb 8984e2340276SBjoern A. Zeeb if (cnt % divide_cnt == 1) 8985e2340276SBjoern A. Zeeb seq_printf(m, " %-15s : ", "[cycle_step]"); 8986e2340276SBjoern A. Zeeb 8987e2340276SBjoern A. Zeeb seq_printf(m, "->b%02d", 8988e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->slot_step_time[store_index])); 8989e2340276SBjoern A. Zeeb if (a2dp->exist) { 8990e2340276SBjoern A. Zeeb a2dp_trx = &pcysta->a2dp_trx[store_index]; 8991e2340276SBjoern A. Zeeb seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", 8992e2340276SBjoern A. Zeeb a2dp_trx->empty_cnt, 8993e2340276SBjoern A. Zeeb a2dp_trx->retry_cnt, 8994e2340276SBjoern A. Zeeb a2dp_trx->tx_rate ? 3 : 2, 8995e2340276SBjoern A. Zeeb a2dp_trx->tx_cnt, 8996e2340276SBjoern A. Zeeb a2dp_trx->ack_cnt, 8997e2340276SBjoern A. Zeeb a2dp_trx->nack_cnt); 8998e2340276SBjoern A. Zeeb } 8999e2340276SBjoern A. Zeeb seq_printf(m, "->w%02d", 9000e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->slot_step_time[store_index + 1])); 9001e2340276SBjoern A. Zeeb if (a2dp->exist) { 9002e2340276SBjoern A. Zeeb a2dp_trx = &pcysta->a2dp_trx[store_index + 1]; 9003e2340276SBjoern A. Zeeb seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", 9004e2340276SBjoern A. Zeeb a2dp_trx->empty_cnt, 9005e2340276SBjoern A. Zeeb a2dp_trx->retry_cnt, 9006e2340276SBjoern A. Zeeb a2dp_trx->tx_rate ? 3 : 2, 9007e2340276SBjoern A. Zeeb a2dp_trx->tx_cnt, 9008e2340276SBjoern A. Zeeb a2dp_trx->ack_cnt, 9009e2340276SBjoern A. Zeeb a2dp_trx->nack_cnt); 9010e2340276SBjoern A. Zeeb } 9011e2340276SBjoern A. Zeeb if (cnt % divide_cnt == 0 || cnt == c_end) 9012e2340276SBjoern A. Zeeb seq_puts(m, "\n"); 9013e2340276SBjoern A. Zeeb } 9014e2340276SBjoern A. Zeeb 9015e2340276SBjoern A. Zeeb if (a2dp->exist) { 9016e2340276SBjoern A. Zeeb seq_printf(m, " %-15s : a2dp_ept:%d, a2dp_late:%d", 9017e2340276SBjoern A. Zeeb "[a2dp_t_sta]", 9018e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->a2dp_ept.cnt), 9019e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->a2dp_ept.cnt_timeout)); 9020e2340276SBjoern A. Zeeb 9021e2340276SBjoern A. Zeeb seq_printf(m, ", avg_t:%d, max_t:%d", 9022e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->a2dp_ept.tavg), 9023e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->a2dp_ept.tmax)); 9024e2340276SBjoern A. Zeeb 9025e2340276SBjoern A. Zeeb seq_puts(m, "\n"); 9026e2340276SBjoern A. Zeeb } 9027e2340276SBjoern A. Zeeb } 9028e2340276SBjoern A. Zeeb 9029e2340276SBjoern A. Zeeb static void _show_fbtc_cysta_v5(struct rtw89_dev *rtwdev, struct seq_file *m) 9030e2340276SBjoern A. Zeeb { 9031e2340276SBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 9032e2340276SBjoern A. Zeeb struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc; 9033e2340276SBjoern A. Zeeb struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; 9034e2340276SBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 9035e2340276SBjoern A. Zeeb struct rtw89_btc_fbtc_a2dp_trx_stat_v4 *a2dp_trx; 9036e2340276SBjoern A. Zeeb struct rtw89_btc_fbtc_cysta_v5 *pcysta; 9037e2340276SBjoern A. Zeeb struct rtw89_btc_rpt_cmn_info *pcinfo; 9038e2340276SBjoern A. Zeeb u8 i, cnt = 0, slot_pair, divide_cnt; 9039e2340276SBjoern A. Zeeb u16 cycle, c_begin, c_end, store_index; 9040e2340276SBjoern A. Zeeb 9041e2340276SBjoern A. Zeeb pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; 9042e2340276SBjoern A. Zeeb if (!pcinfo->valid) 9043e2340276SBjoern A. Zeeb return; 9044e2340276SBjoern A. Zeeb 9045e2340276SBjoern A. Zeeb pcysta = &pfwinfo->rpt_fbtc_cysta.finfo.v5; 9046e2340276SBjoern A. Zeeb seq_printf(m, 9047e2340276SBjoern A. Zeeb " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]", 9048e2340276SBjoern A. Zeeb "[cycle_cnt]", 9049e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->cycles), 9050e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL]), 9051e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL_OK]), 9052e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_SLOT]), 9053e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_OK])); 9054e2340276SBjoern A. Zeeb 9055e2340276SBjoern A. Zeeb for (i = 0; i < CXST_MAX; i++) { 9056e2340276SBjoern A. Zeeb if (!le16_to_cpu(pcysta->slot_cnt[i])) 9057e2340276SBjoern A. Zeeb continue; 9058e2340276SBjoern A. Zeeb 9059e2340276SBjoern A. Zeeb seq_printf(m, ", %s:%d", id_to_slot(i), 9060e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->slot_cnt[i])); 9061e2340276SBjoern A. Zeeb } 9062e2340276SBjoern A. Zeeb 9063e2340276SBjoern A. Zeeb if (dm->tdma_now.rxflctrl) 9064e2340276SBjoern A. Zeeb seq_printf(m, ", leak_rx:%d", 9065e2340276SBjoern A. Zeeb le32_to_cpu(pcysta->leak_slot.cnt_rximr)); 9066e2340276SBjoern A. Zeeb 9067e2340276SBjoern A. Zeeb if (pcysta->collision_cnt) 9068e2340276SBjoern A. Zeeb seq_printf(m, ", collision:%d", pcysta->collision_cnt); 9069e2340276SBjoern A. Zeeb 9070e2340276SBjoern A. Zeeb if (le16_to_cpu(pcysta->skip_cnt)) 9071e2340276SBjoern A. Zeeb seq_printf(m, ", skip:%d", 9072e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->skip_cnt)); 9073e2340276SBjoern A. Zeeb 9074e2340276SBjoern A. Zeeb seq_puts(m, "\n"); 9075e2340276SBjoern A. Zeeb 9076e2340276SBjoern A. Zeeb seq_printf(m, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]", 9077e2340276SBjoern A. Zeeb "[cycle_time]", 9078e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->cycle_time.tavg[CXT_WL]), 9079e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->cycle_time.tavg[CXT_BT]), 9080e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->leak_slot.tavg) / 1000, 9081e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->leak_slot.tavg) % 1000); 9082e2340276SBjoern A. Zeeb seq_printf(m, 9083e2340276SBjoern A. Zeeb ", max_t[wl:%d/bt:%d/lk:%d.%03d]\n", 9084e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->cycle_time.tmax[CXT_WL]), 9085e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->cycle_time.tmax[CXT_BT]), 9086e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->leak_slot.tmax) / 1000, 9087e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->leak_slot.tmax) % 1000); 9088e2340276SBjoern A. Zeeb 9089e2340276SBjoern A. Zeeb cycle = le16_to_cpu(pcysta->cycles); 9090e2340276SBjoern A. Zeeb if (cycle <= 1) 9091e2340276SBjoern A. Zeeb return; 9092e2340276SBjoern A. Zeeb 9093e2340276SBjoern A. Zeeb /* 1 cycle record 1 wl-slot and 1 bt-slot */ 9094e2340276SBjoern A. Zeeb slot_pair = BTC_CYCLE_SLOT_MAX / 2; 9095e2340276SBjoern A. Zeeb 9096e2340276SBjoern A. Zeeb if (cycle <= slot_pair) 9097e2340276SBjoern A. Zeeb c_begin = 1; 9098e2340276SBjoern A. Zeeb else 9099e2340276SBjoern A. Zeeb c_begin = cycle - slot_pair + 1; 9100e2340276SBjoern A. Zeeb 9101e2340276SBjoern A. Zeeb c_end = cycle; 9102e2340276SBjoern A. Zeeb 9103e2340276SBjoern A. Zeeb if (a2dp->exist) 9104e2340276SBjoern A. Zeeb divide_cnt = 3; 9105e2340276SBjoern A. Zeeb else 9106e2340276SBjoern A. Zeeb divide_cnt = BTC_CYCLE_SLOT_MAX / 4; 9107e2340276SBjoern A. Zeeb 9108e2340276SBjoern A. Zeeb if (c_begin > c_end) 9109e2340276SBjoern A. Zeeb return; 9110e2340276SBjoern A. Zeeb 9111e2340276SBjoern A. Zeeb for (cycle = c_begin; cycle <= c_end; cycle++) { 9112e2340276SBjoern A. Zeeb cnt++; 9113e2340276SBjoern A. Zeeb store_index = ((cycle - 1) % slot_pair) * 2; 9114e2340276SBjoern A. Zeeb 9115e2340276SBjoern A. Zeeb if (cnt % divide_cnt == 1) 9116e2340276SBjoern A. Zeeb seq_printf(m, " %-15s : ", "[cycle_step]"); 9117e2340276SBjoern A. Zeeb 9118e2340276SBjoern A. Zeeb seq_printf(m, "->b%02d", 9119e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->slot_step_time[store_index])); 9120e2340276SBjoern A. Zeeb if (a2dp->exist) { 9121e2340276SBjoern A. Zeeb a2dp_trx = &pcysta->a2dp_trx[store_index]; 9122e2340276SBjoern A. Zeeb seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", 9123e2340276SBjoern A. Zeeb a2dp_trx->empty_cnt, 9124e2340276SBjoern A. Zeeb a2dp_trx->retry_cnt, 9125e2340276SBjoern A. Zeeb a2dp_trx->tx_rate ? 3 : 2, 9126e2340276SBjoern A. Zeeb a2dp_trx->tx_cnt, 9127e2340276SBjoern A. Zeeb a2dp_trx->ack_cnt, 9128e2340276SBjoern A. Zeeb a2dp_trx->nack_cnt); 9129e2340276SBjoern A. Zeeb } 9130e2340276SBjoern A. Zeeb seq_printf(m, "->w%02d", 9131e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->slot_step_time[store_index + 1])); 9132e2340276SBjoern A. Zeeb if (a2dp->exist) { 9133e2340276SBjoern A. Zeeb a2dp_trx = &pcysta->a2dp_trx[store_index + 1]; 9134e2340276SBjoern A. Zeeb seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", 9135e2340276SBjoern A. Zeeb a2dp_trx->empty_cnt, 9136e2340276SBjoern A. Zeeb a2dp_trx->retry_cnt, 9137e2340276SBjoern A. Zeeb a2dp_trx->tx_rate ? 3 : 2, 9138e2340276SBjoern A. Zeeb a2dp_trx->tx_cnt, 9139e2340276SBjoern A. Zeeb a2dp_trx->ack_cnt, 9140e2340276SBjoern A. Zeeb a2dp_trx->nack_cnt); 9141e2340276SBjoern A. Zeeb } 9142e2340276SBjoern A. Zeeb if (cnt % divide_cnt == 0 || cnt == c_end) 9143e2340276SBjoern A. Zeeb seq_puts(m, "\n"); 9144e2340276SBjoern A. Zeeb } 9145e2340276SBjoern A. Zeeb 9146e2340276SBjoern A. Zeeb if (a2dp->exist) { 9147e2340276SBjoern A. Zeeb seq_printf(m, " %-15s : a2dp_ept:%d, a2dp_late:%d", 9148e2340276SBjoern A. Zeeb "[a2dp_t_sta]", 9149e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->a2dp_ept.cnt), 9150e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->a2dp_ept.cnt_timeout)); 9151e2340276SBjoern A. Zeeb 9152e2340276SBjoern A. Zeeb seq_printf(m, ", avg_t:%d, max_t:%d", 9153e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->a2dp_ept.tavg), 9154e2340276SBjoern A. Zeeb le16_to_cpu(pcysta->a2dp_ept.tmax)); 9155e2340276SBjoern A. Zeeb 9156e2340276SBjoern A. Zeeb seq_puts(m, "\n"); 9157e2340276SBjoern A. Zeeb } 9158e2340276SBjoern A. Zeeb } 9159e2340276SBjoern A. Zeeb 9160*6d67aabdSBjoern A. Zeeb static void _show_fbtc_cysta_v7(struct rtw89_dev *rtwdev, struct seq_file *m) 9161*6d67aabdSBjoern A. Zeeb { 9162*6d67aabdSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &rtwdev->btc.cx.bt; 9163*6d67aabdSBjoern A. Zeeb struct rtw89_btc_bt_a2dp_desc *a2dp = &bt->link_info.a2dp_desc; 9164*6d67aabdSBjoern A. Zeeb struct rtw89_btc_btf_fwinfo *pfwinfo = &rtwdev->btc.fwinfo; 9165*6d67aabdSBjoern A. Zeeb struct rtw89_btc_fbtc_cysta_v7 *pcysta = NULL; 9166*6d67aabdSBjoern A. Zeeb struct rtw89_btc_dm *dm = &rtwdev->btc.dm; 9167*6d67aabdSBjoern A. Zeeb struct rtw89_btc_rpt_cmn_info *pcinfo; 9168*6d67aabdSBjoern A. Zeeb u16 cycle, c_begin, c_end, s_id; 9169*6d67aabdSBjoern A. Zeeb u8 i, cnt = 0, divide_cnt; 9170*6d67aabdSBjoern A. Zeeb u8 slot_pair; 9171*6d67aabdSBjoern A. Zeeb 9172*6d67aabdSBjoern A. Zeeb pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; 9173*6d67aabdSBjoern A. Zeeb if (!pcinfo->valid) 9174*6d67aabdSBjoern A. Zeeb return; 9175*6d67aabdSBjoern A. Zeeb 9176*6d67aabdSBjoern A. Zeeb pcysta = &pfwinfo->rpt_fbtc_cysta.finfo.v7; 9177*6d67aabdSBjoern A. Zeeb seq_printf(m, "\n\r %-15s : cycle:%d", "[slot_stat]", 9178*6d67aabdSBjoern A. Zeeb le16_to_cpu(pcysta->cycles)); 9179*6d67aabdSBjoern A. Zeeb 9180*6d67aabdSBjoern A. Zeeb for (i = 0; i < CXST_MAX; i++) { 9181*6d67aabdSBjoern A. Zeeb if (!le16_to_cpu(pcysta->slot_cnt[i])) 9182*6d67aabdSBjoern A. Zeeb continue; 9183*6d67aabdSBjoern A. Zeeb seq_printf(m, ", %s:%d", 9184*6d67aabdSBjoern A. Zeeb id_to_slot(i), le16_to_cpu(pcysta->slot_cnt[i])); 9185*6d67aabdSBjoern A. Zeeb } 9186*6d67aabdSBjoern A. Zeeb 9187*6d67aabdSBjoern A. Zeeb if (dm->tdma_now.rxflctrl) 9188*6d67aabdSBjoern A. Zeeb seq_printf(m, ", leak_rx:%d", 9189*6d67aabdSBjoern A. Zeeb le32_to_cpu(pcysta->leak_slot.cnt_rximr)); 9190*6d67aabdSBjoern A. Zeeb 9191*6d67aabdSBjoern A. Zeeb if (pcysta->collision_cnt) 9192*6d67aabdSBjoern A. Zeeb seq_printf(m, ", collision:%d", pcysta->collision_cnt); 9193*6d67aabdSBjoern A. Zeeb 9194*6d67aabdSBjoern A. Zeeb if (pcysta->skip_cnt) 9195*6d67aabdSBjoern A. Zeeb seq_printf(m, ", skip:%d", le16_to_cpu(pcysta->skip_cnt)); 9196*6d67aabdSBjoern A. Zeeb 9197*6d67aabdSBjoern A. Zeeb seq_printf(m, "\n\r %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]", 9198*6d67aabdSBjoern A. Zeeb "[cycle_stat]", 9199*6d67aabdSBjoern A. Zeeb le16_to_cpu(pcysta->cycle_time.tavg[CXT_WL]), 9200*6d67aabdSBjoern A. Zeeb le16_to_cpu(pcysta->cycle_time.tavg[CXT_BT]), 9201*6d67aabdSBjoern A. Zeeb le16_to_cpu(pcysta->leak_slot.tavg) / 1000, 9202*6d67aabdSBjoern A. Zeeb le16_to_cpu(pcysta->leak_slot.tavg) % 1000); 9203*6d67aabdSBjoern A. Zeeb seq_printf(m, ", max_t[wl:%d/bt:%d(>%dms:%d)/lk:%d.%03d]", 9204*6d67aabdSBjoern A. Zeeb le16_to_cpu(pcysta->cycle_time.tmax[CXT_WL]), 9205*6d67aabdSBjoern A. Zeeb le16_to_cpu(pcysta->cycle_time.tmax[CXT_BT]), 9206*6d67aabdSBjoern A. Zeeb dm->bt_slot_flood, dm->cnt_dm[BTC_DCNT_BT_SLOT_FLOOD], 9207*6d67aabdSBjoern A. Zeeb le16_to_cpu(pcysta->leak_slot.tamx) / 1000, 9208*6d67aabdSBjoern A. Zeeb le16_to_cpu(pcysta->leak_slot.tamx) % 1000); 9209*6d67aabdSBjoern A. Zeeb seq_printf(m, ", bcn[all:%d/ok:%d/in_bt:%d/in_bt_ok:%d]", 9210*6d67aabdSBjoern A. Zeeb le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL]), 9211*6d67aabdSBjoern A. Zeeb le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL_OK]), 9212*6d67aabdSBjoern A. Zeeb le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_SLOT]), 9213*6d67aabdSBjoern A. Zeeb le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_OK])); 9214*6d67aabdSBjoern A. Zeeb 9215*6d67aabdSBjoern A. Zeeb if (a2dp->exist) { 9216*6d67aabdSBjoern A. Zeeb seq_printf(m, 9217*6d67aabdSBjoern A. Zeeb "\n\r %-15s : a2dp_ept:%d, a2dp_late:%d(streak 2S:%d/max:%d)", 9218*6d67aabdSBjoern A. Zeeb "[a2dp_stat]", 9219*6d67aabdSBjoern A. Zeeb le16_to_cpu(pcysta->a2dp_ept.cnt), 9220*6d67aabdSBjoern A. Zeeb le16_to_cpu(pcysta->a2dp_ept.cnt_timeout), 9221*6d67aabdSBjoern A. Zeeb a2dp->no_empty_streak_2s, a2dp->no_empty_streak_max); 9222*6d67aabdSBjoern A. Zeeb 9223*6d67aabdSBjoern A. Zeeb seq_printf(m, ", avg_t:%d, max_t:%d", 9224*6d67aabdSBjoern A. Zeeb le16_to_cpu(pcysta->a2dp_ept.tavg), 9225*6d67aabdSBjoern A. Zeeb le16_to_cpu(pcysta->a2dp_ept.tmax)); 9226*6d67aabdSBjoern A. Zeeb } 9227*6d67aabdSBjoern A. Zeeb 9228*6d67aabdSBjoern A. Zeeb if (le16_to_cpu(pcysta->cycles) <= 1) 9229*6d67aabdSBjoern A. Zeeb return; 9230*6d67aabdSBjoern A. Zeeb 9231*6d67aabdSBjoern A. Zeeb /* 1 cycle = 1 wl-slot + 1 bt-slot */ 9232*6d67aabdSBjoern A. Zeeb slot_pair = BTC_CYCLE_SLOT_MAX / 2; 9233*6d67aabdSBjoern A. Zeeb 9234*6d67aabdSBjoern A. Zeeb if (le16_to_cpu(pcysta->cycles) <= slot_pair) 9235*6d67aabdSBjoern A. Zeeb c_begin = 1; 9236*6d67aabdSBjoern A. Zeeb else 9237*6d67aabdSBjoern A. Zeeb c_begin = le16_to_cpu(pcysta->cycles) - slot_pair + 1; 9238*6d67aabdSBjoern A. Zeeb 9239*6d67aabdSBjoern A. Zeeb c_end = le16_to_cpu(pcysta->cycles); 9240*6d67aabdSBjoern A. Zeeb 9241*6d67aabdSBjoern A. Zeeb if (a2dp->exist) 9242*6d67aabdSBjoern A. Zeeb divide_cnt = 2; 9243*6d67aabdSBjoern A. Zeeb else 9244*6d67aabdSBjoern A. Zeeb divide_cnt = 6; 9245*6d67aabdSBjoern A. Zeeb 9246*6d67aabdSBjoern A. Zeeb if (c_begin > c_end) 9247*6d67aabdSBjoern A. Zeeb return; 9248*6d67aabdSBjoern A. Zeeb 9249*6d67aabdSBjoern A. Zeeb for (cycle = c_begin; cycle <= c_end; cycle++) { 9250*6d67aabdSBjoern A. Zeeb cnt++; 9251*6d67aabdSBjoern A. Zeeb s_id = ((cycle - 1) % slot_pair) * 2; 9252*6d67aabdSBjoern A. Zeeb 9253*6d67aabdSBjoern A. Zeeb if (cnt % divide_cnt == 1) { 9254*6d67aabdSBjoern A. Zeeb if (a2dp->exist) 9255*6d67aabdSBjoern A. Zeeb seq_printf(m, "\n\r %-15s : ", "[slotT_wermtan]"); 9256*6d67aabdSBjoern A. Zeeb else 9257*6d67aabdSBjoern A. Zeeb seq_printf(m, "\n\r %-15s : ", "[slotT_rxerr]"); 9258*6d67aabdSBjoern A. Zeeb } 9259*6d67aabdSBjoern A. Zeeb 9260*6d67aabdSBjoern A. Zeeb seq_printf(m, "->b%d", le16_to_cpu(pcysta->slot_step_time[s_id])); 9261*6d67aabdSBjoern A. Zeeb 9262*6d67aabdSBjoern A. Zeeb if (a2dp->exist) 9263*6d67aabdSBjoern A. Zeeb seq_printf(m, "(%d/%d/%d/%dM/%d/%d/%d)", 9264*6d67aabdSBjoern A. Zeeb pcysta->wl_rx_err_ratio[s_id], 9265*6d67aabdSBjoern A. Zeeb pcysta->a2dp_trx[s_id].empty_cnt, 9266*6d67aabdSBjoern A. Zeeb pcysta->a2dp_trx[s_id].retry_cnt, 9267*6d67aabdSBjoern A. Zeeb (pcysta->a2dp_trx[s_id].tx_rate ? 3 : 2), 9268*6d67aabdSBjoern A. Zeeb pcysta->a2dp_trx[s_id].tx_cnt, 9269*6d67aabdSBjoern A. Zeeb pcysta->a2dp_trx[s_id].ack_cnt, 9270*6d67aabdSBjoern A. Zeeb pcysta->a2dp_trx[s_id].nack_cnt); 9271*6d67aabdSBjoern A. Zeeb else 9272*6d67aabdSBjoern A. Zeeb seq_printf(m, "(%d)", pcysta->wl_rx_err_ratio[s_id]); 9273*6d67aabdSBjoern A. Zeeb 9274*6d67aabdSBjoern A. Zeeb seq_printf(m, "->w%d", le16_to_cpu(pcysta->slot_step_time[s_id + 1])); 9275*6d67aabdSBjoern A. Zeeb 9276*6d67aabdSBjoern A. Zeeb if (a2dp->exist) 9277*6d67aabdSBjoern A. Zeeb seq_printf(m, "(%d/%d/%d/%dM/%d/%d/%d)", 9278*6d67aabdSBjoern A. Zeeb pcysta->wl_rx_err_ratio[s_id + 1], 9279*6d67aabdSBjoern A. Zeeb pcysta->a2dp_trx[s_id + 1].empty_cnt, 9280*6d67aabdSBjoern A. Zeeb pcysta->a2dp_trx[s_id + 1].retry_cnt, 9281*6d67aabdSBjoern A. Zeeb (pcysta->a2dp_trx[s_id + 1].tx_rate ? 3 : 2), 9282*6d67aabdSBjoern A. Zeeb pcysta->a2dp_trx[s_id + 1].tx_cnt, 9283*6d67aabdSBjoern A. Zeeb pcysta->a2dp_trx[s_id + 1].ack_cnt, 9284*6d67aabdSBjoern A. Zeeb pcysta->a2dp_trx[s_id + 1].nack_cnt); 9285*6d67aabdSBjoern A. Zeeb else 9286*6d67aabdSBjoern A. Zeeb seq_printf(m, "(%d)", pcysta->wl_rx_err_ratio[s_id + 1]); 9287*6d67aabdSBjoern A. Zeeb } 9288*6d67aabdSBjoern A. Zeeb } 9289*6d67aabdSBjoern A. Zeeb 92908e93258fSBjoern A. Zeeb static void _show_fbtc_nullsta(struct rtw89_dev *rtwdev, struct seq_file *m) 92918e93258fSBjoern A. Zeeb { 92928e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 9293e2340276SBjoern A. Zeeb const struct rtw89_btc_ver *ver = btc->ver; 92948e93258fSBjoern A. Zeeb struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; 9295e2340276SBjoern A. Zeeb struct rtw89_btc_rpt_cmn_info *pcinfo; 9296e2340276SBjoern A. Zeeb union rtw89_btc_fbtc_cynullsta_info *ns; 92978e93258fSBjoern A. Zeeb u8 i = 0; 92988e93258fSBjoern A. Zeeb 92998e93258fSBjoern A. Zeeb if (!btc->dm.tdma_now.rxflctrl) 93008e93258fSBjoern A. Zeeb return; 93018e93258fSBjoern A. Zeeb 93028e93258fSBjoern A. Zeeb pcinfo = &pfwinfo->rpt_fbtc_nullsta.cinfo; 93038e93258fSBjoern A. Zeeb if (!pcinfo->valid) 93048e93258fSBjoern A. Zeeb return; 93058e93258fSBjoern A. Zeeb 93068e93258fSBjoern A. Zeeb ns = &pfwinfo->rpt_fbtc_nullsta.finfo; 9307e2340276SBjoern A. Zeeb if (ver->fcxnullsta == 1) { 93088e93258fSBjoern A. Zeeb for (i = 0; i < 2; i++) { 9309e2340276SBjoern A. Zeeb seq_printf(m, " %-15s : ", "[NULL-STA]"); 93108e93258fSBjoern A. Zeeb seq_printf(m, "null-%d", i); 9311e2340276SBjoern A. Zeeb seq_printf(m, "[ok:%d/", 9312e2340276SBjoern A. Zeeb le32_to_cpu(ns->v1.result[i][1])); 9313e2340276SBjoern A. Zeeb seq_printf(m, "fail:%d/", 9314e2340276SBjoern A. Zeeb le32_to_cpu(ns->v1.result[i][0])); 9315e2340276SBjoern A. Zeeb seq_printf(m, "on_time:%d/", 9316e2340276SBjoern A. Zeeb le32_to_cpu(ns->v1.result[i][2])); 9317e2340276SBjoern A. Zeeb seq_printf(m, "retry:%d/", 9318e2340276SBjoern A. Zeeb le32_to_cpu(ns->v1.result[i][3])); 93198e93258fSBjoern A. Zeeb seq_printf(m, "avg_t:%d.%03d/", 9320e2340276SBjoern A. Zeeb le32_to_cpu(ns->v1.avg_t[i]) / 1000, 9321e2340276SBjoern A. Zeeb le32_to_cpu(ns->v1.avg_t[i]) % 1000); 9322e2340276SBjoern A. Zeeb seq_printf(m, "max_t:%d.%03d]\n", 9323e2340276SBjoern A. Zeeb le32_to_cpu(ns->v1.max_t[i]) / 1000, 9324e2340276SBjoern A. Zeeb le32_to_cpu(ns->v1.max_t[i]) % 1000); 93258e93258fSBjoern A. Zeeb } 9326*6d67aabdSBjoern A. Zeeb } else if (ver->fcxnullsta == 7) { 9327*6d67aabdSBjoern A. Zeeb for (i = 0; i < 2; i++) { 9328*6d67aabdSBjoern A. Zeeb seq_printf(m, " %-15s : ", "[NULL-STA]"); 9329*6d67aabdSBjoern A. Zeeb seq_printf(m, "null-%d", i); 9330*6d67aabdSBjoern A. Zeeb seq_printf(m, "[Tx:%d/", 9331*6d67aabdSBjoern A. Zeeb le32_to_cpu(ns->v7.result[i][4])); 9332*6d67aabdSBjoern A. Zeeb seq_printf(m, "[ok:%d/", 9333*6d67aabdSBjoern A. Zeeb le32_to_cpu(ns->v7.result[i][1])); 9334*6d67aabdSBjoern A. Zeeb seq_printf(m, "fail:%d/", 9335*6d67aabdSBjoern A. Zeeb le32_to_cpu(ns->v7.result[i][0])); 9336*6d67aabdSBjoern A. Zeeb seq_printf(m, "on_time:%d/", 9337*6d67aabdSBjoern A. Zeeb le32_to_cpu(ns->v7.result[i][2])); 9338*6d67aabdSBjoern A. Zeeb seq_printf(m, "retry:%d/", 9339*6d67aabdSBjoern A. Zeeb le32_to_cpu(ns->v7.result[i][3])); 9340*6d67aabdSBjoern A. Zeeb seq_printf(m, "avg_t:%d.%03d/", 9341*6d67aabdSBjoern A. Zeeb le32_to_cpu(ns->v7.tavg[i]) / 1000, 9342*6d67aabdSBjoern A. Zeeb le32_to_cpu(ns->v7.tavg[i]) % 1000); 9343*6d67aabdSBjoern A. Zeeb seq_printf(m, "max_t:%d.%03d]\n", 9344*6d67aabdSBjoern A. Zeeb le32_to_cpu(ns->v7.tmax[i]) / 1000, 9345*6d67aabdSBjoern A. Zeeb le32_to_cpu(ns->v7.tmax[i]) % 1000); 9346*6d67aabdSBjoern A. Zeeb } 9347e2340276SBjoern A. Zeeb } else { 9348e2340276SBjoern A. Zeeb for (i = 0; i < 2; i++) { 9349e2340276SBjoern A. Zeeb seq_printf(m, " %-15s : ", "[NULL-STA]"); 9350e2340276SBjoern A. Zeeb seq_printf(m, "null-%d", i); 9351e2340276SBjoern A. Zeeb seq_printf(m, "[Tx:%d/", 9352e2340276SBjoern A. Zeeb le32_to_cpu(ns->v2.result[i][4])); 9353e2340276SBjoern A. Zeeb seq_printf(m, "[ok:%d/", 9354e2340276SBjoern A. Zeeb le32_to_cpu(ns->v2.result[i][1])); 9355e2340276SBjoern A. Zeeb seq_printf(m, "fail:%d/", 9356e2340276SBjoern A. Zeeb le32_to_cpu(ns->v2.result[i][0])); 9357e2340276SBjoern A. Zeeb seq_printf(m, "on_time:%d/", 9358e2340276SBjoern A. Zeeb le32_to_cpu(ns->v2.result[i][2])); 9359e2340276SBjoern A. Zeeb seq_printf(m, "retry:%d/", 9360e2340276SBjoern A. Zeeb le32_to_cpu(ns->v2.result[i][3])); 9361e2340276SBjoern A. Zeeb seq_printf(m, "avg_t:%d.%03d/", 9362e2340276SBjoern A. Zeeb le32_to_cpu(ns->v2.avg_t[i]) / 1000, 9363e2340276SBjoern A. Zeeb le32_to_cpu(ns->v2.avg_t[i]) % 1000); 9364e2340276SBjoern A. Zeeb seq_printf(m, "max_t:%d.%03d]\n", 9365e2340276SBjoern A. Zeeb le32_to_cpu(ns->v2.max_t[i]) / 1000, 9366e2340276SBjoern A. Zeeb le32_to_cpu(ns->v2.max_t[i]) % 1000); 9367e2340276SBjoern A. Zeeb } 9368e2340276SBjoern A. Zeeb } 93698e93258fSBjoern A. Zeeb } 93708e93258fSBjoern A. Zeeb 9371e2340276SBjoern A. Zeeb static void _show_fbtc_step_v2(struct rtw89_dev *rtwdev, struct seq_file *m) 93728e93258fSBjoern A. Zeeb { 93738e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 93748e93258fSBjoern A. Zeeb struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; 93758e93258fSBjoern A. Zeeb struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; 9376e2340276SBjoern A. Zeeb struct rtw89_btc_fbtc_steps_v2 *pstep = NULL; 9377*6d67aabdSBjoern A. Zeeb const struct rtw89_btc_ver *ver = btc->ver; 93788e93258fSBjoern A. Zeeb u8 type, val, cnt = 0, state = 0; 93798e93258fSBjoern A. Zeeb bool outloop = false; 93808e93258fSBjoern A. Zeeb u16 i, diff_t, n_start = 0, n_stop = 0; 9381*6d67aabdSBjoern A. Zeeb u16 pos_old, pos_new, trace_step; 93828e93258fSBjoern A. Zeeb 93838e93258fSBjoern A. Zeeb pcinfo = &pfwinfo->rpt_fbtc_step.cinfo; 93848e93258fSBjoern A. Zeeb if (!pcinfo->valid) 93858e93258fSBjoern A. Zeeb return; 93868e93258fSBjoern A. Zeeb 9387e2340276SBjoern A. Zeeb pstep = &pfwinfo->rpt_fbtc_step.finfo.v2; 93888e93258fSBjoern A. Zeeb pos_old = le16_to_cpu(pstep->pos_old); 93898e93258fSBjoern A. Zeeb pos_new = le16_to_cpu(pstep->pos_new); 93908e93258fSBjoern A. Zeeb 93918e93258fSBjoern A. Zeeb if (pcinfo->req_fver != pstep->fver) 93928e93258fSBjoern A. Zeeb return; 93938e93258fSBjoern A. Zeeb 93948e93258fSBjoern A. Zeeb /* store step info by using ring instead of FIFO*/ 93958e93258fSBjoern A. Zeeb do { 93968e93258fSBjoern A. Zeeb switch (state) { 93978e93258fSBjoern A. Zeeb case 0: 9398*6d67aabdSBjoern A. Zeeb if (ver->fcxctrl == 7 || ver->fcxctrl == 1) 9399*6d67aabdSBjoern A. Zeeb trace_step = 50; 9400*6d67aabdSBjoern A. Zeeb else 9401*6d67aabdSBjoern A. Zeeb trace_step = btc->ctrl.ctrl.trace_step; 9402*6d67aabdSBjoern A. Zeeb 94038e93258fSBjoern A. Zeeb n_start = pos_old; 94048e93258fSBjoern A. Zeeb if (pos_new >= pos_old) 94058e93258fSBjoern A. Zeeb n_stop = pos_new; 94068e93258fSBjoern A. Zeeb else 9407*6d67aabdSBjoern A. Zeeb n_stop = trace_step - 1; 94088e93258fSBjoern A. Zeeb 94098e93258fSBjoern A. Zeeb state = 1; 94108e93258fSBjoern A. Zeeb break; 94118e93258fSBjoern A. Zeeb case 1: 94128e93258fSBjoern A. Zeeb for (i = n_start; i <= n_stop; i++) { 94138e93258fSBjoern A. Zeeb type = pstep->step[i].type; 94148e93258fSBjoern A. Zeeb val = pstep->step[i].val; 94158e93258fSBjoern A. Zeeb diff_t = le16_to_cpu(pstep->step[i].difft); 94168e93258fSBjoern A. Zeeb 94178e93258fSBjoern A. Zeeb if (type == CXSTEP_NONE || type >= CXSTEP_MAX) 94188e93258fSBjoern A. Zeeb continue; 94198e93258fSBjoern A. Zeeb 94208e93258fSBjoern A. Zeeb if (cnt % 10 == 0) 94218e93258fSBjoern A. Zeeb seq_printf(m, " %-15s : ", "[steps]"); 94228e93258fSBjoern A. Zeeb 94238e93258fSBjoern A. Zeeb seq_printf(m, "-> %s(%02d)(%02d)", 94248e93258fSBjoern A. Zeeb (type == CXSTEP_SLOT ? "SLT" : 94258e93258fSBjoern A. Zeeb "EVT"), (u32)val, diff_t); 94268e93258fSBjoern A. Zeeb if (cnt % 10 == 9) 94278e93258fSBjoern A. Zeeb seq_puts(m, "\n"); 94288e93258fSBjoern A. Zeeb cnt++; 94298e93258fSBjoern A. Zeeb } 94308e93258fSBjoern A. Zeeb 94318e93258fSBjoern A. Zeeb state = 2; 94328e93258fSBjoern A. Zeeb break; 94338e93258fSBjoern A. Zeeb case 2: 94348e93258fSBjoern A. Zeeb if (pos_new < pos_old && n_start != 0) { 94358e93258fSBjoern A. Zeeb n_start = 0; 94368e93258fSBjoern A. Zeeb n_stop = pos_new; 94378e93258fSBjoern A. Zeeb state = 1; 94388e93258fSBjoern A. Zeeb } else { 94398e93258fSBjoern A. Zeeb outloop = true; 94408e93258fSBjoern A. Zeeb } 94418e93258fSBjoern A. Zeeb break; 94428e93258fSBjoern A. Zeeb } 94438e93258fSBjoern A. Zeeb } while (!outloop); 94448e93258fSBjoern A. Zeeb } 94458e93258fSBjoern A. Zeeb 9446e2340276SBjoern A. Zeeb static void _show_fbtc_step_v3(struct rtw89_dev *rtwdev, struct seq_file *m) 9447e2340276SBjoern A. Zeeb { 9448e2340276SBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 9449e2340276SBjoern A. Zeeb struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; 9450e2340276SBjoern A. Zeeb struct rtw89_btc_rpt_cmn_info *pcinfo; 9451e2340276SBjoern A. Zeeb struct rtw89_btc_fbtc_steps_v3 *pstep; 9452e2340276SBjoern A. Zeeb u32 i, n_begin, n_end, array_idx, cnt = 0; 9453e2340276SBjoern A. Zeeb u8 type, val; 9454e2340276SBjoern A. Zeeb u16 diff_t; 9455e2340276SBjoern A. Zeeb 9456e2340276SBjoern A. Zeeb if ((pfwinfo->rpt_en_map & 9457e2340276SBjoern A. Zeeb rtw89_btc_fw_rpt_ver(rtwdev, RPT_EN_FW_STEP_INFO)) == 0) 9458e2340276SBjoern A. Zeeb return; 9459e2340276SBjoern A. Zeeb 9460e2340276SBjoern A. Zeeb pcinfo = &pfwinfo->rpt_fbtc_step.cinfo; 9461e2340276SBjoern A. Zeeb if (!pcinfo->valid) 9462e2340276SBjoern A. Zeeb return; 9463e2340276SBjoern A. Zeeb 9464e2340276SBjoern A. Zeeb pstep = &pfwinfo->rpt_fbtc_step.finfo.v3; 9465e2340276SBjoern A. Zeeb if (pcinfo->req_fver != pstep->fver) 9466e2340276SBjoern A. Zeeb return; 9467e2340276SBjoern A. Zeeb 9468e2340276SBjoern A. Zeeb if (le32_to_cpu(pstep->cnt) <= FCXDEF_STEP) 9469e2340276SBjoern A. Zeeb n_begin = 1; 9470e2340276SBjoern A. Zeeb else 9471e2340276SBjoern A. Zeeb n_begin = le32_to_cpu(pstep->cnt) - FCXDEF_STEP + 1; 9472e2340276SBjoern A. Zeeb 9473e2340276SBjoern A. Zeeb n_end = le32_to_cpu(pstep->cnt); 9474e2340276SBjoern A. Zeeb 9475e2340276SBjoern A. Zeeb if (n_begin > n_end) 9476e2340276SBjoern A. Zeeb return; 9477e2340276SBjoern A. Zeeb 9478e2340276SBjoern A. Zeeb /* restore step info by using ring instead of FIFO */ 9479e2340276SBjoern A. Zeeb for (i = n_begin; i <= n_end; i++) { 9480e2340276SBjoern A. Zeeb array_idx = (i - 1) % FCXDEF_STEP; 9481e2340276SBjoern A. Zeeb type = pstep->step[array_idx].type; 9482e2340276SBjoern A. Zeeb val = pstep->step[array_idx].val; 9483e2340276SBjoern A. Zeeb diff_t = le16_to_cpu(pstep->step[array_idx].difft); 9484e2340276SBjoern A. Zeeb 9485e2340276SBjoern A. Zeeb if (type == CXSTEP_NONE || type >= CXSTEP_MAX) 9486e2340276SBjoern A. Zeeb continue; 9487e2340276SBjoern A. Zeeb 9488e2340276SBjoern A. Zeeb if (cnt % 10 == 0) 9489e2340276SBjoern A. Zeeb seq_printf(m, " %-15s : ", "[steps]"); 9490e2340276SBjoern A. Zeeb 9491e2340276SBjoern A. Zeeb seq_printf(m, "-> %s(%02d)", 9492e2340276SBjoern A. Zeeb (type == CXSTEP_SLOT ? 9493e2340276SBjoern A. Zeeb id_to_slot((u32)val) : 9494e2340276SBjoern A. Zeeb id_to_evt((u32)val)), diff_t); 9495e2340276SBjoern A. Zeeb 9496e2340276SBjoern A. Zeeb if (cnt % 10 == 9) 9497e2340276SBjoern A. Zeeb seq_puts(m, "\n"); 9498e2340276SBjoern A. Zeeb 9499e2340276SBjoern A. Zeeb cnt++; 9500e2340276SBjoern A. Zeeb } 9501e2340276SBjoern A. Zeeb } 9502e2340276SBjoern A. Zeeb 95038e93258fSBjoern A. Zeeb static void _show_fw_dm_msg(struct rtw89_dev *rtwdev, struct seq_file *m) 95048e93258fSBjoern A. Zeeb { 95058e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 9506e2340276SBjoern A. Zeeb const struct rtw89_btc_ver *ver = btc->ver; 95078e93258fSBjoern A. Zeeb 95088e93258fSBjoern A. Zeeb if (!(btc->dm.coex_info_map & BTC_COEX_INFO_DM)) 95098e93258fSBjoern A. Zeeb return; 95108e93258fSBjoern A. Zeeb 95118e93258fSBjoern A. Zeeb _show_error(rtwdev, m); 95128e93258fSBjoern A. Zeeb _show_fbtc_tdma(rtwdev, m); 95138e93258fSBjoern A. Zeeb _show_fbtc_slots(rtwdev, m); 9514e2340276SBjoern A. Zeeb 9515e2340276SBjoern A. Zeeb if (ver->fcxcysta == 2) 9516e2340276SBjoern A. Zeeb _show_fbtc_cysta_v2(rtwdev, m); 9517e2340276SBjoern A. Zeeb else if (ver->fcxcysta == 3) 9518e2340276SBjoern A. Zeeb _show_fbtc_cysta_v3(rtwdev, m); 9519e2340276SBjoern A. Zeeb else if (ver->fcxcysta == 4) 9520e2340276SBjoern A. Zeeb _show_fbtc_cysta_v4(rtwdev, m); 9521e2340276SBjoern A. Zeeb else if (ver->fcxcysta == 5) 9522e2340276SBjoern A. Zeeb _show_fbtc_cysta_v5(rtwdev, m); 9523*6d67aabdSBjoern A. Zeeb else if (ver->fcxcysta == 7) 9524*6d67aabdSBjoern A. Zeeb _show_fbtc_cysta_v7(rtwdev, m); 9525e2340276SBjoern A. Zeeb 95268e93258fSBjoern A. Zeeb _show_fbtc_nullsta(rtwdev, m); 9527e2340276SBjoern A. Zeeb 9528e2340276SBjoern A. Zeeb if (ver->fcxstep == 2) 9529e2340276SBjoern A. Zeeb _show_fbtc_step_v2(rtwdev, m); 9530e2340276SBjoern A. Zeeb else if (ver->fcxstep == 3) 9531e2340276SBjoern A. Zeeb _show_fbtc_step_v3(rtwdev, m); 9532e2340276SBjoern A. Zeeb 95338e93258fSBjoern A. Zeeb } 95348e93258fSBjoern A. Zeeb 9535e2340276SBjoern A. Zeeb static void _get_gnt(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_coex_gnt *gnt_cfg) 9536e2340276SBjoern A. Zeeb { 9537e2340276SBjoern A. Zeeb const struct rtw89_chip_info *chip = rtwdev->chip; 9538e2340276SBjoern A. Zeeb struct rtw89_mac_ax_gnt *gnt; 9539e2340276SBjoern A. Zeeb u32 val, status; 9540e2340276SBjoern A. Zeeb 9541*6d67aabdSBjoern A. Zeeb if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B || 9542*6d67aabdSBjoern A. Zeeb chip->chip_id == RTL8851B || chip->chip_id == RTL8852BT) { 9543e2340276SBjoern A. Zeeb rtw89_mac_read_lte(rtwdev, R_AX_LTE_SW_CFG_1, &val); 9544e2340276SBjoern A. Zeeb rtw89_mac_read_lte(rtwdev, R_AX_GNT_VAL, &status); 9545e2340276SBjoern A. Zeeb 9546e2340276SBjoern A. Zeeb gnt = &gnt_cfg->band[0]; 9547e2340276SBjoern A. Zeeb gnt->gnt_bt_sw_en = !!(val & B_AX_GNT_BT_RFC_S0_SW_CTRL); 9548e2340276SBjoern A. Zeeb gnt->gnt_bt = !!(status & B_AX_GNT_BT_RFC_S0_STA); 9549e2340276SBjoern A. Zeeb gnt->gnt_wl_sw_en = !!(val & B_AX_GNT_WL_RFC_S0_SW_CTRL); 9550e2340276SBjoern A. Zeeb gnt->gnt_wl = !!(status & B_AX_GNT_WL_RFC_S0_STA); 9551e2340276SBjoern A. Zeeb 9552e2340276SBjoern A. Zeeb gnt = &gnt_cfg->band[1]; 9553e2340276SBjoern A. Zeeb gnt->gnt_bt_sw_en = !!(val & B_AX_GNT_BT_RFC_S1_SW_CTRL); 9554e2340276SBjoern A. Zeeb gnt->gnt_bt = !!(status & B_AX_GNT_BT_RFC_S1_STA); 9555e2340276SBjoern A. Zeeb gnt->gnt_wl_sw_en = !!(val & B_AX_GNT_WL_RFC_S1_SW_CTRL); 9556e2340276SBjoern A. Zeeb gnt->gnt_wl = !!(status & B_AX_GNT_WL_RFC_S1_STA); 9557e2340276SBjoern A. Zeeb } else if (chip->chip_id == RTL8852C) { 9558e2340276SBjoern A. Zeeb val = rtw89_read32(rtwdev, R_AX_GNT_SW_CTRL); 9559e2340276SBjoern A. Zeeb status = rtw89_read32(rtwdev, R_AX_GNT_VAL_V1); 9560e2340276SBjoern A. Zeeb 9561e2340276SBjoern A. Zeeb gnt = &gnt_cfg->band[0]; 9562e2340276SBjoern A. Zeeb gnt->gnt_bt_sw_en = !!(val & B_AX_GNT_BT_RFC_S0_SWCTRL); 9563e2340276SBjoern A. Zeeb gnt->gnt_bt = !!(status & B_AX_GNT_BT_RFC_S0); 9564e2340276SBjoern A. Zeeb gnt->gnt_wl_sw_en = !!(val & B_AX_GNT_WL_RFC_S0_SWCTRL); 9565e2340276SBjoern A. Zeeb gnt->gnt_wl = !!(status & B_AX_GNT_WL_RFC_S0); 9566e2340276SBjoern A. Zeeb 9567e2340276SBjoern A. Zeeb gnt = &gnt_cfg->band[1]; 9568e2340276SBjoern A. Zeeb gnt->gnt_bt_sw_en = !!(val & B_AX_GNT_BT_RFC_S1_SWCTRL); 9569e2340276SBjoern A. Zeeb gnt->gnt_bt = !!(status & B_AX_GNT_BT_RFC_S1); 9570e2340276SBjoern A. Zeeb gnt->gnt_wl_sw_en = !!(val & B_AX_GNT_WL_RFC_S1_SWCTRL); 9571e2340276SBjoern A. Zeeb gnt->gnt_wl = !!(status & B_AX_GNT_WL_RFC_S1); 9572e2340276SBjoern A. Zeeb } else { 9573e2340276SBjoern A. Zeeb return; 9574e2340276SBjoern A. Zeeb } 9575e2340276SBjoern A. Zeeb } 9576e2340276SBjoern A. Zeeb 9577*6d67aabdSBjoern A. Zeeb static void _show_gpio_dbg(struct rtw89_dev *rtwdev, struct seq_file *m) 9578*6d67aabdSBjoern A. Zeeb { 9579*6d67aabdSBjoern A. Zeeb struct rtw89_btc_btf_fwinfo *pfwinfo = &rtwdev->btc.fwinfo; 9580*6d67aabdSBjoern A. Zeeb const struct rtw89_btc_ver *ver = rtwdev->btc.ver; 9581*6d67aabdSBjoern A. Zeeb struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; 9582*6d67aabdSBjoern A. Zeeb union rtw89_btc_fbtc_gpio_dbg *gdbg = NULL; 9583*6d67aabdSBjoern A. Zeeb u8 *gpio_map, i; 9584*6d67aabdSBjoern A. Zeeb u32 en_map; 9585*6d67aabdSBjoern A. Zeeb 9586*6d67aabdSBjoern A. Zeeb pcinfo = &pfwinfo->rpt_fbtc_gpio_dbg.cinfo; 9587*6d67aabdSBjoern A. Zeeb gdbg = &rtwdev->btc.fwinfo.rpt_fbtc_gpio_dbg.finfo; 9588*6d67aabdSBjoern A. Zeeb if (!pcinfo->valid) { 9589*6d67aabdSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 9590*6d67aabdSBjoern A. Zeeb "[BTC], %s(): stop due rpt_fbtc_gpio_dbg.cinfo\n", 9591*6d67aabdSBjoern A. Zeeb __func__); 9592*6d67aabdSBjoern A. Zeeb seq_puts(m, "\n"); 9593*6d67aabdSBjoern A. Zeeb return; 9594*6d67aabdSBjoern A. Zeeb } 9595*6d67aabdSBjoern A. Zeeb 9596*6d67aabdSBjoern A. Zeeb if (ver->fcxgpiodbg == 7) { 9597*6d67aabdSBjoern A. Zeeb en_map = le32_to_cpu(gdbg->v7.en_map); 9598*6d67aabdSBjoern A. Zeeb gpio_map = gdbg->v7.gpio_map; 9599*6d67aabdSBjoern A. Zeeb } else { 9600*6d67aabdSBjoern A. Zeeb en_map = le32_to_cpu(gdbg->v1.en_map); 9601*6d67aabdSBjoern A. Zeeb gpio_map = gdbg->v1.gpio_map; 9602*6d67aabdSBjoern A. Zeeb } 9603*6d67aabdSBjoern A. Zeeb 9604*6d67aabdSBjoern A. Zeeb if (!en_map) 9605*6d67aabdSBjoern A. Zeeb return; 9606*6d67aabdSBjoern A. Zeeb 9607*6d67aabdSBjoern A. Zeeb seq_printf(m, " %-15s : enable_map:0x%08x", 9608*6d67aabdSBjoern A. Zeeb "[gpio_dbg]", en_map); 9609*6d67aabdSBjoern A. Zeeb 9610*6d67aabdSBjoern A. Zeeb for (i = 0; i < BTC_DBG_MAX1; i++) { 9611*6d67aabdSBjoern A. Zeeb if (!(en_map & BIT(i))) 9612*6d67aabdSBjoern A. Zeeb continue; 9613*6d67aabdSBjoern A. Zeeb seq_printf(m, ", %s->GPIO%d", id_to_gdbg(i), gpio_map[i]); 9614*6d67aabdSBjoern A. Zeeb } 9615*6d67aabdSBjoern A. Zeeb seq_puts(m, "\n"); 9616*6d67aabdSBjoern A. Zeeb } 9617*6d67aabdSBjoern A. Zeeb 9618e2340276SBjoern A. Zeeb static void _show_mreg_v1(struct rtw89_dev *rtwdev, struct seq_file *m) 96198e93258fSBjoern A. Zeeb { 96208e93258fSBjoern A. Zeeb const struct rtw89_chip_info *chip = rtwdev->chip; 96218e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 96228e93258fSBjoern A. Zeeb struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; 96238e93258fSBjoern A. Zeeb struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; 9624e2340276SBjoern A. Zeeb struct rtw89_btc_fbtc_mreg_val_v1 *pmreg = NULL; 96258e93258fSBjoern A. Zeeb struct rtw89_btc_cx *cx = &btc->cx; 96268e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 96278e93258fSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &btc->cx.bt; 9628e2340276SBjoern A. Zeeb struct rtw89_mac_ax_coex_gnt gnt_cfg = {}; 9629e2340276SBjoern A. Zeeb struct rtw89_mac_ax_gnt gnt; 96308e93258fSBjoern A. Zeeb u8 i = 0, type = 0, cnt = 0; 96318e93258fSBjoern A. Zeeb u32 val, offset; 96328e93258fSBjoern A. Zeeb 96338e93258fSBjoern A. Zeeb if (!(btc->dm.coex_info_map & BTC_COEX_INFO_MREG)) 96348e93258fSBjoern A. Zeeb return; 96358e93258fSBjoern A. Zeeb 96368e93258fSBjoern A. Zeeb seq_puts(m, "========== [HW Status] ==========\n"); 96378e93258fSBjoern A. Zeeb 96388e93258fSBjoern A. Zeeb seq_printf(m, 96398e93258fSBjoern A. Zeeb " %-15s : WL->BT:0x%08x(cnt:%d), BT->WL:0x%08x(total:%d, bt_update:%d)\n", 96408e93258fSBjoern A. Zeeb "[scoreboard]", wl->scbd, cx->cnt_wl[BTC_WCNT_SCBDUPDATE], 96418e93258fSBjoern A. Zeeb bt->scbd, cx->cnt_bt[BTC_BCNT_SCBDREAD], 96428e93258fSBjoern A. Zeeb cx->cnt_bt[BTC_BCNT_SCBDUPDATE]); 96438e93258fSBjoern A. Zeeb 9644e2340276SBjoern A. Zeeb btc->dm.pta_owner = rtw89_mac_get_ctrl_path(rtwdev); 9645e2340276SBjoern A. Zeeb _get_gnt(rtwdev, &gnt_cfg); 9646*6d67aabdSBjoern A. Zeeb 9647e2340276SBjoern A. Zeeb gnt = gnt_cfg.band[0]; 96488e93258fSBjoern A. Zeeb seq_printf(m, 96498e93258fSBjoern A. Zeeb " %-15s : pta_owner:%s, phy-0[gnt_wl:%s-%d/gnt_bt:%s-%d], ", 96508e93258fSBjoern A. Zeeb "[gnt_status]", 9651e2340276SBjoern A. Zeeb chip->chip_id == RTL8852C ? "HW" : 9652e2340276SBjoern A. Zeeb btc->dm.pta_owner == BTC_CTRL_BY_WL ? "WL" : "BT", 9653e2340276SBjoern A. Zeeb gnt.gnt_wl_sw_en ? "SW" : "HW", gnt.gnt_wl, 9654e2340276SBjoern A. Zeeb gnt.gnt_bt_sw_en ? "SW" : "HW", gnt.gnt_bt); 96558e93258fSBjoern A. Zeeb 9656e2340276SBjoern A. Zeeb gnt = gnt_cfg.band[1]; 96578e93258fSBjoern A. Zeeb seq_printf(m, "phy-1[gnt_wl:%s-%d/gnt_bt:%s-%d]\n", 9658e2340276SBjoern A. Zeeb gnt.gnt_wl_sw_en ? "SW" : "HW", 9659e2340276SBjoern A. Zeeb gnt.gnt_wl, 9660e2340276SBjoern A. Zeeb gnt.gnt_bt_sw_en ? "SW" : "HW", 9661e2340276SBjoern A. Zeeb gnt.gnt_bt); 9662*6d67aabdSBjoern A. Zeeb 96638e93258fSBjoern A. Zeeb pcinfo = &pfwinfo->rpt_fbtc_mregval.cinfo; 96648e93258fSBjoern A. Zeeb if (!pcinfo->valid) { 96658e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 96668e93258fSBjoern A. Zeeb "[BTC], %s(): stop due rpt_fbtc_mregval.cinfo\n", 96678e93258fSBjoern A. Zeeb __func__); 96688e93258fSBjoern A. Zeeb return; 96698e93258fSBjoern A. Zeeb } 96708e93258fSBjoern A. Zeeb 9671e2340276SBjoern A. Zeeb pmreg = &pfwinfo->rpt_fbtc_mregval.finfo.v1; 96728e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 96738e93258fSBjoern A. Zeeb "[BTC], %s(): rpt_fbtc_mregval reg_num = %d\n", 96748e93258fSBjoern A. Zeeb __func__, pmreg->reg_num); 96758e93258fSBjoern A. Zeeb 96768e93258fSBjoern A. Zeeb for (i = 0; i < pmreg->reg_num; i++) { 96778e93258fSBjoern A. Zeeb type = (u8)le16_to_cpu(chip->mon_reg[i].type); 96788e93258fSBjoern A. Zeeb offset = le32_to_cpu(chip->mon_reg[i].offset); 96798e93258fSBjoern A. Zeeb val = le32_to_cpu(pmreg->mreg_val[i]); 96808e93258fSBjoern A. Zeeb 96818e93258fSBjoern A. Zeeb if (cnt % 6 == 0) 96828e93258fSBjoern A. Zeeb seq_printf(m, " %-15s : %d_0x%04x=0x%08x", 96838e93258fSBjoern A. Zeeb "[reg]", (u32)type, offset, val); 96848e93258fSBjoern A. Zeeb else 96858e93258fSBjoern A. Zeeb seq_printf(m, ", %d_0x%04x=0x%08x", (u32)type, 96868e93258fSBjoern A. Zeeb offset, val); 96878e93258fSBjoern A. Zeeb if (cnt % 6 == 5) 96888e93258fSBjoern A. Zeeb seq_puts(m, "\n"); 96898e93258fSBjoern A. Zeeb cnt++; 9690e2340276SBjoern A. Zeeb 9691e2340276SBjoern A. Zeeb if (i >= pmreg->reg_num) 9692e2340276SBjoern A. Zeeb seq_puts(m, "\n"); 96938e93258fSBjoern A. Zeeb } 96948e93258fSBjoern A. Zeeb } 96958e93258fSBjoern A. Zeeb 9696e2340276SBjoern A. Zeeb static void _show_mreg_v2(struct rtw89_dev *rtwdev, struct seq_file *m) 9697e2340276SBjoern A. Zeeb { 9698e2340276SBjoern A. Zeeb const struct rtw89_chip_info *chip = rtwdev->chip; 9699e2340276SBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 9700e2340276SBjoern A. Zeeb struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; 9701e2340276SBjoern A. Zeeb struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; 9702e2340276SBjoern A. Zeeb struct rtw89_btc_fbtc_mreg_val_v2 *pmreg = NULL; 9703e2340276SBjoern A. Zeeb struct rtw89_btc_cx *cx = &btc->cx; 9704e2340276SBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &btc->cx.wl; 9705e2340276SBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &btc->cx.bt; 9706e2340276SBjoern A. Zeeb struct rtw89_mac_ax_coex_gnt gnt_cfg = {}; 9707e2340276SBjoern A. Zeeb struct rtw89_mac_ax_gnt gnt; 9708e2340276SBjoern A. Zeeb u8 i = 0, type = 0, cnt = 0; 9709e2340276SBjoern A. Zeeb u32 val, offset; 9710e2340276SBjoern A. Zeeb 9711e2340276SBjoern A. Zeeb if (!(btc->dm.coex_info_map & BTC_COEX_INFO_MREG)) 9712e2340276SBjoern A. Zeeb return; 9713e2340276SBjoern A. Zeeb 9714e2340276SBjoern A. Zeeb seq_puts(m, "========== [HW Status] ==========\n"); 9715e2340276SBjoern A. Zeeb 9716e2340276SBjoern A. Zeeb seq_printf(m, 9717e2340276SBjoern A. Zeeb " %-15s : WL->BT:0x%08x(cnt:%d), BT->WL:0x%08x(total:%d, bt_update:%d)\n", 9718e2340276SBjoern A. Zeeb "[scoreboard]", wl->scbd, cx->cnt_wl[BTC_WCNT_SCBDUPDATE], 9719e2340276SBjoern A. Zeeb bt->scbd, cx->cnt_bt[BTC_BCNT_SCBDREAD], 9720e2340276SBjoern A. Zeeb cx->cnt_bt[BTC_BCNT_SCBDUPDATE]); 9721e2340276SBjoern A. Zeeb 9722e2340276SBjoern A. Zeeb btc->dm.pta_owner = rtw89_mac_get_ctrl_path(rtwdev); 9723e2340276SBjoern A. Zeeb _get_gnt(rtwdev, &gnt_cfg); 9724*6d67aabdSBjoern A. Zeeb 9725e2340276SBjoern A. Zeeb gnt = gnt_cfg.band[0]; 9726e2340276SBjoern A. Zeeb seq_printf(m, 9727*6d67aabdSBjoern A. Zeeb " %-15s : pta_owner:%s, phy-0[gnt_wl:%s-%d/gnt_bt:%s-%d], polut_type:%s", 9728e2340276SBjoern A. Zeeb "[gnt_status]", 9729e2340276SBjoern A. Zeeb chip->chip_id == RTL8852C ? "HW" : 9730e2340276SBjoern A. Zeeb btc->dm.pta_owner == BTC_CTRL_BY_WL ? "WL" : "BT", 9731e2340276SBjoern A. Zeeb gnt.gnt_wl_sw_en ? "SW" : "HW", gnt.gnt_wl, 9732*6d67aabdSBjoern A. Zeeb gnt.gnt_bt_sw_en ? "SW" : "HW", gnt.gnt_bt, 9733*6d67aabdSBjoern A. Zeeb id_to_polut(wl->bt_polut_type[wl->pta_req_mac])); 9734e2340276SBjoern A. Zeeb 9735e2340276SBjoern A. Zeeb gnt = gnt_cfg.band[1]; 9736e2340276SBjoern A. Zeeb seq_printf(m, "phy-1[gnt_wl:%s-%d/gnt_bt:%s-%d]\n", 9737e2340276SBjoern A. Zeeb gnt.gnt_wl_sw_en ? "SW" : "HW", 9738e2340276SBjoern A. Zeeb gnt.gnt_wl, 9739e2340276SBjoern A. Zeeb gnt.gnt_bt_sw_en ? "SW" : "HW", 9740e2340276SBjoern A. Zeeb gnt.gnt_bt); 9741*6d67aabdSBjoern A. Zeeb 9742e2340276SBjoern A. Zeeb pcinfo = &pfwinfo->rpt_fbtc_mregval.cinfo; 9743e2340276SBjoern A. Zeeb if (!pcinfo->valid) { 9744e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 9745e2340276SBjoern A. Zeeb "[BTC], %s(): stop due rpt_fbtc_mregval.cinfo\n", 9746e2340276SBjoern A. Zeeb __func__); 9747e2340276SBjoern A. Zeeb return; 9748e2340276SBjoern A. Zeeb } 9749e2340276SBjoern A. Zeeb 9750e2340276SBjoern A. Zeeb pmreg = &pfwinfo->rpt_fbtc_mregval.finfo.v2; 9751e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, 9752e2340276SBjoern A. Zeeb "[BTC], %s(): rpt_fbtc_mregval reg_num = %d\n", 9753e2340276SBjoern A. Zeeb __func__, pmreg->reg_num); 9754e2340276SBjoern A. Zeeb 9755e2340276SBjoern A. Zeeb for (i = 0; i < pmreg->reg_num; i++) { 9756e2340276SBjoern A. Zeeb type = (u8)le16_to_cpu(chip->mon_reg[i].type); 9757e2340276SBjoern A. Zeeb offset = le32_to_cpu(chip->mon_reg[i].offset); 9758e2340276SBjoern A. Zeeb val = le32_to_cpu(pmreg->mreg_val[i]); 9759e2340276SBjoern A. Zeeb 9760e2340276SBjoern A. Zeeb if (cnt % 6 == 0) 9761e2340276SBjoern A. Zeeb seq_printf(m, " %-15s : %d_0x%04x=0x%08x", 9762e2340276SBjoern A. Zeeb "[reg]", (u32)type, offset, val); 9763e2340276SBjoern A. Zeeb else 9764e2340276SBjoern A. Zeeb seq_printf(m, ", %d_0x%04x=0x%08x", (u32)type, 9765e2340276SBjoern A. Zeeb offset, val); 9766e2340276SBjoern A. Zeeb if (cnt % 6 == 5) 9767e2340276SBjoern A. Zeeb seq_puts(m, "\n"); 9768e2340276SBjoern A. Zeeb cnt++; 9769e2340276SBjoern A. Zeeb 9770e2340276SBjoern A. Zeeb if (i >= pmreg->reg_num) 9771e2340276SBjoern A. Zeeb seq_puts(m, "\n"); 9772e2340276SBjoern A. Zeeb } 9773e2340276SBjoern A. Zeeb } 9774e2340276SBjoern A. Zeeb 9775*6d67aabdSBjoern A. Zeeb static void _show_mreg_v7(struct rtw89_dev *rtwdev, struct seq_file *m) 9776*6d67aabdSBjoern A. Zeeb { 9777*6d67aabdSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 9778*6d67aabdSBjoern A. Zeeb struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; 9779*6d67aabdSBjoern A. Zeeb struct rtw89_btc_fbtc_mreg_val_v7 *pmreg = NULL; 9780*6d67aabdSBjoern A. Zeeb struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; 9781*6d67aabdSBjoern A. Zeeb struct rtw89_btc_cx *cx = &btc->cx; 9782*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &cx->wl; 9783*6d67aabdSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &cx->bt; 9784*6d67aabdSBjoern A. Zeeb struct rtw89_mac_ax_gnt *gnt = NULL; 9785*6d67aabdSBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 9786*6d67aabdSBjoern A. Zeeb u8 i, type, cnt = 0; 9787*6d67aabdSBjoern A. Zeeb u32 val, offset; 9788*6d67aabdSBjoern A. Zeeb 9789*6d67aabdSBjoern A. Zeeb if (!(dm->coex_info_map & BTC_COEX_INFO_MREG)) 9790e2340276SBjoern A. Zeeb return; 9791e2340276SBjoern A. Zeeb 9792*6d67aabdSBjoern A. Zeeb seq_puts(m, "\n\r========== [HW Status] =========="); 9793e2340276SBjoern A. Zeeb 9794*6d67aabdSBjoern A. Zeeb seq_printf(m, 9795*6d67aabdSBjoern A. Zeeb "\n\r %-15s : WL->BT:0x%08x(cnt:%d), BT->WL:0x%08x(total:%d, bt_update:%d)", 9796*6d67aabdSBjoern A. Zeeb "[scoreboard]", wl->scbd, cx->cnt_wl[BTC_WCNT_SCBDUPDATE], 9797*6d67aabdSBjoern A. Zeeb bt->scbd, cx->cnt_bt[BTC_BCNT_SCBDREAD], 9798*6d67aabdSBjoern A. Zeeb cx->cnt_bt[BTC_BCNT_SCBDUPDATE]); 9799*6d67aabdSBjoern A. Zeeb 9800*6d67aabdSBjoern A. Zeeb /* To avoid I/O if WL LPS or power-off */ 9801*6d67aabdSBjoern A. Zeeb dm->pta_owner = rtw89_mac_get_ctrl_path(rtwdev); 9802*6d67aabdSBjoern A. Zeeb 9803*6d67aabdSBjoern A. Zeeb seq_printf(m, 9804*6d67aabdSBjoern A. Zeeb "\n\r %-15s : pta_owner:%s, pta_req_mac:MAC%d, rf_gnt_source: polut_type:%s", 9805*6d67aabdSBjoern A. Zeeb "[gnt_status]", 9806*6d67aabdSBjoern A. Zeeb rtwdev->chip->para_ver & BTC_FEAT_PTA_ONOFF_CTRL ? "HW" : 9807*6d67aabdSBjoern A. Zeeb dm->pta_owner == BTC_CTRL_BY_WL ? "WL" : "BT", 9808*6d67aabdSBjoern A. Zeeb wl->pta_req_mac, id_to_polut(wl->bt_polut_type[wl->pta_req_mac])); 9809*6d67aabdSBjoern A. Zeeb 9810*6d67aabdSBjoern A. Zeeb gnt = &dm->gnt.band[RTW89_PHY_0]; 9811*6d67aabdSBjoern A. Zeeb 9812*6d67aabdSBjoern A. Zeeb seq_printf(m, ", phy-0[gnt_wl:%s-%d/gnt_bt:%s-%d]", 9813*6d67aabdSBjoern A. Zeeb gnt->gnt_wl_sw_en ? "SW" : "HW", gnt->gnt_wl, 9814*6d67aabdSBjoern A. Zeeb gnt->gnt_bt_sw_en ? "SW" : "HW", gnt->gnt_bt); 9815*6d67aabdSBjoern A. Zeeb 9816*6d67aabdSBjoern A. Zeeb if (rtwdev->dbcc_en) { 9817*6d67aabdSBjoern A. Zeeb gnt = &dm->gnt.band[RTW89_PHY_1]; 9818*6d67aabdSBjoern A. Zeeb seq_printf(m, ", phy-1[gnt_wl:%s-%d/gnt_bt:%s-%d]", 9819*6d67aabdSBjoern A. Zeeb gnt->gnt_wl_sw_en ? "SW" : "HW", gnt->gnt_wl, 9820*6d67aabdSBjoern A. Zeeb gnt->gnt_bt_sw_en ? "SW" : "HW", gnt->gnt_bt); 9821*6d67aabdSBjoern A. Zeeb } 9822*6d67aabdSBjoern A. Zeeb 9823*6d67aabdSBjoern A. Zeeb pcinfo = &pfwinfo->rpt_fbtc_mregval.cinfo; 9824*6d67aabdSBjoern A. Zeeb if (!pcinfo->valid) 9825*6d67aabdSBjoern A. Zeeb return; 9826*6d67aabdSBjoern A. Zeeb 9827*6d67aabdSBjoern A. Zeeb pmreg = &pfwinfo->rpt_fbtc_mregval.finfo.v7; 9828*6d67aabdSBjoern A. Zeeb 9829*6d67aabdSBjoern A. Zeeb for (i = 0; i < pmreg->reg_num; i++) { 9830*6d67aabdSBjoern A. Zeeb type = (u8)le16_to_cpu(rtwdev->chip->mon_reg[i].type); 9831*6d67aabdSBjoern A. Zeeb offset = le32_to_cpu(rtwdev->chip->mon_reg[i].offset); 9832*6d67aabdSBjoern A. Zeeb val = le32_to_cpu(pmreg->mreg_val[i]); 9833*6d67aabdSBjoern A. Zeeb 9834*6d67aabdSBjoern A. Zeeb if (cnt % 6 == 0) 9835*6d67aabdSBjoern A. Zeeb seq_printf(m, "\n\r %-15s : %s_0x%x=0x%x", "[reg]", 9836*6d67aabdSBjoern A. Zeeb id_to_regtype(type), offset, val); 9837*6d67aabdSBjoern A. Zeeb else 9838*6d67aabdSBjoern A. Zeeb seq_printf(m, ", %s_0x%x=0x%x", 9839*6d67aabdSBjoern A. Zeeb id_to_regtype(type), offset, val); 9840*6d67aabdSBjoern A. Zeeb cnt++; 9841e2340276SBjoern A. Zeeb } 9842e2340276SBjoern A. Zeeb seq_puts(m, "\n"); 9843e2340276SBjoern A. Zeeb } 9844e2340276SBjoern A. Zeeb 9845e2340276SBjoern A. Zeeb static void _show_summary_v1(struct rtw89_dev *rtwdev, struct seq_file *m) 98468e93258fSBjoern A. Zeeb { 98478e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 98488e93258fSBjoern A. Zeeb struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; 98498e93258fSBjoern A. Zeeb struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; 9850e2340276SBjoern A. Zeeb struct rtw89_btc_fbtc_rpt_ctrl_v1 *prptctrl = NULL; 98518e93258fSBjoern A. Zeeb struct rtw89_btc_cx *cx = &btc->cx; 98528e93258fSBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 98538e93258fSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &cx->wl; 98548e93258fSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &cx->bt; 98558e93258fSBjoern A. Zeeb u32 cnt_sum = 0, *cnt = btc->dm.cnt_notify; 98568e93258fSBjoern A. Zeeb u8 i; 98578e93258fSBjoern A. Zeeb 98588e93258fSBjoern A. Zeeb if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY)) 98598e93258fSBjoern A. Zeeb return; 98608e93258fSBjoern A. Zeeb 98618e93258fSBjoern A. Zeeb seq_puts(m, "========== [Statistics] ==========\n"); 98628e93258fSBjoern A. Zeeb 98638e93258fSBjoern A. Zeeb pcinfo = &pfwinfo->rpt_ctrl.cinfo; 98648e93258fSBjoern A. Zeeb if (pcinfo->valid && !wl->status.map.lps && !wl->status.map.rf_off) { 9865e2340276SBjoern A. Zeeb prptctrl = &pfwinfo->rpt_ctrl.finfo.v1; 98668e93258fSBjoern A. Zeeb 98678e93258fSBjoern A. Zeeb seq_printf(m, 98688e93258fSBjoern A. Zeeb " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d), ", 98698e93258fSBjoern A. Zeeb "[summary]", pfwinfo->cnt_h2c, 98708e93258fSBjoern A. Zeeb pfwinfo->cnt_h2c_fail, prptctrl->h2c_cnt, 98718e93258fSBjoern A. Zeeb pfwinfo->cnt_c2h, prptctrl->c2h_cnt); 98728e93258fSBjoern A. Zeeb 98738e93258fSBjoern A. Zeeb seq_printf(m, 98748e93258fSBjoern A. Zeeb "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x, dm_error_map:0x%x", 98758e93258fSBjoern A. Zeeb pfwinfo->event[BTF_EVNT_RPT], prptctrl->rpt_cnt, 98768e93258fSBjoern A. Zeeb prptctrl->rpt_enable, dm->error.val); 98778e93258fSBjoern A. Zeeb 98788e93258fSBjoern A. Zeeb if (dm->error.map.wl_fw_hang) 98798e93258fSBjoern A. Zeeb seq_puts(m, " (WL FW Hang!!)"); 98808e93258fSBjoern A. Zeeb seq_puts(m, "\n"); 98818e93258fSBjoern A. Zeeb seq_printf(m, 98828e93258fSBjoern A. Zeeb " %-15s : send_ok:%d, send_fail:%d, recv:%d", 98838e93258fSBjoern A. Zeeb "[mailbox]", prptctrl->mb_send_ok_cnt, 98848e93258fSBjoern A. Zeeb prptctrl->mb_send_fail_cnt, prptctrl->mb_recv_cnt); 98858e93258fSBjoern A. Zeeb 98868e93258fSBjoern A. Zeeb seq_printf(m, 98878e93258fSBjoern A. Zeeb "(A2DP_empty:%d, A2DP_flowstop:%d, A2DP_full:%d)\n", 98888e93258fSBjoern A. Zeeb prptctrl->mb_a2dp_empty_cnt, 98898e93258fSBjoern A. Zeeb prptctrl->mb_a2dp_flct_cnt, 98908e93258fSBjoern A. Zeeb prptctrl->mb_a2dp_full_cnt); 98918e93258fSBjoern A. Zeeb 98928e93258fSBjoern A. Zeeb seq_printf(m, 98938e93258fSBjoern A. Zeeb " %-15s : wl_rfk[req:%d/go:%d/reject:%d/timeout:%d]", 98948e93258fSBjoern A. Zeeb "[RFK]", cx->cnt_wl[BTC_WCNT_RFK_REQ], 98958e93258fSBjoern A. Zeeb cx->cnt_wl[BTC_WCNT_RFK_GO], 98968e93258fSBjoern A. Zeeb cx->cnt_wl[BTC_WCNT_RFK_REJECT], 98978e93258fSBjoern A. Zeeb cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]); 98988e93258fSBjoern A. Zeeb 98998e93258fSBjoern A. Zeeb seq_printf(m, 99008e93258fSBjoern A. Zeeb ", bt_rfk[req:%d/go:%d/reject:%d/timeout:%d/fail:%d]\n", 99018e93258fSBjoern A. Zeeb prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_REQ], 99028e93258fSBjoern A. Zeeb prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_GO], 99038e93258fSBjoern A. Zeeb prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_REJECT], 99048e93258fSBjoern A. Zeeb prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_TIMEOUT], 99058e93258fSBjoern A. Zeeb prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_FAIL]); 99068e93258fSBjoern A. Zeeb 99078e93258fSBjoern A. Zeeb if (prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_TIMEOUT] > 0) 99088e93258fSBjoern A. Zeeb bt->rfk_info.map.timeout = 1; 99098e93258fSBjoern A. Zeeb else 99108e93258fSBjoern A. Zeeb bt->rfk_info.map.timeout = 0; 99118e93258fSBjoern A. Zeeb 99128e93258fSBjoern A. Zeeb dm->error.map.wl_rfk_timeout = bt->rfk_info.map.timeout; 99138e93258fSBjoern A. Zeeb } else { 99148e93258fSBjoern A. Zeeb seq_printf(m, 99158e93258fSBjoern A. Zeeb " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d, rpt_cnt=%d, rpt_map=0x%x", 99168e93258fSBjoern A. Zeeb "[summary]", pfwinfo->cnt_h2c, 99178e93258fSBjoern A. Zeeb pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h, 99188e93258fSBjoern A. Zeeb pfwinfo->event[BTF_EVNT_RPT], 99198e93258fSBjoern A. Zeeb btc->fwinfo.rpt_en_map); 99208e93258fSBjoern A. Zeeb seq_puts(m, " (WL FW report invalid!!)\n"); 99218e93258fSBjoern A. Zeeb } 99228e93258fSBjoern A. Zeeb 99238e93258fSBjoern A. Zeeb for (i = 0; i < BTC_NCNT_NUM; i++) 99248e93258fSBjoern A. Zeeb cnt_sum += dm->cnt_notify[i]; 99258e93258fSBjoern A. Zeeb 99268e93258fSBjoern A. Zeeb seq_printf(m, 99278e93258fSBjoern A. Zeeb " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", 99288e93258fSBjoern A. Zeeb "[notify_cnt]", cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], 99298e93258fSBjoern A. Zeeb cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); 99308e93258fSBjoern A. Zeeb 99318e93258fSBjoern A. Zeeb seq_printf(m, 99328e93258fSBjoern A. Zeeb "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d\n", 99338e93258fSBjoern A. Zeeb cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], 99348e93258fSBjoern A. Zeeb cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], 99358e93258fSBjoern A. Zeeb cnt[BTC_NCNT_WL_STA]); 99368e93258fSBjoern A. Zeeb 99378e93258fSBjoern A. Zeeb seq_printf(m, 99388e93258fSBjoern A. Zeeb " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ", 99398e93258fSBjoern A. Zeeb "[notify_cnt]", cnt[BTC_NCNT_SCAN_START], 99408e93258fSBjoern A. Zeeb cnt[BTC_NCNT_SCAN_FINISH], cnt[BTC_NCNT_SWITCH_BAND], 99418e93258fSBjoern A. Zeeb cnt[BTC_NCNT_SPECIAL_PACKET]); 99428e93258fSBjoern A. Zeeb 99438e93258fSBjoern A. Zeeb seq_printf(m, 99448e93258fSBjoern A. Zeeb "timer=%d, control=%d, customerize=%d\n", 99458e93258fSBjoern A. Zeeb cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL], 99468e93258fSBjoern A. Zeeb cnt[BTC_NCNT_CUSTOMERIZE]); 99478e93258fSBjoern A. Zeeb } 99488e93258fSBjoern A. Zeeb 9949e2340276SBjoern A. Zeeb static void _show_summary_v4(struct rtw89_dev *rtwdev, struct seq_file *m) 9950e2340276SBjoern A. Zeeb { 9951e2340276SBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 9952e2340276SBjoern A. Zeeb struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; 9953e2340276SBjoern A. Zeeb struct rtw89_btc_fbtc_rpt_ctrl_v4 *prptctrl; 9954e2340276SBjoern A. Zeeb struct rtw89_btc_rpt_cmn_info *pcinfo; 9955e2340276SBjoern A. Zeeb struct rtw89_btc_cx *cx = &btc->cx; 9956e2340276SBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 9957e2340276SBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &cx->wl; 9958e2340276SBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &cx->bt; 9959e2340276SBjoern A. Zeeb u32 cnt_sum = 0, *cnt = btc->dm.cnt_notify; 9960e2340276SBjoern A. Zeeb u8 i; 9961e2340276SBjoern A. Zeeb 9962e2340276SBjoern A. Zeeb if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY)) 9963e2340276SBjoern A. Zeeb return; 9964e2340276SBjoern A. Zeeb 9965e2340276SBjoern A. Zeeb seq_puts(m, "========== [Statistics] ==========\n"); 9966e2340276SBjoern A. Zeeb 9967e2340276SBjoern A. Zeeb pcinfo = &pfwinfo->rpt_ctrl.cinfo; 9968e2340276SBjoern A. Zeeb if (pcinfo->valid && !wl->status.map.lps && !wl->status.map.rf_off) { 9969e2340276SBjoern A. Zeeb prptctrl = &pfwinfo->rpt_ctrl.finfo.v4; 9970e2340276SBjoern A. Zeeb 9971e2340276SBjoern A. Zeeb seq_printf(m, 9972e2340276SBjoern A. Zeeb " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d), ", 9973e2340276SBjoern A. Zeeb "[summary]", pfwinfo->cnt_h2c, 9974e2340276SBjoern A. Zeeb pfwinfo->cnt_h2c_fail, 9975e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->rpt_info.cnt_h2c), 9976e2340276SBjoern A. Zeeb pfwinfo->cnt_c2h, 9977e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->rpt_info.cnt_c2h)); 9978e2340276SBjoern A. Zeeb 9979e2340276SBjoern A. Zeeb seq_printf(m, 9980e2340276SBjoern A. Zeeb "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x, dm_error_map:0x%x", 9981e2340276SBjoern A. Zeeb pfwinfo->event[BTF_EVNT_RPT], 9982e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->rpt_info.cnt), 9983e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->rpt_info.en), 9984e2340276SBjoern A. Zeeb dm->error.val); 9985e2340276SBjoern A. Zeeb 9986e2340276SBjoern A. Zeeb if (dm->error.map.wl_fw_hang) 9987e2340276SBjoern A. Zeeb seq_puts(m, " (WL FW Hang!!)"); 9988e2340276SBjoern A. Zeeb seq_puts(m, "\n"); 9989e2340276SBjoern A. Zeeb seq_printf(m, 9990e2340276SBjoern A. Zeeb " %-15s : send_ok:%d, send_fail:%d, recv:%d, ", 9991e2340276SBjoern A. Zeeb "[mailbox]", 9992e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok), 9993e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail), 9994e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv)); 9995e2340276SBjoern A. Zeeb 9996e2340276SBjoern A. Zeeb seq_printf(m, 9997e2340276SBjoern A. Zeeb "A2DP_empty:%d(stop:%d, tx:%d, ack:%d, nack:%d)\n", 9998e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty), 9999e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl), 10000e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx), 10001e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack), 10002e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack)); 10003e2340276SBjoern A. Zeeb 10004e2340276SBjoern A. Zeeb seq_printf(m, 10005e2340276SBjoern A. Zeeb " %-15s : wl_rfk[req:%d/go:%d/reject:%d/timeout:%d]", 10006e2340276SBjoern A. Zeeb "[RFK]", cx->cnt_wl[BTC_WCNT_RFK_REQ], 10007e2340276SBjoern A. Zeeb cx->cnt_wl[BTC_WCNT_RFK_GO], 10008e2340276SBjoern A. Zeeb cx->cnt_wl[BTC_WCNT_RFK_REJECT], 10009e2340276SBjoern A. Zeeb cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]); 10010e2340276SBjoern A. Zeeb 10011e2340276SBjoern A. Zeeb seq_printf(m, 10012e2340276SBjoern A. Zeeb ", bt_rfk[req:%d/go:%d/reject:%d/timeout:%d/fail:%d]\n", 10013e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ]), 10014e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_GO]), 10015e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REJECT]), 10016e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_TIMEOUT]), 10017e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_FAIL])); 10018e2340276SBjoern A. Zeeb 10019e2340276SBjoern A. Zeeb if (le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_TIMEOUT]) > 0) 10020e2340276SBjoern A. Zeeb bt->rfk_info.map.timeout = 1; 10021e2340276SBjoern A. Zeeb else 10022e2340276SBjoern A. Zeeb bt->rfk_info.map.timeout = 0; 10023e2340276SBjoern A. Zeeb 10024e2340276SBjoern A. Zeeb dm->error.map.wl_rfk_timeout = bt->rfk_info.map.timeout; 10025e2340276SBjoern A. Zeeb } else { 10026e2340276SBjoern A. Zeeb seq_printf(m, 10027e2340276SBjoern A. Zeeb " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d, rpt_cnt=%d, rpt_map=0x%x", 10028e2340276SBjoern A. Zeeb "[summary]", pfwinfo->cnt_h2c, 10029e2340276SBjoern A. Zeeb pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h, 10030e2340276SBjoern A. Zeeb pfwinfo->event[BTF_EVNT_RPT], 10031e2340276SBjoern A. Zeeb btc->fwinfo.rpt_en_map); 10032e2340276SBjoern A. Zeeb seq_puts(m, " (WL FW report invalid!!)\n"); 10033e2340276SBjoern A. Zeeb } 10034e2340276SBjoern A. Zeeb 10035e2340276SBjoern A. Zeeb for (i = 0; i < BTC_NCNT_NUM; i++) 10036e2340276SBjoern A. Zeeb cnt_sum += dm->cnt_notify[i]; 10037e2340276SBjoern A. Zeeb 10038e2340276SBjoern A. Zeeb seq_printf(m, 10039e2340276SBjoern A. Zeeb " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", 10040e2340276SBjoern A. Zeeb "[notify_cnt]", cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], 10041e2340276SBjoern A. Zeeb cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); 10042e2340276SBjoern A. Zeeb 10043e2340276SBjoern A. Zeeb seq_printf(m, 10044e2340276SBjoern A. Zeeb "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d\n", 10045e2340276SBjoern A. Zeeb cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], 10046e2340276SBjoern A. Zeeb cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], 10047e2340276SBjoern A. Zeeb cnt[BTC_NCNT_WL_STA]); 10048e2340276SBjoern A. Zeeb 10049e2340276SBjoern A. Zeeb seq_printf(m, 10050e2340276SBjoern A. Zeeb " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ", 10051e2340276SBjoern A. Zeeb "[notify_cnt]", cnt[BTC_NCNT_SCAN_START], 10052e2340276SBjoern A. Zeeb cnt[BTC_NCNT_SCAN_FINISH], cnt[BTC_NCNT_SWITCH_BAND], 10053e2340276SBjoern A. Zeeb cnt[BTC_NCNT_SPECIAL_PACKET]); 10054e2340276SBjoern A. Zeeb 10055e2340276SBjoern A. Zeeb seq_printf(m, 10056e2340276SBjoern A. Zeeb "timer=%d, control=%d, customerize=%d\n", 10057e2340276SBjoern A. Zeeb cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL], 10058e2340276SBjoern A. Zeeb cnt[BTC_NCNT_CUSTOMERIZE]); 10059e2340276SBjoern A. Zeeb } 10060e2340276SBjoern A. Zeeb 10061e2340276SBjoern A. Zeeb static void _show_summary_v5(struct rtw89_dev *rtwdev, struct seq_file *m) 10062e2340276SBjoern A. Zeeb { 10063e2340276SBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 10064e2340276SBjoern A. Zeeb struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; 10065e2340276SBjoern A. Zeeb struct rtw89_btc_fbtc_rpt_ctrl_v5 *prptctrl; 10066e2340276SBjoern A. Zeeb struct rtw89_btc_rpt_cmn_info *pcinfo; 10067e2340276SBjoern A. Zeeb struct rtw89_btc_cx *cx = &btc->cx; 10068e2340276SBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 10069e2340276SBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &cx->wl; 10070e2340276SBjoern A. Zeeb u32 cnt_sum = 0, *cnt = btc->dm.cnt_notify; 10071e2340276SBjoern A. Zeeb u8 i; 10072e2340276SBjoern A. Zeeb 10073e2340276SBjoern A. Zeeb if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY)) 10074e2340276SBjoern A. Zeeb return; 10075e2340276SBjoern A. Zeeb 10076e2340276SBjoern A. Zeeb seq_puts(m, "========== [Statistics] ==========\n"); 10077e2340276SBjoern A. Zeeb 10078e2340276SBjoern A. Zeeb pcinfo = &pfwinfo->rpt_ctrl.cinfo; 10079e2340276SBjoern A. Zeeb if (pcinfo->valid && !wl->status.map.lps && !wl->status.map.rf_off) { 10080e2340276SBjoern A. Zeeb prptctrl = &pfwinfo->rpt_ctrl.finfo.v5; 10081e2340276SBjoern A. Zeeb 10082e2340276SBjoern A. Zeeb seq_printf(m, 10083e2340276SBjoern A. Zeeb " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d, len:%d), ", 10084e2340276SBjoern A. Zeeb "[summary]", pfwinfo->cnt_h2c, pfwinfo->cnt_h2c_fail, 10085e2340276SBjoern A. Zeeb le16_to_cpu(prptctrl->rpt_info.cnt_h2c), 10086e2340276SBjoern A. Zeeb pfwinfo->cnt_c2h, 10087e2340276SBjoern A. Zeeb le16_to_cpu(prptctrl->rpt_info.cnt_c2h), 10088e2340276SBjoern A. Zeeb le16_to_cpu(prptctrl->rpt_info.len_c2h)); 10089e2340276SBjoern A. Zeeb 10090e2340276SBjoern A. Zeeb seq_printf(m, 10091e2340276SBjoern A. Zeeb "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x", 10092e2340276SBjoern A. Zeeb pfwinfo->event[BTF_EVNT_RPT], 10093e2340276SBjoern A. Zeeb le16_to_cpu(prptctrl->rpt_info.cnt), 10094e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->rpt_info.en)); 10095e2340276SBjoern A. Zeeb 10096e2340276SBjoern A. Zeeb if (dm->error.map.wl_fw_hang) 10097e2340276SBjoern A. Zeeb seq_puts(m, " (WL FW Hang!!)"); 10098e2340276SBjoern A. Zeeb seq_puts(m, "\n"); 10099e2340276SBjoern A. Zeeb seq_printf(m, 10100e2340276SBjoern A. Zeeb " %-15s : send_ok:%d, send_fail:%d, recv:%d, ", 10101e2340276SBjoern A. Zeeb "[mailbox]", 10102e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok), 10103e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail), 10104e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv)); 10105e2340276SBjoern A. Zeeb 10106e2340276SBjoern A. Zeeb seq_printf(m, 10107e2340276SBjoern A. Zeeb "A2DP_empty:%d(stop:%d, tx:%d, ack:%d, nack:%d)\n", 10108e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty), 10109e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl), 10110e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx), 10111e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack), 10112e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack)); 10113e2340276SBjoern A. Zeeb 10114e2340276SBjoern A. Zeeb seq_printf(m, 10115e2340276SBjoern A. Zeeb " %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d]", 10116e2340276SBjoern A. Zeeb "[RFK/LPS]", cx->cnt_wl[BTC_WCNT_RFK_REQ], 10117e2340276SBjoern A. Zeeb cx->cnt_wl[BTC_WCNT_RFK_GO], 10118e2340276SBjoern A. Zeeb cx->cnt_wl[BTC_WCNT_RFK_REJECT], 10119e2340276SBjoern A. Zeeb cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]); 10120e2340276SBjoern A. Zeeb 10121e2340276SBjoern A. Zeeb seq_printf(m, 10122e2340276SBjoern A. Zeeb ", bt_rfk[req:%d]", 10123e2340276SBjoern A. Zeeb le16_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ])); 10124e2340276SBjoern A. Zeeb 10125e2340276SBjoern A. Zeeb seq_printf(m, 10126e2340276SBjoern A. Zeeb ", AOAC[RF_on:%d/RF_off:%d]", 10127e2340276SBjoern A. Zeeb le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on), 10128e2340276SBjoern A. Zeeb le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off)); 10129e2340276SBjoern A. Zeeb } else { 10130e2340276SBjoern A. Zeeb seq_printf(m, 10131e2340276SBjoern A. Zeeb " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d", 10132e2340276SBjoern A. Zeeb "[summary]", pfwinfo->cnt_h2c, 10133e2340276SBjoern A. Zeeb pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h); 10134e2340276SBjoern A. Zeeb } 10135e2340276SBjoern A. Zeeb 10136e2340276SBjoern A. Zeeb if (!pcinfo->valid || pfwinfo->len_mismch || pfwinfo->fver_mismch || 10137e2340276SBjoern A. Zeeb pfwinfo->err[BTFRE_EXCEPTION]) { 10138e2340276SBjoern A. Zeeb seq_puts(m, "\n"); 10139e2340276SBjoern A. Zeeb seq_printf(m, 10140e2340276SBjoern A. Zeeb " %-15s : WL FW rpt error!![rpt_ctrl_valid:%d/len:" 10141e2340276SBjoern A. Zeeb "0x%x/ver:0x%x/ex:%d/lps=%d/rf_off=%d]", 10142e2340276SBjoern A. Zeeb "[ERROR]", pcinfo->valid, pfwinfo->len_mismch, 10143e2340276SBjoern A. Zeeb pfwinfo->fver_mismch, pfwinfo->err[BTFRE_EXCEPTION], 10144e2340276SBjoern A. Zeeb wl->status.map.lps, wl->status.map.rf_off); 10145e2340276SBjoern A. Zeeb } 10146e2340276SBjoern A. Zeeb 10147e2340276SBjoern A. Zeeb for (i = 0; i < BTC_NCNT_NUM; i++) 10148e2340276SBjoern A. Zeeb cnt_sum += dm->cnt_notify[i]; 10149e2340276SBjoern A. Zeeb 10150e2340276SBjoern A. Zeeb seq_puts(m, "\n"); 10151e2340276SBjoern A. Zeeb seq_printf(m, 10152e2340276SBjoern A. Zeeb " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", 10153e2340276SBjoern A. Zeeb "[notify_cnt]", 10154e2340276SBjoern A. Zeeb cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], 10155e2340276SBjoern A. Zeeb cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); 10156e2340276SBjoern A. Zeeb 10157e2340276SBjoern A. Zeeb seq_printf(m, 10158e2340276SBjoern A. Zeeb "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d", 10159e2340276SBjoern A. Zeeb cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], 10160e2340276SBjoern A. Zeeb cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], 10161e2340276SBjoern A. Zeeb cnt[BTC_NCNT_WL_STA]); 10162e2340276SBjoern A. Zeeb 10163e2340276SBjoern A. Zeeb seq_puts(m, "\n"); 10164e2340276SBjoern A. Zeeb seq_printf(m, 10165e2340276SBjoern A. Zeeb " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ", 10166e2340276SBjoern A. Zeeb "[notify_cnt]", 10167e2340276SBjoern A. Zeeb cnt[BTC_NCNT_SCAN_START], cnt[BTC_NCNT_SCAN_FINISH], 10168e2340276SBjoern A. Zeeb cnt[BTC_NCNT_SWITCH_BAND], cnt[BTC_NCNT_SPECIAL_PACKET]); 10169e2340276SBjoern A. Zeeb 10170e2340276SBjoern A. Zeeb seq_printf(m, 10171e2340276SBjoern A. Zeeb "timer=%d, control=%d, customerize=%d", 10172e2340276SBjoern A. Zeeb cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL], 10173e2340276SBjoern A. Zeeb cnt[BTC_NCNT_CUSTOMERIZE]); 10174e2340276SBjoern A. Zeeb } 10175e2340276SBjoern A. Zeeb 10176e2340276SBjoern A. Zeeb static void _show_summary_v105(struct rtw89_dev *rtwdev, struct seq_file *m) 10177e2340276SBjoern A. Zeeb { 10178e2340276SBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 10179e2340276SBjoern A. Zeeb struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; 10180e2340276SBjoern A. Zeeb struct rtw89_btc_fbtc_rpt_ctrl_v105 *prptctrl; 10181e2340276SBjoern A. Zeeb struct rtw89_btc_rpt_cmn_info *pcinfo; 10182e2340276SBjoern A. Zeeb struct rtw89_btc_cx *cx = &btc->cx; 10183e2340276SBjoern A. Zeeb struct rtw89_btc_dm *dm = &btc->dm; 10184e2340276SBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &cx->wl; 10185e2340276SBjoern A. Zeeb u32 cnt_sum = 0, *cnt = btc->dm.cnt_notify; 10186e2340276SBjoern A. Zeeb u8 i; 10187e2340276SBjoern A. Zeeb 10188e2340276SBjoern A. Zeeb if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY)) 10189e2340276SBjoern A. Zeeb return; 10190e2340276SBjoern A. Zeeb 10191e2340276SBjoern A. Zeeb seq_puts(m, "========== [Statistics] ==========\n"); 10192e2340276SBjoern A. Zeeb 10193e2340276SBjoern A. Zeeb pcinfo = &pfwinfo->rpt_ctrl.cinfo; 10194e2340276SBjoern A. Zeeb if (pcinfo->valid && !wl->status.map.lps && !wl->status.map.rf_off) { 10195e2340276SBjoern A. Zeeb prptctrl = &pfwinfo->rpt_ctrl.finfo.v105; 10196e2340276SBjoern A. Zeeb 10197e2340276SBjoern A. Zeeb seq_printf(m, 10198e2340276SBjoern A. Zeeb " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d, len:%d), ", 10199e2340276SBjoern A. Zeeb "[summary]", pfwinfo->cnt_h2c, pfwinfo->cnt_h2c_fail, 10200e2340276SBjoern A. Zeeb le16_to_cpu(prptctrl->rpt_info.cnt_h2c), 10201e2340276SBjoern A. Zeeb pfwinfo->cnt_c2h, 10202e2340276SBjoern A. Zeeb le16_to_cpu(prptctrl->rpt_info.cnt_c2h), 10203e2340276SBjoern A. Zeeb le16_to_cpu(prptctrl->rpt_info.len_c2h)); 10204e2340276SBjoern A. Zeeb 10205e2340276SBjoern A. Zeeb seq_printf(m, 10206e2340276SBjoern A. Zeeb "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x", 10207e2340276SBjoern A. Zeeb pfwinfo->event[BTF_EVNT_RPT], 10208e2340276SBjoern A. Zeeb le16_to_cpu(prptctrl->rpt_info.cnt), 10209e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->rpt_info.en)); 10210e2340276SBjoern A. Zeeb 10211e2340276SBjoern A. Zeeb if (dm->error.map.wl_fw_hang) 10212e2340276SBjoern A. Zeeb seq_puts(m, " (WL FW Hang!!)"); 10213e2340276SBjoern A. Zeeb seq_puts(m, "\n"); 10214e2340276SBjoern A. Zeeb seq_printf(m, 10215e2340276SBjoern A. Zeeb " %-15s : send_ok:%d, send_fail:%d, recv:%d, ", 10216e2340276SBjoern A. Zeeb "[mailbox]", 10217e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok), 10218e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail), 10219e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv)); 10220e2340276SBjoern A. Zeeb 10221e2340276SBjoern A. Zeeb seq_printf(m, 10222e2340276SBjoern A. Zeeb "A2DP_empty:%d(stop:%d, tx:%d, ack:%d, nack:%d)\n", 10223e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty), 10224e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl), 10225e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx), 10226e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack), 10227e2340276SBjoern A. Zeeb le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack)); 10228e2340276SBjoern A. Zeeb 10229e2340276SBjoern A. Zeeb seq_printf(m, 10230e2340276SBjoern A. Zeeb " %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d]", 10231e2340276SBjoern A. Zeeb "[RFK/LPS]", cx->cnt_wl[BTC_WCNT_RFK_REQ], 10232e2340276SBjoern A. Zeeb cx->cnt_wl[BTC_WCNT_RFK_GO], 10233e2340276SBjoern A. Zeeb cx->cnt_wl[BTC_WCNT_RFK_REJECT], 10234e2340276SBjoern A. Zeeb cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]); 10235e2340276SBjoern A. Zeeb 10236e2340276SBjoern A. Zeeb seq_printf(m, 10237e2340276SBjoern A. Zeeb ", bt_rfk[req:%d]", 10238e2340276SBjoern A. Zeeb le16_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ])); 10239e2340276SBjoern A. Zeeb 10240e2340276SBjoern A. Zeeb seq_printf(m, 10241e2340276SBjoern A. Zeeb ", AOAC[RF_on:%d/RF_off:%d]", 10242e2340276SBjoern A. Zeeb le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on), 10243e2340276SBjoern A. Zeeb le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off)); 10244e2340276SBjoern A. Zeeb } else { 10245e2340276SBjoern A. Zeeb seq_printf(m, 10246e2340276SBjoern A. Zeeb " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d", 10247e2340276SBjoern A. Zeeb "[summary]", pfwinfo->cnt_h2c, 10248e2340276SBjoern A. Zeeb pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h); 10249e2340276SBjoern A. Zeeb } 10250e2340276SBjoern A. Zeeb 10251e2340276SBjoern A. Zeeb if (!pcinfo->valid || pfwinfo->len_mismch || pfwinfo->fver_mismch || 10252e2340276SBjoern A. Zeeb pfwinfo->err[BTFRE_EXCEPTION]) { 10253e2340276SBjoern A. Zeeb seq_puts(m, "\n"); 10254e2340276SBjoern A. Zeeb seq_printf(m, 10255e2340276SBjoern A. Zeeb " %-15s : WL FW rpt error!![rpt_ctrl_valid:%d/len:" 10256e2340276SBjoern A. Zeeb "0x%x/ver:0x%x/ex:%d/lps=%d/rf_off=%d]", 10257e2340276SBjoern A. Zeeb "[ERROR]", pcinfo->valid, pfwinfo->len_mismch, 10258e2340276SBjoern A. Zeeb pfwinfo->fver_mismch, pfwinfo->err[BTFRE_EXCEPTION], 10259e2340276SBjoern A. Zeeb wl->status.map.lps, wl->status.map.rf_off); 10260e2340276SBjoern A. Zeeb } 10261e2340276SBjoern A. Zeeb 10262e2340276SBjoern A. Zeeb for (i = 0; i < BTC_NCNT_NUM; i++) 10263e2340276SBjoern A. Zeeb cnt_sum += dm->cnt_notify[i]; 10264e2340276SBjoern A. Zeeb 10265e2340276SBjoern A. Zeeb seq_puts(m, "\n"); 10266e2340276SBjoern A. Zeeb seq_printf(m, 10267e2340276SBjoern A. Zeeb " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", 10268e2340276SBjoern A. Zeeb "[notify_cnt]", 10269e2340276SBjoern A. Zeeb cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], 10270e2340276SBjoern A. Zeeb cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); 10271e2340276SBjoern A. Zeeb 10272e2340276SBjoern A. Zeeb seq_printf(m, 10273e2340276SBjoern A. Zeeb "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d", 10274e2340276SBjoern A. Zeeb cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], 10275e2340276SBjoern A. Zeeb cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], 10276e2340276SBjoern A. Zeeb cnt[BTC_NCNT_WL_STA]); 10277e2340276SBjoern A. Zeeb 10278e2340276SBjoern A. Zeeb seq_puts(m, "\n"); 10279e2340276SBjoern A. Zeeb seq_printf(m, 10280e2340276SBjoern A. Zeeb " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ", 10281e2340276SBjoern A. Zeeb "[notify_cnt]", 10282e2340276SBjoern A. Zeeb cnt[BTC_NCNT_SCAN_START], cnt[BTC_NCNT_SCAN_FINISH], 10283e2340276SBjoern A. Zeeb cnt[BTC_NCNT_SWITCH_BAND], cnt[BTC_NCNT_SPECIAL_PACKET]); 10284e2340276SBjoern A. Zeeb 10285e2340276SBjoern A. Zeeb seq_printf(m, 10286e2340276SBjoern A. Zeeb "timer=%d, control=%d, customerize=%d", 10287e2340276SBjoern A. Zeeb cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL], 10288e2340276SBjoern A. Zeeb cnt[BTC_NCNT_CUSTOMERIZE]); 10289e2340276SBjoern A. Zeeb } 10290e2340276SBjoern A. Zeeb 10291*6d67aabdSBjoern A. Zeeb static void _show_summary_v8(struct rtw89_dev *rtwdev, struct seq_file *m) 10292*6d67aabdSBjoern A. Zeeb { 10293*6d67aabdSBjoern A. Zeeb struct rtw89_btc_btf_fwinfo *pfwinfo = &rtwdev->btc.fwinfo; 10294*6d67aabdSBjoern A. Zeeb struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; 10295*6d67aabdSBjoern A. Zeeb struct rtw89_btc_fbtc_rpt_ctrl_v8 *prptctrl = NULL; 10296*6d67aabdSBjoern A. Zeeb struct rtw89_btc_cx *cx = &rtwdev->btc.cx; 10297*6d67aabdSBjoern A. Zeeb struct rtw89_btc_dm *dm = &rtwdev->btc.dm; 10298*6d67aabdSBjoern A. Zeeb struct rtw89_btc_wl_info *wl = &cx->wl; 10299*6d67aabdSBjoern A. Zeeb u32 *cnt = rtwdev->btc.dm.cnt_notify; 10300*6d67aabdSBjoern A. Zeeb u32 cnt_sum = 0; 10301*6d67aabdSBjoern A. Zeeb u8 i; 10302*6d67aabdSBjoern A. Zeeb 10303*6d67aabdSBjoern A. Zeeb if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY)) 10304*6d67aabdSBjoern A. Zeeb return; 10305*6d67aabdSBjoern A. Zeeb 10306*6d67aabdSBjoern A. Zeeb seq_printf(m, "%s", "\n\r========== [Statistics] =========="); 10307*6d67aabdSBjoern A. Zeeb 10308*6d67aabdSBjoern A. Zeeb pcinfo = &pfwinfo->rpt_ctrl.cinfo; 10309*6d67aabdSBjoern A. Zeeb if (pcinfo->valid && wl->status.map.lps != BTC_LPS_RF_OFF && 10310*6d67aabdSBjoern A. Zeeb !wl->status.map.rf_off) { 10311*6d67aabdSBjoern A. Zeeb prptctrl = &pfwinfo->rpt_ctrl.finfo.v8; 10312*6d67aabdSBjoern A. Zeeb 10313*6d67aabdSBjoern A. Zeeb seq_printf(m, 10314*6d67aabdSBjoern A. Zeeb "\n\r %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d, len:%d, max:fw-%d/drv-%d), ", 10315*6d67aabdSBjoern A. Zeeb "[summary]", pfwinfo->cnt_h2c, pfwinfo->cnt_h2c_fail, 10316*6d67aabdSBjoern A. Zeeb le16_to_cpu(prptctrl->rpt_info.cnt_h2c), pfwinfo->cnt_c2h, 10317*6d67aabdSBjoern A. Zeeb le16_to_cpu(prptctrl->rpt_info.cnt_c2h), 10318*6d67aabdSBjoern A. Zeeb le16_to_cpu(prptctrl->rpt_info.len_c2h), 10319*6d67aabdSBjoern A. Zeeb (prptctrl->rpt_len_max_h << 8) + prptctrl->rpt_len_max_l, 10320*6d67aabdSBjoern A. Zeeb rtwdev->btc.ver->info_buf); 10321*6d67aabdSBjoern A. Zeeb 10322*6d67aabdSBjoern A. Zeeb seq_printf(m, "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x", 10323*6d67aabdSBjoern A. Zeeb pfwinfo->event[BTF_EVNT_RPT], 10324*6d67aabdSBjoern A. Zeeb le16_to_cpu(prptctrl->rpt_info.cnt), 10325*6d67aabdSBjoern A. Zeeb le32_to_cpu(prptctrl->rpt_info.en)); 10326*6d67aabdSBjoern A. Zeeb 10327*6d67aabdSBjoern A. Zeeb if (dm->error.map.wl_fw_hang) 10328*6d67aabdSBjoern A. Zeeb seq_puts(m, " (WL FW Hang!!)"); 10329*6d67aabdSBjoern A. Zeeb 10330*6d67aabdSBjoern A. Zeeb seq_printf(m, "\n\r %-15s : send_ok:%d, send_fail:%d, recv:%d, ", 10331*6d67aabdSBjoern A. Zeeb "[mailbox]", le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok), 10332*6d67aabdSBjoern A. Zeeb le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail), 10333*6d67aabdSBjoern A. Zeeb le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv)); 10334*6d67aabdSBjoern A. Zeeb 10335*6d67aabdSBjoern A. Zeeb seq_printf(m, "A2DP_empty:%d(stop:%d/tx:%d/ack:%d/nack:%d)", 10336*6d67aabdSBjoern A. Zeeb le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty), 10337*6d67aabdSBjoern A. Zeeb le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl), 10338*6d67aabdSBjoern A. Zeeb le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx), 10339*6d67aabdSBjoern A. Zeeb le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack), 10340*6d67aabdSBjoern A. Zeeb le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack)); 10341*6d67aabdSBjoern A. Zeeb 10342*6d67aabdSBjoern A. Zeeb seq_printf(m, 10343*6d67aabdSBjoern A. Zeeb "\n\r %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d/time:%dms]", 10344*6d67aabdSBjoern A. Zeeb "[RFK/LPS]", cx->cnt_wl[BTC_WCNT_RFK_REQ], 10345*6d67aabdSBjoern A. Zeeb cx->cnt_wl[BTC_WCNT_RFK_GO], 10346*6d67aabdSBjoern A. Zeeb cx->cnt_wl[BTC_WCNT_RFK_REJECT], 10347*6d67aabdSBjoern A. Zeeb cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT], 10348*6d67aabdSBjoern A. Zeeb wl->rfk_info.proc_time); 10349*6d67aabdSBjoern A. Zeeb 10350*6d67aabdSBjoern A. Zeeb seq_printf(m, ", bt_rfk[req:%d]", 10351*6d67aabdSBjoern A. Zeeb le16_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ])); 10352*6d67aabdSBjoern A. Zeeb 10353*6d67aabdSBjoern A. Zeeb seq_printf(m, ", AOAC[RF_on:%d/RF_off:%d]", 10354*6d67aabdSBjoern A. Zeeb le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on), 10355*6d67aabdSBjoern A. Zeeb le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off)); 10356*6d67aabdSBjoern A. Zeeb } else { 10357*6d67aabdSBjoern A. Zeeb seq_printf(m, 10358*6d67aabdSBjoern A. Zeeb "\n\r %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d (lps=%d/rf_off=%d)", 10359*6d67aabdSBjoern A. Zeeb "[summary]", 10360*6d67aabdSBjoern A. Zeeb pfwinfo->cnt_h2c, pfwinfo->cnt_h2c_fail, 10361*6d67aabdSBjoern A. Zeeb pfwinfo->cnt_c2h, 10362*6d67aabdSBjoern A. Zeeb wl->status.map.lps, wl->status.map.rf_off); 10363*6d67aabdSBjoern A. Zeeb } 10364*6d67aabdSBjoern A. Zeeb 10365*6d67aabdSBjoern A. Zeeb for (i = 0; i < BTC_NCNT_NUM; i++) 10366*6d67aabdSBjoern A. Zeeb cnt_sum += dm->cnt_notify[i]; 10367*6d67aabdSBjoern A. Zeeb 10368*6d67aabdSBjoern A. Zeeb seq_printf(m, 10369*6d67aabdSBjoern A. Zeeb "\n\r %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", 10370*6d67aabdSBjoern A. Zeeb "[notify_cnt]", 10371*6d67aabdSBjoern A. Zeeb cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], 10372*6d67aabdSBjoern A. Zeeb cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); 10373*6d67aabdSBjoern A. Zeeb 10374*6d67aabdSBjoern A. Zeeb seq_printf(m, 10375*6d67aabdSBjoern A. Zeeb "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d", 10376*6d67aabdSBjoern A. Zeeb cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], 10377*6d67aabdSBjoern A. Zeeb cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], 10378*6d67aabdSBjoern A. Zeeb cnt[BTC_NCNT_WL_STA]); 10379*6d67aabdSBjoern A. Zeeb 10380*6d67aabdSBjoern A. Zeeb seq_printf(m, 10381*6d67aabdSBjoern A. Zeeb "\n\r %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, switch_chbw=%d, special_pkt=%d, ", 10382*6d67aabdSBjoern A. Zeeb "[notify_cnt]", 10383*6d67aabdSBjoern A. Zeeb cnt[BTC_NCNT_SCAN_START], cnt[BTC_NCNT_SCAN_FINISH], 10384*6d67aabdSBjoern A. Zeeb cnt[BTC_NCNT_SWITCH_BAND], cnt[BTC_NCNT_SWITCH_CHBW], 10385*6d67aabdSBjoern A. Zeeb cnt[BTC_NCNT_SPECIAL_PACKET]); 10386*6d67aabdSBjoern A. Zeeb 10387*6d67aabdSBjoern A. Zeeb seq_printf(m, "timer=%d, customerize=%d, hub_msg=%d, chg_fw=%d, send_cc=%d", 10388*6d67aabdSBjoern A. Zeeb cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CUSTOMERIZE], 10389*6d67aabdSBjoern A. Zeeb rtwdev->btc.hubmsg_cnt, cnt[BTC_NCNT_RESUME_DL_FW], 10390*6d67aabdSBjoern A. Zeeb cnt[BTC_NCNT_COUNTRYCODE]); 10391*6d67aabdSBjoern A. Zeeb } 10392*6d67aabdSBjoern A. Zeeb 103938e93258fSBjoern A. Zeeb void rtw89_btc_dump_info(struct rtw89_dev *rtwdev, struct seq_file *m) 103948e93258fSBjoern A. Zeeb { 103958e93258fSBjoern A. Zeeb struct rtw89_fw_suit *fw_suit = &rtwdev->fw.normal; 103968e93258fSBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 10397e2340276SBjoern A. Zeeb const struct rtw89_btc_ver *ver = btc->ver; 103988e93258fSBjoern A. Zeeb struct rtw89_btc_cx *cx = &btc->cx; 103998e93258fSBjoern A. Zeeb struct rtw89_btc_bt_info *bt = &cx->bt; 104008e93258fSBjoern A. Zeeb 104018e93258fSBjoern A. Zeeb seq_puts(m, "=========================================\n"); 104028e93258fSBjoern A. Zeeb seq_printf(m, "WL FW / BT FW %d.%d.%d.%d / NA\n", 104038e93258fSBjoern A. Zeeb fw_suit->major_ver, fw_suit->minor_ver, 104048e93258fSBjoern A. Zeeb fw_suit->sub_ver, fw_suit->sub_idex); 10405*6d67aabdSBjoern A. Zeeb seq_printf(m, "manual %d\n", btc->manual_ctrl); 104068e93258fSBjoern A. Zeeb 104078e93258fSBjoern A. Zeeb seq_puts(m, "=========================================\n"); 104088e93258fSBjoern A. Zeeb 104098e93258fSBjoern A. Zeeb seq_printf(m, "\n\r %-15s : raw_data[%02x %02x %02x %02x %02x %02x] (type:%s/cnt:%d/same:%d)", 104108e93258fSBjoern A. Zeeb "[bt_info]", 104118e93258fSBjoern A. Zeeb bt->raw_info[2], bt->raw_info[3], 104128e93258fSBjoern A. Zeeb bt->raw_info[4], bt->raw_info[5], 104138e93258fSBjoern A. Zeeb bt->raw_info[6], bt->raw_info[7], 104148e93258fSBjoern A. Zeeb bt->raw_info[0] == BTC_BTINFO_AUTO ? "auto" : "reply", 104158e93258fSBjoern A. Zeeb cx->cnt_bt[BTC_BCNT_INFOUPDATE], 104168e93258fSBjoern A. Zeeb cx->cnt_bt[BTC_BCNT_INFOSAME]); 104178e93258fSBjoern A. Zeeb 104188e93258fSBjoern A. Zeeb seq_puts(m, "\n=========================================\n"); 104198e93258fSBjoern A. Zeeb 104208e93258fSBjoern A. Zeeb _show_cx_info(rtwdev, m); 104218e93258fSBjoern A. Zeeb _show_wl_info(rtwdev, m); 104228e93258fSBjoern A. Zeeb _show_bt_info(rtwdev, m); 104238e93258fSBjoern A. Zeeb _show_dm_info(rtwdev, m); 104248e93258fSBjoern A. Zeeb _show_fw_dm_msg(rtwdev, m); 10425e2340276SBjoern A. Zeeb 10426e2340276SBjoern A. Zeeb if (ver->fcxmreg == 1) 10427e2340276SBjoern A. Zeeb _show_mreg_v1(rtwdev, m); 10428e2340276SBjoern A. Zeeb else if (ver->fcxmreg == 2) 10429e2340276SBjoern A. Zeeb _show_mreg_v2(rtwdev, m); 10430*6d67aabdSBjoern A. Zeeb else if (ver->fcxmreg == 7) 10431*6d67aabdSBjoern A. Zeeb _show_mreg_v7(rtwdev, m); 10432*6d67aabdSBjoern A. Zeeb 10433*6d67aabdSBjoern A. Zeeb _show_gpio_dbg(rtwdev, m); 10434e2340276SBjoern A. Zeeb 10435e2340276SBjoern A. Zeeb if (ver->fcxbtcrpt == 1) 10436e2340276SBjoern A. Zeeb _show_summary_v1(rtwdev, m); 10437e2340276SBjoern A. Zeeb else if (ver->fcxbtcrpt == 4) 10438e2340276SBjoern A. Zeeb _show_summary_v4(rtwdev, m); 10439e2340276SBjoern A. Zeeb else if (ver->fcxbtcrpt == 5) 10440e2340276SBjoern A. Zeeb _show_summary_v5(rtwdev, m); 10441e2340276SBjoern A. Zeeb else if (ver->fcxbtcrpt == 105) 10442e2340276SBjoern A. Zeeb _show_summary_v105(rtwdev, m); 10443*6d67aabdSBjoern A. Zeeb else if (ver->fcxbtcrpt == 8) 10444*6d67aabdSBjoern A. Zeeb _show_summary_v8(rtwdev, m); 10445e2340276SBjoern A. Zeeb } 10446e2340276SBjoern A. Zeeb 10447e2340276SBjoern A. Zeeb void rtw89_coex_recognize_ver(struct rtw89_dev *rtwdev) 10448e2340276SBjoern A. Zeeb { 10449e2340276SBjoern A. Zeeb const struct rtw89_chip_info *chip = rtwdev->chip; 10450e2340276SBjoern A. Zeeb struct rtw89_btc *btc = &rtwdev->btc; 10451e2340276SBjoern A. Zeeb const struct rtw89_btc_ver *btc_ver_def; 10452e2340276SBjoern A. Zeeb const struct rtw89_fw_suit *fw_suit; 10453e2340276SBjoern A. Zeeb u32 suit_ver_code; 10454e2340276SBjoern A. Zeeb int i; 10455e2340276SBjoern A. Zeeb 10456e2340276SBjoern A. Zeeb fw_suit = rtw89_fw_suit_get(rtwdev, RTW89_FW_NORMAL); 10457e2340276SBjoern A. Zeeb suit_ver_code = RTW89_FW_SUIT_VER_CODE(fw_suit); 10458e2340276SBjoern A. Zeeb 10459e2340276SBjoern A. Zeeb for (i = 0; i < ARRAY_SIZE(rtw89_btc_ver_defs); i++) { 10460e2340276SBjoern A. Zeeb btc_ver_def = &rtw89_btc_ver_defs[i]; 10461e2340276SBjoern A. Zeeb 10462e2340276SBjoern A. Zeeb if (chip->chip_id != btc_ver_def->chip_id) 10463e2340276SBjoern A. Zeeb continue; 10464e2340276SBjoern A. Zeeb 10465e2340276SBjoern A. Zeeb if (suit_ver_code >= btc_ver_def->fw_ver_code) { 10466e2340276SBjoern A. Zeeb btc->ver = btc_ver_def; 10467e2340276SBjoern A. Zeeb goto out; 10468e2340276SBjoern A. Zeeb } 10469e2340276SBjoern A. Zeeb } 10470e2340276SBjoern A. Zeeb 10471e2340276SBjoern A. Zeeb btc->ver = &rtw89_btc_ver_defs[RTW89_DEFAULT_BTC_VER_IDX]; 10472e2340276SBjoern A. Zeeb 10473e2340276SBjoern A. Zeeb out: 10474e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC] use version def[%d] = 0x%08x\n", 10475e2340276SBjoern A. Zeeb (int)(btc->ver - rtw89_btc_ver_defs), btc->ver->fw_ver_code); 104768e93258fSBjoern A. Zeeb } 10477