1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ 2 /* Copyright(c) 2019-2020 Realtek Corporation 3 */ 4 5 #ifndef __RTW89_COEX_H__ 6 #define __RTW89_COEX_H__ 7 8 #include "core.h" 9 10 #define BTC_TLV_SLOT_ID_LEN_V7 1 11 #define BTC_SLOT_REQ_TH 2 12 13 #define BTC_FREQ_W2G 2412 14 #define BTC_FREQ_W5G 5005 15 #define BTC_FREQ_W6G 5955 16 17 #define BTC_FREQ_B2G 2402 18 #define BTC_FREQ_B6G 5125 19 20 #define BTC_FREQ_W2G_CH14 2484 21 22 #define BTC_LO_2G_DNM 125 /* LO Coefficient Denominator */ 23 #define BTC_LO_5G_DNM 125 24 #define BTC_LO_6G_DNM 150 25 26 #define BTC_LO_2G_NMR 400 /* LO Coefficient Numerator */ 27 #define BTC_LO_5G_NMR 200 28 #define BTC_LO_6G_NMR 200 29 30 #define BTC_CH_W2G_MIN 1 /* start from 2412MHz */ 31 #define BTC_CH_W2G_MAX 14 32 #define BTC_CH_W5G_MIN 1 /* start from 5005MHz */ 33 #define BTC_CH_W5G_MAX 165 34 #define BTC_CH_W6G_MIN 1 /* start from 5955MHz */ 35 #define BTC_CH_W6G_MAX 233 36 37 #define BTC_CH_B2G_MIN 0 /* start from 2402MHz */ 38 #define BTC_CH_B2G_MAX 78 39 40 #define BTC_CH_B5G_MIN 600 /* start from 5725MHz */ 41 #define BTC_CH_B5G_MAX 1300 42 43 #define BTC_VCO_GUARD_W2W 10 /* WiFi to WiFi VCO freq forbiddened range (MHZ) */ 44 #define BTC_VCO_GUARD_W2B 25 /* WiFi to WiFi VCO freq forbiddened range (MHZ) */ 45 #define BTC_VCO_GUARD_B2B 10 /* WiFi to WiFi VCO freq forbiddened range (MHZ) */ 46 47 enum btc_mode { 48 BTC_MODE_NORMAL, 49 BTC_MODE_WL, 50 BTC_MODE_BT, 51 BTC_MODE_WLOFF, 52 BTC_MODE_COTX, 53 BTC_MODE_MECHANISM_INIT, 54 BTC_MODE_MAX 55 }; 56 57 enum btc_wl_rfk_type { 58 BTC_WRFKT_IQK = 0, 59 BTC_WRFKT_LCK = 1, 60 BTC_WRFKT_DPK = 2, 61 BTC_WRFKT_TXGAPK = 3, 62 BTC_WRFKT_DACK = 4, 63 BTC_WRFKT_RXDCK = 5, 64 BTC_WRFKT_TSSI = 6, 65 BTC_WRFKT_CHLK = 7, 66 }; 67 68 #define NM_EXEC false 69 #define FC_EXEC true 70 71 #define RTW89_COEX_ACT1_WORK_PERIOD round_jiffies_relative(HZ) 72 #define RTW89_COEX_BT_DEVINFO_WORK_PERIOD round_jiffies_relative(HZ * 16) 73 #define RTW89_COEX_RFK_CHK_WORK_PERIOD msecs_to_jiffies(300) 74 #define BTC_RFK_PATH_MAP GENMASK(3, 0) 75 #define BTC_RFK_PHY_MAP GENMASK(5, 4) 76 #define BTC_RFK_BAND_MAP GENMASK(7, 6) 77 78 enum btc_wl_rfk_state { 79 BTC_WRFK_STOP = 0, 80 BTC_WRFK_START = 1, 81 BTC_WRFK_ONESHOT_START = 2, 82 BTC_WRFK_ONESHOT_STOP = 3, 83 }; 84 85 enum btc_pri { 86 BTC_PRI_MASK_RX_RESP = 0, 87 BTC_PRI_MASK_TX_RESP, 88 BTC_PRI_MASK_BEACON, 89 BTC_PRI_MASK_RX_CCK, 90 BTC_PRI_MASK_TX_MNGQ, 91 BTC_PRI_MASK_MAX, 92 }; 93 94 enum btc_bt_trs { 95 BTC_BT_SS_GROUP = 0x0, 96 BTC_BT_TX_GROUP = 0x2, 97 BTC_BT_RX_GROUP = 0x3, 98 BTC_BT_MAX_GROUP, 99 }; 100 101 enum btc_rssi_st { 102 BTC_RSSI_ST_LOW = 0x0, 103 BTC_RSSI_ST_HIGH, 104 BTC_RSSI_ST_STAY_LOW, 105 BTC_RSSI_ST_STAY_HIGH, 106 BTC_RSSI_ST_MAX 107 }; 108 109 enum btc_fddt_en { 110 BTC_FDDT_DISABLE, 111 BTC_FDDT_ENABLE, 112 }; 113 114 #define BTC_RSSI_HIGH(_rssi_) \ 115 ({typeof(_rssi_) __rssi = (_rssi_); \ 116 ((__rssi == BTC_RSSI_ST_HIGH || \ 117 __rssi == BTC_RSSI_ST_STAY_HIGH) ? 1 : 0); }) 118 119 #define BTC_RSSI_LOW(_rssi_) \ 120 ({typeof(_rssi_) __rssi = (_rssi_); \ 121 ((__rssi == BTC_RSSI_ST_LOW || \ 122 __rssi == BTC_RSSI_ST_STAY_LOW) ? 1 : 0); }) 123 124 #define BTC_RSSI_CHANGE(_rssi_) \ 125 ({typeof(_rssi_) __rssi = (_rssi_); \ 126 ((__rssi == BTC_RSSI_ST_LOW || \ 127 __rssi == BTC_RSSI_ST_HIGH) ? 1 : 0); }) 128 129 /* Antenna TX/RX path position masks and helpers */ 130 #define BTC_ANT_TX_MASK 0xf0 131 #define BTC_ANT_RX_MASK 0x0f 132 #define BTC_ANT_SHIFT 4 133 134 enum btc_ant { 135 BTC_ANT_SHARED = 0, 136 BTC_ANT_DEDICATED, 137 BTC_ANTTYPE_MAX 138 }; 139 140 enum btc_bt_btg { 141 BTC_BT_ALONE = 0, 142 BTC_BT_BTG 143 }; 144 145 enum btc_switch { 146 BTC_SWITCH_INTERNAL = 0, 147 BTC_SWITCH_EXTERNAL 148 }; 149 150 enum btc_ant_switch_type { 151 BTC_SWITCH_V1_NONE = 0, /* independent antenna */ 152 BTC_SWITCH_V1_INTERNAL, /* internal-switch: BTGA structure */ 153 }; 154 155 enum btc_pkt_type { 156 PACKET_DHCP, 157 PACKET_ARP, 158 PACKET_EAPOL, 159 PACKET_EAPOL_END, 160 PACKET_ICMP, 161 PACKET_MAX 162 }; 163 164 enum btc_bt_mailbox_id { 165 BTC_BTINFO_REPLY = 0x23, 166 BTC_BTINFO_AUTO = 0x27 167 }; 168 169 enum btc_role_state { 170 BTC_ROLE_START, 171 BTC_ROLE_STOP, 172 BTC_ROLE_CHG_TYPE, 173 BTC_ROLE_MSTS_STA_CONN_START, 174 BTC_ROLE_MSTS_STA_CONN_END, 175 BTC_ROLE_MSTS_STA_DIS_CONN, 176 BTC_ROLE_MSTS_AP_START, 177 BTC_ROLE_MSTS_AP_STOP, 178 BTC_ROLE_STATE_UNKNOWN 179 }; 180 181 enum btc_rfctrl { 182 BTC_RFCTRL_WL_OFF, 183 BTC_RFCTRL_WL_ON, 184 BTC_RFCTRL_LPS_WL_ON, 185 BTC_RFCTRL_FW_CTRL, 186 BTC_RFCTRL_MAX 187 }; 188 189 enum btc_lps_state { 190 BTC_LPS_OFF = 0, 191 BTC_LPS_RF_OFF = 1, 192 BTC_LPS_RF_ON = 2 193 }; 194 195 #define R_BTC_BB_BTG_RX 0x980 196 #define R_BTC_BB_PRE_AGC_S1 0x476C 197 #define R_BTC_BB_PRE_AGC_S0 0x4688 198 199 #define B_BTC_BB_GNT_MUX GENMASK(20, 17) 200 #define B_BTC_BB_PRE_AGC_MASK GENMASK(31, 24) 201 #define B_BTC_BB_PRE_AGC_VAL BIT(31) 202 203 #define BTC_REG_NOTFOUND 0xff 204 205 #define R_BTC_ZB_COEX_TBL_0 0xE328 206 #define R_BTC_ZB_COEX_TBL_1 0xE32c 207 #define R_BTC_ZB_BREAK_TBL 0xE350 208 209 enum btc_ant_div_pos { 210 BTC_ANT_DIV_MAIN = 0, 211 BTC_ANT_DIV_AUX = 1, 212 }; 213 214 enum btc_get_reg_status { 215 BTC_CSTATUS_TXDIV_POS = 0, 216 BTC_CSTATUS_RXDIV_POS = 1, 217 BTC_CSTATUS_BB_GNT_MUX = 2, 218 BTC_CSTATUS_BB_GNT_MUX_MON = 3, 219 BTC_CSTATUS_BB_PRE_AGC = 4, 220 BTC_CSTATUS_BB_PRE_AGC_MON = 5, 221 }; 222 223 enum btc_preagc_type { 224 BTC_PREAGC_DISABLE, 225 BTC_PREAGC_ENABLE, 226 BTC_PREAGC_BB_FWCTRL, 227 BTC_PREAGC_NOTFOUND, 228 }; 229 230 enum btc_btgctrl_type { 231 BTC_BTGCTRL_DISABLE, 232 BTC_BTGCTRL_ENABLE, 233 BTC_BTGCTRL_BB_GNT_FWCTRL, 234 BTC_BTGCTRL_BB_GNT_NOTFOUND, 235 }; 236 237 enum btc_wa_type { 238 BTC_WA_5G_HI_CH_RX = BIT(0), 239 BTC_WA_NULL_AP = BIT(1), 240 BTC_WA_HFP_ZB = BIT(2), /* HFP PTA req bit4 define issue */ 241 BTC_WA_HFP_LAG = BIT(3), /* 52BT WL break BT Rx lag issue */ 242 BTC_WA_INIT_SCAN = BIT(4) /* 52A/C/D init scan move to wl slot WA */ 243 }; 244 245 enum btc_3cx_type { 246 BTC_3CX_NONE = 0, 247 BTC_3CX_BT2 = BIT(0), 248 BTC_3CX_ZB = BIT(1), 249 BTC_3CX_LTE = BIT(2), 250 BTC_3CX_MAX, 251 }; 252 253 enum btc_fddt_type { 254 BTC_FDDT_TYPE_STOP, 255 BTC_FDDT_TYPE_AUTO, 256 BTC_FDDT_TYPE_FIX_TDD, 257 BTC_FDDT_TYPE_FIX_FULL_FDD, 258 BTC_FDDT_MAX, 259 }; 260 261 enum btc_chip_feature { 262 BTC_FEAT_PTA_ONOFF_CTRL = BIT(0), /* on/off ctrl by HW (not 0x73[2]) */ 263 BTC_FEAT_NONBTG_GWL_THRU = BIT(1), /* non-BTG GNT_WL!=0 if GNT_BT = 1 */ 264 BTC_FEAT_WLAN_ACT_MUX = BIT(2), /* separate wlan_act/gnt mux */ 265 BTC_FEAT_NEW_BBAPI_FLOW = BIT(3), /* new btg_ctrl/pre_agc_ctrl */ 266 BTC_FEAT_MLO_SUPPORT = BIT(4), 267 BTC_FEAT_H2C_MACRO = BIT(5), 268 BTC_FEAT_DUAL_BT = BIT(6), 269 BTC_FEAT_BT_6G = BIT(7), 270 BTC_FEAT_MULTI_PTA = BIT(8), 271 BTC_FEAT_DUAL_BTGA = BIT(9) /* the future A-Die */ 272 }; 273 274 enum btc_efuse_ant_function_map { 275 BTC_EFMAP_NONE = 0, 276 BTC_EFMAP_BT0 = BIT(0), 277 BTC_EFMAP_BT1 = BIT(1), 278 BTC_EFMAP_ZB = BIT(2), /* ZB or thread */ 279 BTC_EFMAP_24GP = BIT(3), 280 BTC_EFMAP_ULL = BIT(4), 281 }; 282 283 enum btc_extsoc_interface { /* cx->other.hw_coex */ 284 BTC_EXTSOC_INTF_NONE = 0, 285 BTC_EXTSOC_INTF_PTA = BIT(0), 286 BTC_EXTSOC_INTF_MBX = BIT(1), 287 BTC_EXTSOC_INTF_SWIO = BIT(2), 288 BTC_EXTSOC_INTF_MAX, 289 }; 290 291 enum btc_esoc_type { 292 BTC_ESOC_NONE, 293 BTC_ESOC_8761, 294 BTC_ESOC_8771, 295 BTC_ESOC_SILAB_MG21, 296 BTC_ESOC_NORDI_NRF52840, 297 BTC_ESOC_MAX, 298 }; 299 300 enum btc_wl_mode { 301 BTC_WL_MODE_11B = 0, 302 BTC_WL_MODE_11A = 1, 303 BTC_WL_MODE_11G = 2, 304 BTC_WL_MODE_HT = 3, 305 BTC_WL_MODE_VHT = 4, 306 BTC_WL_MODE_HE = 5, 307 BTC_WL_MODE_NUM, 308 }; 309 310 enum btc_mlo_rf_combin { 311 BTC_MLO_RF_2_PLUS_0 = 0, 312 BTC_MLO_RF_0_PLUS_2 = 1, 313 BTC_MLO_RF_1_PLUS_1 = 2, 314 BTC_MLO_RF_2_PLUS_2 = 3, 315 }; 316 317 void rtw89_btc_init(struct rtw89_dev *rtwdev); 318 void rtw89_btc_ntfy_poweron(struct rtw89_dev *rtwdev); 319 void rtw89_btc_ntfy_poweroff(struct rtw89_dev *rtwdev); 320 void rtw89_btc_ntfy_init(struct rtw89_dev *rtwdev, u8 mode); 321 void rtw89_btc_ntfy_scan_start(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band); 322 void rtw89_btc_ntfy_scan_finish(struct rtw89_dev *rtwdev, u8 phy_idx); 323 void rtw89_btc_ntfy_switch_band(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band); 324 void rtw89_btc_ntfy_specific_packet(struct rtw89_dev *rtwdev, 325 enum btc_pkt_type pkt_type); 326 void rtw89_btc_ntfy_eapol_packet_work(struct wiphy *wiphy, struct wiphy_work *work); 327 void rtw89_btc_ntfy_arp_packet_work(struct wiphy *wiphy, struct wiphy_work *work); 328 void rtw89_btc_ntfy_dhcp_packet_work(struct wiphy *wiphy, struct wiphy_work *work); 329 void rtw89_btc_ntfy_icmp_packet_work(struct wiphy *wiphy, struct wiphy_work *work); 330 void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, 331 struct rtw89_vif_link *rtwvif_link, 332 struct rtw89_sta_link *rtwsta_link, 333 enum btc_role_state state); 334 void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_state); 335 void rtw89_btc_ntfy_wl_rfk(struct rtw89_dev *rtwdev, u8 phy_map, 336 enum btc_wl_rfk_type type, 337 enum btc_wl_rfk_state state); 338 void rtw89_btc_ntfy_wl_sta(struct rtw89_dev *rtwdev); 339 void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb, 340 u32 len, u8 class, u8 func); 341 ssize_t rtw89_btc_dump_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz); 342 void rtw89_coex_act1_work(struct wiphy *wiphy, struct wiphy_work *work); 343 void rtw89_coex_bt_devinfo_work(struct wiphy *wiphy, struct wiphy_work *work); 344 void rtw89_coex_rfk_chk_work(struct wiphy *wiphy, struct wiphy_work *work); 345 void rtw89_coex_power_on(struct rtw89_dev *rtwdev); 346 void rtw89_btc_set_policy(struct rtw89_dev *rtwdev, u16 policy_type); 347 void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type); 348 void rtw89_coex_recognize_ver(struct rtw89_dev *rtwdev); 349 void rtw89_btc_ntfy_preserve_bt_time(struct rtw89_dev *rtwdev, u32 ms); 350 void rtw89_btc_ntfy_conn_rfk(struct rtw89_dev *rtwdev, bool state); 351 352 static inline u8 rtw89_btc_phymap(struct rtw89_dev *rtwdev, 353 enum rtw89_phy_idx phy_idx, 354 enum rtw89_rf_path_bit paths, 355 enum rtw89_chanctx_idx chanctx_idx) 356 { 357 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); 358 u8 phy_map; 359 360 phy_map = FIELD_PREP(BTC_RFK_PATH_MAP, paths) | 361 FIELD_PREP(BTC_RFK_PHY_MAP, BIT(phy_idx)) | 362 FIELD_PREP(BTC_RFK_BAND_MAP, chan->band_type); 363 364 return phy_map; 365 } 366 367 static inline u8 rtw89_btc_path_phymap(struct rtw89_dev *rtwdev, 368 enum rtw89_phy_idx phy_idx, 369 enum rtw89_rf_path path, 370 enum rtw89_chanctx_idx chanctx_idx) 371 { 372 return rtw89_btc_phymap(rtwdev, phy_idx, BIT(path), chanctx_idx); 373 } 374 375 /* return bt req len in TU */ 376 static inline u16 rtw89_coex_query_bt_req_len(struct rtw89_dev *rtwdev, 377 enum rtw89_phy_idx phy_idx) 378 { 379 struct rtw89_btc *btc = &rtwdev->btc; 380 381 return btc->bt_req_len[phy_idx]; 382 } 383 384 static inline u32 rtw89_get_antpath_type(u8 phy_map, u8 type) 385 { 386 return ((phy_map << 8) + type); 387 } 388 389 static inline 390 void _slot_set_le(struct rtw89_btc *btc, u8 sid, __le16 dura, __le32 tbl, __le16 type) 391 { 392 if (btc->ver->fcxslots == 1) { 393 btc->dm.slot.v1[sid].dur = dura; 394 btc->dm.slot.v1[sid].cxtbl = tbl; 395 btc->dm.slot.v1[sid].cxtype = type; 396 } else if (btc->ver->fcxslots == 2 || btc->ver->fcxslots == 7) { 397 btc->dm.slot.v7[sid].dur = dura; 398 btc->dm.slot.v7[sid].cxtype = type; 399 btc->dm.slot.v7[sid].cxtbl = tbl; 400 } 401 } 402 403 static inline 404 void _slot_set(struct rtw89_btc *btc, u8 sid, u16 dura, u32 tbl, u16 type) 405 { 406 _slot_set_le(btc, sid, cpu_to_le16(dura), cpu_to_le32(tbl), cpu_to_le16(type)); 407 } 408 409 static inline 410 void _slot_set_dur(struct rtw89_btc *btc, u8 sid, u16 dura) 411 { 412 if (btc->ver->fcxslots == 1) 413 btc->dm.slot.v1[sid].dur = cpu_to_le16(dura); 414 else if (btc->ver->fcxslots == 2 || btc->ver->fcxslots == 7) 415 btc->dm.slot.v7[sid].dur = cpu_to_le16(dura); 416 } 417 418 static inline 419 void _slot_set_type(struct rtw89_btc *btc, u8 sid, u16 type) 420 { 421 if (btc->ver->fcxslots == 1) 422 btc->dm.slot.v1[sid].cxtype = cpu_to_le16(type); 423 else if (btc->ver->fcxslots == 2 || btc->ver->fcxslots == 7) 424 btc->dm.slot.v7[sid].cxtype = cpu_to_le16(type); 425 } 426 427 static inline 428 void _slot_set_tbl(struct rtw89_btc *btc, u8 sid, u32 tbl) 429 { 430 if (btc->ver->fcxslots == 1) 431 btc->dm.slot.v1[sid].cxtbl = cpu_to_le32(tbl); 432 else if (btc->ver->fcxslots == 2 || btc->ver->fcxslots == 7) 433 btc->dm.slot.v7[sid].cxtbl = cpu_to_le32(tbl); 434 } 435 436 static inline 437 void btc_dw2b(u8 *buf, size_t idx, u32 val) 438 { 439 buf[idx] = u32_get_bits(val, MASKBYTE0); 440 buf[idx + 1] = u32_get_bits(val, MASKBYTE1); 441 buf[idx + 2] = u32_get_bits(val, MASKBYTE2); 442 buf[idx + 3] = u32_get_bits(val, MASKBYTE3); 443 } 444 445 static inline 446 u8 _btc_get_rf_path_from_ant_num(struct rtw89_btc *btc, u8 antnum) 447 { 448 switch (antnum) { 449 default: 450 case 1: 451 return btc->mdinfo.ant.single_pos; 452 case 2: 453 return RF_PATH_AB; 454 case 3: 455 return RF_PATH_ABC; 456 } 457 } 458 459 #endif 460