• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /* Copyright(c) 2018-2019  Realtek Corporation
3  */
4 
5 #include "main.h"
6 #include "coex.h"
7 #include "fw.h"
8 #include "ps.h"
9 #include "debug.h"
10 #include "reg.h"
11 #include "phy.h"
12 
rtw_coex_next_rssi_state(struct rtw_dev * rtwdev,u8 pre_state,u8 rssi,u8 rssi_thresh)13 static u8 rtw_coex_next_rssi_state(struct rtw_dev *rtwdev, u8 pre_state,
14 				   u8 rssi, u8 rssi_thresh)
15 {
16 	struct rtw_chip_info *chip = rtwdev->chip;
17 	u8 tol = chip->rssi_tolerance;
18 	u8 next_state;
19 
20 	if (pre_state == COEX_RSSI_STATE_LOW ||
21 	    pre_state == COEX_RSSI_STATE_STAY_LOW) {
22 		if (rssi >= (rssi_thresh + tol))
23 			next_state = COEX_RSSI_STATE_HIGH;
24 		else
25 			next_state = COEX_RSSI_STATE_STAY_LOW;
26 	} else {
27 		if (rssi < rssi_thresh)
28 			next_state = COEX_RSSI_STATE_LOW;
29 		else
30 			next_state = COEX_RSSI_STATE_STAY_HIGH;
31 	}
32 
33 	return next_state;
34 }
35 
rtw_coex_limited_tx(struct rtw_dev * rtwdev,bool tx_limit_en,bool ampdu_limit_en)36 static void rtw_coex_limited_tx(struct rtw_dev *rtwdev,
37 				bool tx_limit_en, bool ampdu_limit_en)
38 {
39 	struct rtw_chip_info *chip = rtwdev->chip;
40 	struct rtw_coex *coex = &rtwdev->coex;
41 	struct rtw_coex_stat *coex_stat = &coex->stat;
42 	u8 num_of_active_port = 1;
43 
44 	if (!chip->scbd_support)
45 		return;
46 
47 	/* force max tx retry limit = 8 */
48 	if (coex_stat->wl_tx_limit_en == tx_limit_en &&
49 	    coex_stat->wl_ampdu_limit_en == ampdu_limit_en)
50 		return;
51 
52 	if (!coex_stat->wl_tx_limit_en) {
53 		coex_stat->darfrc = rtw_read32(rtwdev, REG_DARFRC);
54 		coex_stat->darfrch = rtw_read32(rtwdev, REG_DARFRCH);
55 		coex_stat->retry_limit = rtw_read16(rtwdev, REG_RETRY_LIMIT);
56 	}
57 
58 	if (!coex_stat->wl_ampdu_limit_en)
59 		coex_stat->ampdu_max_time =
60 				rtw_read8(rtwdev, REG_AMPDU_MAX_TIME_V1);
61 
62 	coex_stat->wl_tx_limit_en = tx_limit_en;
63 	coex_stat->wl_ampdu_limit_en = ampdu_limit_en;
64 
65 	if (tx_limit_en) {
66 		/* set BT polluted packet on for tx rate adaptive,
67 		 * not including tx retry broken by PTA
68 		 */
69 		rtw_write8_set(rtwdev, REG_TX_HANG_CTRL, BIT_EN_GNT_BT_AWAKE);
70 
71 		/* set queue life time to avoid can't reach tx retry limit
72 		 * if tx is always broken by GNT_BT
73 		 */
74 		if (num_of_active_port <= 1)
75 			rtw_write8_set(rtwdev, REG_LIFETIME_EN, 0xf);
76 		rtw_write16(rtwdev, REG_RETRY_LIMIT, 0x0808);
77 
78 		/* auto rate fallback step within 8 retries */
79 		rtw_write32(rtwdev, REG_DARFRC, 0x1000000);
80 		rtw_write32(rtwdev, REG_DARFRCH, 0x4030201);
81 	} else {
82 		rtw_write8_clr(rtwdev, REG_TX_HANG_CTRL, BIT_EN_GNT_BT_AWAKE);
83 		rtw_write8_clr(rtwdev, REG_LIFETIME_EN, 0xf);
84 
85 		rtw_write16(rtwdev, REG_RETRY_LIMIT, coex_stat->retry_limit);
86 		rtw_write32(rtwdev, REG_DARFRC, coex_stat->darfrc);
87 		rtw_write32(rtwdev, REG_DARFRCH, coex_stat->darfrch);
88 	}
89 
90 	if (ampdu_limit_en)
91 		rtw_write8(rtwdev, REG_AMPDU_MAX_TIME_V1, 0x20);
92 	else
93 		rtw_write8(rtwdev, REG_AMPDU_MAX_TIME_V1,
94 			   coex_stat->ampdu_max_time);
95 }
96 
rtw_coex_limited_wl(struct rtw_dev * rtwdev)97 static void rtw_coex_limited_wl(struct rtw_dev *rtwdev)
98 {
99 	struct rtw_coex *coex = &rtwdev->coex;
100 	struct rtw_coex_dm *coex_dm = &coex->dm;
101 	bool tx_limit = false;
102 	bool tx_agg_ctrl = false;
103 
104 	if (!coex->under_5g && coex_dm->bt_status != COEX_BTSTATUS_NCON_IDLE) {
105 		tx_limit = true;
106 		tx_agg_ctrl = true;
107 	}
108 
109 	rtw_coex_limited_tx(rtwdev, tx_limit, tx_agg_ctrl);
110 }
111 
rtw_coex_freerun_check(struct rtw_dev * rtwdev)112 static bool rtw_coex_freerun_check(struct rtw_dev *rtwdev)
113 {
114 	struct rtw_coex *coex = &rtwdev->coex;
115 	struct rtw_coex_dm *coex_dm = &coex->dm;
116 	struct rtw_coex_stat *coex_stat = &coex->stat;
117 	struct rtw_efuse *efuse = &rtwdev->efuse;
118 	u8 bt_rssi;
119 	u8 ant_distance = 10;
120 
121 	if (coex_stat->bt_disabled)
122 		return false;
123 
124 	if (efuse->share_ant || ant_distance <= 5 || !coex_stat->wl_gl_busy)
125 		return false;
126 
127 	if (ant_distance >= 40 || coex_stat->bt_hid_pair_num >= 2)
128 		return true;
129 
130 	/* ant_distance = 5 ~ 40  */
131 	if (COEX_RSSI_HIGH(coex_dm->wl_rssi_state[1]) &&
132 	    COEX_RSSI_HIGH(coex_dm->bt_rssi_state[0]))
133 		return true;
134 
135 	if (coex_stat->wl_tput_dir == COEX_WL_TPUT_TX)
136 		bt_rssi = coex_dm->bt_rssi_state[0];
137 	else
138 		bt_rssi = coex_dm->bt_rssi_state[1];
139 
140 	if (COEX_RSSI_HIGH(coex_dm->wl_rssi_state[3]) &&
141 	    COEX_RSSI_HIGH(bt_rssi) &&
142 	    coex_stat->cnt_wl[COEX_CNT_WL_SCANAP] <= 5)
143 		return true;
144 
145 	return false;
146 }
147 
rtw_coex_wl_slot_extend(struct rtw_dev * rtwdev,bool enable)148 static void rtw_coex_wl_slot_extend(struct rtw_dev *rtwdev, bool enable)
149 {
150 	struct rtw_coex *coex = &rtwdev->coex;
151 	struct rtw_coex_stat *coex_stat = &coex->stat;
152 	u8 para[6] = {0};
153 
154 	para[0] = COEX_H2C69_WL_LEAKAP;
155 	para[1] = PARA1_H2C69_DIS_5MS;
156 
157 	if (enable)
158 		para[1] = PARA1_H2C69_EN_5MS;
159 	else
160 		coex_stat->cnt_wl[COEX_CNT_WL_5MS_NOEXTEND] = 0;
161 
162 	coex_stat->wl_slot_extend = enable;
163 	rtw_fw_bt_wifi_control(rtwdev, para[0], &para[1]);
164 }
165 
rtw_coex_wl_ccklock_action(struct rtw_dev * rtwdev)166 static void rtw_coex_wl_ccklock_action(struct rtw_dev *rtwdev)
167 {
168 	struct rtw_coex *coex = &rtwdev->coex;
169 	struct rtw_coex_stat *coex_stat = &coex->stat;
170 
171 	if (coex->manual_control || coex->stop_dm)
172 		return;
173 
174 
175 	if (coex_stat->tdma_timer_base == 3 && coex_stat->wl_slot_extend) {
176 		rtw_dbg(rtwdev, RTW_DBG_COEX,
177 			"[BTCoex], set h2c 0x69 opcode 12 to turn off 5ms WL slot extend!!\n");
178 		rtw_coex_wl_slot_extend(rtwdev, false);
179 		return;
180 	}
181 
182 	if (coex_stat->wl_slot_extend && coex_stat->wl_force_lps_ctrl &&
183 	    !coex_stat->wl_cck_lock_ever) {
184 		if (coex_stat->wl_fw_dbg_info[7] <= 5)
185 			coex_stat->cnt_wl[COEX_CNT_WL_5MS_NOEXTEND]++;
186 		else
187 			coex_stat->cnt_wl[COEX_CNT_WL_5MS_NOEXTEND] = 0;
188 
189 		rtw_dbg(rtwdev, RTW_DBG_COEX,
190 			"[BTCoex], 5ms WL slot extend cnt = %d!!\n",
191 			coex_stat->cnt_wl[COEX_CNT_WL_5MS_NOEXTEND]);
192 
193 		if (coex_stat->cnt_wl[COEX_CNT_WL_5MS_NOEXTEND] == 7) {
194 			rtw_dbg(rtwdev, RTW_DBG_COEX,
195 				"[BTCoex], set h2c 0x69 opcode 12 to turn off 5ms WL slot extend!!\n");
196 			rtw_coex_wl_slot_extend(rtwdev, false);
197 		}
198 	} else if (!coex_stat->wl_slot_extend && coex_stat->wl_cck_lock) {
199 		rtw_dbg(rtwdev, RTW_DBG_COEX,
200 			"[BTCoex], set h2c 0x69 opcode 12 to turn on 5ms WL slot extend!!\n");
201 
202 		rtw_coex_wl_slot_extend(rtwdev, true);
203 	}
204 }
205 
rtw_coex_wl_ccklock_detect(struct rtw_dev * rtwdev)206 static void rtw_coex_wl_ccklock_detect(struct rtw_dev *rtwdev)
207 {
208 	struct rtw_coex *coex = &rtwdev->coex;
209 	struct rtw_coex_stat *coex_stat = &coex->stat;
210 	struct rtw_coex_dm *coex_dm = &coex->dm;
211 
212 	bool is_cck_lock_rate = false;
213 
214 	if (coex_dm->bt_status == COEX_BTSTATUS_INQ_PAGE ||
215 	    coex_stat->bt_setup_link) {
216 		coex_stat->wl_cck_lock = false;
217 		coex_stat->wl_cck_lock_pre = false;
218 		return;
219 	}
220 
221 	if (coex_stat->wl_rx_rate <= COEX_CCK_2 ||
222 	    coex_stat->wl_rts_rx_rate <= COEX_CCK_2)
223 		is_cck_lock_rate = true;
224 
225 	if (coex_stat->wl_connected && coex_stat->wl_gl_busy &&
226 	    COEX_RSSI_HIGH(coex_dm->wl_rssi_state[3]) &&
227 	    (coex_dm->bt_status == COEX_BTSTATUS_ACL_BUSY ||
228 	     coex_dm->bt_status == COEX_BTSTATUS_ACL_SCO_BUSY ||
229 	     coex_dm->bt_status == COEX_BTSTATUS_SCO_BUSY)) {
230 		if (is_cck_lock_rate) {
231 			coex_stat->wl_cck_lock = true;
232 
233 			rtw_dbg(rtwdev, RTW_DBG_COEX,
234 				"[BTCoex], cck locking...\n");
235 
236 		} else {
237 			coex_stat->wl_cck_lock = false;
238 
239 			rtw_dbg(rtwdev, RTW_DBG_COEX,
240 				"[BTCoex], cck unlock...\n");
241 		}
242 	} else {
243 		coex_stat->wl_cck_lock = false;
244 	}
245 
246 	/* CCK lock identification */
247 	if (coex_stat->wl_cck_lock && !coex_stat->wl_cck_lock_pre)
248 		ieee80211_queue_delayed_work(rtwdev->hw, &coex->wl_ccklock_work,
249 					     3 * HZ);
250 
251 	coex_stat->wl_cck_lock_pre = coex_stat->wl_cck_lock;
252 }
253 
rtw_coex_wl_noisy_detect(struct rtw_dev * rtwdev)254 static void rtw_coex_wl_noisy_detect(struct rtw_dev *rtwdev)
255 {
256 	struct rtw_coex *coex = &rtwdev->coex;
257 	struct rtw_coex_stat *coex_stat = &coex->stat;
258 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
259 	u32 cnt_cck;
260 	bool wl_cck_lock = false;
261 
262 	/* wifi noisy environment identification */
263 	cnt_cck = dm_info->cck_ok_cnt + dm_info->cck_err_cnt;
264 
265 	if (!coex_stat->wl_gl_busy && !wl_cck_lock) {
266 		if (cnt_cck > 250) {
267 			if (coex_stat->cnt_wl[COEX_CNT_WL_NOISY2] < 5)
268 				coex_stat->cnt_wl[COEX_CNT_WL_NOISY2]++;
269 
270 			if (coex_stat->cnt_wl[COEX_CNT_WL_NOISY2] == 5) {
271 				coex_stat->cnt_wl[COEX_CNT_WL_NOISY0] = 0;
272 				coex_stat->cnt_wl[COEX_CNT_WL_NOISY1] = 0;
273 			}
274 		} else if (cnt_cck < 100) {
275 			if (coex_stat->cnt_wl[COEX_CNT_WL_NOISY0] < 5)
276 				coex_stat->cnt_wl[COEX_CNT_WL_NOISY0]++;
277 
278 			if (coex_stat->cnt_wl[COEX_CNT_WL_NOISY0] == 5) {
279 				coex_stat->cnt_wl[COEX_CNT_WL_NOISY1] = 0;
280 				coex_stat->cnt_wl[COEX_CNT_WL_NOISY2] = 0;
281 			}
282 		} else {
283 			if (coex_stat->cnt_wl[COEX_CNT_WL_NOISY1] < 5)
284 				coex_stat->cnt_wl[COEX_CNT_WL_NOISY1]++;
285 
286 			if (coex_stat->cnt_wl[COEX_CNT_WL_NOISY1] == 5) {
287 				coex_stat->cnt_wl[COEX_CNT_WL_NOISY0] = 0;
288 				coex_stat->cnt_wl[COEX_CNT_WL_NOISY2] = 0;
289 			}
290 		}
291 
292 		if (coex_stat->cnt_wl[COEX_CNT_WL_NOISY2] == 5)
293 			coex_stat->wl_noisy_level = 2;
294 		else if (coex_stat->cnt_wl[COEX_CNT_WL_NOISY1] == 5)
295 			coex_stat->wl_noisy_level = 1;
296 		else
297 			coex_stat->wl_noisy_level = 0;
298 
299 		rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], wl_noisy_level = %d\n",
300 			coex_stat->wl_noisy_level);
301 	}
302 }
303 
rtw_coex_tdma_timer_base(struct rtw_dev * rtwdev,u8 type)304 static void rtw_coex_tdma_timer_base(struct rtw_dev *rtwdev, u8 type)
305 {
306 	struct rtw_coex *coex = &rtwdev->coex;
307 	struct rtw_coex_stat *coex_stat = &coex->stat;
308 	u8 para[2] = {0};
309 	u8 times;
310 	u16 tbtt_interval = coex_stat->wl_beacon_interval;
311 
312 	if (coex_stat->tdma_timer_base == type)
313 		return;
314 
315 	coex_stat->tdma_timer_base = type;
316 
317 	para[0] = COEX_H2C69_TDMA_SLOT;
318 
319 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], tbtt_interval = %d\n",
320 		tbtt_interval);
321 
322 	if (type == TDMA_TIMER_TYPE_4SLOT && tbtt_interval < 120) {
323 		para[1] = PARA1_H2C69_TDMA_4SLOT; /* 4-slot */
324 	} else if (tbtt_interval < 80 && tbtt_interval > 0) {
325 		times = 100 / tbtt_interval;
326 		if (100 % tbtt_interval != 0)
327 			times++;
328 
329 		para[1] = FIELD_PREP(PARA1_H2C69_TBTT_TIMES, times);
330 	} else if (tbtt_interval >= 180) {
331 		times = tbtt_interval / 100;
332 		if (tbtt_interval % 100 <= 80)
333 			times--;
334 
335 		para[1] = FIELD_PREP(PARA1_H2C69_TBTT_TIMES, times) |
336 			  FIELD_PREP(PARA1_H2C69_TBTT_DIV100, 1);
337 	} else {
338 		para[1] = PARA1_H2C69_TDMA_2SLOT;
339 	}
340 
341 	rtw_fw_bt_wifi_control(rtwdev, para[0], &para[1]);
342 
343 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s(): h2c_0x69 = 0x%x\n",
344 		__func__, para[1]);
345 
346 	/* no 5ms_wl_slot_extend for 4-slot mode  */
347 	if (coex_stat->tdma_timer_base == 3)
348 		rtw_coex_wl_ccklock_action(rtwdev);
349 }
350 
rtw_coex_set_wl_pri_mask(struct rtw_dev * rtwdev,u8 bitmap,u8 data)351 static void rtw_coex_set_wl_pri_mask(struct rtw_dev *rtwdev, u8 bitmap,
352 				     u8 data)
353 {
354 	u32 addr;
355 
356 	addr = REG_BT_COEX_TABLE_H + (bitmap / 8);
357 	bitmap = bitmap % 8;
358 
359 	rtw_write8_mask(rtwdev, addr, BIT(bitmap), data);
360 }
361 
rtw_coex_write_scbd(struct rtw_dev * rtwdev,u16 bitpos,bool set)362 void rtw_coex_write_scbd(struct rtw_dev *rtwdev, u16 bitpos, bool set)
363 {
364 	struct rtw_chip_info *chip = rtwdev->chip;
365 	struct rtw_coex *coex = &rtwdev->coex;
366 	struct rtw_coex_stat *coex_stat = &coex->stat;
367 	u16 val = 0x2;
368 
369 	if (!chip->scbd_support)
370 		return;
371 
372 	val |= coex_stat->score_board;
373 
374 	/* for 8822b, scbd[10] is CQDDR on
375 	 * for 8822c, scbd[10] is no fix 2M
376 	 */
377 	if (!chip->new_scbd10_def && (bitpos & COEX_SCBD_FIX2M)) {
378 		if (set)
379 			val &= ~COEX_SCBD_FIX2M;
380 		else
381 			val |= COEX_SCBD_FIX2M;
382 	} else {
383 		if (set)
384 			val |= bitpos;
385 		else
386 			val &= ~bitpos;
387 	}
388 
389 	if (val != coex_stat->score_board) {
390 		coex_stat->score_board = val;
391 		val |= BIT_BT_INT_EN;
392 		rtw_write16(rtwdev, REG_WIFI_BT_INFO, val);
393 	}
394 }
395 EXPORT_SYMBOL(rtw_coex_write_scbd);
396 
rtw_coex_read_scbd(struct rtw_dev * rtwdev)397 static u16 rtw_coex_read_scbd(struct rtw_dev *rtwdev)
398 {
399 	struct rtw_chip_info *chip = rtwdev->chip;
400 
401 	if (!chip->scbd_support)
402 		return 0;
403 
404 	return (rtw_read16(rtwdev, REG_WIFI_BT_INFO)) & ~(BIT_BT_INT_EN);
405 }
406 
rtw_coex_check_rfk(struct rtw_dev * rtwdev)407 static void rtw_coex_check_rfk(struct rtw_dev *rtwdev)
408 {
409 	struct rtw_chip_info *chip = rtwdev->chip;
410 	struct rtw_coex *coex = &rtwdev->coex;
411 	struct rtw_coex_stat *coex_stat = &coex->stat;
412 	struct rtw_coex_rfe *coex_rfe = &coex->rfe;
413 	u8 cnt = 0;
414 	u32 wait_cnt;
415 	bool btk, wlk;
416 
417 	if (coex_rfe->wlg_at_btg && chip->scbd_support &&
418 	    coex_stat->bt_iqk_state != 0xff) {
419 		rtw_dbg(rtwdev, RTW_DBG_COEX,
420 			"[BTCoex], (Before Ant Setup) Delay by IQK\n");
421 
422 		wait_cnt = COEX_RFK_TIMEOUT / COEX_MIN_DELAY;
423 		do {
424 			/* BT RFK */
425 			btk = !!(rtw_coex_read_scbd(rtwdev) & COEX_SCBD_BT_RFK);
426 
427 			/* WL RFK */
428 			wlk = !!(rtw_read8(rtwdev, REG_ARFR4) & BIT_WL_RFK);
429 
430 			if (!btk && !wlk)
431 				break;
432 
433 			rtw_dbg(rtwdev, RTW_DBG_COEX,
434 				"[BTCoex], (Before Ant Setup) wlk = %d, btk = %d\n",
435 				wlk, btk);
436 
437 			mdelay(COEX_MIN_DELAY);
438 		} while (++cnt < wait_cnt);
439 
440 		if (cnt >= wait_cnt)
441 			coex_stat->bt_iqk_state = 0xff;
442 	}
443 }
444 
rtw_coex_query_bt_info(struct rtw_dev * rtwdev)445 static void rtw_coex_query_bt_info(struct rtw_dev *rtwdev)
446 {
447 	struct rtw_coex *coex = &rtwdev->coex;
448 	struct rtw_coex_stat *coex_stat = &coex->stat;
449 
450 	if (coex_stat->bt_disabled)
451 		return;
452 
453 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
454 
455 	rtw_fw_query_bt_info(rtwdev);
456 }
457 
rtw_coex_gnt_workaround(struct rtw_dev * rtwdev,bool force,u8 mode)458 static void rtw_coex_gnt_workaround(struct rtw_dev *rtwdev, bool force, u8 mode)
459 {
460 	rtw_coex_set_gnt_fix(rtwdev);
461 }
462 
rtw_coex_monitor_bt_enable(struct rtw_dev * rtwdev)463 static void rtw_coex_monitor_bt_enable(struct rtw_dev *rtwdev)
464 {
465 	struct rtw_chip_info *chip = rtwdev->chip;
466 	struct rtw_coex *coex = &rtwdev->coex;
467 	struct rtw_coex_stat *coex_stat = &coex->stat;
468 	struct rtw_coex_dm *coex_dm = &coex->dm;
469 	bool bt_disabled = false;
470 	u16 score_board;
471 
472 	if (chip->scbd_support) {
473 		score_board = rtw_coex_read_scbd(rtwdev);
474 		bt_disabled = !(score_board & COEX_SCBD_ONOFF);
475 	}
476 
477 	if (coex_stat->bt_disabled != bt_disabled) {
478 		rtw_dbg(rtwdev, RTW_DBG_COEX,
479 			"[BTCoex], BT state changed (%d) -> (%d)\n",
480 			coex_stat->bt_disabled, bt_disabled);
481 
482 		coex_stat->bt_disabled = bt_disabled;
483 		coex_stat->bt_ble_scan_type = 0;
484 		coex_dm->cur_bt_lna_lvl = 0;
485 
486 		if (!coex_stat->bt_disabled) {
487 			coex_stat->bt_reenable = true;
488 			ieee80211_queue_delayed_work(rtwdev->hw,
489 						     &coex->bt_reenable_work,
490 						     15 * HZ);
491 		} else {
492 			coex_stat->bt_mailbox_reply = false;
493 			coex_stat->bt_reenable = false;
494 		}
495 	}
496 }
497 
rtw_coex_update_wl_link_info(struct rtw_dev * rtwdev,u8 reason)498 static void rtw_coex_update_wl_link_info(struct rtw_dev *rtwdev, u8 reason)
499 {
500 	struct rtw_coex *coex = &rtwdev->coex;
501 	struct rtw_coex_stat *coex_stat = &coex->stat;
502 	struct rtw_coex_dm *coex_dm = &coex->dm;
503 	struct rtw_chip_info *chip = rtwdev->chip;
504 	struct rtw_traffic_stats *stats = &rtwdev->stats;
505 	bool is_5G = false;
506 	bool wl_busy = false;
507 	bool scan = false, link = false;
508 	int i;
509 	u8 rssi_state;
510 	u8 rssi_step;
511 	u8 rssi;
512 
513 	scan = test_bit(RTW_FLAG_SCANNING, rtwdev->flags);
514 	coex_stat->wl_connected = !!rtwdev->sta_cnt;
515 
516 	wl_busy = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags);
517 	if (wl_busy != coex_stat->wl_gl_busy) {
518 		if (wl_busy)
519 			coex_stat->wl_gl_busy = true;
520 		else
521 			ieee80211_queue_delayed_work(rtwdev->hw,
522 						     &coex->wl_remain_work,
523 						     12 * HZ);
524 	}
525 
526 	if (stats->tx_throughput > stats->rx_throughput)
527 		coex_stat->wl_tput_dir = COEX_WL_TPUT_TX;
528 	else
529 		coex_stat->wl_tput_dir = COEX_WL_TPUT_RX;
530 
531 	if (scan || link || reason == COEX_RSN_2GCONSTART ||
532 	    reason == COEX_RSN_2GSCANSTART || reason == COEX_RSN_2GSWITCHBAND)
533 		coex_stat->wl_linkscan_proc = true;
534 	else
535 		coex_stat->wl_linkscan_proc = false;
536 
537 	rtw_coex_wl_noisy_detect(rtwdev);
538 
539 	for (i = 0; i < 4; i++) {
540 		rssi_state = coex_dm->wl_rssi_state[i];
541 		rssi_step = chip->wl_rssi_step[i];
542 		rssi = rtwdev->dm_info.min_rssi;
543 		rssi_state = rtw_coex_next_rssi_state(rtwdev, rssi_state,
544 						      rssi, rssi_step);
545 		coex_dm->wl_rssi_state[i] = rssi_state;
546 	}
547 
548 	if (coex_stat->wl_linkscan_proc || coex_stat->wl_hi_pri_task1 ||
549 	    coex_stat->wl_hi_pri_task2 || coex_stat->wl_gl_busy)
550 		rtw_coex_write_scbd(rtwdev, COEX_SCBD_SCAN, true);
551 	else
552 		rtw_coex_write_scbd(rtwdev, COEX_SCBD_SCAN, false);
553 
554 	switch (reason) {
555 	case COEX_RSN_5GSCANSTART:
556 	case COEX_RSN_5GSWITCHBAND:
557 	case COEX_RSN_5GCONSTART:
558 
559 		is_5G = true;
560 		break;
561 	case COEX_RSN_2GSCANSTART:
562 	case COEX_RSN_2GSWITCHBAND:
563 	case COEX_RSN_2GCONSTART:
564 
565 		is_5G = false;
566 		break;
567 	default:
568 		if (rtwdev->hal.current_band_type == RTW_BAND_5G)
569 			is_5G = true;
570 		else
571 			is_5G = false;
572 		break;
573 	}
574 
575 	coex->under_5g = is_5G;
576 }
577 
get_payload_from_coex_resp(struct sk_buff * resp)578 static inline u8 *get_payload_from_coex_resp(struct sk_buff *resp)
579 {
580 	struct rtw_c2h_cmd *c2h;
581 	u32 pkt_offset;
582 
583 	pkt_offset = *((u32 *)resp->cb);
584 	c2h = (struct rtw_c2h_cmd *)(resp->data + pkt_offset);
585 
586 	return c2h->payload;
587 }
588 
rtw_coex_info_response(struct rtw_dev * rtwdev,struct sk_buff * skb)589 void rtw_coex_info_response(struct rtw_dev *rtwdev, struct sk_buff *skb)
590 {
591 	struct rtw_coex *coex = &rtwdev->coex;
592 	u8 *payload = get_payload_from_coex_resp(skb);
593 
594 	if (payload[0] != COEX_RESP_ACK_BY_WL_FW) {
595 		dev_kfree_skb_any(skb);
596 		return;
597 	}
598 
599 	skb_queue_tail(&coex->queue, skb);
600 	wake_up(&coex->wait);
601 }
602 
rtw_coex_info_request(struct rtw_dev * rtwdev,struct rtw_coex_info_req * req)603 static struct sk_buff *rtw_coex_info_request(struct rtw_dev *rtwdev,
604 					     struct rtw_coex_info_req *req)
605 {
606 	struct rtw_coex *coex = &rtwdev->coex;
607 	struct sk_buff *skb_resp = NULL;
608 
609 	mutex_lock(&coex->mutex);
610 
611 	rtw_fw_query_bt_mp_info(rtwdev, req);
612 
613 	if (!wait_event_timeout(coex->wait, !skb_queue_empty(&coex->queue),
614 				COEX_REQUEST_TIMEOUT)) {
615 		rtw_err(rtwdev, "coex request time out\n");
616 		goto out;
617 	}
618 
619 	skb_resp = skb_dequeue(&coex->queue);
620 	if (!skb_resp) {
621 		rtw_err(rtwdev, "failed to get coex info response\n");
622 		goto out;
623 	}
624 
625 out:
626 	mutex_unlock(&coex->mutex);
627 	return skb_resp;
628 }
629 
rtw_coex_get_bt_scan_type(struct rtw_dev * rtwdev,u8 * scan_type)630 static bool rtw_coex_get_bt_scan_type(struct rtw_dev *rtwdev, u8 *scan_type)
631 {
632 	struct rtw_coex_info_req req = {0};
633 	struct sk_buff *skb;
634 	u8 *payload;
635 
636 	req.op_code = BT_MP_INFO_OP_SCAN_TYPE;
637 	skb = rtw_coex_info_request(rtwdev, &req);
638 	if (!skb)
639 		return false;
640 
641 	payload = get_payload_from_coex_resp(skb);
642 	*scan_type = GET_COEX_RESP_BT_SCAN_TYPE(payload);
643 	dev_kfree_skb_any(skb);
644 	return true;
645 }
646 
rtw_coex_set_lna_constrain_level(struct rtw_dev * rtwdev,u8 lna_constrain_level)647 static bool rtw_coex_set_lna_constrain_level(struct rtw_dev *rtwdev,
648 					     u8 lna_constrain_level)
649 {
650 	struct rtw_coex_info_req req = {0};
651 	struct sk_buff *skb;
652 
653 	req.op_code = BT_MP_INFO_OP_LNA_CONSTRAINT;
654 	req.para1 = lna_constrain_level;
655 	skb = rtw_coex_info_request(rtwdev, &req);
656 	if (!skb)
657 		return false;
658 
659 	dev_kfree_skb_any(skb);
660 	return true;
661 }
662 
663 #define case_BTSTATUS(src) \
664 	case COEX_BTSTATUS_##src: return #src
665 
rtw_coex_get_bt_status_string(u8 bt_status)666 static const char *rtw_coex_get_bt_status_string(u8 bt_status)
667 {
668 	switch (bt_status) {
669 	case_BTSTATUS(NCON_IDLE);
670 	case_BTSTATUS(CON_IDLE);
671 	case_BTSTATUS(INQ_PAGE);
672 	case_BTSTATUS(ACL_BUSY);
673 	case_BTSTATUS(SCO_BUSY);
674 	case_BTSTATUS(ACL_SCO_BUSY);
675 	default:
676 		return "Unknown";
677 	}
678 }
679 
rtw_coex_update_bt_link_info(struct rtw_dev * rtwdev)680 static void rtw_coex_update_bt_link_info(struct rtw_dev *rtwdev)
681 {
682 	struct rtw_coex *coex = &rtwdev->coex;
683 	struct rtw_coex_stat *coex_stat = &coex->stat;
684 	struct rtw_coex_dm *coex_dm = &coex->dm;
685 	struct rtw_chip_info *chip = rtwdev->chip;
686 	u8 i;
687 	u8 rssi_state;
688 	u8 rssi_step;
689 	u8 rssi;
690 
691 	/* update wl/bt rssi by btinfo */
692 	for (i = 0; i < COEX_RSSI_STEP; i++) {
693 		rssi_state = coex_dm->bt_rssi_state[i];
694 		rssi_step = chip->bt_rssi_step[i];
695 		rssi = coex_stat->bt_rssi;
696 		rssi_state = rtw_coex_next_rssi_state(rtwdev, rssi_state, rssi,
697 						      rssi_step);
698 		coex_dm->bt_rssi_state[i] = rssi_state;
699 	}
700 
701 	if (coex_stat->bt_ble_scan_en &&
702 	    coex_stat->cnt_bt[COEX_CNT_BT_INFOUPDATE] % 3 == 0) {
703 		u8 scan_type;
704 
705 		if (rtw_coex_get_bt_scan_type(rtwdev, &scan_type)) {
706 			coex_stat->bt_ble_scan_type = scan_type;
707 			if ((coex_stat->bt_ble_scan_type & 0x1) == 0x1)
708 				coex_stat->bt_init_scan = true;
709 			else
710 				coex_stat->bt_init_scan = false;
711 		}
712 	}
713 
714 	coex_stat->bt_profile_num = 0;
715 
716 	/* set link exist status */
717 	if (!(coex_stat->bt_info_lb2 & COEX_INFO_CONNECTION)) {
718 		coex_stat->bt_link_exist = false;
719 		coex_stat->bt_pan_exist = false;
720 		coex_stat->bt_a2dp_exist = false;
721 		coex_stat->bt_hid_exist = false;
722 		coex_stat->bt_hfp_exist = false;
723 	} else {
724 		/* connection exists */
725 		coex_stat->bt_link_exist = true;
726 		if (coex_stat->bt_info_lb2 & COEX_INFO_FTP) {
727 			coex_stat->bt_pan_exist = true;
728 			coex_stat->bt_profile_num++;
729 		} else {
730 			coex_stat->bt_pan_exist = false;
731 		}
732 
733 		if (coex_stat->bt_info_lb2 & COEX_INFO_A2DP) {
734 			coex_stat->bt_a2dp_exist = true;
735 			coex_stat->bt_profile_num++;
736 		} else {
737 			coex_stat->bt_a2dp_exist = false;
738 		}
739 
740 		if (coex_stat->bt_info_lb2 & COEX_INFO_HID) {
741 			coex_stat->bt_hid_exist = true;
742 			coex_stat->bt_profile_num++;
743 		} else {
744 			coex_stat->bt_hid_exist = false;
745 		}
746 
747 		if (coex_stat->bt_info_lb2 & COEX_INFO_SCO_ESCO) {
748 			coex_stat->bt_hfp_exist = true;
749 			coex_stat->bt_profile_num++;
750 		} else {
751 			coex_stat->bt_hfp_exist = false;
752 		}
753 	}
754 
755 	if (coex_stat->bt_info_lb2 & COEX_INFO_INQ_PAGE) {
756 		coex_dm->bt_status = COEX_BTSTATUS_INQ_PAGE;
757 	} else if (!(coex_stat->bt_info_lb2 & COEX_INFO_CONNECTION)) {
758 		coex_dm->bt_status = COEX_BTSTATUS_NCON_IDLE;
759 		coex_stat->bt_multi_link_remain = false;
760 	} else if (coex_stat->bt_info_lb2 == COEX_INFO_CONNECTION) {
761 		coex_dm->bt_status = COEX_BTSTATUS_CON_IDLE;
762 	} else if ((coex_stat->bt_info_lb2 & COEX_INFO_SCO_ESCO) ||
763 		   (coex_stat->bt_info_lb2 & COEX_INFO_SCO_BUSY)) {
764 		if (coex_stat->bt_info_lb2 & COEX_INFO_ACL_BUSY)
765 			coex_dm->bt_status = COEX_BTSTATUS_ACL_SCO_BUSY;
766 		else
767 			coex_dm->bt_status = COEX_BTSTATUS_SCO_BUSY;
768 	} else if (coex_stat->bt_info_lb2 & COEX_INFO_ACL_BUSY) {
769 		coex_dm->bt_status = COEX_BTSTATUS_ACL_BUSY;
770 	} else {
771 		coex_dm->bt_status = COEX_BTSTATUS_MAX;
772 	}
773 
774 	coex_stat->cnt_bt[COEX_CNT_BT_INFOUPDATE]++;
775 
776 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s(), %s!!!\n", __func__,
777 		rtw_coex_get_bt_status_string(coex_dm->bt_status));
778 }
779 
rtw_coex_update_wl_ch_info(struct rtw_dev * rtwdev,u8 type)780 static void rtw_coex_update_wl_ch_info(struct rtw_dev *rtwdev, u8 type)
781 {
782 	struct rtw_chip_info *chip = rtwdev->chip;
783 	struct rtw_coex_dm *coex_dm = &rtwdev->coex.dm;
784 	u8 link = 0;
785 	u8 center_chan = 0;
786 	u8 bw;
787 	int i;
788 
789 	bw = rtwdev->hal.current_band_width;
790 
791 	if (type != COEX_MEDIA_DISCONNECT)
792 		center_chan = rtwdev->hal.current_channel;
793 
794 	if (center_chan == 0) {
795 		link = 0;
796 		center_chan = 0;
797 		bw = 0;
798 	} else if (center_chan <= 14) {
799 		link = 0x1;
800 
801 		if (bw == RTW_CHANNEL_WIDTH_40)
802 			bw = chip->bt_afh_span_bw40;
803 		else
804 			bw = chip->bt_afh_span_bw20;
805 	} else if (chip->afh_5g_num > 1) {
806 		for (i = 0; i < chip->afh_5g_num; i++) {
807 			if (center_chan == chip->afh_5g[i].wl_5g_ch) {
808 				link = 0x3;
809 				center_chan = chip->afh_5g[i].bt_skip_ch;
810 				bw = chip->afh_5g[i].bt_skip_span;
811 				break;
812 			}
813 		}
814 	}
815 
816 	coex_dm->wl_ch_info[0] = link;
817 	coex_dm->wl_ch_info[1] = center_chan;
818 	coex_dm->wl_ch_info[2] = bw;
819 
820 	rtw_fw_wl_ch_info(rtwdev, link, center_chan, bw);
821 	rtw_dbg(rtwdev, RTW_DBG_COEX,
822 		"[BTCoex], %s: para[0:2] = 0x%x 0x%x 0x%x\n", __func__, link,
823 		center_chan, bw);
824 }
825 
rtw_coex_set_bt_tx_power(struct rtw_dev * rtwdev,u8 bt_pwr_dec_lvl)826 static void rtw_coex_set_bt_tx_power(struct rtw_dev *rtwdev, u8 bt_pwr_dec_lvl)
827 {
828 	struct rtw_coex *coex = &rtwdev->coex;
829 	struct rtw_coex_dm *coex_dm = &coex->dm;
830 
831 	if (bt_pwr_dec_lvl == coex_dm->cur_bt_pwr_lvl)
832 		return;
833 
834 	coex_dm->cur_bt_pwr_lvl = bt_pwr_dec_lvl;
835 
836 	rtw_fw_force_bt_tx_power(rtwdev, bt_pwr_dec_lvl);
837 }
838 
rtw_coex_set_bt_rx_gain(struct rtw_dev * rtwdev,u8 bt_lna_lvl)839 static void rtw_coex_set_bt_rx_gain(struct rtw_dev *rtwdev, u8 bt_lna_lvl)
840 {
841 	struct rtw_coex *coex = &rtwdev->coex;
842 	struct rtw_coex_dm *coex_dm = &coex->dm;
843 
844 	if (bt_lna_lvl == coex_dm->cur_bt_lna_lvl)
845 		return;
846 
847 	coex_dm->cur_bt_lna_lvl = bt_lna_lvl;
848 
849 	/* notify BT rx gain table changed */
850 	if (bt_lna_lvl < 7) {
851 		rtw_coex_set_lna_constrain_level(rtwdev, bt_lna_lvl);
852 		rtw_coex_write_scbd(rtwdev, COEX_SCBD_RXGAIN, true);
853 	} else {
854 		rtw_coex_write_scbd(rtwdev, COEX_SCBD_RXGAIN, false);
855 	}
856 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s(): bt_rx_LNA_level = %d\n",
857 		__func__, bt_lna_lvl);
858 }
859 
rtw_coex_set_rf_para(struct rtw_dev * rtwdev,struct coex_rf_para para)860 static void rtw_coex_set_rf_para(struct rtw_dev *rtwdev,
861 				 struct coex_rf_para para)
862 {
863 	struct rtw_coex *coex = &rtwdev->coex;
864 	struct rtw_coex_stat *coex_stat = &coex->stat;
865 	u8 offset = 0;
866 
867 	if (coex->freerun && coex_stat->cnt_wl[COEX_CNT_WL_SCANAP] <= 5)
868 		offset = 3;
869 
870 	rtw_coex_set_wl_tx_power(rtwdev, para.wl_pwr_dec_lvl);
871 	rtw_coex_set_bt_tx_power(rtwdev, para.bt_pwr_dec_lvl + offset);
872 	rtw_coex_set_wl_rx_gain(rtwdev, para.wl_low_gain_en);
873 	rtw_coex_set_bt_rx_gain(rtwdev, para.bt_lna_lvl);
874 }
875 
rtw_coex_read_indirect_reg(struct rtw_dev * rtwdev,u16 addr)876 u32 rtw_coex_read_indirect_reg(struct rtw_dev *rtwdev, u16 addr)
877 {
878 	u32 val;
879 
880 	if (!ltecoex_read_reg(rtwdev, addr, &val)) {
881 		rtw_err(rtwdev, "failed to read indirect register\n");
882 		return 0;
883 	}
884 
885 	return val;
886 }
887 EXPORT_SYMBOL(rtw_coex_read_indirect_reg);
888 
rtw_coex_write_indirect_reg(struct rtw_dev * rtwdev,u16 addr,u32 mask,u32 val)889 void rtw_coex_write_indirect_reg(struct rtw_dev *rtwdev, u16 addr,
890 				 u32 mask, u32 val)
891 {
892 	u32 shift = __ffs(mask);
893 	u32 tmp;
894 
895 	tmp = rtw_coex_read_indirect_reg(rtwdev, addr);
896 	tmp = (tmp & (~mask)) | ((val << shift) & mask);
897 
898 	if (!ltecoex_reg_write(rtwdev, addr, tmp))
899 		rtw_err(rtwdev, "failed to write indirect register\n");
900 }
901 EXPORT_SYMBOL(rtw_coex_write_indirect_reg);
902 
rtw_coex_coex_ctrl_owner(struct rtw_dev * rtwdev,bool wifi_control)903 static void rtw_coex_coex_ctrl_owner(struct rtw_dev *rtwdev, bool wifi_control)
904 {
905 	struct rtw_chip_info *chip = rtwdev->chip;
906 	const struct rtw_hw_reg *btg_reg = chip->btg_reg;
907 
908 	if (wifi_control) {
909 		rtw_write8_set(rtwdev, REG_SYS_SDIO_CTRL + 3,
910 			       BIT_LTE_MUX_CTRL_PATH >> 24);
911 		if (btg_reg)
912 			rtw_write8_set(rtwdev, btg_reg->addr, btg_reg->mask);
913 	} else {
914 		rtw_write8_clr(rtwdev, REG_SYS_SDIO_CTRL + 3,
915 			       BIT_LTE_MUX_CTRL_PATH >> 24);
916 		if (btg_reg)
917 			rtw_write8_clr(rtwdev, btg_reg->addr, btg_reg->mask);
918 	}
919 }
920 
rtw_coex_set_gnt_bt(struct rtw_dev * rtwdev,u8 state)921 static void rtw_coex_set_gnt_bt(struct rtw_dev *rtwdev, u8 state)
922 {
923 	rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0xc000, state);
924 	rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0x0c00, state);
925 }
926 
rtw_coex_set_gnt_wl(struct rtw_dev * rtwdev,u8 state)927 static void rtw_coex_set_gnt_wl(struct rtw_dev *rtwdev, u8 state)
928 {
929 	rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0x3000, state);
930 	rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0x0300, state);
931 }
932 
rtw_btc_wltoggle_table_a(struct rtw_dev * rtwdev,bool force,u8 table_case)933 static void rtw_btc_wltoggle_table_a(struct rtw_dev *rtwdev, bool force,
934 				     u8 table_case)
935 {
936 	struct rtw_chip_info *chip = rtwdev->chip;
937 	struct rtw_efuse *efuse = &rtwdev->efuse;
938 	u8 h2c_para[6] = {0};
939 	u32 table_wl = 0x5a5a5a5a;
940 
941 	h2c_para[0] = COEX_H2C69_TOGGLE_TABLE_A;
942 	/* no definition */
943 	h2c_para[1] = 0x1;
944 
945 	if (efuse->share_ant) {
946 		if (table_case < chip->table_sant_num)
947 			table_wl = chip->table_sant[table_case].wl;
948 	} else {
949 		if (table_case < chip->table_nsant_num)
950 			table_wl = chip->table_nsant[table_case].wl;
951 	}
952 
953 	/* tell WL FW WL slot toggle table-A*/
954 	h2c_para[2] = (u8)u32_get_bits(table_wl, GENMASK(7, 0));
955 	h2c_para[3] = (u8)u32_get_bits(table_wl, GENMASK(15, 8));
956 	h2c_para[4] = (u8)u32_get_bits(table_wl, GENMASK(23, 16));
957 	h2c_para[5] = (u8)u32_get_bits(table_wl, GENMASK(31, 24));
958 
959 	rtw_fw_bt_wifi_control(rtwdev, h2c_para[0], &h2c_para[1]);
960 
961 	rtw_dbg(rtwdev, RTW_DBG_COEX,
962 		"[BTCoex], %s(): H2C = [%02x %02x %02x %02x %02x %02x]\n",
963 		__func__, h2c_para[0], h2c_para[1], h2c_para[2],
964 		h2c_para[3], h2c_para[4], h2c_para[5]);
965 }
966 
967 #define COEX_WL_SLOT_TOGLLE 0x5a5a5aaa
rtw_btc_wltoggle_table_b(struct rtw_dev * rtwdev,bool force,u8 interval,u32 table)968 static void rtw_btc_wltoggle_table_b(struct rtw_dev *rtwdev, bool force,
969 				     u8 interval, u32 table)
970 {
971 	struct rtw_coex *coex = &rtwdev->coex;
972 	struct rtw_coex_stat *coex_stat = &coex->stat;
973 	u8 cur_h2c_para[6] = {0};
974 	u8 i;
975 
976 	cur_h2c_para[0] = COEX_H2C69_TOGGLE_TABLE_B;
977 	cur_h2c_para[1] = interval;
978 	cur_h2c_para[2] = (u8)u32_get_bits(table, GENMASK(7, 0));
979 	cur_h2c_para[3] = (u8)u32_get_bits(table, GENMASK(15, 8));
980 	cur_h2c_para[4] = (u8)u32_get_bits(table, GENMASK(23, 16));
981 	cur_h2c_para[5] = (u8)u32_get_bits(table, GENMASK(31, 24));
982 
983 	coex_stat->wl_toggle_interval = interval;
984 
985 	for (i = 0; i <= 5; i++)
986 		coex_stat->wl_toggle_para[i] = cur_h2c_para[i];
987 
988 	rtw_fw_bt_wifi_control(rtwdev, cur_h2c_para[0], &cur_h2c_para[1]);
989 
990 	rtw_dbg(rtwdev, RTW_DBG_COEX,
991 		"[BTCoex], %s(): H2C = [%02x %02x %02x %02x %02x %02x]\n",
992 		__func__, cur_h2c_para[0], cur_h2c_para[1], cur_h2c_para[2],
993 		cur_h2c_para[3], cur_h2c_para[4], cur_h2c_para[5]);
994 }
995 
rtw_coex_set_table(struct rtw_dev * rtwdev,bool force,u32 table0,u32 table1)996 static void rtw_coex_set_table(struct rtw_dev *rtwdev, bool force, u32 table0,
997 			       u32 table1)
998 {
999 #define DEF_BRK_TABLE_VAL 0xf0ffffff
1000 	struct rtw_coex *coex = &rtwdev->coex;
1001 	struct rtw_coex_dm *coex_dm = &coex->dm;
1002 
1003 	/* If last tdma is wl slot toggle, force write table*/
1004 	if (!force && coex_dm->reason != COEX_RSN_LPS) {
1005 		if (table0 == rtw_read32(rtwdev, REG_BT_COEX_TABLE0) &&
1006 		    table1 == rtw_read32(rtwdev, REG_BT_COEX_TABLE1))
1007 			return;
1008 	}
1009 	rtw_write32(rtwdev, REG_BT_COEX_TABLE0, table0);
1010 	rtw_write32(rtwdev, REG_BT_COEX_TABLE1, table1);
1011 	rtw_write32(rtwdev, REG_BT_COEX_BRK_TABLE, DEF_BRK_TABLE_VAL);
1012 
1013 	rtw_dbg(rtwdev, RTW_DBG_COEX,
1014 		"[BTCoex], %s(): 0x6c0 = %x, 0x6c4 = %x\n", __func__, table0,
1015 		table1);
1016 }
1017 
rtw_coex_table(struct rtw_dev * rtwdev,bool force,u8 type)1018 static void rtw_coex_table(struct rtw_dev *rtwdev, bool force, u8 type)
1019 {
1020 	struct rtw_coex *coex = &rtwdev->coex;
1021 	struct rtw_coex_dm *coex_dm = &coex->dm;
1022 	struct rtw_chip_info *chip = rtwdev->chip;
1023 	struct rtw_efuse *efuse = &rtwdev->efuse;
1024 	struct rtw_coex_stat *coex_stat = &coex->stat;
1025 
1026 	coex_dm->cur_table = type;
1027 
1028 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], Coex_Table - %d\n", type);
1029 
1030 	if (efuse->share_ant) {
1031 		if (type < chip->table_sant_num)
1032 			rtw_coex_set_table(rtwdev, force,
1033 					   chip->table_sant[type].bt,
1034 					   chip->table_sant[type].wl);
1035 	} else {
1036 		type = type - 100;
1037 		if (type < chip->table_nsant_num)
1038 			rtw_coex_set_table(rtwdev, force,
1039 					   chip->table_nsant[type].bt,
1040 					   chip->table_nsant[type].wl);
1041 	}
1042 	if (coex_stat->wl_slot_toggle_change)
1043 		rtw_btc_wltoggle_table_a(rtwdev, true, type);
1044 }
1045 
rtw_coex_ignore_wlan_act(struct rtw_dev * rtwdev,bool enable)1046 static void rtw_coex_ignore_wlan_act(struct rtw_dev *rtwdev, bool enable)
1047 {
1048 	struct rtw_coex *coex = &rtwdev->coex;
1049 
1050 	if (coex->manual_control || coex->stop_dm)
1051 		return;
1052 
1053 	rtw_fw_bt_ignore_wlan_action(rtwdev, enable);
1054 }
1055 
rtw_coex_power_save_state(struct rtw_dev * rtwdev,u8 ps_type,u8 lps_val,u8 rpwm_val)1056 static void rtw_coex_power_save_state(struct rtw_dev *rtwdev, u8 ps_type,
1057 				      u8 lps_val, u8 rpwm_val)
1058 {
1059 	struct rtw_coex *coex = &rtwdev->coex;
1060 	struct rtw_coex_stat *coex_stat = &coex->stat;
1061 	u8 lps_mode = 0x0;
1062 
1063 	lps_mode = rtwdev->lps_conf.mode;
1064 
1065 	switch (ps_type) {
1066 	case COEX_PS_WIFI_NATIVE:
1067 		/* recover to original 32k low power setting */
1068 		coex_stat->wl_force_lps_ctrl = false;
1069 		rtw_dbg(rtwdev, RTW_DBG_COEX,
1070 			"[BTCoex], %s(): COEX_PS_WIFI_NATIVE\n", __func__);
1071 		rtw_leave_lps(rtwdev);
1072 		break;
1073 	case COEX_PS_LPS_OFF:
1074 		coex_stat->wl_force_lps_ctrl = true;
1075 		if (lps_mode)
1076 			rtw_fw_coex_tdma_type(rtwdev, 0, 0, 0, 0, 0);
1077 
1078 		rtw_leave_lps(rtwdev);
1079 		rtw_dbg(rtwdev, RTW_DBG_COEX,
1080 			"[BTCoex], %s(): COEX_PS_LPS_OFF\n", __func__);
1081 		break;
1082 	default:
1083 		break;
1084 	}
1085 }
1086 
rtw_coex_set_tdma(struct rtw_dev * rtwdev,u8 byte1,u8 byte2,u8 byte3,u8 byte4,u8 byte5)1087 static void rtw_coex_set_tdma(struct rtw_dev *rtwdev, u8 byte1, u8 byte2,
1088 			      u8 byte3, u8 byte4, u8 byte5)
1089 {
1090 	struct rtw_coex *coex = &rtwdev->coex;
1091 	struct rtw_coex_dm *coex_dm = &coex->dm;
1092 	struct rtw_chip_info *chip = rtwdev->chip;
1093 	struct rtw_coex_stat *coex_stat = &coex->stat;
1094 	u8 ps_type = COEX_PS_WIFI_NATIVE;
1095 	bool ap_enable = false;
1096 
1097 	if (ap_enable && (byte1 & BIT(4) && !(byte1 & BIT(5)))) {
1098 		rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s(): AP mode\n",
1099 			__func__);
1100 
1101 		byte1 &= ~BIT(4);
1102 		byte1 |= BIT(5);
1103 
1104 		byte5 |= BIT(5);
1105 		byte5 &= ~BIT(6);
1106 
1107 		ps_type = COEX_PS_WIFI_NATIVE;
1108 		rtw_coex_power_save_state(rtwdev, ps_type, 0x0, 0x0);
1109 	} else if (byte1 & BIT(4) && !(byte1 & BIT(5))) {
1110 		rtw_dbg(rtwdev, RTW_DBG_COEX,
1111 			"[BTCoex], %s(): Force LPS (byte1 = 0x%x)\n", __func__,
1112 			byte1);
1113 
1114 		if (chip->pstdma_type == COEX_PSTDMA_FORCE_LPSOFF)
1115 			ps_type = COEX_PS_LPS_OFF;
1116 		else
1117 			ps_type = COEX_PS_LPS_ON;
1118 		rtw_coex_power_save_state(rtwdev, ps_type, 0x50, 0x4);
1119 	} else {
1120 		rtw_dbg(rtwdev, RTW_DBG_COEX,
1121 			"[BTCoex], %s(): native power save (byte1 = 0x%x)\n",
1122 			__func__, byte1);
1123 
1124 		ps_type = COEX_PS_WIFI_NATIVE;
1125 		rtw_coex_power_save_state(rtwdev, ps_type, 0x0, 0x0);
1126 	}
1127 
1128 	coex_dm->ps_tdma_para[0] = byte1;
1129 	coex_dm->ps_tdma_para[1] = byte2;
1130 	coex_dm->ps_tdma_para[2] = byte3;
1131 	coex_dm->ps_tdma_para[3] = byte4;
1132 	coex_dm->ps_tdma_para[4] = byte5;
1133 
1134 	rtw_fw_coex_tdma_type(rtwdev, byte1, byte2, byte3, byte4, byte5);
1135 
1136 	if (byte1 & BIT(2)) {
1137 		coex_stat->wl_slot_toggle = true;
1138 		coex_stat->wl_slot_toggle_change = false;
1139 	} else {
1140 		coex_stat->wl_slot_toggle_change = coex_stat->wl_slot_toggle;
1141 		coex_stat->wl_slot_toggle = false;
1142 	}
1143 }
1144 
rtw_coex_tdma(struct rtw_dev * rtwdev,bool force,u32 tcase)1145 static void rtw_coex_tdma(struct rtw_dev *rtwdev, bool force, u32 tcase)
1146 {
1147 	struct rtw_coex *coex = &rtwdev->coex;
1148 	struct rtw_coex_dm *coex_dm = &coex->dm;
1149 	struct rtw_coex_stat *coex_stat = &coex->stat;
1150 	struct rtw_chip_info *chip = rtwdev->chip;
1151 	struct rtw_efuse *efuse = &rtwdev->efuse;
1152 	u8 n, type;
1153 	bool turn_on;
1154 	bool wl_busy = false;
1155 
1156 	if (tcase & TDMA_4SLOT) /* 4-slot (50ms) mode */
1157 		rtw_coex_tdma_timer_base(rtwdev, TDMA_TIMER_TYPE_4SLOT);
1158 	else
1159 		rtw_coex_tdma_timer_base(rtwdev, TDMA_TIMER_TYPE_2SLOT);
1160 
1161 	type = (u8)(tcase & 0xff);
1162 
1163 	turn_on = (type == 0 || type == 100) ? false : true;
1164 
1165 	if (!force && turn_on == coex_dm->cur_ps_tdma_on &&
1166 	    type == coex_dm->cur_ps_tdma) {
1167 		rtw_dbg(rtwdev, RTW_DBG_COEX,
1168 			"[BTCoex], Skip TDMA because no change TDMA(%s, %d)\n",
1169 			(coex_dm->cur_ps_tdma_on ? "on" : "off"),
1170 			coex_dm->cur_ps_tdma);
1171 
1172 		return;
1173 	}
1174 	wl_busy = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags);
1175 
1176 	if ((coex_stat->bt_a2dp_exist &&
1177 	     (coex_stat->bt_inq_remain || coex_stat->bt_multi_link)) ||
1178 	    !wl_busy)
1179 		rtw_coex_write_scbd(rtwdev, COEX_SCBD_TDMA, false);
1180 	else
1181 		rtw_coex_write_scbd(rtwdev, COEX_SCBD_TDMA, true);
1182 
1183 	/* update pre state */
1184 	coex_dm->cur_ps_tdma_on = turn_on;
1185 	coex_dm->cur_ps_tdma = type;
1186 
1187 	if (efuse->share_ant) {
1188 		if (type < chip->tdma_sant_num)
1189 			rtw_coex_set_tdma(rtwdev,
1190 					  chip->tdma_sant[type].para[0],
1191 					  chip->tdma_sant[type].para[1],
1192 					  chip->tdma_sant[type].para[2],
1193 					  chip->tdma_sant[type].para[3],
1194 					  chip->tdma_sant[type].para[4]);
1195 	} else {
1196 		n = type - 100;
1197 		if (n < chip->tdma_nsant_num)
1198 			rtw_coex_set_tdma(rtwdev,
1199 					  chip->tdma_nsant[n].para[0],
1200 					  chip->tdma_nsant[n].para[1],
1201 					  chip->tdma_nsant[n].para[2],
1202 					  chip->tdma_nsant[n].para[3],
1203 					  chip->tdma_nsant[n].para[4]);
1204 	}
1205 
1206 
1207 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], coex tdma type(%s, %d)\n",
1208 		turn_on ? "on" : "off", type);
1209 }
1210 
rtw_coex_set_ant_path(struct rtw_dev * rtwdev,bool force,u8 phase)1211 static void rtw_coex_set_ant_path(struct rtw_dev *rtwdev, bool force, u8 phase)
1212 {
1213 	struct rtw_coex *coex = &rtwdev->coex;
1214 	struct rtw_coex_stat *coex_stat = &coex->stat;
1215 	struct rtw_coex_rfe *coex_rfe = &coex->rfe;
1216 	struct rtw_coex_dm *coex_dm = &coex->dm;
1217 	u8 ctrl_type = COEX_SWITCH_CTRL_MAX;
1218 	u8 pos_type = COEX_SWITCH_TO_MAX;
1219 
1220 	if (!force && coex_dm->cur_ant_pos_type == phase)
1221 		return;
1222 
1223 	coex_dm->cur_ant_pos_type = phase;
1224 
1225 	/* avoid switch coex_ctrl_owner during BT IQK */
1226 	rtw_coex_check_rfk(rtwdev);
1227 
1228 	rtw_dbg(rtwdev, RTW_DBG_COEX,
1229 		"[BTCoex],  coex_stat->bt_disabled = 0x%x\n",
1230 		coex_stat->bt_disabled);
1231 
1232 	switch (phase) {
1233 	case COEX_SET_ANT_POWERON:
1234 		rtw_dbg(rtwdev, RTW_DBG_COEX,
1235 			"[BTCoex], %s() - PHASE_COEX_POWERON\n", __func__);
1236 		/* set path control owner to BT at power-on */
1237 		if (coex_stat->bt_disabled)
1238 			rtw_coex_coex_ctrl_owner(rtwdev, true);
1239 		else
1240 			rtw_coex_coex_ctrl_owner(rtwdev, false);
1241 
1242 		ctrl_type = COEX_SWITCH_CTRL_BY_BBSW;
1243 		pos_type = COEX_SWITCH_TO_BT;
1244 		break;
1245 	case COEX_SET_ANT_INIT:
1246 		rtw_dbg(rtwdev, RTW_DBG_COEX,
1247 			"[BTCoex], %s() - PHASE_COEX_INIT\n", __func__);
1248 		if (coex_stat->bt_disabled) {
1249 			/* set GNT_BT to SW low */
1250 			rtw_coex_set_gnt_bt(rtwdev, COEX_GNT_SET_SW_LOW);
1251 
1252 			/* set GNT_WL to SW high */
1253 			rtw_coex_set_gnt_wl(rtwdev, COEX_GNT_SET_SW_HIGH);
1254 		} else {
1255 			/* set GNT_BT to SW high */
1256 			rtw_coex_set_gnt_bt(rtwdev, COEX_GNT_SET_SW_HIGH);
1257 
1258 			/* set GNT_WL to SW low */
1259 			rtw_coex_set_gnt_wl(rtwdev, COEX_GNT_SET_SW_LOW);
1260 		}
1261 
1262 		/* set path control owner to wl at initial step */
1263 		rtw_coex_coex_ctrl_owner(rtwdev, true);
1264 
1265 		ctrl_type = COEX_SWITCH_CTRL_BY_BBSW;
1266 		pos_type = COEX_SWITCH_TO_BT;
1267 		break;
1268 	case COEX_SET_ANT_WONLY:
1269 		rtw_dbg(rtwdev, RTW_DBG_COEX,
1270 			"[BTCoex], %s() - PHASE_WLANONLY_INIT\n", __func__);
1271 		/* set GNT_BT to SW Low */
1272 		rtw_coex_set_gnt_bt(rtwdev, COEX_GNT_SET_SW_LOW);
1273 
1274 		/* set GNT_WL to SW high */
1275 		rtw_coex_set_gnt_wl(rtwdev, COEX_GNT_SET_SW_HIGH);
1276 
1277 		/* set path control owner to wl at initial step */
1278 		rtw_coex_coex_ctrl_owner(rtwdev, true);
1279 
1280 		ctrl_type = COEX_SWITCH_CTRL_BY_BBSW;
1281 		pos_type = COEX_SWITCH_TO_WLG;
1282 		break;
1283 	case COEX_SET_ANT_WOFF:
1284 		rtw_dbg(rtwdev, RTW_DBG_COEX,
1285 			"[BTCoex], %s() - PHASE_WLAN_OFF\n", __func__);
1286 		/* set path control owner to BT */
1287 		rtw_coex_coex_ctrl_owner(rtwdev, false);
1288 
1289 		ctrl_type = COEX_SWITCH_CTRL_BY_BT;
1290 		pos_type = COEX_SWITCH_TO_NOCARE;
1291 		break;
1292 	case COEX_SET_ANT_2G:
1293 		rtw_dbg(rtwdev, RTW_DBG_COEX,
1294 			"[BTCoex], %s() - PHASE_2G_RUNTIME\n", __func__);
1295 		/* set GNT_BT to PTA */
1296 		rtw_coex_set_gnt_bt(rtwdev, COEX_GNT_SET_HW_PTA);
1297 
1298 		/* set GNT_WL to PTA */
1299 		rtw_coex_set_gnt_wl(rtwdev, COEX_GNT_SET_HW_PTA);
1300 
1301 		/* set path control owner to wl at runtime step */
1302 		rtw_coex_coex_ctrl_owner(rtwdev, true);
1303 
1304 		ctrl_type = COEX_SWITCH_CTRL_BY_PTA;
1305 		pos_type = COEX_SWITCH_TO_NOCARE;
1306 		break;
1307 	case COEX_SET_ANT_5G:
1308 		rtw_dbg(rtwdev, RTW_DBG_COEX,
1309 			"[BTCoex], %s() - PHASE_5G_RUNTIME\n", __func__);
1310 
1311 		/* set GNT_BT to HW PTA */
1312 		rtw_coex_set_gnt_bt(rtwdev, COEX_GNT_SET_HW_PTA);
1313 
1314 		/* set GNT_WL to SW high */
1315 		rtw_coex_set_gnt_wl(rtwdev, COEX_GNT_SET_SW_HIGH);
1316 
1317 		/* set path control owner to wl at runtime step */
1318 		rtw_coex_coex_ctrl_owner(rtwdev, true);
1319 
1320 		ctrl_type = COEX_SWITCH_CTRL_BY_BBSW;
1321 		pos_type = COEX_SWITCH_TO_WLA;
1322 		break;
1323 	case COEX_SET_ANT_2G_FREERUN:
1324 		rtw_dbg(rtwdev, RTW_DBG_COEX,
1325 			"[BTCoex], %s() - PHASE_2G_FREERUN\n", __func__);
1326 
1327 		/* set GNT_BT to HW PTA */
1328 		rtw_coex_set_gnt_bt(rtwdev, COEX_GNT_SET_HW_PTA);
1329 
1330 		/* Set GNT_WL to SW high */
1331 		rtw_coex_set_gnt_wl(rtwdev, COEX_GNT_SET_SW_HIGH);
1332 
1333 		/* set path control owner to wl at runtime step */
1334 		rtw_coex_coex_ctrl_owner(rtwdev, true);
1335 
1336 		ctrl_type = COEX_SWITCH_CTRL_BY_BBSW;
1337 		pos_type = COEX_SWITCH_TO_WLG_BT;
1338 		break;
1339 	case COEX_SET_ANT_2G_WLBT:
1340 		rtw_dbg(rtwdev, RTW_DBG_COEX,
1341 			"[BTCoex], %s() - PHASE_2G_WLBT\n", __func__);
1342 		/* set GNT_BT to HW PTA */
1343 		rtw_coex_set_gnt_bt(rtwdev, COEX_GNT_SET_HW_PTA);
1344 
1345 		/* Set GNT_WL to HW PTA */
1346 		rtw_coex_set_gnt_wl(rtwdev, COEX_GNT_SET_HW_PTA);
1347 
1348 		/* set path control owner to wl at runtime step */
1349 		rtw_coex_coex_ctrl_owner(rtwdev, true);
1350 
1351 		ctrl_type = COEX_SWITCH_CTRL_BY_BBSW;
1352 		pos_type = COEX_SWITCH_TO_WLG_BT;
1353 		break;
1354 	default:
1355 		WARN(1, "unknown phase when setting antenna path\n");
1356 		return;
1357 	}
1358 
1359 	if (ctrl_type < COEX_SWITCH_CTRL_MAX && pos_type < COEX_SWITCH_TO_MAX &&
1360 	    coex_rfe->ant_switch_exist)
1361 		rtw_coex_set_ant_switch(rtwdev, ctrl_type, pos_type);
1362 }
1363 
1364 #define case_ALGO(src) \
1365 	case COEX_ALGO_##src: return #src
1366 
rtw_coex_get_algo_string(u8 algo)1367 static const char *rtw_coex_get_algo_string(u8 algo)
1368 {
1369 	switch (algo) {
1370 	case_ALGO(NOPROFILE);
1371 	case_ALGO(HFP);
1372 	case_ALGO(HID);
1373 	case_ALGO(A2DP);
1374 	case_ALGO(PAN);
1375 	case_ALGO(A2DP_HID);
1376 	case_ALGO(A2DP_PAN);
1377 	case_ALGO(PAN_HID);
1378 	case_ALGO(A2DP_PAN_HID);
1379 	default:
1380 		return "Unknown";
1381 	}
1382 }
1383 
1384 #define case_BT_PROFILE(src) \
1385 	case BPM_##src: return #src
1386 
rtw_coex_get_bt_profile_string(u8 bt_profile)1387 static const char *rtw_coex_get_bt_profile_string(u8 bt_profile)
1388 {
1389 	switch (bt_profile) {
1390 	case_BT_PROFILE(NOPROFILE);
1391 	case_BT_PROFILE(HFP);
1392 	case_BT_PROFILE(HID);
1393 	case_BT_PROFILE(A2DP);
1394 	case_BT_PROFILE(PAN);
1395 	case_BT_PROFILE(HID_HFP);
1396 	case_BT_PROFILE(A2DP_HFP);
1397 	case_BT_PROFILE(A2DP_HID);
1398 	case_BT_PROFILE(A2DP_HID_HFP);
1399 	case_BT_PROFILE(PAN_HFP);
1400 	case_BT_PROFILE(PAN_HID);
1401 	case_BT_PROFILE(PAN_HID_HFP);
1402 	case_BT_PROFILE(PAN_A2DP);
1403 	case_BT_PROFILE(PAN_A2DP_HFP);
1404 	case_BT_PROFILE(PAN_A2DP_HID);
1405 	case_BT_PROFILE(PAN_A2DP_HID_HFP);
1406 	default:
1407 		return "Unknown";
1408 	}
1409 }
1410 
rtw_coex_algorithm(struct rtw_dev * rtwdev)1411 static u8 rtw_coex_algorithm(struct rtw_dev *rtwdev)
1412 {
1413 	struct rtw_coex *coex = &rtwdev->coex;
1414 	struct rtw_coex_stat *coex_stat = &coex->stat;
1415 	u8 algorithm = COEX_ALGO_NOPROFILE;
1416 	u8 profile_map = 0;
1417 
1418 	if (coex_stat->bt_hfp_exist)
1419 		profile_map |= BPM_HFP;
1420 	if (coex_stat->bt_hid_exist)
1421 		profile_map |= BPM_HID;
1422 	if (coex_stat->bt_a2dp_exist)
1423 		profile_map |= BPM_A2DP;
1424 	if (coex_stat->bt_pan_exist)
1425 		profile_map |= BPM_PAN;
1426 
1427 	switch (profile_map) {
1428 	case BPM_HFP:
1429 		algorithm = COEX_ALGO_HFP;
1430 		break;
1431 	case           BPM_HID:
1432 	case BPM_HFP + BPM_HID:
1433 		algorithm = COEX_ALGO_HID;
1434 		break;
1435 	case BPM_HFP           + BPM_A2DP:
1436 	case           BPM_HID + BPM_A2DP:
1437 	case BPM_HFP + BPM_HID + BPM_A2DP:
1438 		algorithm = COEX_ALGO_A2DP_HID;
1439 		break;
1440 	case BPM_HFP                      + BPM_PAN:
1441 	case           BPM_HID            + BPM_PAN:
1442 	case BPM_HFP + BPM_HID            + BPM_PAN:
1443 		algorithm = COEX_ALGO_PAN_HID;
1444 		break;
1445 	case BPM_HFP           + BPM_A2DP + BPM_PAN:
1446 	case           BPM_HID + BPM_A2DP + BPM_PAN:
1447 	case BPM_HFP + BPM_HID + BPM_A2DP + BPM_PAN:
1448 		algorithm = COEX_ALGO_A2DP_PAN_HID;
1449 		break;
1450 	case                                BPM_PAN:
1451 		algorithm = COEX_ALGO_PAN;
1452 		break;
1453 	case                     BPM_A2DP + BPM_PAN:
1454 		algorithm = COEX_ALGO_A2DP_PAN;
1455 		break;
1456 	case                     BPM_A2DP:
1457 		if (coex_stat->bt_multi_link) {
1458 			if (coex_stat->bt_hid_pair_num > 0)
1459 				algorithm = COEX_ALGO_A2DP_HID;
1460 			else
1461 				algorithm = COEX_ALGO_A2DP_PAN;
1462 		} else {
1463 			algorithm = COEX_ALGO_A2DP;
1464 		}
1465 		break;
1466 	default:
1467 		algorithm = COEX_ALGO_NOPROFILE;
1468 		break;
1469 	}
1470 
1471 	rtw_dbg(rtwdev, RTW_DBG_COEX,
1472 		"[BTCoex], BT Profile = %s => Algorithm = %s\n",
1473 		rtw_coex_get_bt_profile_string(profile_map),
1474 		rtw_coex_get_algo_string(algorithm));
1475 	return algorithm;
1476 }
1477 
rtw_coex_action_coex_all_off(struct rtw_dev * rtwdev)1478 static void rtw_coex_action_coex_all_off(struct rtw_dev *rtwdev)
1479 {
1480 	struct rtw_efuse *efuse = &rtwdev->efuse;
1481 	struct rtw_chip_info *chip = rtwdev->chip;
1482 	u8 table_case, tdma_case;
1483 
1484 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
1485 	rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
1486 
1487 	if (efuse->share_ant) {
1488 		/* Shared-Ant */
1489 		table_case = 2;
1490 		tdma_case = 0;
1491 	} else {
1492 		/* Non-Shared-Ant */
1493 		table_case = 100;
1494 		tdma_case = 100;
1495 	}
1496 
1497 	rtw_coex_table(rtwdev, false, table_case);
1498 	rtw_coex_tdma(rtwdev, false, tdma_case);
1499 }
1500 
rtw_coex_action_freerun(struct rtw_dev * rtwdev)1501 static void rtw_coex_action_freerun(struct rtw_dev *rtwdev)
1502 {
1503 	struct rtw_coex *coex = &rtwdev->coex;
1504 	struct rtw_coex_stat *coex_stat = &coex->stat;
1505 	struct rtw_coex_dm *coex_dm = &coex->dm;
1506 	struct rtw_efuse *efuse = &rtwdev->efuse;
1507 	struct rtw_chip_info *chip = rtwdev->chip;
1508 	u8 level = 0;
1509 	bool bt_afh_loss = true;
1510 
1511 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
1512 
1513 	if (efuse->share_ant)
1514 		return;
1515 
1516 	coex->freerun = true;
1517 
1518 	if (bt_afh_loss)
1519 		rtw_coex_update_wl_ch_info(rtwdev, COEX_MEDIA_CONNECT);
1520 
1521 	rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G_FREERUN);
1522 
1523 	rtw_coex_write_scbd(rtwdev, COEX_SCBD_FIX2M, false);
1524 
1525 	if (COEX_RSSI_HIGH(coex_dm->wl_rssi_state[0]))
1526 		level = 2;
1527 	else if (COEX_RSSI_HIGH(coex_dm->wl_rssi_state[1]))
1528 		level = 3;
1529 	else if (COEX_RSSI_HIGH(coex_dm->wl_rssi_state[2]))
1530 		level = 4;
1531 	else
1532 		level = 5;
1533 
1534 	if (level > chip->wl_rf_para_num - 1)
1535 		level = chip->wl_rf_para_num - 1;
1536 
1537 	if (coex_stat->wl_tput_dir == COEX_WL_TPUT_TX)
1538 		rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_tx[level]);
1539 	else
1540 		rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[level]);
1541 
1542 	rtw_coex_table(rtwdev, false, 100);
1543 	rtw_coex_tdma(rtwdev, false, 100);
1544 }
1545 
rtw_coex_action_rf4ce(struct rtw_dev * rtwdev)1546 static void rtw_coex_action_rf4ce(struct rtw_dev *rtwdev)
1547 {
1548 	struct rtw_efuse *efuse = &rtwdev->efuse;
1549 	struct rtw_chip_info *chip = rtwdev->chip;
1550 	u8 table_case, tdma_case;
1551 
1552 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
1553 
1554 	rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
1555 	rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
1556 
1557 	if (efuse->share_ant) {
1558 		/* Shared-Ant */
1559 		table_case = 9;
1560 		tdma_case = 16;
1561 	} else {
1562 		/* Non-Shared-Ant */
1563 		table_case = 100;
1564 		tdma_case = 100;
1565 	}
1566 
1567 	rtw_coex_table(rtwdev, false, table_case);
1568 	rtw_coex_tdma(rtwdev, false, tdma_case);
1569 }
1570 
rtw_coex_action_bt_whql_test(struct rtw_dev * rtwdev)1571 static void rtw_coex_action_bt_whql_test(struct rtw_dev *rtwdev)
1572 {
1573 	struct rtw_efuse *efuse = &rtwdev->efuse;
1574 	struct rtw_chip_info *chip = rtwdev->chip;
1575 	u8 table_case, tdma_case;
1576 
1577 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
1578 
1579 	rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
1580 	rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
1581 
1582 	if (efuse->share_ant) {
1583 		/* Shared-Ant */
1584 		table_case = 2;
1585 		tdma_case = 0;
1586 	} else {
1587 		/* Non-Shared-Ant */
1588 		table_case = 100;
1589 		tdma_case = 100;
1590 	}
1591 
1592 	rtw_coex_table(rtwdev, false, table_case);
1593 	rtw_coex_tdma(rtwdev, false, tdma_case);
1594 }
1595 
rtw_coex_action_bt_relink(struct rtw_dev * rtwdev)1596 static void rtw_coex_action_bt_relink(struct rtw_dev *rtwdev)
1597 {
1598 	struct rtw_coex *coex = &rtwdev->coex;
1599 	struct rtw_coex_stat *coex_stat = &coex->stat;
1600 	struct rtw_efuse *efuse = &rtwdev->efuse;
1601 	struct rtw_chip_info *chip = rtwdev->chip;
1602 	u8 table_case, tdma_case;
1603 	u32 slot_type = 0;
1604 
1605 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
1606 
1607 	rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
1608 	rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
1609 
1610 	if (efuse->share_ant) { /* Shared-Ant */
1611 		if (coex_stat->wl_gl_busy) {
1612 			table_case = 26;
1613 			if (coex_stat->bt_hid_exist &&
1614 			    coex_stat->bt_profile_num == 1) {
1615 				slot_type = TDMA_4SLOT;
1616 				tdma_case = 20;
1617 			} else {
1618 				tdma_case = 20;
1619 			}
1620 		} else {
1621 			table_case = 1;
1622 			tdma_case = 0;
1623 		}
1624 	} else { /* Non-Shared-Ant */
1625 		if (coex_stat->wl_gl_busy)
1626 			table_case = 115;
1627 		else
1628 			table_case = 100;
1629 		tdma_case = 100;
1630 	}
1631 
1632 	rtw_coex_table(rtwdev, false, table_case);
1633 	rtw_coex_tdma(rtwdev, false, tdma_case | slot_type);
1634 }
1635 
rtw_coex_action_bt_idle(struct rtw_dev * rtwdev)1636 static void rtw_coex_action_bt_idle(struct rtw_dev *rtwdev)
1637 {
1638 	struct rtw_coex *coex = &rtwdev->coex;
1639 	struct rtw_coex_stat *coex_stat = &coex->stat;
1640 	struct rtw_coex_dm *coex_dm = &coex->dm;
1641 	struct rtw_efuse *efuse = &rtwdev->efuse;
1642 	struct rtw_chip_info *chip = rtwdev->chip;
1643 	struct rtw_coex_rfe *coex_rfe = &coex->rfe;
1644 	u8 table_case = 0xff, tdma_case = 0xff;
1645 
1646 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
1647 	rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
1648 
1649 	if (coex_rfe->ant_switch_with_bt &&
1650 	    coex_dm->bt_status == COEX_BTSTATUS_NCON_IDLE) {
1651 		if (efuse->share_ant &&
1652 		    COEX_RSSI_HIGH(coex_dm->wl_rssi_state[3]) &&
1653 		    coex_stat->wl_gl_busy) {
1654 			table_case = 0;
1655 			tdma_case = 0;
1656 		} else if (!efuse->share_ant) {
1657 			table_case = 100;
1658 			tdma_case = 100;
1659 		}
1660 	}
1661 
1662 	if (table_case != 0xff && tdma_case != 0xff) {
1663 		rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G_FREERUN);
1664 		goto exit;
1665 	}
1666 
1667 	rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
1668 
1669 	if (efuse->share_ant) {
1670 		/* Shared-Ant */
1671 		if (!coex_stat->wl_gl_busy) {
1672 			table_case = 10;
1673 			tdma_case = 3;
1674 		} else if (coex_dm->bt_status == COEX_BTSTATUS_NCON_IDLE) {
1675 			table_case = 11;
1676 
1677 			if (coex_stat->lo_pri_rx + coex_stat->lo_pri_tx > 250)
1678 				tdma_case = 17;
1679 			else
1680 				tdma_case = 7;
1681 		} else {
1682 			table_case = 12;
1683 			tdma_case = 7;
1684 		}
1685 	} else {
1686 		/* Non-Shared-Ant */
1687 		if (!coex_stat->wl_gl_busy) {
1688 			table_case = 112;
1689 			tdma_case = 104;
1690 		} else if ((coex_stat->bt_ble_scan_type & 0x2) &&
1691 			   coex_dm->bt_status == COEX_BTSTATUS_NCON_IDLE) {
1692 			table_case = 114;
1693 			tdma_case = 103;
1694 		} else {
1695 			table_case = 112;
1696 			tdma_case = 103;
1697 		}
1698 	}
1699 
1700 exit:
1701 	rtw_coex_table(rtwdev, false, table_case);
1702 	rtw_coex_tdma(rtwdev, false, tdma_case);
1703 }
1704 
rtw_coex_action_bt_inquiry(struct rtw_dev * rtwdev)1705 static void rtw_coex_action_bt_inquiry(struct rtw_dev *rtwdev)
1706 {
1707 	struct rtw_coex *coex = &rtwdev->coex;
1708 	struct rtw_coex_stat *coex_stat = &coex->stat;
1709 	struct rtw_efuse *efuse = &rtwdev->efuse;
1710 	struct rtw_chip_info *chip = rtwdev->chip;
1711 	bool wl_hi_pri = false;
1712 	u8 table_case, tdma_case;
1713 	u32 slot_type = 0;
1714 
1715 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
1716 	rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
1717 	rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
1718 
1719 	if (coex_stat->wl_linkscan_proc || coex_stat->wl_hi_pri_task1 ||
1720 	    coex_stat->wl_hi_pri_task2)
1721 		wl_hi_pri = true;
1722 
1723 	if (efuse->share_ant) {
1724 		/* Shared-Ant */
1725 		if (wl_hi_pri) {
1726 			rtw_dbg(rtwdev, RTW_DBG_COEX,
1727 				"[BTCoex], bt inq/page +  wifi hi-pri task\n");
1728 			table_case = 15;
1729 
1730 			if (coex_stat->bt_profile_num > 0)
1731 				tdma_case = 10;
1732 			else if (coex_stat->wl_hi_pri_task1)
1733 				tdma_case = 6;
1734 			else if (!coex_stat->bt_page)
1735 				tdma_case = 8;
1736 			else
1737 				tdma_case = 9;
1738 		} else if (coex_stat->wl_gl_busy) {
1739 			rtw_dbg(rtwdev, RTW_DBG_COEX,
1740 				"[BTCoex], bt inq/page + wifi busy\n");
1741 			if (coex_stat->bt_profile_num == 0) {
1742 				table_case = 12;
1743 				tdma_case = 18;
1744 			} else if (coex_stat->bt_profile_num == 1 &&
1745 				   !coex_stat->bt_a2dp_exist) {
1746 				slot_type = TDMA_4SLOT;
1747 				table_case = 12;
1748 				tdma_case = 20;
1749 			} else {
1750 				slot_type = TDMA_4SLOT;
1751 				table_case = 12;
1752 				tdma_case = 26;
1753 			}
1754 		} else if (coex_stat->wl_connected) {
1755 			rtw_dbg(rtwdev, RTW_DBG_COEX,
1756 				"[BTCoex], bt inq/page + wifi connected\n");
1757 			table_case = 9;
1758 			tdma_case = 27;
1759 		} else {
1760 			rtw_dbg(rtwdev, RTW_DBG_COEX,
1761 				"[BTCoex], bt inq/page + wifi not-connected\n");
1762 			table_case = 1;
1763 			tdma_case = 0;
1764 		}
1765 	} else {
1766 		/* Non_Shared-Ant */
1767 		if (wl_hi_pri) {
1768 			rtw_dbg(rtwdev, RTW_DBG_COEX,
1769 				"[BTCoex], bt inq/page +  wifi hi-pri task\n");
1770 			table_case = 114;
1771 
1772 			if (coex_stat->bt_profile_num > 0)
1773 				tdma_case = 110;
1774 			else if (coex_stat->wl_hi_pri_task1)
1775 				tdma_case = 106;
1776 			else if (!coex_stat->bt_page)
1777 				tdma_case = 108;
1778 			else
1779 				tdma_case = 109;
1780 		}  else if (coex_stat->wl_gl_busy) {
1781 			rtw_dbg(rtwdev, RTW_DBG_COEX,
1782 				"[BTCoex], bt inq/page + wifi busy\n");
1783 			table_case = 114;
1784 			tdma_case = 121;
1785 		} else if (coex_stat->wl_connected) {
1786 			rtw_dbg(rtwdev, RTW_DBG_COEX,
1787 				"[BTCoex], bt inq/page +  wifi connected\n");
1788 			table_case = 101;
1789 			tdma_case = 100;
1790 		} else {
1791 			rtw_dbg(rtwdev, RTW_DBG_COEX,
1792 				"[BTCoex], bt inq/page +  wifi not-connected\n");
1793 			table_case = 101;
1794 			tdma_case = 100;
1795 		}
1796 	}
1797 
1798 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], wifi hi(%d), bt page(%d)\n",
1799 		wl_hi_pri, coex_stat->bt_page);
1800 
1801 	rtw_coex_table(rtwdev, false, table_case);
1802 	rtw_coex_tdma(rtwdev, false, tdma_case | slot_type);
1803 }
1804 
rtw_coex_action_bt_hfp(struct rtw_dev * rtwdev)1805 static void rtw_coex_action_bt_hfp(struct rtw_dev *rtwdev)
1806 {
1807 	struct rtw_coex *coex = &rtwdev->coex;
1808 	struct rtw_coex_stat *coex_stat = &coex->stat;
1809 	struct rtw_efuse *efuse = &rtwdev->efuse;
1810 	struct rtw_chip_info *chip = rtwdev->chip;
1811 	u8 table_case, tdma_case;
1812 
1813 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
1814 	rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
1815 	rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
1816 
1817 	if (efuse->share_ant) {
1818 		/* Shared-Ant */
1819 		if (coex_stat->bt_multi_link) {
1820 			table_case = 10;
1821 			tdma_case = 17;
1822 		} else {
1823 			table_case = 10;
1824 			tdma_case = 5;
1825 		}
1826 	} else {
1827 		/* Non-Shared-Ant */
1828 		if (coex_stat->bt_multi_link) {
1829 			table_case = 112;
1830 			tdma_case = 117;
1831 		} else {
1832 			table_case = 105;
1833 			tdma_case = 100;
1834 		}
1835 	}
1836 
1837 	rtw_coex_table(rtwdev, false, table_case);
1838 	rtw_coex_tdma(rtwdev, false, tdma_case);
1839 }
1840 
rtw_coex_action_bt_hid(struct rtw_dev * rtwdev)1841 static void rtw_coex_action_bt_hid(struct rtw_dev *rtwdev)
1842 {
1843 	struct rtw_coex *coex = &rtwdev->coex;
1844 	struct rtw_coex_stat *coex_stat = &coex->stat;
1845 	struct rtw_efuse *efuse = &rtwdev->efuse;
1846 	struct rtw_chip_info *chip = rtwdev->chip;
1847 	u8 table_case, tdma_case;
1848 	u32 slot_type = 0;
1849 	bool bt_multi_link_remain = false, is_toggle_table = false;
1850 
1851 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
1852 	rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
1853 	rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
1854 
1855 	if (efuse->share_ant) {
1856 		/* Shared-Ant */
1857 		if (coex_stat->bt_ble_exist) {
1858 			/* RCU */
1859 			if (coex_stat->cnt_wl[COEX_CNT_WL_SCANAP] > 5) {
1860 				table_case = 26;
1861 				tdma_case = 2;
1862 			} else {
1863 				table_case = 27;
1864 				tdma_case = 9;
1865 			}
1866 		} else {
1867 			/* Legacy HID  */
1868 			if (coex_stat->bt_profile_num == 1 &&
1869 			    (coex_stat->bt_multi_link ||
1870 			    (coex_stat->lo_pri_rx +
1871 			     coex_stat->lo_pri_tx > 360) ||
1872 			     coex_stat->bt_slave ||
1873 			     bt_multi_link_remain)) {
1874 				slot_type = TDMA_4SLOT;
1875 				table_case = 12;
1876 				tdma_case = 20;
1877 			} else if (coex_stat->bt_a2dp_active) {
1878 				table_case = 9;
1879 				tdma_case = 18;
1880 			} else if (coex_stat->bt_418_hid_exist &&
1881 				   coex_stat->wl_gl_busy) {
1882 				is_toggle_table = true;
1883 				slot_type = TDMA_4SLOT;
1884 				table_case = 9;
1885 				tdma_case = 24;
1886 			} else if (coex_stat->bt_ble_hid_exist &&
1887 				   coex_stat->wl_gl_busy) {
1888 				table_case = 32;
1889 				tdma_case = 9;
1890 			} else {
1891 				table_case = 9;
1892 				tdma_case = 9;
1893 			}
1894 		}
1895 	} else {
1896 		/* Non-Shared-Ant */
1897 		if (coex_stat->bt_ble_exist) {
1898 			/* BLE */
1899 			if (coex_stat->cnt_wl[COEX_CNT_WL_SCANAP] > 5) {
1900 				table_case = 121;
1901 				tdma_case = 102;
1902 			} else {
1903 				table_case = 122;
1904 				tdma_case = 109;
1905 			}
1906 		} else if (coex_stat->bt_a2dp_active) {
1907 			table_case = 113;
1908 			tdma_case = 118;
1909 		} else {
1910 			table_case = 113;
1911 			tdma_case = 104;
1912 		}
1913 	}
1914 
1915 	rtw_coex_table(rtwdev, false, table_case);
1916 	if (is_toggle_table) {
1917 		rtw_btc_wltoggle_table_a(rtwdev, true, table_case);
1918 		rtw_btc_wltoggle_table_b(rtwdev, false, 1, COEX_WL_SLOT_TOGLLE);
1919 	}
1920 
1921 	rtw_coex_tdma(rtwdev, false, tdma_case | slot_type);
1922 }
1923 
rtw_coex_action_bt_a2dp(struct rtw_dev * rtwdev)1924 static void rtw_coex_action_bt_a2dp(struct rtw_dev *rtwdev)
1925 {
1926 	struct rtw_coex *coex = &rtwdev->coex;
1927 	struct rtw_coex_stat *coex_stat = &coex->stat;
1928 	struct rtw_coex_dm *coex_dm = &coex->dm;
1929 	struct rtw_efuse *efuse = &rtwdev->efuse;
1930 	struct rtw_chip_info *chip = rtwdev->chip;
1931 	u8 table_case, tdma_case;
1932 	u32 slot_type = 0;
1933 
1934 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
1935 
1936 	rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
1937 	rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
1938 
1939 	slot_type = TDMA_4SLOT;
1940 
1941 	if (efuse->share_ant) {
1942 		/* Shared-Ant */
1943 		if (coex_stat->wl_gl_busy && coex_stat->wl_noisy_level == 0)
1944 			table_case = 12;
1945 		else
1946 			table_case = 9;
1947 
1948 		if (coex_stat->wl_connecting || !coex_stat->wl_gl_busy)
1949 			tdma_case = 14;
1950 		else
1951 			tdma_case = 13;
1952 	} else {
1953 		/* Non-Shared-Ant */
1954 		table_case = 112;
1955 
1956 		if (COEX_RSSI_HIGH(coex_dm->wl_rssi_state[1]))
1957 			tdma_case = 112;
1958 		else
1959 			tdma_case = 113;
1960 	}
1961 
1962 	rtw_coex_table(rtwdev, false, table_case);
1963 	rtw_coex_tdma(rtwdev, false, tdma_case | slot_type);
1964 }
1965 
rtw_coex_action_bt_a2dpsink(struct rtw_dev * rtwdev)1966 static void rtw_coex_action_bt_a2dpsink(struct rtw_dev *rtwdev)
1967 {
1968 	struct rtw_coex *coex = &rtwdev->coex;
1969 	struct rtw_coex_stat *coex_stat = &coex->stat;
1970 	struct rtw_efuse *efuse = &rtwdev->efuse;
1971 	struct rtw_chip_info *chip = rtwdev->chip;
1972 	u8 table_case, tdma_case;
1973 	bool ap_enable = false;
1974 
1975 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
1976 
1977 	rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
1978 	rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
1979 
1980 	if (efuse->share_ant) { /* Shared-Ant */
1981 		if (ap_enable) {
1982 			table_case = 2;
1983 			tdma_case = 0;
1984 		} else if (coex_stat->wl_gl_busy) {
1985 			table_case = 28;
1986 			tdma_case = 20;
1987 		} else {
1988 			table_case = 28;
1989 			tdma_case = 26;
1990 		}
1991 	} else { /* Non-Shared-Ant */
1992 		if (ap_enable) {
1993 			table_case = 100;
1994 			tdma_case = 100;
1995 		} else {
1996 			table_case = 119;
1997 			tdma_case = 120;
1998 		}
1999 	}
2000 
2001 	rtw_coex_table(rtwdev, false, table_case);
2002 	rtw_coex_tdma(rtwdev, false, tdma_case);
2003 }
2004 
rtw_coex_action_bt_pan(struct rtw_dev * rtwdev)2005 static void rtw_coex_action_bt_pan(struct rtw_dev *rtwdev)
2006 {
2007 	struct rtw_coex *coex = &rtwdev->coex;
2008 	struct rtw_coex_stat *coex_stat = &coex->stat;
2009 	struct rtw_efuse *efuse = &rtwdev->efuse;
2010 	struct rtw_chip_info *chip = rtwdev->chip;
2011 	u8 table_case, tdma_case;
2012 
2013 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
2014 	rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
2015 	rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
2016 
2017 	if (efuse->share_ant) {
2018 		/* Shared-Ant */
2019 		if (coex_stat->wl_gl_busy && coex_stat->wl_noisy_level == 0)
2020 			table_case = 14;
2021 		else
2022 			table_case = 10;
2023 
2024 		if (coex_stat->wl_gl_busy)
2025 			tdma_case = 17;
2026 		else
2027 			tdma_case = 20;
2028 	} else {
2029 		/* Non-Shared-Ant */
2030 		table_case = 112;
2031 
2032 		if (coex_stat->wl_gl_busy)
2033 			tdma_case = 117;
2034 		else
2035 			tdma_case = 119;
2036 	}
2037 
2038 	rtw_coex_table(rtwdev, false, table_case);
2039 	rtw_coex_tdma(rtwdev, false, tdma_case);
2040 }
2041 
rtw_coex_action_bt_a2dp_hid(struct rtw_dev * rtwdev)2042 static void rtw_coex_action_bt_a2dp_hid(struct rtw_dev *rtwdev)
2043 {
2044 	struct rtw_coex *coex = &rtwdev->coex;
2045 	struct rtw_coex_stat *coex_stat = &coex->stat;
2046 	struct rtw_coex_dm *coex_dm = &coex->dm;
2047 	struct rtw_efuse *efuse = &rtwdev->efuse;
2048 	struct rtw_chip_info *chip = rtwdev->chip;
2049 	u8 table_case, tdma_case, interval = 0;
2050 	u32 slot_type = 0;
2051 	bool is_toggle_table = false;
2052 
2053 	slot_type = TDMA_4SLOT;
2054 
2055 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
2056 	rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
2057 	rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
2058 
2059 	if (efuse->share_ant) {
2060 		/* Shared-Ant */
2061 		if (coex_stat->bt_ble_exist) {
2062 			table_case = 26; /* for RCU */
2063 		} else if (coex_stat->bt_418_hid_exist) {
2064 			table_case = 9;
2065 			interval = 1;
2066 		} else {
2067 			table_case = 9;
2068 		}
2069 
2070 		if (coex_stat->wl_connecting || !coex_stat->wl_gl_busy) {
2071 			tdma_case = 14;
2072 		} else if (coex_stat->bt_418_hid_exist) {
2073 			is_toggle_table = true;
2074 			tdma_case = 23;
2075 		} else {
2076 			tdma_case = 13;
2077 		}
2078 	} else {
2079 		/* Non-Shared-Ant */
2080 		if (coex_stat->bt_ble_exist)
2081 			table_case = 121;
2082 		else
2083 			table_case = 113;
2084 
2085 		if (COEX_RSSI_HIGH(coex_dm->wl_rssi_state[1]))
2086 			tdma_case = 112;
2087 		else
2088 			tdma_case = 113;
2089 	}
2090 
2091 	rtw_coex_table(rtwdev, false, table_case);
2092 	if (is_toggle_table) {
2093 		rtw_btc_wltoggle_table_a(rtwdev, true, table_case);
2094 		rtw_btc_wltoggle_table_b(rtwdev, false, interval, COEX_WL_SLOT_TOGLLE);
2095 	}
2096 	rtw_coex_tdma(rtwdev, false, tdma_case | slot_type);
2097 }
2098 
rtw_coex_action_bt_a2dp_pan(struct rtw_dev * rtwdev)2099 static void rtw_coex_action_bt_a2dp_pan(struct rtw_dev *rtwdev)
2100 {
2101 	struct rtw_coex *coex = &rtwdev->coex;
2102 	struct rtw_coex_stat *coex_stat = &coex->stat;
2103 	struct rtw_efuse *efuse = &rtwdev->efuse;
2104 	struct rtw_chip_info *chip = rtwdev->chip;
2105 	u8 table_case, tdma_case;
2106 	bool wl_cpt_test = false, bt_cpt_test = false;
2107 
2108 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
2109 
2110 	rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
2111 	rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
2112 	if (efuse->share_ant) {
2113 		/* Shared-Ant */
2114 		if (wl_cpt_test) {
2115 			if (coex_stat->wl_gl_busy) {
2116 				table_case = 20;
2117 				tdma_case = 17;
2118 			} else {
2119 				table_case = 10;
2120 				tdma_case = 15;
2121 			}
2122 		} else if (bt_cpt_test) {
2123 			table_case = 26;
2124 			tdma_case = 26;
2125 		} else {
2126 			if (coex_stat->wl_gl_busy &&
2127 			    coex_stat->wl_noisy_level == 0)
2128 				table_case = 14;
2129 			else
2130 				table_case = 10;
2131 
2132 			if (coex_stat->wl_gl_busy)
2133 				tdma_case = 15;
2134 			else
2135 				tdma_case = 20;
2136 		}
2137 	} else {
2138 		/* Non-Shared-Ant */
2139 		table_case = 112;
2140 
2141 		if (coex_stat->wl_gl_busy)
2142 			tdma_case = 115;
2143 		else
2144 			tdma_case = 120;
2145 	}
2146 
2147 	if (wl_cpt_test)
2148 		rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[1]);
2149 	else
2150 		rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
2151 
2152 	rtw_coex_table(rtwdev, false, table_case);
2153 	rtw_coex_tdma(rtwdev, false, tdma_case);
2154 }
2155 
rtw_coex_action_bt_pan_hid(struct rtw_dev * rtwdev)2156 static void rtw_coex_action_bt_pan_hid(struct rtw_dev *rtwdev)
2157 {
2158 	struct rtw_coex *coex = &rtwdev->coex;
2159 	struct rtw_coex_stat *coex_stat = &coex->stat;
2160 	struct rtw_efuse *efuse = &rtwdev->efuse;
2161 	struct rtw_chip_info *chip = rtwdev->chip;
2162 	u8 table_case, tdma_case;
2163 
2164 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
2165 
2166 	rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
2167 	rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
2168 
2169 	if (efuse->share_ant) {
2170 		/* Shared-Ant */
2171 		table_case = 9;
2172 
2173 		if (coex_stat->wl_gl_busy)
2174 			tdma_case = 18;
2175 		else
2176 			tdma_case = 19;
2177 	} else {
2178 		/* Non-Shared-Ant */
2179 		table_case = 113;
2180 
2181 		if (coex_stat->wl_gl_busy)
2182 			tdma_case = 117;
2183 		else
2184 			tdma_case = 119;
2185 	}
2186 
2187 	rtw_coex_table(rtwdev, false, table_case);
2188 	rtw_coex_tdma(rtwdev, false, tdma_case);
2189 }
2190 
rtw_coex_action_bt_a2dp_pan_hid(struct rtw_dev * rtwdev)2191 static void rtw_coex_action_bt_a2dp_pan_hid(struct rtw_dev *rtwdev)
2192 {
2193 	struct rtw_coex *coex = &rtwdev->coex;
2194 	struct rtw_coex_stat *coex_stat = &coex->stat;
2195 	struct rtw_efuse *efuse = &rtwdev->efuse;
2196 	struct rtw_chip_info *chip = rtwdev->chip;
2197 	u8 table_case, tdma_case;
2198 
2199 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
2200 	rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
2201 	rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
2202 
2203 	if (efuse->share_ant) {
2204 		/* Shared-Ant */
2205 		table_case = 10;
2206 
2207 		if (coex_stat->wl_gl_busy)
2208 			tdma_case = 15;
2209 		else
2210 			tdma_case = 20;
2211 	} else {
2212 		/* Non-Shared-Ant */
2213 		table_case = 113;
2214 
2215 		if (coex_stat->wl_gl_busy)
2216 			tdma_case = 115;
2217 		else
2218 			tdma_case = 120;
2219 	}
2220 
2221 	rtw_coex_table(rtwdev, false, table_case);
2222 	rtw_coex_tdma(rtwdev, false, tdma_case);
2223 }
2224 
rtw_coex_action_wl_under5g(struct rtw_dev * rtwdev)2225 static void rtw_coex_action_wl_under5g(struct rtw_dev *rtwdev)
2226 {
2227 	struct rtw_efuse *efuse = &rtwdev->efuse;
2228 	struct rtw_chip_info *chip = rtwdev->chip;
2229 	u8 table_case, tdma_case;
2230 
2231 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
2232 
2233 	rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_5G);
2234 	rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
2235 
2236 	rtw_coex_write_scbd(rtwdev, COEX_SCBD_FIX2M, false);
2237 
2238 	if (efuse->share_ant) {
2239 		/* Shared-Ant */
2240 		table_case = 0;
2241 		tdma_case = 0;
2242 	} else {
2243 		/* Non-Shared-Ant */
2244 		table_case = 100;
2245 		tdma_case = 100;
2246 	}
2247 
2248 	rtw_coex_table(rtwdev, false, table_case);
2249 	rtw_coex_tdma(rtwdev, false, tdma_case);
2250 }
2251 
rtw_coex_action_wl_only(struct rtw_dev * rtwdev)2252 static void rtw_coex_action_wl_only(struct rtw_dev *rtwdev)
2253 {
2254 	struct rtw_efuse *efuse = &rtwdev->efuse;
2255 	struct rtw_chip_info *chip = rtwdev->chip;
2256 	u8 table_case, tdma_case;
2257 
2258 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
2259 	rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
2260 	rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
2261 
2262 	if (efuse->share_ant) {
2263 		/* Shared-Ant */
2264 		table_case = 2;
2265 		tdma_case = 0;
2266 	} else {
2267 		/* Non-Shared-Ant */
2268 		table_case = 100;
2269 		tdma_case = 100;
2270 	}
2271 
2272 	rtw_coex_table(rtwdev, false, table_case);
2273 	rtw_coex_tdma(rtwdev, false, tdma_case);
2274 }
2275 
rtw_coex_action_wl_native_lps(struct rtw_dev * rtwdev)2276 static void rtw_coex_action_wl_native_lps(struct rtw_dev *rtwdev)
2277 {
2278 	struct rtw_coex *coex = &rtwdev->coex;
2279 	struct rtw_efuse *efuse = &rtwdev->efuse;
2280 	struct rtw_chip_info *chip = rtwdev->chip;
2281 	u8 table_case, tdma_case;
2282 
2283 	if (coex->under_5g)
2284 		return;
2285 
2286 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
2287 
2288 	rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
2289 	rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
2290 
2291 	if (efuse->share_ant) {
2292 		/* Shared-Ant */
2293 		table_case = 28;
2294 		tdma_case = 0;
2295 	} else {
2296 		/* Non-Shared-Ant */
2297 		table_case = 100;
2298 		tdma_case = 100;
2299 	}
2300 
2301 	rtw_coex_table(rtwdev, false, table_case);
2302 	rtw_coex_tdma(rtwdev, false, tdma_case);
2303 }
2304 
rtw_coex_action_wl_linkscan(struct rtw_dev * rtwdev)2305 static void rtw_coex_action_wl_linkscan(struct rtw_dev *rtwdev)
2306 {
2307 	struct rtw_coex *coex = &rtwdev->coex;
2308 	struct rtw_coex_stat *coex_stat = &coex->stat;
2309 	struct rtw_efuse *efuse = &rtwdev->efuse;
2310 	struct rtw_chip_info *chip = rtwdev->chip;
2311 	u8 table_case, tdma_case;
2312 	u32 slot_type = 0;
2313 
2314 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
2315 	rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
2316 	rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
2317 
2318 	if (efuse->share_ant) { /* Shared-Ant */
2319 		if (coex_stat->bt_a2dp_exist) {
2320 			slot_type = TDMA_4SLOT;
2321 			tdma_case = 11;
2322 			if (coex_stat->wl_gl_busy)
2323 				table_case = 26;
2324 			else
2325 				table_case = 9;
2326 		} else {
2327 			table_case = 9;
2328 			tdma_case = 7;
2329 		}
2330 	} else { /* Non-Shared-Ant */
2331 		if (coex_stat->bt_a2dp_exist) {
2332 			slot_type = TDMA_4SLOT;
2333 			table_case = 112;
2334 			tdma_case = 111;
2335 		} else {
2336 			table_case = 112;
2337 			tdma_case = 107;
2338 		}
2339 	}
2340 
2341 	rtw_coex_table(rtwdev, false, table_case);
2342 	rtw_coex_tdma(rtwdev, false, tdma_case | slot_type);
2343 }
2344 
rtw_coex_action_wl_not_connected(struct rtw_dev * rtwdev)2345 static void rtw_coex_action_wl_not_connected(struct rtw_dev *rtwdev)
2346 {
2347 	struct rtw_efuse *efuse = &rtwdev->efuse;
2348 	struct rtw_chip_info *chip = rtwdev->chip;
2349 	u8 table_case, tdma_case;
2350 
2351 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
2352 	rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
2353 	rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
2354 
2355 	if (efuse->share_ant) {
2356 		/* Shared-Ant */
2357 		table_case = 1;
2358 		tdma_case = 0;
2359 	} else {
2360 		/* Non-Shared-Ant */
2361 		table_case = 100;
2362 		tdma_case = 100;
2363 	}
2364 
2365 	rtw_coex_table(rtwdev, false, table_case);
2366 	rtw_coex_tdma(rtwdev, false, tdma_case);
2367 }
2368 
rtw_coex_action_wl_connected(struct rtw_dev * rtwdev)2369 static void rtw_coex_action_wl_connected(struct rtw_dev *rtwdev)
2370 {
2371 	struct rtw_coex *coex = &rtwdev->coex;
2372 	struct rtw_coex_stat *coex_stat = &coex->stat;
2373 	u8 algorithm;
2374 
2375 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
2376 
2377 	algorithm = rtw_coex_algorithm(rtwdev);
2378 
2379 	switch (algorithm) {
2380 	case COEX_ALGO_HFP:
2381 		rtw_coex_action_bt_hfp(rtwdev);
2382 		break;
2383 	case COEX_ALGO_HID:
2384 		if (rtw_coex_freerun_check(rtwdev))
2385 			rtw_coex_action_freerun(rtwdev);
2386 		else
2387 			rtw_coex_action_bt_hid(rtwdev);
2388 		break;
2389 	case COEX_ALGO_A2DP:
2390 		if (rtw_coex_freerun_check(rtwdev))
2391 			rtw_coex_action_freerun(rtwdev);
2392 		else if (coex_stat->bt_a2dp_sink)
2393 			rtw_coex_action_bt_a2dpsink(rtwdev);
2394 		else
2395 			rtw_coex_action_bt_a2dp(rtwdev);
2396 		break;
2397 	case COEX_ALGO_PAN:
2398 		rtw_coex_action_bt_pan(rtwdev);
2399 		break;
2400 	case COEX_ALGO_A2DP_HID:
2401 		if (rtw_coex_freerun_check(rtwdev))
2402 			rtw_coex_action_freerun(rtwdev);
2403 		else
2404 			rtw_coex_action_bt_a2dp_hid(rtwdev);
2405 		break;
2406 	case COEX_ALGO_A2DP_PAN:
2407 		rtw_coex_action_bt_a2dp_pan(rtwdev);
2408 		break;
2409 	case COEX_ALGO_PAN_HID:
2410 		rtw_coex_action_bt_pan_hid(rtwdev);
2411 		break;
2412 	case COEX_ALGO_A2DP_PAN_HID:
2413 		rtw_coex_action_bt_a2dp_pan_hid(rtwdev);
2414 		break;
2415 	default:
2416 	case COEX_ALGO_NOPROFILE:
2417 		rtw_coex_action_bt_idle(rtwdev);
2418 		break;
2419 	}
2420 }
2421 
rtw_coex_run_coex(struct rtw_dev * rtwdev,u8 reason)2422 static void rtw_coex_run_coex(struct rtw_dev *rtwdev, u8 reason)
2423 {
2424 	struct rtw_coex *coex = &rtwdev->coex;
2425 	struct rtw_coex_dm *coex_dm = &coex->dm;
2426 	struct rtw_coex_stat *coex_stat = &coex->stat;
2427 	bool rf4ce_en = false;
2428 
2429 	lockdep_assert_held(&rtwdev->mutex);
2430 
2431 	if (!test_bit(RTW_FLAG_RUNNING, rtwdev->flags))
2432 		return;
2433 
2434 	coex_dm->reason = reason;
2435 
2436 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s(): reason = %d\n", __func__,
2437 		reason);
2438 
2439 	/* update wifi_link_info_ext variable */
2440 	rtw_coex_update_wl_link_info(rtwdev, reason);
2441 
2442 	rtw_coex_monitor_bt_enable(rtwdev);
2443 
2444 	if (coex->manual_control) {
2445 		rtw_dbg(rtwdev, RTW_DBG_COEX,
2446 			"[BTCoex], return for Manual CTRL!!\n");
2447 		return;
2448 	}
2449 
2450 	if (coex->stop_dm) {
2451 		rtw_dbg(rtwdev, RTW_DBG_COEX,
2452 			"[BTCoex], return for Stop Coex DM!!\n");
2453 		return;
2454 	}
2455 
2456 	if (coex_stat->wl_under_ips) {
2457 		rtw_dbg(rtwdev, RTW_DBG_COEX,
2458 			"[BTCoex], return for wifi is under IPS!!\n");
2459 		return;
2460 	}
2461 
2462 	if (coex->freeze && coex_dm->reason == COEX_RSN_BTINFO &&
2463 	    !coex_stat->bt_setup_link) {
2464 		rtw_dbg(rtwdev, RTW_DBG_COEX,
2465 			"[BTCoex], return for coex_freeze!!\n");
2466 		return;
2467 	}
2468 
2469 	coex_stat->cnt_wl[COEX_CNT_WL_COEXRUN]++;
2470 	coex->freerun = false;
2471 
2472 	/* Pure-5G Coex Process */
2473 	if (coex->under_5g) {
2474 		coex_stat->wl_coex_mode = COEX_WLINK_5G;
2475 		rtw_coex_action_wl_under5g(rtwdev);
2476 		goto exit;
2477 	}
2478 
2479 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], WiFi is single-port 2G!!\n");
2480 	coex_stat->wl_coex_mode = COEX_WLINK_2G1PORT;
2481 
2482 	if (coex_stat->bt_disabled) {
2483 		if (coex_stat->wl_connected && rf4ce_en)
2484 			rtw_coex_action_rf4ce(rtwdev);
2485 		else if (!coex_stat->wl_connected)
2486 			rtw_coex_action_wl_not_connected(rtwdev);
2487 		else
2488 			rtw_coex_action_wl_only(rtwdev);
2489 		goto exit;
2490 	}
2491 
2492 	if (coex_stat->wl_under_lps && !coex_stat->wl_force_lps_ctrl) {
2493 		rtw_coex_action_wl_native_lps(rtwdev);
2494 		goto exit;
2495 	}
2496 
2497 	if (coex_stat->bt_whck_test) {
2498 		rtw_coex_action_bt_whql_test(rtwdev);
2499 		goto exit;
2500 	}
2501 
2502 	if (coex_stat->bt_setup_link) {
2503 		rtw_coex_action_bt_relink(rtwdev);
2504 		goto exit;
2505 	}
2506 
2507 	if (coex_stat->bt_inq_page) {
2508 		rtw_coex_action_bt_inquiry(rtwdev);
2509 		goto exit;
2510 	}
2511 
2512 	if ((coex_dm->bt_status == COEX_BTSTATUS_NCON_IDLE ||
2513 	     coex_dm->bt_status == COEX_BTSTATUS_CON_IDLE) &&
2514 	     coex_stat->wl_connected) {
2515 		rtw_coex_action_bt_idle(rtwdev);
2516 		goto exit;
2517 	}
2518 
2519 	if (coex_stat->wl_linkscan_proc && !coex->freerun) {
2520 		rtw_coex_action_wl_linkscan(rtwdev);
2521 		goto exit;
2522 	}
2523 
2524 	if (coex_stat->wl_connected) {
2525 		rtw_coex_action_wl_connected(rtwdev);
2526 		goto exit;
2527 	} else {
2528 		rtw_coex_action_wl_not_connected(rtwdev);
2529 		goto exit;
2530 	}
2531 
2532 exit:
2533 	rtw_coex_gnt_workaround(rtwdev, false, coex_stat->wl_coex_mode);
2534 	rtw_coex_limited_wl(rtwdev);
2535 }
2536 
rtw_coex_init_coex_var(struct rtw_dev * rtwdev)2537 static void rtw_coex_init_coex_var(struct rtw_dev *rtwdev)
2538 {
2539 	struct rtw_coex *coex = &rtwdev->coex;
2540 	struct rtw_coex_stat *coex_stat = &coex->stat;
2541 	struct rtw_coex_dm *coex_dm = &coex->dm;
2542 	u8 i;
2543 
2544 	memset(coex_dm, 0, sizeof(*coex_dm));
2545 	memset(coex_stat, 0, sizeof(*coex_stat));
2546 
2547 	for (i = 0; i < COEX_CNT_WL_MAX; i++)
2548 		coex_stat->cnt_wl[i] = 0;
2549 
2550 	for (i = 0; i < COEX_CNT_BT_MAX; i++)
2551 		coex_stat->cnt_bt[i] = 0;
2552 
2553 	for (i = 0; i < ARRAY_SIZE(coex_dm->bt_rssi_state); i++)
2554 		coex_dm->bt_rssi_state[i] = COEX_RSSI_STATE_LOW;
2555 
2556 	for (i = 0; i < ARRAY_SIZE(coex_dm->wl_rssi_state); i++)
2557 		coex_dm->wl_rssi_state[i] = COEX_RSSI_STATE_LOW;
2558 
2559 	coex_stat->wl_coex_mode = COEX_WLINK_MAX;
2560 	coex_stat->wl_rx_rate = DESC_RATE5_5M;
2561 	coex_stat->wl_rts_rx_rate = DESC_RATE5_5M;
2562 }
2563 
__rtw_coex_init_hw_config(struct rtw_dev * rtwdev,bool wifi_only)2564 static void __rtw_coex_init_hw_config(struct rtw_dev *rtwdev, bool wifi_only)
2565 {
2566 	struct rtw_coex *coex = &rtwdev->coex;
2567 	struct rtw_coex_stat *coex_stat = &coex->stat;
2568 
2569 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
2570 
2571 	rtw_coex_init_coex_var(rtwdev);
2572 
2573 	coex_stat->kt_ver = u8_get_bits(rtw_read8(rtwdev, 0xf1), GENMASK(7, 4));
2574 
2575 	rtw_coex_monitor_bt_enable(rtwdev);
2576 	rtw_coex_wl_slot_extend(rtwdev, coex_stat->wl_slot_extend);
2577 
2578 	rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION);
2579 
2580 	rtw_coex_set_rfe_type(rtwdev);
2581 	rtw_coex_set_init(rtwdev);
2582 
2583 	/* set Tx response = Hi-Pri (ex: Transmitting ACK,BA,CTS) */
2584 	rtw_coex_set_wl_pri_mask(rtwdev, COEX_WLPRI_TX_RSP, 1);
2585 
2586 	/* set Tx beacon = Hi-Pri */
2587 	rtw_coex_set_wl_pri_mask(rtwdev, COEX_WLPRI_TX_BEACON, 1);
2588 
2589 	/* set Tx beacon queue = Hi-Pri */
2590 	rtw_coex_set_wl_pri_mask(rtwdev, COEX_WLPRI_TX_BEACONQ, 1);
2591 
2592 	/* antenna config */
2593 	if (coex->wl_rf_off) {
2594 		rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_WOFF);
2595 		rtw_coex_write_scbd(rtwdev, COEX_SCBD_ALL, false);
2596 		coex->stop_dm = true;
2597 
2598 		rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s(): RF Off\n",
2599 			__func__);
2600 	} else if (wifi_only) {
2601 		rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_WONLY);
2602 		rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE | COEX_SCBD_ONOFF,
2603 				    true);
2604 		coex->stop_dm = true;
2605 	} else {
2606 		rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_INIT);
2607 		rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE | COEX_SCBD_ONOFF,
2608 				    true);
2609 		coex->stop_dm = false;
2610 		coex->freeze = true;
2611 	}
2612 
2613 	/* PTA parameter */
2614 	rtw_coex_table(rtwdev, true, 1);
2615 	rtw_coex_tdma(rtwdev, true, 0);
2616 	rtw_coex_query_bt_info(rtwdev);
2617 }
2618 
rtw_coex_power_on_setting(struct rtw_dev * rtwdev)2619 void rtw_coex_power_on_setting(struct rtw_dev *rtwdev)
2620 {
2621 	struct rtw_coex *coex = &rtwdev->coex;
2622 	u8 table_case = 1;
2623 
2624 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
2625 
2626 	coex->stop_dm = true;
2627 	coex->wl_rf_off = false;
2628 
2629 	/* enable BB, we can write 0x948 */
2630 	rtw_write8_set(rtwdev, REG_SYS_FUNC_EN,
2631 		       BIT_FEN_BB_GLB_RST | BIT_FEN_BB_RSTB);
2632 
2633 	rtw_coex_monitor_bt_enable(rtwdev);
2634 	rtw_coex_set_rfe_type(rtwdev);
2635 
2636 	/* set antenna path to BT */
2637 	rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_POWERON);
2638 
2639 	rtw_coex_table(rtwdev, true, table_case);
2640 	/* red x issue */
2641 	rtw_write8(rtwdev, 0xff1a, 0x0);
2642 	rtw_coex_set_gnt_debug(rtwdev);
2643 }
2644 
rtw_coex_power_off_setting(struct rtw_dev * rtwdev)2645 void rtw_coex_power_off_setting(struct rtw_dev *rtwdev)
2646 {
2647 	rtw_write16(rtwdev, REG_WIFI_BT_INFO, BIT_BT_INT_EN);
2648 }
2649 
rtw_coex_init_hw_config(struct rtw_dev * rtwdev,bool wifi_only)2650 void rtw_coex_init_hw_config(struct rtw_dev *rtwdev, bool wifi_only)
2651 {
2652 	__rtw_coex_init_hw_config(rtwdev, wifi_only);
2653 }
2654 
rtw_coex_ips_notify(struct rtw_dev * rtwdev,u8 type)2655 void rtw_coex_ips_notify(struct rtw_dev *rtwdev, u8 type)
2656 {
2657 	struct rtw_coex *coex = &rtwdev->coex;
2658 	struct rtw_coex_stat *coex_stat = &coex->stat;
2659 
2660 	if (coex->manual_control || coex->stop_dm)
2661 		return;
2662 
2663 	if (type == COEX_IPS_ENTER) {
2664 		rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], IPS ENTER notify\n");
2665 
2666 		coex_stat->wl_under_ips = true;
2667 
2668 		/* for lps off */
2669 		rtw_coex_write_scbd(rtwdev, COEX_SCBD_ALL, false);
2670 
2671 		rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_WOFF);
2672 		rtw_coex_action_coex_all_off(rtwdev);
2673 	} else if (type == COEX_IPS_LEAVE) {
2674 		rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], IPS LEAVE notify\n");
2675 
2676 		rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE | COEX_SCBD_ONOFF, true);
2677 		/* run init hw config (exclude wifi only) */
2678 		__rtw_coex_init_hw_config(rtwdev, false);
2679 
2680 		coex_stat->wl_under_ips = false;
2681 	}
2682 }
2683 
rtw_coex_lps_notify(struct rtw_dev * rtwdev,u8 type)2684 void rtw_coex_lps_notify(struct rtw_dev *rtwdev, u8 type)
2685 {
2686 	struct rtw_coex *coex = &rtwdev->coex;
2687 	struct rtw_coex_stat *coex_stat = &coex->stat;
2688 
2689 	if (coex->manual_control || coex->stop_dm)
2690 		return;
2691 
2692 	if (type == COEX_LPS_ENABLE) {
2693 		rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], LPS ENABLE notify\n");
2694 
2695 		coex_stat->wl_under_lps = true;
2696 
2697 		if (coex_stat->wl_force_lps_ctrl) {
2698 			/* for ps-tdma */
2699 			rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE, true);
2700 		} else {
2701 			/* for native ps */
2702 			rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE, false);
2703 			rtw_coex_write_scbd(rtwdev, COEX_SCBD_WLBUSY, false);
2704 
2705 			rtw_coex_run_coex(rtwdev, COEX_RSN_LPS);
2706 		}
2707 	} else if (type == COEX_LPS_DISABLE) {
2708 		rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], LPS DISABLE notify\n");
2709 
2710 		coex_stat->wl_under_lps = false;
2711 
2712 		/* for lps off */
2713 		rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE, true);
2714 
2715 		if (!coex_stat->wl_force_lps_ctrl)
2716 			rtw_coex_query_bt_info(rtwdev);
2717 
2718 		rtw_coex_run_coex(rtwdev, COEX_RSN_LPS);
2719 	}
2720 }
2721 
rtw_coex_scan_notify(struct rtw_dev * rtwdev,u8 type)2722 void rtw_coex_scan_notify(struct rtw_dev *rtwdev, u8 type)
2723 {
2724 	struct rtw_coex *coex = &rtwdev->coex;
2725 	struct rtw_coex_stat *coex_stat = &coex->stat;
2726 
2727 	if (coex->manual_control || coex->stop_dm)
2728 		return;
2729 
2730 	coex->freeze = false;
2731 	rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE | COEX_SCBD_ONOFF, true);
2732 
2733 	if (type == COEX_SCAN_START_5G) {
2734 		rtw_dbg(rtwdev, RTW_DBG_COEX,
2735 			"[BTCoex], SCAN START notify (5G)\n");
2736 
2737 		rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_5G);
2738 		rtw_coex_run_coex(rtwdev, COEX_RSN_5GSCANSTART);
2739 	} else if ((type == COEX_SCAN_START_2G) || (type == COEX_SCAN_START)) {
2740 		rtw_dbg(rtwdev, RTW_DBG_COEX,
2741 			"[BTCoex], SCAN START notify (2G)\n");
2742 
2743 		coex_stat->wl_hi_pri_task2 = true;
2744 
2745 		/* Force antenna setup for no scan result issue */
2746 		rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_2G);
2747 		rtw_coex_run_coex(rtwdev, COEX_RSN_2GSCANSTART);
2748 	} else {
2749 		coex_stat->cnt_wl[COEX_CNT_WL_SCANAP] = 30; /* To do */
2750 
2751 		rtw_dbg(rtwdev, RTW_DBG_COEX,
2752 			"[BTCoex], SCAN FINISH notify (Scan-AP = %d)\n",
2753 			coex_stat->cnt_wl[COEX_CNT_WL_SCANAP]);
2754 
2755 		coex_stat->wl_hi_pri_task2 = false;
2756 		rtw_coex_run_coex(rtwdev, COEX_RSN_SCANFINISH);
2757 	}
2758 }
2759 
rtw_coex_switchband_notify(struct rtw_dev * rtwdev,u8 type)2760 void rtw_coex_switchband_notify(struct rtw_dev *rtwdev, u8 type)
2761 {
2762 	struct rtw_coex *coex = &rtwdev->coex;
2763 
2764 	if (coex->manual_control || coex->stop_dm)
2765 		return;
2766 
2767 	if (type == COEX_SWITCH_TO_5G) {
2768 		rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s(): TO_5G\n",
2769 			__func__);
2770 	} else if (type == COEX_SWITCH_TO_24G_NOFORSCAN) {
2771 		rtw_dbg(rtwdev, RTW_DBG_COEX,
2772 			"[BTCoex], %s(): TO_24G_NOFORSCAN\n", __func__);
2773 	} else {
2774 		rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s(): TO_2G\n",
2775 			__func__);
2776 	}
2777 
2778 	if (type == COEX_SWITCH_TO_5G)
2779 		rtw_coex_run_coex(rtwdev, COEX_RSN_5GSWITCHBAND);
2780 	else if (type == COEX_SWITCH_TO_24G_NOFORSCAN)
2781 		rtw_coex_run_coex(rtwdev, COEX_RSN_2GSWITCHBAND);
2782 	else
2783 		rtw_coex_scan_notify(rtwdev, COEX_SCAN_START_2G);
2784 }
2785 
rtw_coex_connect_notify(struct rtw_dev * rtwdev,u8 type)2786 void rtw_coex_connect_notify(struct rtw_dev *rtwdev, u8 type)
2787 {
2788 	struct rtw_coex *coex = &rtwdev->coex;
2789 	struct rtw_coex_stat *coex_stat = &coex->stat;
2790 
2791 	if (coex->manual_control || coex->stop_dm)
2792 		return;
2793 
2794 	rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE | COEX_SCBD_ONOFF, true);
2795 
2796 	if (type == COEX_ASSOCIATE_5G_START) {
2797 		rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s(): 5G start\n",
2798 			__func__);
2799 
2800 		rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_5G);
2801 		rtw_coex_run_coex(rtwdev, COEX_RSN_5GCONSTART);
2802 	} else if (type == COEX_ASSOCIATE_5G_FINISH) {
2803 		rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s(): 5G finish\n",
2804 			__func__);
2805 
2806 		rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_5G);
2807 		rtw_coex_run_coex(rtwdev, COEX_RSN_5GCONFINISH);
2808 	} else if (type == COEX_ASSOCIATE_START) {
2809 		coex_stat->wl_hi_pri_task1 = true;
2810 		coex_stat->wl_connecting = true;
2811 		coex_stat->cnt_wl[COEX_CNT_WL_CONNPKT] = 2;
2812 		coex_stat->wl_connecting = true;
2813 		ieee80211_queue_delayed_work(rtwdev->hw,
2814 					     &coex->wl_connecting_work, 2 * HZ);
2815 
2816 		rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s(): 2G start\n",
2817 			__func__);
2818 		/* Force antenna setup for no scan result issue */
2819 		rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_2G);
2820 
2821 		rtw_coex_run_coex(rtwdev, COEX_RSN_2GCONSTART);
2822 
2823 		/* To keep TDMA case during connect process,
2824 		 * to avoid changed by Btinfo and runcoexmechanism
2825 		 */
2826 		coex->freeze = true;
2827 		ieee80211_queue_delayed_work(rtwdev->hw, &coex->defreeze_work,
2828 					     5 * HZ);
2829 	} else {
2830 		coex_stat->wl_hi_pri_task1 = false;
2831 		coex->freeze = false;
2832 		coex_stat->wl_connecting = false;
2833 
2834 		rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s(): 2G finish\n",
2835 			__func__);
2836 		rtw_coex_run_coex(rtwdev, COEX_RSN_2GCONFINISH);
2837 	}
2838 }
2839 
rtw_coex_media_status_notify(struct rtw_dev * rtwdev,u8 type)2840 void rtw_coex_media_status_notify(struct rtw_dev *rtwdev, u8 type)
2841 {
2842 	struct rtw_coex *coex = &rtwdev->coex;
2843 	struct rtw_coex_stat *coex_stat = &coex->stat;
2844 
2845 	if (coex->manual_control || coex->stop_dm)
2846 		return;
2847 
2848 	if (type == COEX_MEDIA_CONNECT_5G) {
2849 		rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s(): 5G\n", __func__);
2850 
2851 		rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE, true);
2852 
2853 		rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_5G);
2854 		rtw_coex_run_coex(rtwdev, COEX_RSN_5GMEDIA);
2855 	} else if (type == COEX_MEDIA_CONNECT) {
2856 		rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s(): 2G\n", __func__);
2857 
2858 		coex_stat->wl_connecting = false;
2859 
2860 		rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE, true);
2861 
2862 		/* Force antenna setup for no scan result issue */
2863 		rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_2G);
2864 
2865 		/* Set CCK Rx high Pri */
2866 		rtw_coex_set_wl_pri_mask(rtwdev, COEX_WLPRI_RX_CCK, 1);
2867 		rtw_coex_run_coex(rtwdev, COEX_RSN_2GMEDIA);
2868 	} else {
2869 		rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s(): disconnect!!\n",
2870 			__func__);
2871 		rtw_coex_set_wl_pri_mask(rtwdev, COEX_WLPRI_RX_CCK, 0);
2872 		rtw_coex_run_coex(rtwdev, COEX_RSN_MEDIADISCON);
2873 	}
2874 
2875 	rtw_coex_update_wl_ch_info(rtwdev, type);
2876 }
2877 
rtw_coex_bt_info_notify(struct rtw_dev * rtwdev,u8 * buf,u8 length)2878 void rtw_coex_bt_info_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length)
2879 {
2880 	struct rtw_coex *coex = &rtwdev->coex;
2881 	struct rtw_coex_stat *coex_stat = &coex->stat;
2882 	struct rtw_chip_info *chip = rtwdev->chip;
2883 	struct rtw_coex_dm *coex_dm = &coex->dm;
2884 	u32 bt_relink_time;
2885 	u8 i, rsp_source = 0, type;
2886 	bool inq_page = false;
2887 
2888 	rsp_source = buf[0] & 0xf;
2889 	if (rsp_source >= COEX_BTINFO_SRC_MAX)
2890 		return;
2891 	coex_stat->cnt_bt_info_c2h[rsp_source]++;
2892 
2893 	if (rsp_source == COEX_BTINFO_SRC_BT_IQK) {
2894 		coex_stat->bt_iqk_state = buf[1];
2895 		if (coex_stat->bt_iqk_state == 0)
2896 			coex_stat->cnt_bt[COEX_CNT_BT_IQK]++;
2897 		else if (coex_stat->bt_iqk_state == 2)
2898 			coex_stat->cnt_bt[COEX_CNT_BT_IQKFAIL]++;
2899 
2900 		rtw_dbg(rtwdev, RTW_DBG_COEX,
2901 			"[BTCoex], BT IQK by bt_info, data0 = 0x%02x\n",
2902 			buf[1]);
2903 
2904 		return;
2905 	}
2906 
2907 	if (rsp_source == COEX_BTINFO_SRC_BT_SCBD) {
2908 		rtw_dbg(rtwdev, RTW_DBG_COEX,
2909 			"[BTCoex], BT Scoreboard change notify by WL FW c2h, 0xaa = 0x%02x, 0xab = 0x%02x\n",
2910 			buf[1], buf[2]);
2911 
2912 		rtw_coex_monitor_bt_enable(rtwdev);
2913 		if (coex_stat->bt_disabled != coex_stat->bt_disabled_pre) {
2914 			coex_stat->bt_disabled_pre = coex_stat->bt_disabled;
2915 			rtw_coex_run_coex(rtwdev, COEX_RSN_BTINFO);
2916 		}
2917 		return;
2918 	}
2919 
2920 	if (rsp_source == COEX_BTINFO_SRC_H2C60) {
2921 		rtw_dbg(rtwdev, RTW_DBG_COEX,
2922 			"[BTCoex], H2C 0x60 content replied by WL FW: H2C_0x60 = [%02x %02x %02x %02x %02x]\n",
2923 			buf[1], buf[2], buf[3], buf[4], buf[5]);
2924 
2925 		for (i = 1; i <= COEX_WL_TDMA_PARA_LENGTH; i++)
2926 			coex_dm->fw_tdma_para[i - 1] = buf[i];
2927 		return;
2928 	}
2929 
2930 	if (rsp_source == COEX_BTINFO_SRC_WL_FW) {
2931 		rtw_dbg(rtwdev, RTW_DBG_COEX,
2932 			"[BTCoex], bt_info reply by WL FW\n");
2933 
2934 		rtw_coex_update_bt_link_info(rtwdev);
2935 		return;
2936 	}
2937 
2938 	if (rsp_source == COEX_BTINFO_SRC_BT_RSP ||
2939 	    rsp_source == COEX_BTINFO_SRC_BT_ACT) {
2940 		if (coex_stat->bt_disabled) {
2941 			coex_stat->bt_disabled = false;
2942 			coex_stat->bt_reenable = true;
2943 			ieee80211_queue_delayed_work(rtwdev->hw,
2944 						     &coex->bt_reenable_work,
2945 						     15 * HZ);
2946 			rtw_dbg(rtwdev, RTW_DBG_COEX,
2947 				"[BTCoex], BT enable detected by bt_info\n");
2948 		}
2949 	}
2950 
2951 	if (length != COEX_BTINFO_LENGTH) {
2952 		rtw_dbg(rtwdev, RTW_DBG_COEX,
2953 			"[BTCoex], Bt_info length = %d invalid!!\n", length);
2954 
2955 		return;
2956 	}
2957 
2958 	rtw_dbg(rtwdev, RTW_DBG_COEX,
2959 		"[BTCoex], Bt_info[%d], len=%d, data=[%02x %02x %02x %02x %02x %02x]\n",
2960 		buf[0], length, buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
2961 
2962 	for (i = 0; i < COEX_BTINFO_LENGTH; i++)
2963 		coex_stat->bt_info_c2h[rsp_source][i] = buf[i];
2964 
2965 	/* get the same info from bt, skip it */
2966 	if (coex_stat->bt_info_c2h[rsp_source][1] == coex_stat->bt_info_lb2 &&
2967 	    coex_stat->bt_info_c2h[rsp_source][2] == coex_stat->bt_info_lb3 &&
2968 	    coex_stat->bt_info_c2h[rsp_source][3] == coex_stat->bt_info_hb0 &&
2969 	    coex_stat->bt_info_c2h[rsp_source][4] == coex_stat->bt_info_hb1 &&
2970 	    coex_stat->bt_info_c2h[rsp_source][5] == coex_stat->bt_info_hb2 &&
2971 	    coex_stat->bt_info_c2h[rsp_source][6] == coex_stat->bt_info_hb3) {
2972 		rtw_dbg(rtwdev, RTW_DBG_COEX,
2973 			"[BTCoex], Return because Btinfo duplicate!!\n");
2974 		return;
2975 	}
2976 
2977 	coex_stat->bt_info_lb2 = coex_stat->bt_info_c2h[rsp_source][1];
2978 	coex_stat->bt_info_lb3 = coex_stat->bt_info_c2h[rsp_source][2];
2979 	coex_stat->bt_info_hb0 = coex_stat->bt_info_c2h[rsp_source][3];
2980 	coex_stat->bt_info_hb1 = coex_stat->bt_info_c2h[rsp_source][4];
2981 	coex_stat->bt_info_hb2 = coex_stat->bt_info_c2h[rsp_source][5];
2982 	coex_stat->bt_info_hb3 = coex_stat->bt_info_c2h[rsp_source][6];
2983 
2984 	/* 0xff means BT is under WHCK test */
2985 	coex_stat->bt_whck_test = (coex_stat->bt_info_lb2 == 0xff);
2986 
2987 	inq_page = ((coex_stat->bt_info_lb2 & BIT(2)) == BIT(2));
2988 
2989 	if (inq_page != coex_stat->bt_inq_page) {
2990 		cancel_delayed_work_sync(&coex->bt_remain_work);
2991 		coex_stat->bt_inq_page = inq_page;
2992 
2993 		if (inq_page)
2994 			coex_stat->bt_inq_remain = true;
2995 		else
2996 			ieee80211_queue_delayed_work(rtwdev->hw,
2997 						     &coex->bt_remain_work,
2998 						     4 * HZ);
2999 	}
3000 	coex_stat->bt_acl_busy = ((coex_stat->bt_info_lb2 & BIT(3)) == BIT(3));
3001 	if (chip->ble_hid_profile_support) {
3002 		if (coex_stat->bt_info_lb2 & BIT(5)) {
3003 			if (coex_stat->bt_info_hb1 & BIT(0)) {
3004 				/*BLE HID*/
3005 				coex_stat->bt_ble_hid_exist = true;
3006 			} else {
3007 				coex_stat->bt_ble_hid_exist = false;
3008 			}
3009 			coex_stat->bt_ble_exist = false;
3010 		} else if (coex_stat->bt_info_hb1 & BIT(0)) {
3011 			/*RCU*/
3012 			coex_stat->bt_ble_hid_exist = false;
3013 			coex_stat->bt_ble_exist = true;
3014 		} else {
3015 			coex_stat->bt_ble_hid_exist = false;
3016 			coex_stat->bt_ble_exist = false;
3017 		}
3018 	} else {
3019 		if (coex_stat->bt_info_hb1 & BIT(0)) {
3020 			if (coex_stat->bt_hid_slot == 1 &&
3021 			    coex_stat->hi_pri_rx + 100 < coex_stat->hi_pri_tx &&
3022 			    coex_stat->hi_pri_rx < 100) {
3023 				coex_stat->bt_ble_hid_exist = true;
3024 				coex_stat->bt_ble_exist = false;
3025 			} else {
3026 				coex_stat->bt_ble_hid_exist = false;
3027 				coex_stat->bt_ble_exist = true;
3028 			}
3029 		} else {
3030 			coex_stat->bt_ble_hid_exist = false;
3031 			coex_stat->bt_ble_exist = false;
3032 		}
3033 	}
3034 
3035 	coex_stat->cnt_bt[COEX_CNT_BT_RETRY] = coex_stat->bt_info_lb3 & 0xf;
3036 	if (coex_stat->cnt_bt[COEX_CNT_BT_RETRY] >= 1)
3037 		coex_stat->cnt_bt[COEX_CNT_BT_POPEVENT]++;
3038 
3039 	coex_stat->bt_fix_2M = ((coex_stat->bt_info_lb3 & BIT(4)) == BIT(4));
3040 	coex_stat->bt_inq = ((coex_stat->bt_info_lb3 & BIT(5)) == BIT(5));
3041 	if (coex_stat->bt_inq)
3042 		coex_stat->cnt_bt[COEX_CNT_BT_INQ]++;
3043 
3044 	coex_stat->bt_page = ((coex_stat->bt_info_lb3 & BIT(7)) == BIT(7));
3045 	if (coex_stat->bt_page)
3046 		coex_stat->cnt_bt[COEX_CNT_BT_PAGE]++;
3047 
3048 	/* unit: % (value-100 to translate to unit: dBm in coex info) */
3049 	if (chip->bt_rssi_type == COEX_BTRSSI_RATIO) {
3050 		coex_stat->bt_rssi = coex_stat->bt_info_hb0 * 2 + 10;
3051 	} else {
3052 		if (coex_stat->bt_info_hb0 <= 127)
3053 			coex_stat->bt_rssi = 100;
3054 		else if (256 - coex_stat->bt_info_hb0 <= 100)
3055 			coex_stat->bt_rssi = 100 - (256 - coex_stat->bt_info_hb0);
3056 		else
3057 			coex_stat->bt_rssi = 0;
3058 	}
3059 
3060 	if (coex_stat->bt_info_hb1 & BIT(1))
3061 		coex_stat->cnt_bt[COEX_CNT_BT_REINIT]++;
3062 
3063 	if (coex_stat->bt_info_hb1 & BIT(2)) {
3064 		coex_stat->cnt_bt[COEX_CNT_BT_SETUPLINK]++;
3065 		coex_stat->bt_setup_link = true;
3066 		if (coex_stat->bt_reenable)
3067 			bt_relink_time = 6 * HZ;
3068 		else
3069 			bt_relink_time = 1 * HZ;
3070 
3071 		ieee80211_queue_delayed_work(rtwdev->hw,
3072 					     &coex->bt_relink_work,
3073 					     bt_relink_time);
3074 
3075 		rtw_dbg(rtwdev, RTW_DBG_COEX,
3076 			"[BTCoex], Re-Link start in BT info!!\n");
3077 	}
3078 
3079 	if (coex_stat->bt_info_hb1 & BIT(3))
3080 		coex_stat->cnt_bt[COEX_CNT_BT_IGNWLANACT]++;
3081 
3082 	coex_stat->bt_ble_voice = ((coex_stat->bt_info_hb1 & BIT(4)) == BIT(4));
3083 	coex_stat->bt_ble_scan_en = ((coex_stat->bt_info_hb1 & BIT(5)) == BIT(5));
3084 	if (coex_stat->bt_info_hb1 & BIT(6))
3085 		coex_stat->cnt_bt[COEX_CNT_BT_ROLESWITCH]++;
3086 
3087 	coex_stat->bt_multi_link = ((coex_stat->bt_info_hb1 & BIT(7)) == BIT(7));
3088 	/* for multi_link = 0 but bt pkt remain exist */
3089 	/* Use PS-TDMA to protect WL RX */
3090 	if (!coex_stat->bt_multi_link && coex_stat->bt_multi_link_pre) {
3091 		coex_stat->bt_multi_link_remain = true;
3092 		ieee80211_queue_delayed_work(rtwdev->hw,
3093 					     &coex->bt_multi_link_remain_work,
3094 					     3 * HZ);
3095 	}
3096 	coex_stat->bt_multi_link_pre = coex_stat->bt_multi_link;
3097 
3098 	/* resend wifi info to bt, it is reset and lost the info */
3099 	if (coex_stat->bt_info_hb1 & BIT(1)) {
3100 		rtw_dbg(rtwdev, RTW_DBG_COEX,
3101 			"[BTCoex], BT Re-init, send wifi BW & Chnl to BT!!\n");
3102 
3103 		if (coex_stat->wl_connected)
3104 			type = COEX_MEDIA_CONNECT;
3105 		else
3106 			type = COEX_MEDIA_DISCONNECT;
3107 		rtw_coex_update_wl_ch_info(rtwdev, type);
3108 	}
3109 
3110 	/* if ignore_wlan_act && not set_up_link */
3111 	if ((coex_stat->bt_info_hb1 & BIT(3)) &&
3112 	    (!(coex_stat->bt_info_hb1 & BIT(2)))) {
3113 		rtw_dbg(rtwdev, RTW_DBG_COEX,
3114 			"[BTCoex], BT ext info bit3 check, set BT NOT to ignore Wlan active!!\n");
3115 		rtw_coex_ignore_wlan_act(rtwdev, false);
3116 	}
3117 
3118 	coex_stat->bt_opp_exist = ((coex_stat->bt_info_hb2 & BIT(0)) == BIT(0));
3119 	if (coex_stat->bt_info_hb2 & BIT(1))
3120 		coex_stat->cnt_bt[COEX_CNT_BT_AFHUPDATE]++;
3121 
3122 	coex_stat->bt_a2dp_active = (coex_stat->bt_info_hb2 & BIT(2)) == BIT(2);
3123 	coex_stat->bt_slave = ((coex_stat->bt_info_hb2 & BIT(3)) == BIT(3));
3124 	coex_stat->bt_hid_slot = (coex_stat->bt_info_hb2 & 0x30) >> 4;
3125 	coex_stat->bt_hid_pair_num = (coex_stat->bt_info_hb2 & 0xc0) >> 6;
3126 	if (coex_stat->bt_hid_pair_num > 0 && coex_stat->bt_hid_slot >= 2)
3127 		coex_stat->bt_418_hid_exist = true;
3128 	else if (coex_stat->bt_hid_pair_num == 0 || coex_stat->bt_hid_slot == 1)
3129 		coex_stat->bt_418_hid_exist = false;
3130 
3131 	if ((coex_stat->bt_info_lb2 & 0x49) == 0x49)
3132 		coex_stat->bt_a2dp_bitpool = (coex_stat->bt_info_hb3 & 0x7f);
3133 	else
3134 		coex_stat->bt_a2dp_bitpool = 0;
3135 
3136 	coex_stat->bt_a2dp_sink = ((coex_stat->bt_info_hb3 & BIT(7)) == BIT(7));
3137 
3138 	rtw_coex_update_bt_link_info(rtwdev);
3139 	rtw_coex_run_coex(rtwdev, COEX_RSN_BTINFO);
3140 }
3141 
rtw_coex_wl_fwdbginfo_notify(struct rtw_dev * rtwdev,u8 * buf,u8 length)3142 void rtw_coex_wl_fwdbginfo_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length)
3143 {
3144 	struct rtw_coex *coex = &rtwdev->coex;
3145 	struct rtw_coex_stat *coex_stat = &coex->stat;
3146 	u8 val;
3147 	int i;
3148 
3149 	rtw_dbg(rtwdev, RTW_DBG_COEX,
3150 		"[BTCoex], WiFi Fw Dbg info = %8ph (len = %d)\n",
3151 		buf, length);
3152 	if (WARN(length < 8, "invalid wl info c2h length\n"))
3153 		return;
3154 
3155 	if (buf[0] != 0x08)
3156 		return;
3157 
3158 	for (i = 1; i < 8; i++) {
3159 		val = coex_stat->wl_fw_dbg_info_pre[i];
3160 		if (buf[i] >= val)
3161 			coex_stat->wl_fw_dbg_info[i] = buf[i] - val;
3162 		else
3163 			coex_stat->wl_fw_dbg_info[i] = 255 - val + buf[i];
3164 
3165 		coex_stat->wl_fw_dbg_info_pre[i] = buf[i];
3166 	}
3167 
3168 	coex_stat->cnt_wl[COEX_CNT_WL_FW_NOTIFY]++;
3169 	rtw_coex_wl_ccklock_action(rtwdev);
3170 	rtw_coex_wl_ccklock_detect(rtwdev);
3171 }
3172 
rtw_coex_wl_status_change_notify(struct rtw_dev * rtwdev,u32 type)3173 void rtw_coex_wl_status_change_notify(struct rtw_dev *rtwdev, u32 type)
3174 {
3175 	rtw_coex_run_coex(rtwdev, COEX_RSN_WLSTATUS);
3176 }
3177 
rtw_coex_bt_relink_work(struct work_struct * work)3178 void rtw_coex_bt_relink_work(struct work_struct *work)
3179 {
3180 	struct rtw_dev *rtwdev = container_of(work, struct rtw_dev,
3181 					      coex.bt_relink_work.work);
3182 	struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat;
3183 
3184 	mutex_lock(&rtwdev->mutex);
3185 	coex_stat->bt_setup_link = false;
3186 	rtw_coex_run_coex(rtwdev, COEX_RSN_WLSTATUS);
3187 	mutex_unlock(&rtwdev->mutex);
3188 }
3189 
rtw_coex_bt_reenable_work(struct work_struct * work)3190 void rtw_coex_bt_reenable_work(struct work_struct *work)
3191 {
3192 	struct rtw_dev *rtwdev = container_of(work, struct rtw_dev,
3193 					      coex.bt_reenable_work.work);
3194 	struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat;
3195 
3196 	mutex_lock(&rtwdev->mutex);
3197 	coex_stat->bt_reenable = false;
3198 	mutex_unlock(&rtwdev->mutex);
3199 }
3200 
rtw_coex_defreeze_work(struct work_struct * work)3201 void rtw_coex_defreeze_work(struct work_struct *work)
3202 {
3203 	struct rtw_dev *rtwdev = container_of(work, struct rtw_dev,
3204 					      coex.defreeze_work.work);
3205 	struct rtw_coex *coex = &rtwdev->coex;
3206 	struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat;
3207 
3208 	mutex_lock(&rtwdev->mutex);
3209 	coex->freeze = false;
3210 	coex_stat->wl_hi_pri_task1 = false;
3211 	rtw_coex_run_coex(rtwdev, COEX_RSN_WLSTATUS);
3212 	mutex_unlock(&rtwdev->mutex);
3213 }
3214 
rtw_coex_wl_remain_work(struct work_struct * work)3215 void rtw_coex_wl_remain_work(struct work_struct *work)
3216 {
3217 	struct rtw_dev *rtwdev = container_of(work, struct rtw_dev,
3218 					      coex.wl_remain_work.work);
3219 	struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat;
3220 
3221 	mutex_lock(&rtwdev->mutex);
3222 	coex_stat->wl_gl_busy = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags);
3223 	rtw_coex_run_coex(rtwdev, COEX_RSN_WLSTATUS);
3224 	mutex_unlock(&rtwdev->mutex);
3225 }
3226 
rtw_coex_bt_remain_work(struct work_struct * work)3227 void rtw_coex_bt_remain_work(struct work_struct *work)
3228 {
3229 	struct rtw_dev *rtwdev = container_of(work, struct rtw_dev,
3230 					      coex.bt_remain_work.work);
3231 	struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat;
3232 
3233 	mutex_lock(&rtwdev->mutex);
3234 	coex_stat->bt_inq_remain = coex_stat->bt_inq_page;
3235 	rtw_coex_run_coex(rtwdev, COEX_RSN_BTSTATUS);
3236 	mutex_unlock(&rtwdev->mutex);
3237 }
3238 
rtw_coex_wl_connecting_work(struct work_struct * work)3239 void rtw_coex_wl_connecting_work(struct work_struct *work)
3240 {
3241 	struct rtw_dev *rtwdev = container_of(work, struct rtw_dev,
3242 					      coex.wl_connecting_work.work);
3243 	struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat;
3244 
3245 	mutex_lock(&rtwdev->mutex);
3246 	coex_stat->wl_connecting = false;
3247 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], WL connecting stop!!\n");
3248 	rtw_coex_run_coex(rtwdev, COEX_RSN_WLSTATUS);
3249 	mutex_unlock(&rtwdev->mutex);
3250 }
3251 
rtw_coex_bt_multi_link_remain_work(struct work_struct * work)3252 void rtw_coex_bt_multi_link_remain_work(struct work_struct *work)
3253 {
3254 	struct rtw_dev *rtwdev = container_of(work, struct rtw_dev,
3255 		coex.bt_multi_link_remain_work.work);
3256 	struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat;
3257 
3258 	mutex_lock(&rtwdev->mutex);
3259 	coex_stat->bt_multi_link_remain = false;
3260 	mutex_unlock(&rtwdev->mutex);
3261 }
3262 
rtw_coex_wl_ccklock_work(struct work_struct * work)3263 void rtw_coex_wl_ccklock_work(struct work_struct *work)
3264 {
3265 	struct rtw_dev *rtwdev = container_of(work, struct rtw_dev,
3266 					      coex.wl_ccklock_work.work);
3267 	struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat;
3268 
3269 	mutex_lock(&rtwdev->mutex);
3270 	coex_stat->wl_cck_lock = false;
3271 	mutex_unlock(&rtwdev->mutex);
3272 }
3273 
3274 #ifdef CONFIG_RTW88_DEBUGFS
3275 #define INFO_SIZE	80
3276 
3277 #define case_BTINFO(src) \
3278 	case COEX_BTINFO_SRC_##src: return #src
3279 
rtw_coex_get_bt_info_src_string(u8 bt_info_src)3280 static const char *rtw_coex_get_bt_info_src_string(u8 bt_info_src)
3281 {
3282 	switch (bt_info_src) {
3283 	case_BTINFO(WL_FW);
3284 	case_BTINFO(BT_RSP);
3285 	case_BTINFO(BT_ACT);
3286 	default:
3287 		return "Unknown";
3288 	}
3289 }
3290 
3291 #define case_RSN(src) \
3292 	case COEX_RSN_##src: return #src
3293 
rtw_coex_get_reason_string(u8 reason)3294 static const char *rtw_coex_get_reason_string(u8 reason)
3295 {
3296 	switch (reason) {
3297 	case_RSN(2GSCANSTART);
3298 	case_RSN(5GSCANSTART);
3299 	case_RSN(SCANFINISH);
3300 	case_RSN(2GSWITCHBAND);
3301 	case_RSN(5GSWITCHBAND);
3302 	case_RSN(2GCONSTART);
3303 	case_RSN(5GCONSTART);
3304 	case_RSN(2GCONFINISH);
3305 	case_RSN(5GCONFINISH);
3306 	case_RSN(2GMEDIA);
3307 	case_RSN(5GMEDIA);
3308 	case_RSN(MEDIADISCON);
3309 	case_RSN(BTINFO);
3310 	case_RSN(LPS);
3311 	case_RSN(WLSTATUS);
3312 	default:
3313 		return "Unknown";
3314 	}
3315 }
3316 
rtw_coex_get_table_index(struct rtw_dev * rtwdev,u32 wl_reg_6c0,u32 wl_reg_6c4)3317 static u8 rtw_coex_get_table_index(struct rtw_dev *rtwdev, u32 wl_reg_6c0,
3318 				   u32 wl_reg_6c4)
3319 {
3320 	struct rtw_chip_info *chip = rtwdev->chip;
3321 	struct rtw_efuse *efuse = &rtwdev->efuse;
3322 	u8 ans = 0xFF;
3323 	u8 n, i;
3324 	u32 load_bt_val;
3325 	u32 load_wl_val;
3326 	bool share_ant = efuse->share_ant;
3327 
3328 	if (share_ant)
3329 		n = chip->table_sant_num;
3330 	else
3331 		n = chip->table_nsant_num;
3332 
3333 	for (i = 0; i < n; i++) {
3334 		if (share_ant) {
3335 			load_bt_val = chip->table_sant[i].bt;
3336 			load_wl_val = chip->table_sant[i].wl;
3337 		} else {
3338 			load_bt_val = chip->table_nsant[i].bt;
3339 			load_wl_val = chip->table_nsant[i].wl;
3340 		}
3341 
3342 		if (wl_reg_6c0 == load_bt_val &&
3343 		    wl_reg_6c4 == load_wl_val) {
3344 			ans = i;
3345 			if (!share_ant)
3346 				ans += 100;
3347 			break;
3348 		}
3349 	}
3350 
3351 	return ans;
3352 }
3353 
rtw_coex_get_tdma_index(struct rtw_dev * rtwdev,u8 * tdma_para)3354 static u8 rtw_coex_get_tdma_index(struct rtw_dev *rtwdev, u8 *tdma_para)
3355 {
3356 	struct rtw_efuse *efuse = &rtwdev->efuse;
3357 	struct rtw_chip_info *chip = rtwdev->chip;
3358 	u8 ans = 0xFF;
3359 	u8 n, i, j;
3360 	u8 load_cur_tab_val;
3361 	bool valid = false;
3362 	bool share_ant = efuse->share_ant;
3363 
3364 	if (share_ant)
3365 		n = chip->tdma_sant_num;
3366 	else
3367 		n = chip->tdma_nsant_num;
3368 
3369 	for (i = 0; i < n; i++) {
3370 		valid = false;
3371 		for (j = 0; j < 5; j++) {
3372 			if (share_ant)
3373 				load_cur_tab_val = chip->tdma_sant[i].para[j];
3374 			else
3375 				load_cur_tab_val = chip->tdma_nsant[i].para[j];
3376 
3377 			if (*(tdma_para + j) != load_cur_tab_val)
3378 				break;
3379 
3380 			if (j == 4)
3381 				valid = true;
3382 		}
3383 		if (valid) {
3384 			ans = i;
3385 			break;
3386 		}
3387 	}
3388 
3389 	return ans;
3390 }
3391 
rtw_coex_addr_info(struct rtw_dev * rtwdev,const struct rtw_reg_domain * reg,char addr_info[],int n)3392 static int rtw_coex_addr_info(struct rtw_dev *rtwdev,
3393 			      const struct rtw_reg_domain *reg,
3394 			      char addr_info[], int n)
3395 {
3396 	const char *rf_prefix = "";
3397 	const char *sep = n == 0 ? "" : "/ ";
3398 	int ffs, fls;
3399 	int max_fls;
3400 
3401 	if (INFO_SIZE - n <= 0)
3402 		return 0;
3403 
3404 	switch (reg->domain) {
3405 	case RTW_REG_DOMAIN_MAC32:
3406 		max_fls = 31;
3407 		break;
3408 	case RTW_REG_DOMAIN_MAC16:
3409 		max_fls = 15;
3410 		break;
3411 	case RTW_REG_DOMAIN_MAC8:
3412 		max_fls = 7;
3413 		break;
3414 	case RTW_REG_DOMAIN_RF_A:
3415 	case RTW_REG_DOMAIN_RF_B:
3416 		rf_prefix = "RF_";
3417 		max_fls = 19;
3418 		break;
3419 	default:
3420 		return 0;
3421 	}
3422 
3423 	ffs = __ffs(reg->mask);
3424 	fls = __fls(reg->mask);
3425 
3426 	if (ffs == 0 && fls == max_fls)
3427 		return scnprintf(addr_info + n, INFO_SIZE - n, "%s%s%x",
3428 				 sep, rf_prefix, reg->addr);
3429 	else if (ffs == fls)
3430 		return scnprintf(addr_info + n, INFO_SIZE - n, "%s%s%x[%d]",
3431 				 sep, rf_prefix, reg->addr, ffs);
3432 	else
3433 		return scnprintf(addr_info + n, INFO_SIZE - n, "%s%s%x[%d:%d]",
3434 				 sep, rf_prefix, reg->addr, fls, ffs);
3435 }
3436 
rtw_coex_val_info(struct rtw_dev * rtwdev,const struct rtw_reg_domain * reg,char val_info[],int n)3437 static int rtw_coex_val_info(struct rtw_dev *rtwdev,
3438 			     const struct rtw_reg_domain *reg,
3439 			     char val_info[], int n)
3440 {
3441 	const char *sep = n == 0 ? "" : "/ ";
3442 	u8 rf_path;
3443 
3444 	if (INFO_SIZE - n <= 0)
3445 		return 0;
3446 
3447 	switch (reg->domain) {
3448 	case RTW_REG_DOMAIN_MAC32:
3449 		return scnprintf(val_info + n, INFO_SIZE - n, "%s0x%x", sep,
3450 				 rtw_read32_mask(rtwdev, reg->addr, reg->mask));
3451 	case RTW_REG_DOMAIN_MAC16:
3452 		return scnprintf(val_info + n, INFO_SIZE - n, "%s0x%x", sep,
3453 				 rtw_read16_mask(rtwdev, reg->addr, reg->mask));
3454 	case RTW_REG_DOMAIN_MAC8:
3455 		return scnprintf(val_info + n, INFO_SIZE - n, "%s0x%x", sep,
3456 				 rtw_read8_mask(rtwdev, reg->addr, reg->mask));
3457 	case RTW_REG_DOMAIN_RF_A:
3458 		rf_path = RF_PATH_A;
3459 		break;
3460 	case RTW_REG_DOMAIN_RF_B:
3461 		rf_path = RF_PATH_B;
3462 		break;
3463 	default:
3464 		return 0;
3465 	}
3466 
3467 	/* only RF go through here */
3468 	return scnprintf(val_info + n, INFO_SIZE - n, "%s0x%x", sep,
3469 			 rtw_read_rf(rtwdev, rf_path, reg->addr, reg->mask));
3470 }
3471 
rtw_coex_set_coexinfo_hw(struct rtw_dev * rtwdev,struct seq_file * m)3472 static void rtw_coex_set_coexinfo_hw(struct rtw_dev *rtwdev, struct seq_file *m)
3473 {
3474 	struct rtw_chip_info *chip = rtwdev->chip;
3475 	const struct rtw_reg_domain *reg;
3476 	char addr_info[INFO_SIZE];
3477 	int n_addr = 0;
3478 	char val_info[INFO_SIZE];
3479 	int n_val = 0;
3480 	int i;
3481 
3482 	for (i = 0; i < chip->coex_info_hw_regs_num; i++) {
3483 		reg = &chip->coex_info_hw_regs[i];
3484 
3485 		n_addr += rtw_coex_addr_info(rtwdev, reg, addr_info, n_addr);
3486 		n_val += rtw_coex_val_info(rtwdev, reg, val_info, n_val);
3487 
3488 		if (reg->domain == RTW_REG_DOMAIN_NL) {
3489 			seq_printf(m, "%-40s = %s\n", addr_info, val_info);
3490 			n_addr = 0;
3491 			n_val = 0;
3492 		}
3493 	}
3494 
3495 	if (n_addr != 0 && n_val != 0)
3496 		seq_printf(m, "%-40s = %s\n", addr_info, val_info);
3497 }
3498 
rtw_coex_get_bt_reg(struct rtw_dev * rtwdev,u8 type,u16 addr,u16 * val)3499 static bool rtw_coex_get_bt_reg(struct rtw_dev *rtwdev,
3500 				u8 type, u16 addr, u16 *val)
3501 {
3502 	struct rtw_coex_info_req req = {0};
3503 	struct sk_buff *skb;
3504 	__le16 le_addr;
3505 	u8 *payload;
3506 
3507 	le_addr = cpu_to_le16(addr);
3508 	req.op_code = BT_MP_INFO_OP_READ_REG;
3509 	req.para1 = type;
3510 	req.para2 = le16_get_bits(le_addr, GENMASK(7, 0));
3511 	req.para3 = le16_get_bits(le_addr, GENMASK(15, 8));
3512 	skb = rtw_coex_info_request(rtwdev, &req);
3513 	if (!skb) {
3514 		*val = 0xeaea;
3515 		return false;
3516 	}
3517 
3518 	payload = get_payload_from_coex_resp(skb);
3519 	*val = GET_COEX_RESP_BT_REG_VAL(payload);
3520 	dev_kfree_skb_any(skb);
3521 
3522 	return true;
3523 }
3524 
rtw_coex_get_bt_patch_version(struct rtw_dev * rtwdev,u32 * patch_version)3525 static bool rtw_coex_get_bt_patch_version(struct rtw_dev *rtwdev,
3526 					  u32 *patch_version)
3527 {
3528 	struct rtw_coex_info_req req = {0};
3529 	struct sk_buff *skb;
3530 	u8 *payload;
3531 
3532 	req.op_code = BT_MP_INFO_OP_PATCH_VER;
3533 	skb = rtw_coex_info_request(rtwdev, &req);
3534 	if (!skb)
3535 		return false;
3536 
3537 	payload = get_payload_from_coex_resp(skb);
3538 	*patch_version = GET_COEX_RESP_BT_PATCH_VER(payload);
3539 	dev_kfree_skb_any(skb);
3540 
3541 	return true;
3542 }
3543 
rtw_coex_get_bt_supported_version(struct rtw_dev * rtwdev,u32 * supported_version)3544 static bool rtw_coex_get_bt_supported_version(struct rtw_dev *rtwdev,
3545 					      u32 *supported_version)
3546 {
3547 	struct rtw_coex_info_req req = {0};
3548 	struct sk_buff *skb;
3549 	u8 *payload;
3550 
3551 	req.op_code = BT_MP_INFO_OP_SUPP_VER;
3552 	skb = rtw_coex_info_request(rtwdev, &req);
3553 	if (!skb)
3554 		return false;
3555 
3556 	payload = get_payload_from_coex_resp(skb);
3557 	*supported_version = GET_COEX_RESP_BT_SUPP_VER(payload);
3558 	dev_kfree_skb_any(skb);
3559 
3560 	return true;
3561 }
3562 
rtw_coex_get_bt_supported_feature(struct rtw_dev * rtwdev,u32 * supported_feature)3563 static bool rtw_coex_get_bt_supported_feature(struct rtw_dev *rtwdev,
3564 					      u32 *supported_feature)
3565 {
3566 	struct rtw_coex_info_req req = {0};
3567 	struct sk_buff *skb;
3568 	u8 *payload;
3569 
3570 	req.op_code = BT_MP_INFO_OP_SUPP_FEAT;
3571 	skb = rtw_coex_info_request(rtwdev, &req);
3572 	if (!skb)
3573 		return false;
3574 
3575 	payload = get_payload_from_coex_resp(skb);
3576 	*supported_feature = GET_COEX_RESP_BT_SUPP_FEAT(payload);
3577 	dev_kfree_skb_any(skb);
3578 
3579 	return true;
3580 }
3581 
3582 struct rtw_coex_sta_stat_iter_data {
3583 	struct rtw_vif *rtwvif;
3584 	struct seq_file *file;
3585 };
3586 
rtw_coex_sta_stat_iter(void * data,struct ieee80211_sta * sta)3587 static void rtw_coex_sta_stat_iter(void *data, struct ieee80211_sta *sta)
3588 {
3589 	struct rtw_coex_sta_stat_iter_data *sta_iter_data = data;
3590 	struct rtw_vif *rtwvif = sta_iter_data->rtwvif;
3591 	struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv;
3592 	struct seq_file *m = sta_iter_data->file;
3593 	struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
3594 	u8 rssi;
3595 
3596 	if (si->vif != vif)
3597 		return;
3598 
3599 	rssi = ewma_rssi_read(&si->avg_rssi);
3600 	seq_printf(m, "\tPeer %3d\n", si->mac_id);
3601 	seq_printf(m, "\t\t%-24s = %d\n", "RSSI", rssi);
3602 	seq_printf(m, "\t\t%-24s = %d\n", "BW mode", si->bw_mode);
3603 }
3604 
3605 struct rtw_coex_vif_stat_iter_data {
3606 	struct rtw_dev *rtwdev;
3607 	struct seq_file *file;
3608 };
3609 
rtw_coex_vif_stat_iter(void * data,u8 * mac,struct ieee80211_vif * vif)3610 static void rtw_coex_vif_stat_iter(void *data, u8 *mac,
3611 				   struct ieee80211_vif *vif)
3612 {
3613 	struct rtw_coex_vif_stat_iter_data *vif_iter_data = data;
3614 	struct rtw_coex_sta_stat_iter_data sta_iter_data;
3615 	struct rtw_dev *rtwdev = vif_iter_data->rtwdev;
3616 	struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
3617 	struct seq_file *m = vif_iter_data->file;
3618 	struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
3619 
3620 	seq_printf(m, "Iface on Port (%d)\n", rtwvif->port);
3621 	seq_printf(m, "\t%-32s = %d\n",
3622 		   "Beacon interval", bss_conf->beacon_int);
3623 	seq_printf(m, "\t%-32s = %d\n",
3624 		   "Network Type", rtwvif->net_type);
3625 
3626 	sta_iter_data.rtwvif = rtwvif;
3627 	sta_iter_data.file = m;
3628 	rtw_iterate_stas_atomic(rtwdev, rtw_coex_sta_stat_iter,
3629 				&sta_iter_data);
3630 }
3631 
3632 #define case_WLINK(src) \
3633 	case COEX_WLINK_##src: return #src
3634 
rtw_coex_get_wl_coex_mode(u8 coex_wl_link_mode)3635 static const char *rtw_coex_get_wl_coex_mode(u8 coex_wl_link_mode)
3636 {
3637 	switch (coex_wl_link_mode) {
3638 	case_WLINK(2G1PORT);
3639 	case_WLINK(5G);
3640 	default:
3641 		return "Unknown";
3642 	}
3643 }
3644 
rtw_coex_display_coex_info(struct rtw_dev * rtwdev,struct seq_file * m)3645 void rtw_coex_display_coex_info(struct rtw_dev *rtwdev, struct seq_file *m)
3646 {
3647 	struct rtw_chip_info *chip = rtwdev->chip;
3648 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
3649 	struct rtw_coex *coex = &rtwdev->coex;
3650 	struct rtw_coex_stat *coex_stat = &coex->stat;
3651 	struct rtw_coex_dm *coex_dm = &coex->dm;
3652 	struct rtw_hal *hal = &rtwdev->hal;
3653 	struct rtw_efuse *efuse = &rtwdev->efuse;
3654 	struct rtw_fw_state *fw = &rtwdev->fw;
3655 	struct rtw_coex_vif_stat_iter_data vif_iter_data;
3656 	u8 reason = coex_dm->reason;
3657 	u8 sys_lte;
3658 	u16 score_board_WB, score_board_BW;
3659 	u32 wl_reg_6c0, wl_reg_6c4, wl_reg_6c8, wl_reg_778, wl_reg_6cc;
3660 	u32 lte_coex, bt_coex;
3661 	u32 bt_hi_pri, bt_lo_pri;
3662 	int i;
3663 
3664 	score_board_BW = rtw_coex_read_scbd(rtwdev);
3665 	score_board_WB = coex_stat->score_board;
3666 	wl_reg_6c0 = rtw_read32(rtwdev, REG_BT_COEX_TABLE0);
3667 	wl_reg_6c4 = rtw_read32(rtwdev, REG_BT_COEX_TABLE1);
3668 	wl_reg_6c8 = rtw_read32(rtwdev, REG_BT_COEX_BRK_TABLE);
3669 	wl_reg_6cc = rtw_read32(rtwdev, REG_BT_COEX_TABLE_H);
3670 	wl_reg_778 = rtw_read8(rtwdev, REG_BT_STAT_CTRL);
3671 
3672 	bt_hi_pri = rtw_read32(rtwdev, REG_BT_ACT_STATISTICS);
3673 	bt_lo_pri = rtw_read32(rtwdev, REG_BT_ACT_STATISTICS_1);
3674 	rtw_write8(rtwdev, REG_BT_COEX_ENH_INTR_CTRL,
3675 		   BIT_R_GRANTALL_WLMASK | BIT_STATIS_BT_EN);
3676 
3677 	coex_stat->hi_pri_tx = FIELD_GET(MASKLWORD, bt_hi_pri);
3678 	coex_stat->hi_pri_rx = FIELD_GET(MASKHWORD, bt_hi_pri);
3679 
3680 	coex_stat->lo_pri_tx = FIELD_GET(MASKLWORD, bt_lo_pri);
3681 	coex_stat->lo_pri_rx = FIELD_GET(MASKHWORD, bt_lo_pri);
3682 
3683 	sys_lte = rtw_read8(rtwdev, 0x73);
3684 	lte_coex = rtw_coex_read_indirect_reg(rtwdev, 0x38);
3685 	bt_coex = rtw_coex_read_indirect_reg(rtwdev, 0x54);
3686 
3687 	if (!coex_stat->bt_disabled && !coex_stat->bt_mailbox_reply) {
3688 		rtw_coex_get_bt_supported_version(rtwdev,
3689 				&coex_stat->bt_supported_version);
3690 		rtw_coex_get_bt_patch_version(rtwdev, &coex_stat->patch_ver);
3691 		rtw_coex_get_bt_supported_feature(rtwdev,
3692 				&coex_stat->bt_supported_feature);
3693 		rtw_coex_get_bt_reg(rtwdev, 3, 0xae, &coex_stat->bt_reg_vendor_ae);
3694 		rtw_coex_get_bt_reg(rtwdev, 3, 0xac, &coex_stat->bt_reg_vendor_ac);
3695 
3696 		if (coex_stat->patch_ver != 0)
3697 			coex_stat->bt_mailbox_reply = true;
3698 	}
3699 
3700 	rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
3701 	seq_printf(m, "**********************************************\n");
3702 	seq_printf(m, "\t\tBT Coexist info %x\n", chip->id);
3703 	seq_printf(m, "**********************************************\n");
3704 
3705 	if (coex->manual_control) {
3706 		seq_puts(m, "============[Under Manual Control]============\n");
3707 		seq_puts(m, "==========================================\n");
3708 
3709 	} else if (coex->stop_dm) {
3710 		seq_puts(m, "============[Coex is STOPPED]============\n");
3711 		seq_puts(m, "==========================================\n");
3712 
3713 	} else if (coex->freeze) {
3714 		seq_puts(m, "============[coex_freeze]============\n");
3715 		seq_puts(m, "==========================================\n");
3716 	}
3717 
3718 	seq_printf(m, "%-40s = %s/ %d\n",
3719 		   "Mech/ RFE",
3720 		   efuse->share_ant ? "Shared" : "Non-Shared",
3721 		   efuse->rfe_option);
3722 	seq_printf(m, "%-40s = %08x/ 0x%02x/ 0x%08x %s\n",
3723 		   "Coex Ver/ BT Dez/ BT Rpt",
3724 		   chip->coex_para_ver, chip->bt_desired_ver,
3725 		   coex_stat->bt_supported_version,
3726 		   coex_stat->bt_disabled ? "(BT disabled)" :
3727 		   coex_stat->bt_supported_version >= chip->bt_desired_ver ?
3728 		   "(Match)" : "(Mismatch)");
3729 	seq_printf(m, "%-40s = %s/ %u/ %d\n",
3730 		   "Role/ RoleSwCnt/ IgnWL/ Feature",
3731 		   coex_stat->bt_slave ? "Slave" : "Master",
3732 		   coex_stat->cnt_bt[COEX_CNT_BT_ROLESWITCH],
3733 		   coex_dm->ignore_wl_act);
3734 	seq_printf(m, "%-40s = %u.%u/ 0x%x/ 0x%x/ %c\n",
3735 		   "WL FW/ BT FW/ BT FW Desired/ KT",
3736 		   fw->version, fw->sub_version,
3737 		   coex_stat->patch_ver,
3738 		   chip->wl_fw_desired_ver, coex_stat->kt_ver + 65);
3739 	seq_printf(m, "%-40s = %u/ %u/ %u/ ch-(%u)\n",
3740 		   "AFH Map",
3741 		   coex_dm->wl_ch_info[0], coex_dm->wl_ch_info[1],
3742 		   coex_dm->wl_ch_info[2], hal->current_channel);
3743 
3744 	rtw_debugfs_get_simple_phy_info(m);
3745 	seq_printf(m, "**********************************************\n");
3746 	seq_printf(m, "\t\tBT Status\n");
3747 	seq_printf(m, "**********************************************\n");
3748 	seq_printf(m, "%-40s = %s/ %ddBm/ %u/ %u\n",
3749 		   "BT status/ rssi/ retry/ pop",
3750 		   coex_dm->bt_status == COEX_BTSTATUS_NCON_IDLE ? "non-conn" :
3751 		   coex_dm->bt_status == COEX_BTSTATUS_CON_IDLE ? "conn-idle" : "busy",
3752 		   coex_stat->bt_rssi - 100,
3753 		   coex_stat->cnt_bt[COEX_CNT_BT_RETRY],
3754 		   coex_stat->cnt_bt[COEX_CNT_BT_POPEVENT]);
3755 	seq_printf(m, "%-40s = %s%s%s%s%s (multi-link %d)\n",
3756 		   "Profiles",
3757 		   coex_stat->bt_a2dp_exist ? (coex_stat->bt_a2dp_sink ?
3758 					       "A2DP sink," : "A2DP,") : "",
3759 		   coex_stat->bt_hfp_exist ? "HFP," : "",
3760 		   coex_stat->bt_hid_exist ?
3761 		   (coex_stat->bt_ble_exist ? "HID(RCU)," :
3762 		    coex_stat->bt_hid_slot >= 2 ? "HID(4/18)" :
3763 		    coex_stat->bt_ble_hid_exist ? "HID(BLE)" :
3764 		    "HID(2/18),") : "",
3765 		   coex_stat->bt_pan_exist ? coex_stat->bt_opp_exist ?
3766 		   "OPP," : "PAN," : "",
3767 		   coex_stat->bt_ble_voice ? "Voice," : "",
3768 		   coex_stat->bt_multi_link);
3769 	seq_printf(m, "%-40s = %u/ %u/ %u/ 0x%08x\n",
3770 		   "Reinit/ Relink/ IgnWl/ Feature",
3771 		   coex_stat->cnt_bt[COEX_CNT_BT_REINIT],
3772 		   coex_stat->cnt_bt[COEX_CNT_BT_SETUPLINK],
3773 		   coex_stat->cnt_bt[COEX_CNT_BT_IGNWLANACT],
3774 		   coex_stat->bt_supported_feature);
3775 	seq_printf(m, "%-40s = %u/ %u/ %u/ %u\n",
3776 		   "Page/ Inq/ iqk/ iqk fail",
3777 		   coex_stat->cnt_bt[COEX_CNT_BT_PAGE],
3778 		   coex_stat->cnt_bt[COEX_CNT_BT_INQ],
3779 		   coex_stat->cnt_bt[COEX_CNT_BT_IQK],
3780 		   coex_stat->cnt_bt[COEX_CNT_BT_IQKFAIL]);
3781 	seq_printf(m, "%-40s = 0x%04x/ 0x%04x/ 0x%04x/ 0x%04x\n",
3782 		   "0xae/ 0xac/ score board (W->B)/ (B->W)",
3783 		   coex_stat->bt_reg_vendor_ae,
3784 		   coex_stat->bt_reg_vendor_ac,
3785 		   score_board_WB, score_board_BW);
3786 	seq_printf(m, "%-40s = %u/%u, %u/%u\n",
3787 		   "Hi-Pri TX/RX, Lo-Pri TX/RX",
3788 		   coex_stat->hi_pri_tx, coex_stat->hi_pri_rx,
3789 		   coex_stat->lo_pri_tx, coex_stat->lo_pri_rx);
3790 	for (i = 0; i < COEX_BTINFO_SRC_BT_IQK; i++)
3791 		seq_printf(m, "%-40s = %7ph\n",
3792 			   rtw_coex_get_bt_info_src_string(i),
3793 			   coex_stat->bt_info_c2h[i]);
3794 
3795 	seq_printf(m, "**********************************************\n");
3796 	seq_printf(m, "\t\tWiFi Status\n");
3797 	seq_printf(m, "**********************************************\n");
3798 	seq_printf(m, "%-40s = %d\n",
3799 		   "Scanning", test_bit(RTW_FLAG_SCANNING, rtwdev->flags));
3800 	seq_printf(m, "%-40s = %u/ TX %d Mbps/ RX %d Mbps\n",
3801 		   "G_busy/ TX/ RX",
3802 		   coex_stat->wl_gl_busy,
3803 		   rtwdev->stats.tx_throughput, rtwdev->stats.rx_throughput);
3804 	seq_printf(m, "%-40s = %u/ %u/ %u\n",
3805 		   "IPS/ Low Power/ PS mode",
3806 		   test_bit(RTW_FLAG_INACTIVE_PS, rtwdev->flags),
3807 		   test_bit(RTW_FLAG_LEISURE_PS_DEEP, rtwdev->flags),
3808 		   rtwdev->lps_conf.mode);
3809 
3810 	vif_iter_data.rtwdev = rtwdev;
3811 	vif_iter_data.file = m;
3812 	rtw_iterate_vifs_atomic(rtwdev, rtw_coex_vif_stat_iter, &vif_iter_data);
3813 
3814 	if (coex->manual_control) {
3815 		seq_printf(m, "**********************************************\n");
3816 		seq_printf(m, "\t\tMechanism (Under Manual)\n");
3817 		seq_printf(m, "**********************************************\n");
3818 		seq_printf(m, "%-40s = %5ph (%d)\n",
3819 			   "TDMA Now",
3820 			   coex_dm->fw_tdma_para,
3821 			   rtw_coex_get_tdma_index(rtwdev,
3822 						   &coex_dm->fw_tdma_para[0]));
3823 	} else {
3824 		seq_printf(m, "**********************************************\n");
3825 		seq_printf(m, "\t\tMechanism\n");
3826 		seq_printf(m, "**********************************************\n");
3827 		seq_printf(m, "%-40s = %5ph (case-%d)\n",
3828 			   "TDMA",
3829 			   coex_dm->ps_tdma_para, coex_dm->cur_ps_tdma);
3830 	}
3831 	seq_printf(m, "%-40s = %s/ %s/ %d\n",
3832 		   "Coex Mode/Free Run/Timer base",
3833 		   rtw_coex_get_wl_coex_mode(coex_stat->wl_coex_mode),
3834 		   coex->freerun ? "Yes" : "No",
3835 		   coex_stat->tdma_timer_base);
3836 	seq_printf(m, "%-40s = %d(%d)/ 0x%08x/ 0x%08x/ 0x%08x\n",
3837 		   "Table/ 0x6c0/ 0x6c4/ 0x6c8",
3838 		   coex_dm->cur_table,
3839 		   rtw_coex_get_table_index(rtwdev, wl_reg_6c0, wl_reg_6c4),
3840 		   wl_reg_6c0, wl_reg_6c4, wl_reg_6c8);
3841 	seq_printf(m, "%-40s = 0x%08x/ 0x%08x/ %d/ reason (%s)\n",
3842 		   "0x778/ 0x6cc/ Run Count/ Reason",
3843 		   wl_reg_778, wl_reg_6cc,
3844 		   coex_stat->cnt_wl[COEX_CNT_WL_COEXRUN],
3845 		   rtw_coex_get_reason_string(reason));
3846 	seq_printf(m, "%-40s = %3ph\n",
3847 		   "AFH Map to BT",
3848 		   coex_dm->wl_ch_info);
3849 	seq_printf(m, "%-40s = %s/ %d\n",
3850 		   "AntDiv/ BtCtrlLPS/ g_busy",
3851 		   coex_stat->wl_force_lps_ctrl ? "On" : "Off",
3852 		   coex_stat->wl_gl_busy);
3853 	seq_printf(m, "%-40s = %u/ %u/ %u/ %u/ %u\n",
3854 		   "Null All/ Retry/ Ack/ BT Empty/ BT Late",
3855 		   coex_stat->wl_fw_dbg_info[1], coex_stat->wl_fw_dbg_info[2],
3856 		   coex_stat->wl_fw_dbg_info[3], coex_stat->wl_fw_dbg_info[4],
3857 		   coex_stat->wl_fw_dbg_info[5]);
3858 	seq_printf(m, "%-40s = %u/ %u/ %s/ %u\n",
3859 		   "Cnt TDMA Toggle/ Lk 5ms/ Lk 5ms on/ FW",
3860 		   coex_stat->wl_fw_dbg_info[6],
3861 		   coex_stat->wl_fw_dbg_info[7],
3862 		   coex_stat->wl_slot_extend ? "Yes" : "No",
3863 		   coex_stat->cnt_wl[COEX_CNT_WL_FW_NOTIFY]);
3864 	seq_printf(m, "%-40s = %d/ %d/ %s/ %d\n",
3865 		   "WL_TxPw/ BT_TxPw/ WL_Rx/ BT_LNA_Lvl",
3866 		   coex_dm->cur_wl_pwr_lvl,
3867 		   coex_dm->cur_bt_pwr_lvl,
3868 		   coex_dm->cur_wl_rx_low_gain_en ? "On" : "Off",
3869 		   coex_dm->cur_bt_lna_lvl);
3870 
3871 	seq_printf(m, "**********************************************\n");
3872 	seq_printf(m, "\t\tHW setting\n");
3873 	seq_printf(m, "**********************************************\n");
3874 	seq_printf(m, "%-40s = %s/ %s\n",
3875 		   "LTE Coex/ Path Owner",
3876 		   lte_coex & BIT(7) ? "ON" : "OFF",
3877 		   sys_lte & BIT(2) ? "WL" : "BT");
3878 	seq_printf(m, "%-40s = RF:%s_BB:%s/ RF:%s_BB:%s/ %s\n",
3879 		   "GNT_WL_CTRL/ GNT_BT_CTRL/ Dbg",
3880 		   lte_coex & BIT(12) ? "SW" : "HW",
3881 		   lte_coex & BIT(8) ? "SW" : "HW",
3882 		   lte_coex & BIT(14) ? "SW" : "HW",
3883 		   lte_coex & BIT(10) ? "SW" : "HW",
3884 		   sys_lte & BIT(3) ? "On" : "Off");
3885 	seq_printf(m, "%-40s = %lu/ %lu\n",
3886 		   "GNT_WL/ GNT_BT",
3887 		   (bt_coex & BIT(2)) >> 2, (bt_coex & BIT(3)) >> 3);
3888 	seq_printf(m, "%-40s = %u/ %u/ %u/ %u\n",
3889 		   "CRC OK CCK/ OFDM/ HT/ VHT",
3890 		   dm_info->cck_ok_cnt, dm_info->ofdm_ok_cnt,
3891 		   dm_info->ht_ok_cnt, dm_info->vht_ok_cnt);
3892 	seq_printf(m, "%-40s = %u/ %u/ %u/ %u\n",
3893 		   "CRC ERR CCK/ OFDM/ HT/ VHT",
3894 		   dm_info->cck_err_cnt, dm_info->ofdm_err_cnt,
3895 		   dm_info->ht_err_cnt, dm_info->vht_err_cnt);
3896 	seq_printf(m, "%-40s = %s/ %s/ %s/ %u\n",
3897 		   "HiPr/ Locking/ Locked/ Noisy",
3898 		   coex_stat->wl_hi_pri_task1 ? "Y" : "N",
3899 		   coex_stat->wl_cck_lock ? "Y" : "N",
3900 		   coex_stat->wl_cck_lock_ever ? "Y" : "N",
3901 		   coex_stat->wl_noisy_level);
3902 
3903 	rtw_coex_set_coexinfo_hw(rtwdev, m);
3904 	seq_printf(m, "%-40s = %d/ %d/ %d/ %d\n",
3905 		   "EVM A/ EVM B/ SNR A/ SNR B",
3906 		   -dm_info->rx_evm_dbm[RF_PATH_A],
3907 		   -dm_info->rx_evm_dbm[RF_PATH_B],
3908 		   -dm_info->rx_snr[RF_PATH_A],
3909 		   -dm_info->rx_snr[RF_PATH_B]);
3910 	seq_printf(m, "%-40s = %d/ %d/ %d/ %d\n",
3911 		   "CCK-CCA/CCK-FA/OFDM-CCA/OFDM-FA",
3912 		   dm_info->cck_cca_cnt, dm_info->cck_fa_cnt,
3913 		   dm_info->ofdm_cca_cnt, dm_info->ofdm_fa_cnt);
3914 	seq_printf(m, "%-40s = %d/ %d/ %d/ %d\n", "CRC OK CCK/11g/11n/11ac",
3915 		   dm_info->cck_ok_cnt, dm_info->ofdm_ok_cnt,
3916 		   dm_info->ht_ok_cnt, dm_info->vht_ok_cnt);
3917 	seq_printf(m, "%-40s = %d/ %d/ %d/ %d\n", "CRC Err CCK/11g/11n/11ac",
3918 		   dm_info->cck_err_cnt, dm_info->ofdm_err_cnt,
3919 		   dm_info->ht_err_cnt, dm_info->vht_err_cnt);
3920 
3921 }
3922 #endif /* CONFIG_RTW88_DEBUGFS */
3923