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