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_H2C_MAXLEN 2020 11 #define BTC_TLV_SLOT_ID_LEN_V7 1 12 13 enum btc_mode { 14 BTC_MODE_NORMAL, 15 BTC_MODE_WL, 16 BTC_MODE_BT, 17 BTC_MODE_WLOFF, 18 BTC_MODE_MAX 19 }; 20 21 enum btc_wl_rfk_type { 22 BTC_WRFKT_IQK = 0, 23 BTC_WRFKT_LCK = 1, 24 BTC_WRFKT_DPK = 2, 25 BTC_WRFKT_TXGAPK = 3, 26 BTC_WRFKT_DACK = 4, 27 BTC_WRFKT_RXDCK = 5, 28 BTC_WRFKT_TSSI = 6, 29 BTC_WRFKT_CHLK = 7, 30 }; 31 32 #define NM_EXEC false 33 #define FC_EXEC true 34 35 #define RTW89_COEX_ACT1_WORK_PERIOD round_jiffies_relative(HZ * 4) 36 #define RTW89_COEX_BT_DEVINFO_WORK_PERIOD round_jiffies_relative(HZ * 16) 37 #define RTW89_COEX_RFK_CHK_WORK_PERIOD msecs_to_jiffies(300) 38 #define BTC_RFK_PATH_MAP GENMASK(3, 0) 39 #define BTC_RFK_PHY_MAP GENMASK(5, 4) 40 #define BTC_RFK_BAND_MAP GENMASK(7, 6) 41 42 enum btc_wl_rfk_state { 43 BTC_WRFK_STOP = 0, 44 BTC_WRFK_START = 1, 45 BTC_WRFK_ONESHOT_START = 2, 46 BTC_WRFK_ONESHOT_STOP = 3, 47 }; 48 49 enum btc_pri { 50 BTC_PRI_MASK_RX_RESP = 0, 51 BTC_PRI_MASK_TX_RESP, 52 BTC_PRI_MASK_BEACON, 53 BTC_PRI_MASK_RX_CCK, 54 BTC_PRI_MASK_TX_MNGQ, 55 BTC_PRI_MASK_MAX, 56 }; 57 58 enum btc_bt_trs { 59 BTC_BT_SS_GROUP = 0x0, 60 BTC_BT_TX_GROUP = 0x2, 61 BTC_BT_RX_GROUP = 0x3, 62 BTC_BT_MAX_GROUP, 63 }; 64 65 enum btc_rssi_st { 66 BTC_RSSI_ST_LOW = 0x0, 67 BTC_RSSI_ST_HIGH, 68 BTC_RSSI_ST_STAY_LOW, 69 BTC_RSSI_ST_STAY_HIGH, 70 BTC_RSSI_ST_MAX 71 }; 72 73 enum btc_fddt_en { 74 BTC_FDDT_DISABLE, 75 BTC_FDDT_ENABLE, 76 }; 77 78 #define BTC_RSSI_HIGH(_rssi_) \ 79 ({typeof(_rssi_) __rssi = (_rssi_); \ 80 ((__rssi == BTC_RSSI_ST_HIGH || \ 81 __rssi == BTC_RSSI_ST_STAY_HIGH) ? 1 : 0); }) 82 83 #define BTC_RSSI_LOW(_rssi_) \ 84 ({typeof(_rssi_) __rssi = (_rssi_); \ 85 ((__rssi == BTC_RSSI_ST_LOW || \ 86 __rssi == BTC_RSSI_ST_STAY_LOW) ? 1 : 0); }) 87 88 #define BTC_RSSI_CHANGE(_rssi_) \ 89 ({typeof(_rssi_) __rssi = (_rssi_); \ 90 ((__rssi == BTC_RSSI_ST_LOW || \ 91 __rssi == BTC_RSSI_ST_HIGH) ? 1 : 0); }) 92 93 enum btc_ant { 94 BTC_ANT_SHARED = 0, 95 BTC_ANT_DEDICATED, 96 BTC_ANTTYPE_MAX 97 }; 98 99 enum btc_bt_btg { 100 BTC_BT_ALONE = 0, 101 BTC_BT_BTG 102 }; 103 104 enum btc_switch { 105 BTC_SWITCH_INTERNAL = 0, 106 BTC_SWITCH_EXTERNAL 107 }; 108 109 enum btc_pkt_type { 110 PACKET_DHCP, 111 PACKET_ARP, 112 PACKET_EAPOL, 113 PACKET_EAPOL_END, 114 PACKET_ICMP, 115 PACKET_MAX 116 }; 117 118 enum btc_bt_mailbox_id { 119 BTC_BTINFO_REPLY = 0x23, 120 BTC_BTINFO_AUTO = 0x27 121 }; 122 123 enum btc_role_state { 124 BTC_ROLE_START, 125 BTC_ROLE_STOP, 126 BTC_ROLE_CHG_TYPE, 127 BTC_ROLE_MSTS_STA_CONN_START, 128 BTC_ROLE_MSTS_STA_CONN_END, 129 BTC_ROLE_MSTS_STA_DIS_CONN, 130 BTC_ROLE_MSTS_AP_START, 131 BTC_ROLE_MSTS_AP_STOP, 132 BTC_ROLE_STATE_UNKNOWN 133 }; 134 135 enum btc_rfctrl { 136 BTC_RFCTRL_WL_OFF, 137 BTC_RFCTRL_WL_ON, 138 BTC_RFCTRL_LPS_WL_ON, 139 BTC_RFCTRL_FW_CTRL, 140 BTC_RFCTRL_MAX 141 }; 142 143 enum btc_lps_state { 144 BTC_LPS_OFF = 0, 145 BTC_LPS_RF_OFF = 1, 146 BTC_LPS_RF_ON = 2 147 }; 148 149 #define R_BTC_BB_BTG_RX 0x980 150 #define R_BTC_BB_PRE_AGC_S1 0x476C 151 #define R_BTC_BB_PRE_AGC_S0 0x4688 152 153 #define B_BTC_BB_GNT_MUX GENMASK(20, 17) 154 #define B_BTC_BB_PRE_AGC_MASK GENMASK(31, 24) 155 #define B_BTC_BB_PRE_AGC_VAL BIT(31) 156 157 #define BTC_REG_NOTFOUND 0xff 158 159 #define R_BTC_ZB_COEX_TBL_0 0xE328 160 #define R_BTC_ZB_COEX_TBL_1 0xE32c 161 #define R_BTC_ZB_BREAK_TBL 0xE350 162 163 enum btc_ant_div_pos { 164 BTC_ANT_DIV_MAIN = 0, 165 BTC_ANT_DIV_AUX = 1, 166 }; 167 168 enum btc_get_reg_status { 169 BTC_CSTATUS_TXDIV_POS = 0, 170 BTC_CSTATUS_RXDIV_POS = 1, 171 BTC_CSTATUS_BB_GNT_MUX = 2, 172 BTC_CSTATUS_BB_GNT_MUX_MON = 3, 173 BTC_CSTATUS_BB_PRE_AGC = 4, 174 BTC_CSTATUS_BB_PRE_AGC_MON = 5, 175 }; 176 177 enum btc_preagc_type { 178 BTC_PREAGC_DISABLE, 179 BTC_PREAGC_ENABLE, 180 BTC_PREAGC_BB_FWCTRL, 181 BTC_PREAGC_NOTFOUND, 182 }; 183 184 enum btc_btgctrl_type { 185 BTC_BTGCTRL_DISABLE, 186 BTC_BTGCTRL_ENABLE, 187 BTC_BTGCTRL_BB_GNT_FWCTRL, 188 BTC_BTGCTRL_BB_GNT_NOTFOUND, 189 }; 190 191 enum btc_wa_type { 192 BTC_WA_5G_HI_CH_RX = BIT(0), 193 BTC_WA_NULL_AP = BIT(1), 194 BTC_WA_HFP_ZB = BIT(2), /* HFP PTA req bit4 define issue */ 195 }; 196 197 enum btc_3cx_type { 198 BTC_3CX_NONE = 0, 199 BTC_3CX_BT2 = BIT(0), 200 BTC_3CX_ZB = BIT(1), 201 BTC_3CX_LTE = BIT(2), 202 BTC_3CX_MAX, 203 }; 204 205 enum btc_chip_feature { 206 BTC_FEAT_PTA_ONOFF_CTRL = BIT(0), /* on/off ctrl by HW (not 0x73[2]) */ 207 BTC_FEAT_NONBTG_GWL_THRU = BIT(1), /* non-BTG GNT_WL!=0 if GNT_BT = 1 */ 208 BTC_FEAT_WLAN_ACT_MUX = BIT(2), /* separate wlan_act/gnt mux */ 209 BTC_FEAT_NEW_BBAPI_FLOW = BIT(3), /* new btg_ctrl/pre_agc_ctrl */ 210 BTC_FEAT_MLO_SUPPORT = BIT(4), 211 BTC_FEAT_H2C_MACRO = BIT(5), 212 }; 213 214 enum btc_wl_mode { 215 BTC_WL_MODE_11B = 0, 216 BTC_WL_MODE_11A = 1, 217 BTC_WL_MODE_11G = 2, 218 BTC_WL_MODE_HT = 3, 219 BTC_WL_MODE_VHT = 4, 220 BTC_WL_MODE_HE = 5, 221 BTC_WL_MODE_NUM, 222 }; 223 224 void rtw89_btc_ntfy_poweron(struct rtw89_dev *rtwdev); 225 void rtw89_btc_ntfy_poweroff(struct rtw89_dev *rtwdev); 226 void rtw89_btc_ntfy_init(struct rtw89_dev *rtwdev, u8 mode); 227 void rtw89_btc_ntfy_scan_start(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band); 228 void rtw89_btc_ntfy_scan_finish(struct rtw89_dev *rtwdev, u8 phy_idx); 229 void rtw89_btc_ntfy_switch_band(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band); 230 void rtw89_btc_ntfy_specific_packet(struct rtw89_dev *rtwdev, 231 enum btc_pkt_type pkt_type); 232 void rtw89_btc_ntfy_eapol_packet_work(struct work_struct *work); 233 void rtw89_btc_ntfy_arp_packet_work(struct work_struct *work); 234 void rtw89_btc_ntfy_dhcp_packet_work(struct work_struct *work); 235 void rtw89_btc_ntfy_icmp_packet_work(struct work_struct *work); 236 void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, 237 struct rtw89_sta *rtwsta, enum btc_role_state state); 238 void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_state); 239 void rtw89_btc_ntfy_wl_rfk(struct rtw89_dev *rtwdev, u8 phy_map, 240 enum btc_wl_rfk_type type, 241 enum btc_wl_rfk_state state); 242 void rtw89_btc_ntfy_wl_sta(struct rtw89_dev *rtwdev); 243 void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb, 244 u32 len, u8 class, u8 func); 245 void rtw89_btc_dump_info(struct rtw89_dev *rtwdev, struct seq_file *m); 246 void rtw89_coex_act1_work(struct work_struct *work); 247 void rtw89_coex_bt_devinfo_work(struct work_struct *work); 248 void rtw89_coex_rfk_chk_work(struct work_struct *work); 249 void rtw89_coex_power_on(struct rtw89_dev *rtwdev); 250 void rtw89_btc_set_policy(struct rtw89_dev *rtwdev, u16 policy_type); 251 void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type); 252 void rtw89_coex_recognize_ver(struct rtw89_dev *rtwdev); 253 254 static inline u8 rtw89_btc_phymap(struct rtw89_dev *rtwdev, 255 enum rtw89_phy_idx phy_idx, 256 enum rtw89_rf_path_bit paths) 257 { 258 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); 259 u8 phy_map; 260 261 phy_map = FIELD_PREP(BTC_RFK_PATH_MAP, paths) | 262 FIELD_PREP(BTC_RFK_PHY_MAP, BIT(phy_idx)) | 263 FIELD_PREP(BTC_RFK_BAND_MAP, chan->band_type); 264 265 return phy_map; 266 } 267 268 static inline u8 rtw89_btc_path_phymap(struct rtw89_dev *rtwdev, 269 enum rtw89_phy_idx phy_idx, 270 enum rtw89_rf_path path) 271 { 272 return rtw89_btc_phymap(rtwdev, phy_idx, BIT(path)); 273 } 274 275 /* return bt req len in TU */ 276 static inline u16 rtw89_coex_query_bt_req_len(struct rtw89_dev *rtwdev, 277 enum rtw89_phy_idx phy_idx) 278 { 279 struct rtw89_btc *btc = &rtwdev->btc; 280 281 return btc->bt_req_len; 282 } 283 284 static inline u32 rtw89_get_antpath_type(u8 phy_map, u8 type) 285 { 286 return ((phy_map << 8) + type); 287 } 288 289 static inline 290 void _slot_set_le(struct rtw89_btc *btc, u8 sid, __le16 dura, __le32 tbl, __le16 type) 291 { 292 if (btc->ver->fcxslots == 1) { 293 btc->dm.slot.v1[sid].dur = dura; 294 btc->dm.slot.v1[sid].cxtbl = tbl; 295 btc->dm.slot.v1[sid].cxtype = type; 296 } else if (btc->ver->fcxslots == 7) { 297 btc->dm.slot.v7[sid].dur = dura; 298 btc->dm.slot.v7[sid].cxtype = type; 299 btc->dm.slot.v7[sid].cxtbl = tbl; 300 } 301 } 302 303 static inline 304 void _slot_set(struct rtw89_btc *btc, u8 sid, u16 dura, u32 tbl, u16 type) 305 { 306 _slot_set_le(btc, sid, cpu_to_le16(dura), cpu_to_le32(tbl), cpu_to_le16(type)); 307 } 308 309 static inline 310 void _slot_set_dur(struct rtw89_btc *btc, u8 sid, u16 dura) 311 { 312 if (btc->ver->fcxslots == 1) 313 btc->dm.slot.v1[sid].dur = cpu_to_le16(dura); 314 else if (btc->ver->fcxslots == 7) 315 btc->dm.slot.v7[sid].dur = cpu_to_le16(dura); 316 } 317 318 static inline 319 void _slot_set_type(struct rtw89_btc *btc, u8 sid, u16 type) 320 { 321 if (btc->ver->fcxslots == 1) 322 btc->dm.slot.v1[sid].cxtype = cpu_to_le16(type); 323 else if (btc->ver->fcxslots == 7) 324 btc->dm.slot.v7[sid].cxtype = cpu_to_le16(type); 325 } 326 327 static inline 328 void _slot_set_tbl(struct rtw89_btc *btc, u8 sid, u32 tbl) 329 { 330 if (btc->ver->fcxslots == 1) 331 btc->dm.slot.v1[sid].cxtbl = cpu_to_le32(tbl); 332 else if (btc->ver->fcxslots == 7) 333 btc->dm.slot.v7[sid].cxtbl = cpu_to_le32(tbl); 334 } 335 336 #endif 337