xref: /linux/drivers/net/wireless/realtek/rtw89/coex.h (revision 860a9bed265146b10311bcadbbcef59c3af4454d)
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