xref: /linux/drivers/staging/rtl8723bs/hal/HalBtc8723b1Ant.c (revision 762f99f4f3cb41a775b5157dd761217beba65873)
1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
5  *
6  ******************************************************************************/
7 
8 #include "Mp_Precomp.h"
9 
10 /*  Global variables, these are static variables */
11 static struct coex_dm_8723b_1ant GLCoexDm8723b1Ant;
12 static struct coex_dm_8723b_1ant *pCoexDm = &GLCoexDm8723b1Ant;
13 static struct coex_sta_8723b_1ant GLCoexSta8723b1Ant;
14 static struct coex_sta_8723b_1ant *pCoexSta = &GLCoexSta8723b1Ant;
15 
16 /*  local function proto type if needed */
17 /*  local function start with halbtc8723b1ant_ */
halbtc8723b1ant_BtRssiState(u8 levelNum,u8 rssiThresh,u8 rssiThresh1)18 static u8 halbtc8723b1ant_BtRssiState(
19 	u8 levelNum, u8 rssiThresh, u8 rssiThresh1
20 )
21 {
22 	s32 btRssi = 0;
23 	u8 btRssiState = pCoexSta->preBtRssiState;
24 
25 	btRssi = pCoexSta->btRssi;
26 
27 	if (levelNum == 2) {
28 		if (
29 			(pCoexSta->preBtRssiState == BTC_RSSI_STATE_LOW) ||
30 			(pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_LOW)
31 		) {
32 			if (btRssi >= (rssiThresh + BTC_RSSI_COEX_THRESH_TOL_8723B_1ANT))
33 
34 				btRssiState = BTC_RSSI_STATE_HIGH;
35 			else
36 				btRssiState = BTC_RSSI_STATE_STAY_LOW;
37 		} else {
38 			if (btRssi < rssiThresh)
39 				btRssiState = BTC_RSSI_STATE_LOW;
40 			else
41 				btRssiState = BTC_RSSI_STATE_STAY_HIGH;
42 		}
43 	} else if (levelNum == 3) {
44 		if (rssiThresh > rssiThresh1)
45 			return pCoexSta->preBtRssiState;
46 
47 		if (
48 			(pCoexSta->preBtRssiState == BTC_RSSI_STATE_LOW) ||
49 			(pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_LOW)
50 		) {
51 			if (btRssi >= (rssiThresh + BTC_RSSI_COEX_THRESH_TOL_8723B_1ANT))
52 				btRssiState = BTC_RSSI_STATE_MEDIUM;
53 			else
54 				btRssiState = BTC_RSSI_STATE_STAY_LOW;
55 		} else if (
56 			(pCoexSta->preBtRssiState == BTC_RSSI_STATE_MEDIUM) ||
57 			(pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_MEDIUM)
58 		) {
59 			if (btRssi >= (rssiThresh1 + BTC_RSSI_COEX_THRESH_TOL_8723B_1ANT))
60 				btRssiState = BTC_RSSI_STATE_HIGH;
61 			else if (btRssi < rssiThresh)
62 				btRssiState = BTC_RSSI_STATE_LOW;
63 			else
64 				btRssiState = BTC_RSSI_STATE_STAY_MEDIUM;
65 		} else {
66 			if (btRssi < rssiThresh1)
67 				btRssiState = BTC_RSSI_STATE_MEDIUM;
68 			else
69 				btRssiState = BTC_RSSI_STATE_STAY_HIGH;
70 		}
71 	}
72 
73 	pCoexSta->preBtRssiState = btRssiState;
74 
75 	return btRssiState;
76 }
77 
halbtc8723b1ant_UpdateRaMask(struct btc_coexist * pBtCoexist,bool bForceExec,u32 disRateMask)78 static void halbtc8723b1ant_UpdateRaMask(
79 	struct btc_coexist *pBtCoexist, bool bForceExec, u32 disRateMask
80 )
81 {
82 	pCoexDm->curRaMask = disRateMask;
83 
84 	if (bForceExec || (pCoexDm->preRaMask != pCoexDm->curRaMask))
85 		pBtCoexist->fBtcSet(
86 			pBtCoexist,
87 			BTC_SET_ACT_UPDATE_RAMASK,
88 			&pCoexDm->curRaMask
89 		);
90 	pCoexDm->preRaMask = pCoexDm->curRaMask;
91 }
92 
halbtc8723b1ant_AutoRateFallbackRetry(struct btc_coexist * pBtCoexist,bool bForceExec,u8 type)93 static void halbtc8723b1ant_AutoRateFallbackRetry(
94 	struct btc_coexist *pBtCoexist, bool bForceExec, u8 type
95 )
96 {
97 	bool bWifiUnderBMode = false;
98 
99 	pCoexDm->curArfrType = type;
100 
101 	if (bForceExec || (pCoexDm->preArfrType != pCoexDm->curArfrType)) {
102 		switch (pCoexDm->curArfrType) {
103 		case 0:	/*  normal mode */
104 			pBtCoexist->fBtcWrite4Byte(
105 				pBtCoexist, 0x430, pCoexDm->backupArfrCnt1
106 			);
107 			pBtCoexist->fBtcWrite4Byte(
108 				pBtCoexist, 0x434, pCoexDm->backupArfrCnt2
109 			);
110 			break;
111 		case 1:
112 			pBtCoexist->fBtcGet(
113 				pBtCoexist, BTC_GET_BL_WIFI_UNDER_B_MODE, &bWifiUnderBMode
114 			);
115 			if (bWifiUnderBMode) {
116 				pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x430, 0x0);
117 				pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x434, 0x01010101);
118 			} else {
119 				pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x430, 0x0);
120 				pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x434, 0x04030201);
121 			}
122 			break;
123 		default:
124 			break;
125 		}
126 	}
127 
128 	pCoexDm->preArfrType = pCoexDm->curArfrType;
129 }
130 
halbtc8723b1ant_RetryLimit(struct btc_coexist * pBtCoexist,bool bForceExec,u8 type)131 static void halbtc8723b1ant_RetryLimit(
132 	struct btc_coexist *pBtCoexist, bool bForceExec, u8 type
133 )
134 {
135 	pCoexDm->curRetryLimitType = type;
136 
137 	if (
138 		bForceExec ||
139 		(pCoexDm->preRetryLimitType != pCoexDm->curRetryLimitType)
140 	) {
141 		switch (pCoexDm->curRetryLimitType) {
142 		case 0:	/*  normal mode */
143 			pBtCoexist->fBtcWrite2Byte(
144 				pBtCoexist, 0x42a, pCoexDm->backupRetryLimit
145 			);
146 			break;
147 		case 1:	/*  retry limit =8 */
148 			pBtCoexist->fBtcWrite2Byte(pBtCoexist, 0x42a, 0x0808);
149 			break;
150 		default:
151 			break;
152 		}
153 	}
154 
155 	pCoexDm->preRetryLimitType = pCoexDm->curRetryLimitType;
156 }
157 
halbtc8723b1ant_AmpduMaxTime(struct btc_coexist * pBtCoexist,bool bForceExec,u8 type)158 static void halbtc8723b1ant_AmpduMaxTime(
159 	struct btc_coexist *pBtCoexist, bool bForceExec, u8 type
160 )
161 {
162 	pCoexDm->curAmpduTimeType = type;
163 
164 	if (
165 		bForceExec || (pCoexDm->preAmpduTimeType != pCoexDm->curAmpduTimeType)
166 	) {
167 		switch (pCoexDm->curAmpduTimeType) {
168 		case 0:	/*  normal mode */
169 			pBtCoexist->fBtcWrite1Byte(
170 				pBtCoexist, 0x456, pCoexDm->backupAmpduMaxTime
171 			);
172 			break;
173 		case 1:	/*  AMPDU timw = 0x38 * 32us */
174 			pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x456, 0x38);
175 			break;
176 		default:
177 			break;
178 		}
179 	}
180 
181 	pCoexDm->preAmpduTimeType = pCoexDm->curAmpduTimeType;
182 }
183 
halbtc8723b1ant_LimitedTx(struct btc_coexist * pBtCoexist,bool bForceExec,u8 raMaskType,u8 arfrType,u8 retryLimitType,u8 ampduTimeType)184 static void halbtc8723b1ant_LimitedTx(
185 	struct btc_coexist *pBtCoexist,
186 	bool bForceExec,
187 	u8 raMaskType,
188 	u8 arfrType,
189 	u8 retryLimitType,
190 	u8 ampduTimeType
191 )
192 {
193 	switch (raMaskType) {
194 	case 0:	/*  normal mode */
195 		halbtc8723b1ant_UpdateRaMask(pBtCoexist, bForceExec, 0x0);
196 		break;
197 	case 1:	/*  disable cck 1/2 */
198 		halbtc8723b1ant_UpdateRaMask(pBtCoexist, bForceExec, 0x00000003);
199 		break;
200 	case 2:	/*  disable cck 1/2/5.5, ofdm 6/9/12/18/24, mcs 0/1/2/3/4 */
201 		halbtc8723b1ant_UpdateRaMask(pBtCoexist, bForceExec, 0x0001f1f7);
202 		break;
203 	default:
204 		break;
205 	}
206 
207 	halbtc8723b1ant_AutoRateFallbackRetry(pBtCoexist, bForceExec, arfrType);
208 	halbtc8723b1ant_RetryLimit(pBtCoexist, bForceExec, retryLimitType);
209 	halbtc8723b1ant_AmpduMaxTime(pBtCoexist, bForceExec, ampduTimeType);
210 }
211 
halbtc8723b1ant_LimitedRx(struct btc_coexist * pBtCoexist,bool bForceExec,bool bRejApAggPkt,bool bBtCtrlAggBufSize,u8 aggBufSize)212 static void halbtc8723b1ant_LimitedRx(
213 	struct btc_coexist *pBtCoexist,
214 	bool bForceExec,
215 	bool bRejApAggPkt,
216 	bool bBtCtrlAggBufSize,
217 	u8 aggBufSize
218 )
219 {
220 	bool bRejectRxAgg = bRejApAggPkt;
221 	bool bBtCtrlRxAggSize = bBtCtrlAggBufSize;
222 	u8 rxAggSize = aggBufSize;
223 
224 	/*  */
225 	/*	Rx Aggregation related setting */
226 	/*  */
227 	pBtCoexist->fBtcSet(
228 		pBtCoexist, BTC_SET_BL_TO_REJ_AP_AGG_PKT, &bRejectRxAgg
229 	);
230 	/*  decide BT control aggregation buf size or not */
231 	pBtCoexist->fBtcSet(
232 		pBtCoexist, BTC_SET_BL_BT_CTRL_AGG_SIZE, &bBtCtrlRxAggSize
233 	);
234 	/*  aggregation buf size, only work when BT control Rx aggregation size. */
235 	pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_U1_AGG_BUF_SIZE, &rxAggSize);
236 	/*  real update aggregation setting */
237 	pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL);
238 
239 
240 }
241 
halbtc8723b1ant_QueryBtInfo(struct btc_coexist * pBtCoexist)242 static void halbtc8723b1ant_QueryBtInfo(struct btc_coexist *pBtCoexist)
243 {
244 	u8 H2C_Parameter[1] = {0};
245 
246 	pCoexSta->bC2hBtInfoReqSent = true;
247 
248 	H2C_Parameter[0] |= BIT0;	/*  trigger */
249 
250 	pBtCoexist->fBtcFillH2c(pBtCoexist, 0x61, 1, H2C_Parameter);
251 }
252 
halbtc8723b1ant_MonitorBtCtr(struct btc_coexist * pBtCoexist)253 static void halbtc8723b1ant_MonitorBtCtr(struct btc_coexist *pBtCoexist)
254 {
255 	u32 regHPTxRx, regLPTxRx, u4Tmp;
256 	u32 regHPTx = 0, regHPRx = 0, regLPTx = 0, regLPRx = 0;
257 	static u8 NumOfBtCounterChk;
258 
259        /* to avoid 0x76e[3] = 1 (WLAN_Act control by PTA) during IPS */
260 	/* if (! (pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x76e) & 0x8)) */
261 
262 	if (pCoexSta->bUnderIps) {
263 		pCoexSta->highPriorityTx = 65535;
264 		pCoexSta->highPriorityRx = 65535;
265 		pCoexSta->lowPriorityTx = 65535;
266 		pCoexSta->lowPriorityRx = 65535;
267 		return;
268 	}
269 
270 	regHPTxRx = 0x770;
271 	regLPTxRx = 0x774;
272 
273 	u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, regHPTxRx);
274 	regHPTx = u4Tmp & bMaskLWord;
275 	regHPRx = (u4Tmp & bMaskHWord) >> 16;
276 
277 	u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, regLPTxRx);
278 	regLPTx = u4Tmp & bMaskLWord;
279 	regLPRx = (u4Tmp & bMaskHWord) >> 16;
280 
281 	pCoexSta->highPriorityTx = regHPTx;
282 	pCoexSta->highPriorityRx = regHPRx;
283 	pCoexSta->lowPriorityTx = regLPTx;
284 	pCoexSta->lowPriorityRx = regLPRx;
285 
286 	if ((pCoexSta->lowPriorityTx >= 1050) && (!pCoexSta->bC2hBtInquiryPage))
287 		pCoexSta->popEventCnt++;
288 
289 	/*  reset counter */
290 	pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0xc);
291 
292 	if ((regHPTx == 0) && (regHPRx == 0) && (regLPTx == 0) && (regLPRx == 0)) {
293 		NumOfBtCounterChk++;
294 		if (NumOfBtCounterChk >= 3) {
295 			halbtc8723b1ant_QueryBtInfo(pBtCoexist);
296 			NumOfBtCounterChk = 0;
297 		}
298 	}
299 }
300 
301 
halbtc8723b1ant_MonitorWiFiCtr(struct btc_coexist * pBtCoexist)302 static void halbtc8723b1ant_MonitorWiFiCtr(struct btc_coexist *pBtCoexist)
303 {
304 	s32	wifiRssi = 0;
305 	bool bWifiBusy = false, bWifiUnderBMode = false;
306 	static u8 nCCKLockCounter;
307 
308 	pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy);
309 	pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi);
310 	pBtCoexist->fBtcGet(
311 		pBtCoexist, BTC_GET_BL_WIFI_UNDER_B_MODE, &bWifiUnderBMode
312 	);
313 
314 	if (pCoexSta->bUnderIps) {
315 		pCoexSta->nCRCOK_CCK = 0;
316 		pCoexSta->nCRCOK_11g = 0;
317 		pCoexSta->nCRCOK_11n = 0;
318 		pCoexSta->nCRCOK_11nAgg = 0;
319 
320 		pCoexSta->nCRCErr_CCK = 0;
321 		pCoexSta->nCRCErr_11g = 0;
322 		pCoexSta->nCRCErr_11n = 0;
323 		pCoexSta->nCRCErr_11nAgg = 0;
324 	} else {
325 		pCoexSta->nCRCOK_CCK	= pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xf88);
326 		pCoexSta->nCRCOK_11g	= pBtCoexist->fBtcRead2Byte(pBtCoexist, 0xf94);
327 		pCoexSta->nCRCOK_11n	= pBtCoexist->fBtcRead2Byte(pBtCoexist, 0xf90);
328 		pCoexSta->nCRCOK_11nAgg = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0xfb8);
329 
330 		pCoexSta->nCRCErr_CCK	 = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xf84);
331 		pCoexSta->nCRCErr_11g	 = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0xf96);
332 		pCoexSta->nCRCErr_11n	 = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0xf92);
333 		pCoexSta->nCRCErr_11nAgg = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0xfba);
334 	}
335 
336 
337 	/* reset counter */
338 	pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0xf16, 0x1, 0x1);
339 	pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0xf16, 0x1, 0x0);
340 
341 	if (bWifiBusy && (wifiRssi >= 30) && !bWifiUnderBMode) {
342 		if (
343 			(pCoexDm->btStatus == BT_8723B_1ANT_BT_STATUS_ACL_BUSY) ||
344 			(pCoexDm->btStatus == BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY) ||
345 			(pCoexDm->btStatus == BT_8723B_1ANT_BT_STATUS_SCO_BUSY)
346 		) {
347 			if (
348 				pCoexSta->nCRCOK_CCK > (
349 					pCoexSta->nCRCOK_11g +
350 					pCoexSta->nCRCOK_11n +
351 					pCoexSta->nCRCOK_11nAgg
352 				)
353 			) {
354 				if (nCCKLockCounter < 5)
355 					nCCKLockCounter++;
356 			} else {
357 				if (nCCKLockCounter > 0)
358 					nCCKLockCounter--;
359 			}
360 
361 		} else {
362 			if (nCCKLockCounter > 0)
363 				nCCKLockCounter--;
364 		}
365 	} else {
366 		if (nCCKLockCounter > 0)
367 			nCCKLockCounter--;
368 	}
369 
370 	if (!pCoexSta->bPreCCKLock) {
371 
372 		if (nCCKLockCounter >= 5)
373 			pCoexSta->bCCKLock = true;
374 		else
375 			pCoexSta->bCCKLock = false;
376 	} else {
377 		if (nCCKLockCounter == 0)
378 			pCoexSta->bCCKLock = false;
379 		else
380 			pCoexSta->bCCKLock = true;
381 	}
382 
383 	pCoexSta->bPreCCKLock =  pCoexSta->bCCKLock;
384 
385 
386 }
387 
halbtc8723b1ant_IsWifiStatusChanged(struct btc_coexist * pBtCoexist)388 static bool halbtc8723b1ant_IsWifiStatusChanged(struct btc_coexist *pBtCoexist)
389 {
390 	static bool	bPreWifiBusy, bPreUnder4way, bPreBtHsOn;
391 	bool bWifiBusy = false, bUnder4way = false, bBtHsOn = false;
392 	bool bWifiConnected = false;
393 
394 	pBtCoexist->fBtcGet(
395 		pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected
396 	);
397 	pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy);
398 	pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn);
399 	pBtCoexist->fBtcGet(
400 		pBtCoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &bUnder4way
401 	);
402 
403 	if (bWifiConnected) {
404 		if (bWifiBusy != bPreWifiBusy) {
405 			bPreWifiBusy = bWifiBusy;
406 			return true;
407 		}
408 
409 		if (bUnder4way != bPreUnder4way) {
410 			bPreUnder4way = bUnder4way;
411 			return true;
412 		}
413 
414 		if (bBtHsOn != bPreBtHsOn) {
415 			bPreBtHsOn = bBtHsOn;
416 			return true;
417 		}
418 	}
419 
420 	return false;
421 }
422 
halbtc8723b1ant_UpdateBtLinkInfo(struct btc_coexist * pBtCoexist)423 static void halbtc8723b1ant_UpdateBtLinkInfo(struct btc_coexist *pBtCoexist)
424 {
425 	struct btc_bt_link_info *pBtLinkInfo = &pBtCoexist->btLinkInfo;
426 	bool bBtHsOn = false;
427 
428 	pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn);
429 
430 	pBtLinkInfo->bBtLinkExist = pCoexSta->bBtLinkExist;
431 	pBtLinkInfo->bScoExist = pCoexSta->bScoExist;
432 	pBtLinkInfo->bA2dpExist = pCoexSta->bA2dpExist;
433 	pBtLinkInfo->bPanExist = pCoexSta->bPanExist;
434 	pBtLinkInfo->bHidExist = pCoexSta->bHidExist;
435 
436 	/*  work around for HS mode. */
437 	if (bBtHsOn) {
438 		pBtLinkInfo->bPanExist = true;
439 		pBtLinkInfo->bBtLinkExist = true;
440 	}
441 
442 	/*  check if Sco only */
443 	if (
444 		pBtLinkInfo->bScoExist &&
445 		!pBtLinkInfo->bA2dpExist &&
446 		!pBtLinkInfo->bPanExist &&
447 		!pBtLinkInfo->bHidExist
448 	)
449 		pBtLinkInfo->bScoOnly = true;
450 	else
451 		pBtLinkInfo->bScoOnly = false;
452 
453 	/*  check if A2dp only */
454 	if (
455 		!pBtLinkInfo->bScoExist &&
456 		pBtLinkInfo->bA2dpExist &&
457 		!pBtLinkInfo->bPanExist &&
458 		!pBtLinkInfo->bHidExist
459 	)
460 		pBtLinkInfo->bA2dpOnly = true;
461 	else
462 		pBtLinkInfo->bA2dpOnly = false;
463 
464 	/*  check if Pan only */
465 	if (
466 		!pBtLinkInfo->bScoExist &&
467 		!pBtLinkInfo->bA2dpExist &&
468 		pBtLinkInfo->bPanExist &&
469 		!pBtLinkInfo->bHidExist
470 	)
471 		pBtLinkInfo->bPanOnly = true;
472 	else
473 		pBtLinkInfo->bPanOnly = false;
474 
475 	/*  check if Hid only */
476 	if (
477 		!pBtLinkInfo->bScoExist &&
478 		!pBtLinkInfo->bA2dpExist &&
479 		!pBtLinkInfo->bPanExist &&
480 		pBtLinkInfo->bHidExist
481 	)
482 		pBtLinkInfo->bHidOnly = true;
483 	else
484 		pBtLinkInfo->bHidOnly = false;
485 }
486 
halbtc8723b1ant_ActionAlgorithm(struct btc_coexist * pBtCoexist)487 static u8 halbtc8723b1ant_ActionAlgorithm(struct btc_coexist *pBtCoexist)
488 {
489 	struct btc_bt_link_info *pBtLinkInfo = &pBtCoexist->btLinkInfo;
490 	bool bBtHsOn = false;
491 	u8 algorithm = BT_8723B_1ANT_COEX_ALGO_UNDEFINED;
492 	u8 numOfDiffProfile = 0;
493 
494 	pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn);
495 
496 	if (!pBtLinkInfo->bBtLinkExist)
497 		return algorithm;
498 
499 	if (pBtLinkInfo->bScoExist)
500 		numOfDiffProfile++;
501 	if (pBtLinkInfo->bHidExist)
502 		numOfDiffProfile++;
503 	if (pBtLinkInfo->bPanExist)
504 		numOfDiffProfile++;
505 	if (pBtLinkInfo->bA2dpExist)
506 		numOfDiffProfile++;
507 
508 	if (numOfDiffProfile == 1) {
509 		if (pBtLinkInfo->bScoExist) {
510 			algorithm = BT_8723B_1ANT_COEX_ALGO_SCO;
511 		} else {
512 			if (pBtLinkInfo->bHidExist) {
513 				algorithm = BT_8723B_1ANT_COEX_ALGO_HID;
514 			} else if (pBtLinkInfo->bA2dpExist) {
515 				algorithm = BT_8723B_1ANT_COEX_ALGO_A2DP;
516 			} else if (pBtLinkInfo->bPanExist) {
517 				if (bBtHsOn)
518 					algorithm = BT_8723B_1ANT_COEX_ALGO_PANHS;
519 				else
520 					algorithm = BT_8723B_1ANT_COEX_ALGO_PANEDR;
521 			}
522 		}
523 	} else if (numOfDiffProfile == 2) {
524 		if (pBtLinkInfo->bScoExist) {
525 			if (pBtLinkInfo->bHidExist) {
526 				algorithm = BT_8723B_1ANT_COEX_ALGO_HID;
527 			} else if (pBtLinkInfo->bA2dpExist) {
528 				algorithm = BT_8723B_1ANT_COEX_ALGO_SCO;
529 			} else if (pBtLinkInfo->bPanExist) {
530 				if (bBtHsOn)
531 					algorithm = BT_8723B_1ANT_COEX_ALGO_SCO;
532 				else
533 					algorithm = BT_8723B_1ANT_COEX_ALGO_PANEDR_HID;
534 			}
535 		} else {
536 			if (pBtLinkInfo->bHidExist && pBtLinkInfo->bA2dpExist) {
537 				algorithm = BT_8723B_1ANT_COEX_ALGO_HID_A2DP;
538 			} else if (pBtLinkInfo->bHidExist && pBtLinkInfo->bPanExist) {
539 				if (bBtHsOn)
540 					algorithm = BT_8723B_1ANT_COEX_ALGO_HID_A2DP;
541 				else
542 					algorithm = BT_8723B_1ANT_COEX_ALGO_PANEDR_HID;
543 			} else if (pBtLinkInfo->bPanExist && pBtLinkInfo->bA2dpExist) {
544 				if (bBtHsOn)
545 					algorithm = BT_8723B_1ANT_COEX_ALGO_A2DP_PANHS;
546 				else
547 					algorithm = BT_8723B_1ANT_COEX_ALGO_PANEDR_A2DP;
548 			}
549 		}
550 	} else if (numOfDiffProfile == 3) {
551 		if (pBtLinkInfo->bScoExist) {
552 			if (pBtLinkInfo->bHidExist && pBtLinkInfo->bA2dpExist) {
553 				algorithm = BT_8723B_1ANT_COEX_ALGO_HID;
554 			} else if (
555 				pBtLinkInfo->bHidExist && pBtLinkInfo->bPanExist
556 			) {
557 				if (bBtHsOn)
558 					algorithm = BT_8723B_1ANT_COEX_ALGO_HID_A2DP;
559 				else
560 					algorithm = BT_8723B_1ANT_COEX_ALGO_PANEDR_HID;
561 			} else if (pBtLinkInfo->bPanExist && pBtLinkInfo->bA2dpExist) {
562 				if (bBtHsOn)
563 					algorithm = BT_8723B_1ANT_COEX_ALGO_SCO;
564 				else
565 					algorithm = BT_8723B_1ANT_COEX_ALGO_PANEDR_HID;
566 			}
567 		} else {
568 			if (
569 				pBtLinkInfo->bHidExist &&
570 				pBtLinkInfo->bPanExist &&
571 				pBtLinkInfo->bA2dpExist
572 			) {
573 				if (bBtHsOn)
574 					algorithm = BT_8723B_1ANT_COEX_ALGO_HID_A2DP;
575 				else
576 					algorithm = BT_8723B_1ANT_COEX_ALGO_HID_A2DP_PANEDR;
577 			}
578 		}
579 	} else if (numOfDiffProfile >= 3) {
580 		if (pBtLinkInfo->bScoExist) {
581 			if (
582 				pBtLinkInfo->bHidExist &&
583 				pBtLinkInfo->bPanExist &&
584 				pBtLinkInfo->bA2dpExist
585 			) {
586 				if (!bBtHsOn)
587 					algorithm = BT_8723B_1ANT_COEX_ALGO_PANEDR_HID;
588 
589 			}
590 		}
591 	}
592 
593 	return algorithm;
594 }
595 
halbtc8723b1ant_SetSwPenaltyTxRateAdaptive(struct btc_coexist * pBtCoexist,bool bLowPenaltyRa)596 static void halbtc8723b1ant_SetSwPenaltyTxRateAdaptive(
597 	struct btc_coexist *pBtCoexist, bool bLowPenaltyRa
598 )
599 {
600 	u8 H2C_Parameter[6] = {0};
601 
602 	H2C_Parameter[0] = 0x6;	/*  opCode, 0x6 = Retry_Penalty */
603 
604 	if (bLowPenaltyRa) {
605 		H2C_Parameter[1] |= BIT0;
606 		H2C_Parameter[2] = 0x00;  /* normal rate except MCS7/6/5, OFDM54/48/36 */
607 		H2C_Parameter[3] = 0xf7;  /* MCS7 or OFDM54 */
608 		H2C_Parameter[4] = 0xf8;  /* MCS6 or OFDM48 */
609 		H2C_Parameter[5] = 0xf9;	/* MCS5 or OFDM36 */
610 	}
611 
612 	pBtCoexist->fBtcFillH2c(pBtCoexist, 0x69, 6, H2C_Parameter);
613 }
614 
halbtc8723b1ant_LowPenaltyRa(struct btc_coexist * pBtCoexist,bool bForceExec,bool bLowPenaltyRa)615 static void halbtc8723b1ant_LowPenaltyRa(
616 	struct btc_coexist *pBtCoexist, bool bForceExec, bool bLowPenaltyRa
617 )
618 {
619 	pCoexDm->bCurLowPenaltyRa = bLowPenaltyRa;
620 
621 	if (!bForceExec) {
622 		if (pCoexDm->bPreLowPenaltyRa == pCoexDm->bCurLowPenaltyRa)
623 			return;
624 	}
625 	halbtc8723b1ant_SetSwPenaltyTxRateAdaptive(
626 		pBtCoexist, pCoexDm->bCurLowPenaltyRa
627 	);
628 
629 	pCoexDm->bPreLowPenaltyRa = pCoexDm->bCurLowPenaltyRa;
630 }
631 
halbtc8723b1ant_SetCoexTable(struct btc_coexist * pBtCoexist,u32 val0x6c0,u32 val0x6c4,u32 val0x6c8,u8 val0x6cc)632 static void halbtc8723b1ant_SetCoexTable(
633 	struct btc_coexist *pBtCoexist,
634 	u32 val0x6c0,
635 	u32 val0x6c4,
636 	u32 val0x6c8,
637 	u8 val0x6cc
638 )
639 {
640 	pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c0, val0x6c0);
641 
642 	pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c4, val0x6c4);
643 
644 	pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c8, val0x6c8);
645 
646 	pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cc, val0x6cc);
647 }
648 
halbtc8723b1ant_CoexTable(struct btc_coexist * pBtCoexist,bool bForceExec,u32 val0x6c0,u32 val0x6c4,u32 val0x6c8,u8 val0x6cc)649 static void halbtc8723b1ant_CoexTable(
650 	struct btc_coexist *pBtCoexist,
651 	bool bForceExec,
652 	u32 val0x6c0,
653 	u32 val0x6c4,
654 	u32 val0x6c8,
655 	u8 val0x6cc
656 )
657 {
658 	pCoexDm->curVal0x6c0 = val0x6c0;
659 	pCoexDm->curVal0x6c4 = val0x6c4;
660 	pCoexDm->curVal0x6c8 = val0x6c8;
661 	pCoexDm->curVal0x6cc = val0x6cc;
662 
663 	if (!bForceExec) {
664 		if (
665 			(pCoexDm->preVal0x6c0 == pCoexDm->curVal0x6c0) &&
666 		    (pCoexDm->preVal0x6c4 == pCoexDm->curVal0x6c4) &&
667 		    (pCoexDm->preVal0x6c8 == pCoexDm->curVal0x6c8) &&
668 		    (pCoexDm->preVal0x6cc == pCoexDm->curVal0x6cc)
669 		)
670 			return;
671 	}
672 
673 	halbtc8723b1ant_SetCoexTable(
674 		pBtCoexist, val0x6c0, val0x6c4, val0x6c8, val0x6cc
675 	);
676 
677 	pCoexDm->preVal0x6c0 = pCoexDm->curVal0x6c0;
678 	pCoexDm->preVal0x6c4 = pCoexDm->curVal0x6c4;
679 	pCoexDm->preVal0x6c8 = pCoexDm->curVal0x6c8;
680 	pCoexDm->preVal0x6cc = pCoexDm->curVal0x6cc;
681 }
682 
halbtc8723b1ant_CoexTableWithType(struct btc_coexist * pBtCoexist,bool bForceExec,u8 type)683 static void halbtc8723b1ant_CoexTableWithType(
684 	struct btc_coexist *pBtCoexist, bool bForceExec, u8 type
685 )
686 {
687 	pCoexSta->nCoexTableType = type;
688 
689 	switch (type) {
690 	case 0:
691 		halbtc8723b1ant_CoexTable(
692 			pBtCoexist, bForceExec, 0x55555555, 0x55555555, 0xffffff, 0x3
693 		);
694 		break;
695 	case 1:
696 		halbtc8723b1ant_CoexTable(
697 			pBtCoexist, bForceExec, 0x55555555, 0x5a5a5a5a, 0xffffff, 0x3
698 		);
699 		break;
700 	case 2:
701 		halbtc8723b1ant_CoexTable(
702 			pBtCoexist, bForceExec, 0x5a5a5a5a, 0x5a5a5a5a, 0xffffff, 0x3
703 		);
704 		break;
705 	case 3:
706 		halbtc8723b1ant_CoexTable(
707 			pBtCoexist, bForceExec, 0xaaaa5555, 0xaaaa5a5a, 0xffffff, 0x3
708 		);
709 		break;
710 	case 4:
711 		halbtc8723b1ant_CoexTable(
712 			pBtCoexist, bForceExec, 0x55555555, 0xaaaa5a5a, 0xffffff, 0x3
713 		);
714 		break;
715 	case 5:
716 		halbtc8723b1ant_CoexTable(
717 			pBtCoexist, bForceExec, 0x5a5a5a5a, 0xaaaa5a5a, 0xffffff, 0x3
718 		);
719 		break;
720 	case 6:
721 		halbtc8723b1ant_CoexTable(
722 			pBtCoexist, bForceExec, 0x55555555, 0xaaaaaaaa, 0xffffff, 0x3
723 		);
724 		break;
725 	case 7:
726 		halbtc8723b1ant_CoexTable(
727 			pBtCoexist, bForceExec, 0xaaaaaaaa, 0xaaaaaaaa, 0xffffff, 0x3
728 		);
729 		break;
730 	default:
731 		break;
732 	}
733 }
734 
halbtc8723b1ant_SetFwIgnoreWlanAct(struct btc_coexist * pBtCoexist,bool bEnable)735 static void halbtc8723b1ant_SetFwIgnoreWlanAct(
736 	struct btc_coexist *pBtCoexist, bool bEnable
737 )
738 {
739 	u8 H2C_Parameter[1] = {0};
740 
741 	if (bEnable)
742 		H2C_Parameter[0] |= BIT0; /* function enable */
743 
744 	pBtCoexist->fBtcFillH2c(pBtCoexist, 0x63, 1, H2C_Parameter);
745 }
746 
halbtc8723b1ant_IgnoreWlanAct(struct btc_coexist * pBtCoexist,bool bForceExec,bool bEnable)747 static void halbtc8723b1ant_IgnoreWlanAct(
748 	struct btc_coexist *pBtCoexist, bool bForceExec, bool bEnable
749 )
750 {
751 	pCoexDm->bCurIgnoreWlanAct = bEnable;
752 
753 	if (!bForceExec) {
754 		if (pCoexDm->bPreIgnoreWlanAct == pCoexDm->bCurIgnoreWlanAct)
755 			return;
756 	}
757 	halbtc8723b1ant_SetFwIgnoreWlanAct(pBtCoexist, bEnable);
758 
759 	pCoexDm->bPreIgnoreWlanAct = pCoexDm->bCurIgnoreWlanAct;
760 }
761 
halbtc8723b1ant_SetLpsRpwm(struct btc_coexist * pBtCoexist,u8 lpsVal,u8 rpwmVal)762 static void halbtc8723b1ant_SetLpsRpwm(
763 	struct btc_coexist *pBtCoexist, u8 lpsVal, u8 rpwmVal
764 )
765 {
766 	u8 lps = lpsVal;
767 	u8 rpwm = rpwmVal;
768 
769 	pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_U1_LPS_VAL, &lps);
770 	pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_U1_RPWM_VAL, &rpwm);
771 }
772 
halbtc8723b1ant_LpsRpwm(struct btc_coexist * pBtCoexist,bool bForceExec,u8 lpsVal,u8 rpwmVal)773 static void halbtc8723b1ant_LpsRpwm(
774 	struct btc_coexist *pBtCoexist, bool bForceExec, u8 lpsVal, u8 rpwmVal
775 )
776 {
777 	pCoexDm->curLps = lpsVal;
778 	pCoexDm->curRpwm = rpwmVal;
779 
780 	if (!bForceExec) {
781 		if (
782 			(pCoexDm->preLps == pCoexDm->curLps) &&
783 			(pCoexDm->preRpwm == pCoexDm->curRpwm)
784 		) {
785 			return;
786 		}
787 	}
788 	halbtc8723b1ant_SetLpsRpwm(pBtCoexist, lpsVal, rpwmVal);
789 
790 	pCoexDm->preLps = pCoexDm->curLps;
791 	pCoexDm->preRpwm = pCoexDm->curRpwm;
792 }
793 
halbtc8723b1ant_SwMechanism(struct btc_coexist * pBtCoexist,bool bLowPenaltyRA)794 static void halbtc8723b1ant_SwMechanism(
795 	struct btc_coexist *pBtCoexist, bool bLowPenaltyRA
796 )
797 {
798 	halbtc8723b1ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, bLowPenaltyRA);
799 }
800 
halbtc8723b1ant_SetAntPath(struct btc_coexist * pBtCoexist,u8 antPosType,bool bInitHwCfg,bool bWifiOff)801 static void halbtc8723b1ant_SetAntPath(
802 	struct btc_coexist *pBtCoexist, u8 antPosType, bool bInitHwCfg, bool bWifiOff
803 )
804 {
805 	struct btc_board_info *pBoardInfo = &pBtCoexist->boardInfo;
806 	u32 fwVer = 0, u4Tmp = 0, cntBtCalChk = 0;
807 	bool bPgExtSwitch = false;
808 	bool bUseExtSwitch = false;
809 	bool bIsInMpMode = false;
810 	u8 H2C_Parameter[2] = {0}, u1Tmp = 0;
811 
812 	pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_EXT_SWITCH, &bPgExtSwitch);
813 	pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer); /*  [31:16]=fw ver, [15:0]=fw sub ver */
814 
815 	if ((fwVer > 0 && fwVer < 0xc0000) || bPgExtSwitch)
816 		bUseExtSwitch = true;
817 
818 	if (bInitHwCfg) {
819 		pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x780); /* WiFi TRx Mask on */
820 		pBtCoexist->fBtcSetBtReg(pBtCoexist, BTC_BT_REG_RF, 0x3c, 0x15); /* BT TRx Mask on */
821 
822 		if (fwVer >= 0x180000) {
823 			/* Use H2C to set GNT_BT to HIGH */
824 			H2C_Parameter[0] = 1;
825 			pBtCoexist->fBtcFillH2c(pBtCoexist, 0x6E, 1, H2C_Parameter);
826 		} else /*  set grant_bt to high */
827 			pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x765, 0x18);
828 
829 		/* set wlan_act control by PTA */
830 		pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0x4);
831 
832 		pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x67, 0x20, 0x1); /* BT select s0/s1 is controlled by WiFi */
833 
834 		pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x39, 0x8, 0x1);
835 		pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x974, 0xff);
836 		pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x944, 0x3, 0x3);
837 		pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x930, 0x77);
838 	} else if (bWifiOff) {
839 		if (fwVer >= 0x180000) {
840 			/* Use H2C to set GNT_BT to HIGH */
841 			H2C_Parameter[0] = 1;
842 			pBtCoexist->fBtcFillH2c(pBtCoexist, 0x6E, 1, H2C_Parameter);
843 		} else /*  set grant_bt to high */
844 			pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x765, 0x18);
845 
846 		/* set wlan_act to always low */
847 		pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0x4);
848 
849 		pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_IS_IN_MP_MODE, &bIsInMpMode);
850 		if (!bIsInMpMode)
851 			pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x67, 0x20, 0x0); /* BT select s0/s1 is controlled by BT */
852 		else
853 			pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x67, 0x20, 0x1); /* BT select s0/s1 is controlled by WiFi */
854 
855 		/*  0x4c[24:23]= 00, Set Antenna control by BT_RFE_CTRL	BT Vendor 0xac = 0xf002 */
856 		u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x4c);
857 		u4Tmp &= ~BIT23;
858 		u4Tmp &= ~BIT24;
859 		pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x4c, u4Tmp);
860 	} else {
861 		/* Use H2C to set GNT_BT to LOW */
862 		if (fwVer >= 0x180000) {
863 			if (pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x765) != 0) {
864 				H2C_Parameter[0] = 0;
865 				pBtCoexist->fBtcFillH2c(pBtCoexist, 0x6E, 1, H2C_Parameter);
866 			}
867 		} else {
868 			/*  BT calibration check */
869 			while (cntBtCalChk <= 20) {
870 				u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x49d);
871 				cntBtCalChk++;
872 
873 				if (u1Tmp & BIT0)
874 					mdelay(50);
875 				else
876 					break;
877 			}
878 
879 			/*  set grant_bt to PTA */
880 			pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x765, 0x0);
881 		}
882 
883 		if (pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x76e) != 0xc)
884 			/* set wlan_act control by PTA */
885 			pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0xc);
886 	}
887 
888 	if (bUseExtSwitch) {
889 		if (bInitHwCfg) {
890 			/*  0x4c[23]= 0, 0x4c[24]= 1  Antenna control by WL/BT */
891 			u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x4c);
892 			u4Tmp &= ~BIT23;
893 			u4Tmp |= BIT24;
894 			pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x4c, u4Tmp);
895 
896 			pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x0); /*  fixed internal switch S1->WiFi, S0->BT */
897 
898 			if (pBoardInfo->btdmAntPos == BTC_ANTENNA_AT_MAIN_PORT) {
899 				/* tell firmware "no antenna inverse" */
900 				H2C_Parameter[0] = 0;
901 				H2C_Parameter[1] = 1;  /* ext switch type */
902 				pBtCoexist->fBtcFillH2c(pBtCoexist, 0x65, 2, H2C_Parameter);
903 			} else {
904 				/* tell firmware "antenna inverse" */
905 				H2C_Parameter[0] = 1;
906 				H2C_Parameter[1] = 1;  /* ext switch type */
907 				pBtCoexist->fBtcFillH2c(pBtCoexist, 0x65, 2, H2C_Parameter);
908 			}
909 		}
910 
911 
912 		/*  ext switch setting */
913 		switch (antPosType) {
914 		case BTC_ANT_PATH_WIFI:
915 			if (pBoardInfo->btdmAntPos == BTC_ANTENNA_AT_MAIN_PORT)
916 				pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x92c, 0x3, 0x1);
917 			else
918 				pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x92c, 0x3, 0x2);
919 			break;
920 		case BTC_ANT_PATH_BT:
921 			if (pBoardInfo->btdmAntPos == BTC_ANTENNA_AT_MAIN_PORT)
922 				pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x92c, 0x3, 0x2);
923 			else
924 				pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x92c, 0x3, 0x1);
925 			break;
926 		default:
927 		case BTC_ANT_PATH_PTA:
928 			if (pBoardInfo->btdmAntPos == BTC_ANTENNA_AT_MAIN_PORT)
929 				pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x92c, 0x3, 0x1);
930 			else
931 				pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x92c, 0x3, 0x2);
932 			break;
933 		}
934 
935 	} else {
936 		if (bInitHwCfg) {
937 			/*  0x4c[23]= 1, 0x4c[24]= 0  Antenna control by 0x64 */
938 			u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x4c);
939 			u4Tmp |= BIT23;
940 			u4Tmp &= ~BIT24;
941 			pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x4c, u4Tmp);
942 
943 			/* Fix Ext switch Main->S1, Aux->S0 */
944 			pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x64, 0x1, 0x0);
945 
946 			if (pBoardInfo->btdmAntPos == BTC_ANTENNA_AT_MAIN_PORT) {
947 
948 				/* tell firmware "no antenna inverse" */
949 				H2C_Parameter[0] = 0;
950 				H2C_Parameter[1] = 0;  /* internal switch type */
951 				pBtCoexist->fBtcFillH2c(pBtCoexist, 0x65, 2, H2C_Parameter);
952 			} else {
953 
954 				/* tell firmware "antenna inverse" */
955 				H2C_Parameter[0] = 1;
956 				H2C_Parameter[1] = 0;  /* internal switch type */
957 				pBtCoexist->fBtcFillH2c(pBtCoexist, 0x65, 2, H2C_Parameter);
958 			}
959 		}
960 
961 
962 		/*  internal switch setting */
963 		switch (antPosType) {
964 		case BTC_ANT_PATH_WIFI:
965 			if (pBoardInfo->btdmAntPos == BTC_ANTENNA_AT_MAIN_PORT)
966 				pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x0);
967 			else
968 				pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x280);
969 			break;
970 		case BTC_ANT_PATH_BT:
971 			if (pBoardInfo->btdmAntPos == BTC_ANTENNA_AT_MAIN_PORT)
972 				pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x280);
973 			else
974 				pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x0);
975 			break;
976 		default:
977 		case BTC_ANT_PATH_PTA:
978 			if (pBoardInfo->btdmAntPos == BTC_ANTENNA_AT_MAIN_PORT)
979 				pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x200);
980 			else
981 				pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x80);
982 			break;
983 		}
984 	}
985 }
986 
halbtc8723b1ant_SetFwPstdma(struct btc_coexist * pBtCoexist,u8 byte1,u8 byte2,u8 byte3,u8 byte4,u8 byte5)987 static void halbtc8723b1ant_SetFwPstdma(
988 	struct btc_coexist *pBtCoexist, u8 byte1, u8 byte2, u8 byte3, u8 byte4, u8 byte5
989 )
990 {
991 	u8 H2C_Parameter[5] = {0};
992 	u8 realByte1 = byte1, realByte5 = byte5;
993 	bool bApEnable = false;
994 
995 	pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable);
996 
997 	if (bApEnable) {
998 		if (byte1 & BIT4 && !(byte1 & BIT5)) {
999 			realByte1 &= ~BIT4;
1000 			realByte1 |= BIT5;
1001 
1002 			realByte5 |= BIT5;
1003 			realByte5 &= ~BIT6;
1004 		}
1005 	}
1006 
1007 	H2C_Parameter[0] = realByte1;
1008 	H2C_Parameter[1] = byte2;
1009 	H2C_Parameter[2] = byte3;
1010 	H2C_Parameter[3] = byte4;
1011 	H2C_Parameter[4] = realByte5;
1012 
1013 	pCoexDm->psTdmaPara[0] = realByte1;
1014 	pCoexDm->psTdmaPara[1] = byte2;
1015 	pCoexDm->psTdmaPara[2] = byte3;
1016 	pCoexDm->psTdmaPara[3] = byte4;
1017 	pCoexDm->psTdmaPara[4] = realByte5;
1018 
1019 	pBtCoexist->fBtcFillH2c(pBtCoexist, 0x60, 5, H2C_Parameter);
1020 }
1021 
1022 
halbtc8723b1ant_PsTdma(struct btc_coexist * pBtCoexist,bool bForceExec,bool bTurnOn,u8 type)1023 static void halbtc8723b1ant_PsTdma(
1024 	struct btc_coexist *pBtCoexist, bool bForceExec, bool bTurnOn, u8 type
1025 )
1026 {
1027 	struct btc_bt_link_info *pBtLinkInfo = &pBtCoexist->btLinkInfo;
1028 	bool bWifiBusy = false;
1029 	u8 rssiAdjustVal = 0;
1030 	u8 psTdmaByte4Val = 0x50, psTdmaByte0Val = 0x51, psTdmaByte3Val =  0x10;
1031 	s8 nWiFiDurationAdjust = 0x0;
1032 	/* u32 fwVer = 0; */
1033 
1034 	pCoexDm->bCurPsTdmaOn = bTurnOn;
1035 	pCoexDm->curPsTdma = type;
1036 
1037 	pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy);
1038 
1039 	if (!bForceExec) {
1040 		if (
1041 			(pCoexDm->bPrePsTdmaOn == pCoexDm->bCurPsTdmaOn) &&
1042 			(pCoexDm->prePsTdma == pCoexDm->curPsTdma)
1043 		)
1044 			return;
1045 	}
1046 
1047 	if (pCoexSta->nScanAPNum <= 5)
1048 		nWiFiDurationAdjust = 5;
1049 	else if  (pCoexSta->nScanAPNum >= 40)
1050 		nWiFiDurationAdjust = -15;
1051 	else if  (pCoexSta->nScanAPNum >= 20)
1052 		nWiFiDurationAdjust = -10;
1053 
1054 	if (!pCoexSta->bForceLpsOn) { /* only for A2DP-only case 1/2/9/11 */
1055 		psTdmaByte0Val = 0x61;  /* no null-pkt */
1056 		psTdmaByte3Val = 0x11; /*  no tx-pause at BT-slot */
1057 		psTdmaByte4Val = 0x10; /*  0x778 = d/1 toggle */
1058 	}
1059 
1060 
1061 	if (bTurnOn) {
1062 		if (pBtLinkInfo->bSlaveRole)
1063 			psTdmaByte4Val = psTdmaByte4Val | 0x1;  /* 0x778 = 0x1 at wifi slot (no blocking BT Low-Pri pkts) */
1064 
1065 
1066 		switch (type) {
1067 		default:
1068 			halbtc8723b1ant_SetFwPstdma(
1069 				pBtCoexist, 0x51, 0x1a, 0x1a, 0x0, psTdmaByte4Val
1070 			);
1071 			break;
1072 		case 1:
1073 			halbtc8723b1ant_SetFwPstdma(
1074 				pBtCoexist,
1075 				psTdmaByte0Val,
1076 				0x3a + nWiFiDurationAdjust,
1077 				0x03,
1078 				psTdmaByte3Val,
1079 				psTdmaByte4Val
1080 			);
1081 			break;
1082 		case 2:
1083 			halbtc8723b1ant_SetFwPstdma(
1084 				pBtCoexist,
1085 				psTdmaByte0Val,
1086 				0x2d + nWiFiDurationAdjust,
1087 				0x03,
1088 				psTdmaByte3Val,
1089 				psTdmaByte4Val
1090 			);
1091 			break;
1092 		case 3:
1093 			halbtc8723b1ant_SetFwPstdma(
1094 				pBtCoexist, 0x51, 0x1d, 0x1d, 0x0, 0x10
1095 			);
1096 			break;
1097 		case 4:
1098 			halbtc8723b1ant_SetFwPstdma(
1099 				pBtCoexist, 0x93, 0x15, 0x3, 0x14, 0x0
1100 			);
1101 			break;
1102 		case 5:
1103 			halbtc8723b1ant_SetFwPstdma(
1104 				pBtCoexist, 0x61, 0x15, 0x3, 0x11, 0x10
1105 			);
1106 			break;
1107 		case 6:
1108 			halbtc8723b1ant_SetFwPstdma(
1109 				pBtCoexist, 0x61, 0x20, 0x3, 0x11, 0x11
1110 			);
1111 			break;
1112 		case 7:
1113 			halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0x13, 0xc, 0x5, 0x0, 0x0);
1114 			break;
1115 		case 8:
1116 			halbtc8723b1ant_SetFwPstdma(
1117 				pBtCoexist, 0x93, 0x25, 0x3, 0x10, 0x0
1118 			);
1119 			break;
1120 		case 9:
1121 			halbtc8723b1ant_SetFwPstdma(
1122 				pBtCoexist,
1123 				psTdmaByte0Val,
1124 				0x21,
1125 				0x3,
1126 				psTdmaByte3Val,
1127 				psTdmaByte4Val
1128 			);
1129 			break;
1130 		case 10:
1131 			halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0x13, 0xa, 0xa, 0x0, 0x40);
1132 			break;
1133 		case 11:
1134 			halbtc8723b1ant_SetFwPstdma(
1135 				pBtCoexist,
1136 				psTdmaByte0Val,
1137 				0x21,
1138 				0x03,
1139 				psTdmaByte3Val,
1140 				psTdmaByte4Val
1141 			);
1142 			break;
1143 		case 12:
1144 			halbtc8723b1ant_SetFwPstdma(
1145 				pBtCoexist, 0x51, 0x0a, 0x0a, 0x0, 0x50
1146 			);
1147 			break;
1148 		case 13:
1149 			halbtc8723b1ant_SetFwPstdma(
1150 				pBtCoexist, 0x51, 0x12, 0x12, 0x0, 0x10
1151 			);
1152 			break;
1153 		case 14:
1154 			halbtc8723b1ant_SetFwPstdma(
1155 				pBtCoexist, 0x51, 0x21, 0x3, 0x10, psTdmaByte4Val
1156 			);
1157 			break;
1158 		case 15:
1159 			halbtc8723b1ant_SetFwPstdma(
1160 				pBtCoexist, 0x13, 0xa, 0x3, 0x8, 0x0
1161 			);
1162 			break;
1163 		case 16:
1164 			halbtc8723b1ant_SetFwPstdma(
1165 				pBtCoexist, 0x93, 0x15, 0x3, 0x10, 0x0
1166 			);
1167 			break;
1168 		case 18:
1169 			halbtc8723b1ant_SetFwPstdma(
1170 				pBtCoexist, 0x93, 0x25, 0x3, 0x10, 0x0
1171 			);
1172 			break;
1173 		case 20:
1174 			halbtc8723b1ant_SetFwPstdma(
1175 				pBtCoexist, 0x61, 0x3f, 0x03, 0x11, 0x10
1176 
1177 			);
1178 			break;
1179 		case 21:
1180 			halbtc8723b1ant_SetFwPstdma(
1181 				pBtCoexist, 0x61, 0x25, 0x03, 0x11, 0x11
1182 			);
1183 			break;
1184 		case 22:
1185 			halbtc8723b1ant_SetFwPstdma(
1186 				pBtCoexist, 0x61, 0x25, 0x03, 0x11, 0x10
1187 			);
1188 			break;
1189 		case 23:
1190 			halbtc8723b1ant_SetFwPstdma(
1191 				pBtCoexist, 0xe3, 0x25, 0x3, 0x31, 0x18
1192 			);
1193 			break;
1194 		case 24:
1195 			halbtc8723b1ant_SetFwPstdma(
1196 				pBtCoexist, 0xe3, 0x15, 0x3, 0x31, 0x18
1197 			);
1198 			break;
1199 		case 25:
1200 			halbtc8723b1ant_SetFwPstdma(
1201 				pBtCoexist, 0xe3, 0xa, 0x3, 0x31, 0x18
1202 			);
1203 			break;
1204 		case 26:
1205 			halbtc8723b1ant_SetFwPstdma(
1206 				pBtCoexist, 0xe3, 0xa, 0x3, 0x31, 0x18
1207 			);
1208 			break;
1209 		case 27:
1210 			halbtc8723b1ant_SetFwPstdma(
1211 				pBtCoexist, 0xe3, 0x25, 0x3, 0x31, 0x98
1212 			);
1213 			break;
1214 		case 28:
1215 			halbtc8723b1ant_SetFwPstdma(
1216 				pBtCoexist, 0x69, 0x25, 0x3, 0x31, 0x0
1217 			);
1218 			break;
1219 		case 29:
1220 			halbtc8723b1ant_SetFwPstdma(
1221 				pBtCoexist, 0xab, 0x1a, 0x1a, 0x1, 0x10
1222 			);
1223 			break;
1224 		case 30:
1225 			halbtc8723b1ant_SetFwPstdma(
1226 				pBtCoexist, 0x51, 0x30, 0x3, 0x10, 0x10
1227 			);
1228 			break;
1229 		case 31:
1230 			halbtc8723b1ant_SetFwPstdma(
1231 				pBtCoexist, 0xd3, 0x1a, 0x1a, 0x0, 0x58
1232 			);
1233 			break;
1234 		case 32:
1235 			halbtc8723b1ant_SetFwPstdma(
1236 				pBtCoexist, 0x61, 0x35, 0x3, 0x11, 0x11
1237 			);
1238 			break;
1239 		case 33:
1240 			halbtc8723b1ant_SetFwPstdma(
1241 				pBtCoexist, 0xa3, 0x25, 0x3, 0x30, 0x90
1242 			);
1243 			break;
1244 		case 34:
1245 			halbtc8723b1ant_SetFwPstdma(
1246 				pBtCoexist, 0x53, 0x1a, 0x1a, 0x0, 0x10
1247 			);
1248 			break;
1249 		case 35:
1250 			halbtc8723b1ant_SetFwPstdma(
1251 				pBtCoexist, 0x63, 0x1a, 0x1a, 0x0, 0x10
1252 			);
1253 			break;
1254 		case 36:
1255 			halbtc8723b1ant_SetFwPstdma(
1256 				pBtCoexist, 0xd3, 0x12, 0x3, 0x14, 0x50
1257 			);
1258 			break;
1259 		case 40: /*  SoftAP only with no sta associated, BT disable , TDMA mode for power saving */
1260 			/* here softap mode screen off will cost 70-80mA for phone */
1261 			halbtc8723b1ant_SetFwPstdma(
1262 				pBtCoexist, 0x23, 0x18, 0x00, 0x10, 0x24
1263 			);
1264 			break;
1265 		}
1266 	} else {
1267 
1268 		/*  disable PS tdma */
1269 		switch (type) {
1270 		case 8: /* PTA Control */
1271 			halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0x8, 0x0, 0x0, 0x0, 0x0);
1272 			halbtc8723b1ant_SetAntPath(
1273 				pBtCoexist, BTC_ANT_PATH_PTA, false, false
1274 			);
1275 			break;
1276 		case 0:
1277 		default:  /* Software control, Antenna at BT side */
1278 			halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x0, 0x0);
1279 			halbtc8723b1ant_SetAntPath(
1280 				pBtCoexist, BTC_ANT_PATH_BT, false, false
1281 			);
1282 			break;
1283 		case 9:   /* Software control, Antenna at WiFi side */
1284 			halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x0, 0x0);
1285 			halbtc8723b1ant_SetAntPath(
1286 				pBtCoexist, BTC_ANT_PATH_WIFI, false, false
1287 			);
1288 			break;
1289 		}
1290 	}
1291 
1292 	rssiAdjustVal = 0;
1293 	pBtCoexist->fBtcSet(
1294 		pBtCoexist, BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE, &rssiAdjustVal
1295 	);
1296 
1297 	/*  update pre state */
1298 	pCoexDm->bPrePsTdmaOn = pCoexDm->bCurPsTdmaOn;
1299 	pCoexDm->prePsTdma = pCoexDm->curPsTdma;
1300 }
1301 
halbtc8723b1ant_IsCommonAction(struct btc_coexist * pBtCoexist)1302 static bool halbtc8723b1ant_IsCommonAction(struct btc_coexist *pBtCoexist)
1303 {
1304 	bool bCommon = false, bWifiConnected = false, bWifiBusy = false;
1305 
1306 	pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected);
1307 	pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy);
1308 
1309 	if (
1310 		!bWifiConnected &&
1311 		pCoexDm->btStatus == BT_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE
1312 	) {
1313 		/* halbtc8723b1ant_SwMechanism(pBtCoexist, false); */
1314 
1315 		bCommon = true;
1316 	} else if (
1317 		bWifiConnected &&
1318 		(pCoexDm->btStatus == BT_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE)
1319 	) {
1320 		/* halbtc8723b1ant_SwMechanism(pBtCoexist, false); */
1321 
1322 		bCommon = true;
1323 	} else if (
1324 		!bWifiConnected &&
1325 		(pCoexDm->btStatus == BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE)
1326 	) {
1327 		/* halbtc8723b1ant_SwMechanism(pBtCoexist, false); */
1328 
1329 		bCommon = true;
1330 	} else if (
1331 		bWifiConnected &&
1332 		(pCoexDm->btStatus == BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE)
1333 	) {
1334 		/* halbtc8723b1ant_SwMechanism(pBtCoexist, false); */
1335 
1336 		bCommon = true;
1337 	} else if (
1338 		!bWifiConnected &&
1339 		(pCoexDm->btStatus != BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE)
1340 	) {
1341 		/* halbtc8723b1ant_SwMechanism(pBtCoexist, false); */
1342 
1343 		bCommon = true;
1344 	} else {
1345 		bCommon = false;
1346 	}
1347 
1348 	return bCommon;
1349 }
1350 
1351 
halbtc8723b1ant_TdmaDurationAdjustForAcl(struct btc_coexist * pBtCoexist,u8 wifiStatus)1352 static void halbtc8723b1ant_TdmaDurationAdjustForAcl(
1353 	struct btc_coexist *pBtCoexist, u8 wifiStatus
1354 )
1355 {
1356 	static s32 up, dn, m, n, WaitCount;
1357 	s32 result;   /* 0: no change, +1: increase WiFi duration, -1: decrease WiFi duration */
1358 	u8 retryCount = 0, btInfoExt;
1359 
1360 	if (
1361 		(wifiStatus == BT_8723B_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN) ||
1362 		(wifiStatus == BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN) ||
1363 		(wifiStatus == BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT)
1364 	) {
1365 		if (
1366 			pCoexDm->curPsTdma != 1 &&
1367 			pCoexDm->curPsTdma != 2 &&
1368 			pCoexDm->curPsTdma != 3 &&
1369 			pCoexDm->curPsTdma != 9
1370 		) {
1371 			halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 9);
1372 			pCoexDm->psTdmaDuAdjType = 9;
1373 
1374 			up = 0;
1375 			dn = 0;
1376 			m = 1;
1377 			n = 3;
1378 			result = 0;
1379 			WaitCount = 0;
1380 		}
1381 		return;
1382 	}
1383 
1384 	if (!pCoexDm->bAutoTdmaAdjust) {
1385 		pCoexDm->bAutoTdmaAdjust = true;
1386 
1387 		halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 2);
1388 		pCoexDm->psTdmaDuAdjType = 2;
1389 		/*  */
1390 		up = 0;
1391 		dn = 0;
1392 		m = 1;
1393 		n = 3;
1394 		result = 0;
1395 		WaitCount = 0;
1396 	} else {
1397 		/* acquire the BT TRx retry count from BT_Info byte2 */
1398 		retryCount = pCoexSta->btRetryCnt;
1399 		btInfoExt = pCoexSta->btInfoExt;
1400 
1401 		if (pCoexSta->lowPriorityTx > 1050 || pCoexSta->lowPriorityRx > 1250)
1402 			retryCount++;
1403 
1404 		result = 0;
1405 		WaitCount++;
1406 
1407 		if (retryCount == 0) { /*  no retry in the last 2-second duration */
1408 			up++;
1409 			dn--;
1410 
1411 			if (dn <= 0)
1412 				dn = 0;
1413 
1414 			if (up >= n) { /*  if 連續 n 個2秒 retry count為0, 則調寬WiFi duration */
1415 				WaitCount = 0;
1416 				n = 3;
1417 				up = 0;
1418 				dn = 0;
1419 				result = 1;
1420 			}
1421 		} else if (retryCount <= 3) { /*  <=3 retry in the last 2-second duration */
1422 			up--;
1423 			dn++;
1424 
1425 			if (up <= 0)
1426 				up = 0;
1427 
1428 			if (dn == 2) { /*  if 連續 2 個2秒 retry count< 3, 則調窄WiFi duration */
1429 				if (WaitCount <= 2)
1430 					m++; /*  避免一直在兩個level中來回 */
1431 				else
1432 					m = 1;
1433 
1434 				if (m >= 20) /* m 最大值 = 20 ' 最大120秒 recheck是否調整 WiFi duration. */
1435 					m = 20;
1436 
1437 				n = 3 * m;
1438 				up = 0;
1439 				dn = 0;
1440 				WaitCount = 0;
1441 				result = -1;
1442 			}
1443 		} else { /* retry count > 3, 只要1次 retry count > 3, 則調窄WiFi duration */
1444 			if (WaitCount == 1)
1445 				m++; /*  避免一直在兩個level中來回 */
1446 			else
1447 				m = 1;
1448 
1449 			if (m >= 20) /* m 最大值 = 20 ' 最大120秒 recheck是否調整 WiFi duration. */
1450 				m = 20;
1451 
1452 			n = 3 * m;
1453 			up = 0;
1454 			dn = 0;
1455 			WaitCount = 0;
1456 			result = -1;
1457 		}
1458 
1459 		if (result == -1) {
1460 			if (
1461 				BT_INFO_8723B_1ANT_A2DP_BASIC_RATE(btInfoExt) &&
1462 				((pCoexDm->curPsTdma == 1) || (pCoexDm->curPsTdma == 2))
1463 			) {
1464 				halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 9);
1465 				pCoexDm->psTdmaDuAdjType = 9;
1466 			} else if (pCoexDm->curPsTdma == 1) {
1467 				halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 2);
1468 				pCoexDm->psTdmaDuAdjType = 2;
1469 			} else if (pCoexDm->curPsTdma == 2) {
1470 				halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 9);
1471 				pCoexDm->psTdmaDuAdjType = 9;
1472 			} else if (pCoexDm->curPsTdma == 9) {
1473 				halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 11);
1474 				pCoexDm->psTdmaDuAdjType = 11;
1475 			}
1476 		} else if (result == 1) {
1477 			if (
1478 				BT_INFO_8723B_1ANT_A2DP_BASIC_RATE(btInfoExt) &&
1479 				((pCoexDm->curPsTdma == 1) || (pCoexDm->curPsTdma == 2))
1480 			) {
1481 				halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 9);
1482 				pCoexDm->psTdmaDuAdjType = 9;
1483 			} else if (pCoexDm->curPsTdma == 11) {
1484 				halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 9);
1485 				pCoexDm->psTdmaDuAdjType = 9;
1486 			} else if (pCoexDm->curPsTdma == 9) {
1487 				halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 2);
1488 				pCoexDm->psTdmaDuAdjType = 2;
1489 			} else if (pCoexDm->curPsTdma == 2) {
1490 				halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 1);
1491 				pCoexDm->psTdmaDuAdjType = 1;
1492 			}
1493 		}
1494 
1495 		if (
1496 			pCoexDm->curPsTdma != 1 &&
1497 			pCoexDm->curPsTdma != 2 &&
1498 			pCoexDm->curPsTdma != 9 &&
1499 			pCoexDm->curPsTdma != 11
1500 		) /*  recover to previous adjust type */
1501 			halbtc8723b1ant_PsTdma(
1502 				pBtCoexist, NORMAL_EXEC, true, pCoexDm->psTdmaDuAdjType
1503 			);
1504 	}
1505 }
1506 
halbtc8723b1ant_PsTdmaCheckForPowerSaveState(struct btc_coexist * pBtCoexist,bool bNewPsState)1507 static void halbtc8723b1ant_PsTdmaCheckForPowerSaveState(
1508 	struct btc_coexist *pBtCoexist, bool bNewPsState
1509 )
1510 {
1511 	u8 lpsMode = 0x0;
1512 
1513 	pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_LPS_MODE, &lpsMode);
1514 
1515 	if (lpsMode) {	/*  already under LPS state */
1516 		if (bNewPsState) {
1517 			/*  keep state under LPS, do nothing. */
1518 		} else /*  will leave LPS state, turn off psTdma first */
1519 			halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, false, 0);
1520 	} else {						/*  NO PS state */
1521 		if (bNewPsState) /*  will enter LPS state, turn off psTdma first */
1522 			halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, false, 0);
1523 		else {
1524 			/*  keep state under NO PS state, do nothing. */
1525 		}
1526 	}
1527 }
1528 
halbtc8723b1ant_PowerSaveState(struct btc_coexist * pBtCoexist,u8 psType,u8 lpsVal,u8 rpwmVal)1529 static void halbtc8723b1ant_PowerSaveState(
1530 	struct btc_coexist *pBtCoexist, u8 psType, u8 lpsVal, u8 rpwmVal
1531 )
1532 {
1533 	bool bLowPwrDisable = false;
1534 
1535 	switch (psType) {
1536 	case BTC_PS_WIFI_NATIVE:
1537 		/*  recover to original 32k low power setting */
1538 		bLowPwrDisable = false;
1539 		pBtCoexist->fBtcSet(
1540 			pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable
1541 		);
1542 		pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_NORMAL_LPS, NULL);
1543 		pCoexSta->bForceLpsOn = false;
1544 		break;
1545 	case BTC_PS_LPS_ON:
1546 		halbtc8723b1ant_PsTdmaCheckForPowerSaveState(pBtCoexist, true);
1547 		halbtc8723b1ant_LpsRpwm(pBtCoexist, NORMAL_EXEC, lpsVal, rpwmVal);
1548 		/*  when coex force to enter LPS, do not enter 32k low power. */
1549 		bLowPwrDisable = true;
1550 		pBtCoexist->fBtcSet(
1551 			pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable
1552 		);
1553 		/*  power save must executed before psTdma. */
1554 		pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_ENTER_LPS, NULL);
1555 		pCoexSta->bForceLpsOn = true;
1556 		break;
1557 	case BTC_PS_LPS_OFF:
1558 		halbtc8723b1ant_PsTdmaCheckForPowerSaveState(pBtCoexist, false);
1559 		pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_LEAVE_LPS, NULL);
1560 		pCoexSta->bForceLpsOn = false;
1561 		break;
1562 	default:
1563 		break;
1564 	}
1565 }
1566 
1567 /*  */
1568 /*  */
1569 /*	Software Coex Mechanism start */
1570 /*  */
1571 /*  */
1572 
1573 /*  */
1574 /*  */
1575 /*	Non-Software Coex Mechanism start */
1576 /*  */
1577 /*  */
halbtc8723b1ant_ActionWifiMultiPort(struct btc_coexist * pBtCoexist)1578 static void halbtc8723b1ant_ActionWifiMultiPort(struct btc_coexist *pBtCoexist)
1579 {
1580 	halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
1581 
1582 	halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, false, 8);
1583 	halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2);
1584 }
1585 
halbtc8723b1ant_ActionHs(struct btc_coexist * pBtCoexist)1586 static void halbtc8723b1ant_ActionHs(struct btc_coexist *pBtCoexist)
1587 {
1588 	halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 5);
1589 	halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2);
1590 }
1591 
halbtc8723b1ant_ActionBtInquiry(struct btc_coexist * pBtCoexist)1592 static void halbtc8723b1ant_ActionBtInquiry(struct btc_coexist *pBtCoexist)
1593 {
1594 	struct btc_bt_link_info *pBtLinkInfo = &pBtCoexist->btLinkInfo;
1595 	bool bWifiConnected = false;
1596 	bool bApEnable = false;
1597 	bool bWifiBusy = false;
1598 	bool bBtBusy = false;
1599 
1600 	pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable);
1601 	pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected);
1602 	pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy);
1603 	pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bBtBusy);
1604 
1605 	if (!bWifiConnected && !pCoexSta->bWiFiIsHighPriTask) {
1606 		halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
1607 		halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, false, 8);
1608 
1609 		halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0);
1610 	} else if (
1611 		pBtLinkInfo->bScoExist ||
1612 		pBtLinkInfo->bHidExist ||
1613 		pBtLinkInfo->bA2dpExist
1614 	) {
1615 		/*  SCO/HID/A2DP busy */
1616 		halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
1617 		halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 32);
1618 
1619 		halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4);
1620 	} else if (pBtLinkInfo->bPanExist || bWifiBusy) {
1621 		halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
1622 		halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 20);
1623 
1624 		halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4);
1625 	} else {
1626 		halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
1627 		halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, false, 8);
1628 
1629 		halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7);
1630 	}
1631 }
1632 
halbtc8723b1ant_ActionBtScoHidOnlyBusy(struct btc_coexist * pBtCoexist,u8 wifiStatus)1633 static void halbtc8723b1ant_ActionBtScoHidOnlyBusy(
1634 	struct btc_coexist *pBtCoexist, u8 wifiStatus
1635 )
1636 {
1637 	struct btc_bt_link_info *pBtLinkInfo = &pBtCoexist->btLinkInfo;
1638 	bool bWifiConnected = false;
1639 
1640 	pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected);
1641 
1642 	/*  tdma and coex table */
1643 
1644 	if (pBtLinkInfo->bScoExist) {
1645 		halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 5);
1646 		halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 5);
1647 	} else { /* HID */
1648 		halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 6);
1649 		halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 5);
1650 	}
1651 }
1652 
halbtc8723b1ant_ActionWifiConnectedBtAclBusy(struct btc_coexist * pBtCoexist,u8 wifiStatus)1653 static void halbtc8723b1ant_ActionWifiConnectedBtAclBusy(
1654 	struct btc_coexist *pBtCoexist, u8 wifiStatus
1655 )
1656 {
1657 	struct btc_bt_link_info *pBtLinkInfo = &pBtCoexist->btLinkInfo;
1658 
1659 	halbtc8723b1ant_BtRssiState(2, 28, 0);
1660 
1661 	if ((pCoexSta->lowPriorityRx >= 1000) && (pCoexSta->lowPriorityRx != 65535))
1662 		pBtLinkInfo->bSlaveRole = true;
1663 	else
1664 		pBtLinkInfo->bSlaveRole = false;
1665 
1666 	if (pBtLinkInfo->bHidOnly) { /* HID */
1667 		halbtc8723b1ant_ActionBtScoHidOnlyBusy(pBtCoexist, wifiStatus);
1668 		pCoexDm->bAutoTdmaAdjust = false;
1669 		return;
1670 	} else if (pBtLinkInfo->bA2dpOnly) { /* A2DP */
1671 		if (wifiStatus == BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE) {
1672 			halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 32);
1673 			halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4);
1674 			pCoexDm->bAutoTdmaAdjust = false;
1675 		} else {
1676 			halbtc8723b1ant_TdmaDurationAdjustForAcl(pBtCoexist, wifiStatus);
1677 			halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4);
1678 			pCoexDm->bAutoTdmaAdjust = true;
1679 		}
1680 	} else if (pBtLinkInfo->bHidExist && pBtLinkInfo->bA2dpExist) { /* HID+A2DP */
1681 		halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 14);
1682 		pCoexDm->bAutoTdmaAdjust = false;
1683 
1684 		halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4);
1685 	} else if (
1686 		pBtLinkInfo->bPanOnly ||
1687 		(pBtLinkInfo->bHidExist && pBtLinkInfo->bPanExist)
1688 	) { /* PAN(OPP, FTP), HID+PAN(OPP, FTP) */
1689 		halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 3);
1690 		halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4);
1691 		pCoexDm->bAutoTdmaAdjust = false;
1692 	} else if (
1693 		(pBtLinkInfo->bA2dpExist && pBtLinkInfo->bPanExist) ||
1694 		(pBtLinkInfo->bHidExist && pBtLinkInfo->bA2dpExist && pBtLinkInfo->bPanExist)
1695 	) { /* A2DP+PAN(OPP, FTP), HID+A2DP+PAN(OPP, FTP) */
1696 		halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 13);
1697 		halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4);
1698 		pCoexDm->bAutoTdmaAdjust = false;
1699 	} else {
1700 		/* BT no-profile busy (0x9) */
1701 		halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 32);
1702 		halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4);
1703 		pCoexDm->bAutoTdmaAdjust = false;
1704 	}
1705 }
1706 
halbtc8723b1ant_ActionWifiNotConnected(struct btc_coexist * pBtCoexist)1707 static void halbtc8723b1ant_ActionWifiNotConnected(struct btc_coexist *pBtCoexist)
1708 {
1709 	/*  power save state */
1710 	halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
1711 
1712 	/*  tdma and coex table */
1713 	halbtc8723b1ant_PsTdma(pBtCoexist, FORCE_EXEC, false, 8);
1714 	halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0);
1715 }
1716 
halbtc8723b1ant_ActionWifiNotConnectedScan(struct btc_coexist * pBtCoexist)1717 static void halbtc8723b1ant_ActionWifiNotConnectedScan(
1718 	struct btc_coexist *pBtCoexist
1719 )
1720 {
1721 	struct btc_bt_link_info *pBtLinkInfo = &pBtCoexist->btLinkInfo;
1722 
1723 	halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
1724 
1725 	/*  tdma and coex table */
1726 	if (pCoexDm->btStatus == BT_8723B_1ANT_BT_STATUS_ACL_BUSY) {
1727 		if (pBtLinkInfo->bA2dpExist) {
1728 			halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 32);
1729 			halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4);
1730 		} else if (pBtLinkInfo->bA2dpExist && pBtLinkInfo->bPanExist) {
1731 			halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 22);
1732 			halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4);
1733 		} else {
1734 			halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 20);
1735 			halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4);
1736 		}
1737 	} else if (
1738 		(pCoexDm->btStatus == BT_8723B_1ANT_BT_STATUS_SCO_BUSY) ||
1739 		(pCoexDm->btStatus == BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY)
1740 	) {
1741 		halbtc8723b1ant_ActionBtScoHidOnlyBusy(
1742 			pBtCoexist, BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN
1743 		);
1744 	} else {
1745 		/* Bryant Add */
1746 		halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, false, 8);
1747 		halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2);
1748 	}
1749 }
1750 
halbtc8723b1ant_ActionWifiNotConnectedAssoAuth(struct btc_coexist * pBtCoexist)1751 static void halbtc8723b1ant_ActionWifiNotConnectedAssoAuth(
1752 	struct btc_coexist *pBtCoexist
1753 )
1754 {
1755 	struct btc_bt_link_info *pBtLinkInfo = &pBtCoexist->btLinkInfo;
1756 
1757 	halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
1758 
1759 	/*  tdma and coex table */
1760 	if (
1761 		(pBtLinkInfo->bScoExist) ||
1762 		(pBtLinkInfo->bHidExist) ||
1763 		(pBtLinkInfo->bA2dpExist)
1764 	) {
1765 		halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 32);
1766 		halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4);
1767 	} else if (pBtLinkInfo->bPanExist) {
1768 		halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 20);
1769 		halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4);
1770 	} else {
1771 		halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, false, 8);
1772 		halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2);
1773 	}
1774 }
1775 
halbtc8723b1ant_ActionWifiConnectedScan(struct btc_coexist * pBtCoexist)1776 static void halbtc8723b1ant_ActionWifiConnectedScan(struct btc_coexist *pBtCoexist)
1777 {
1778 	struct btc_bt_link_info *pBtLinkInfo = &pBtCoexist->btLinkInfo;
1779 
1780 	halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
1781 
1782 	/*  tdma and coex table */
1783 	if (pCoexDm->btStatus == BT_8723B_1ANT_BT_STATUS_ACL_BUSY) {
1784 		if (pBtLinkInfo->bA2dpExist) {
1785 			halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 32);
1786 			halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4);
1787 		} else if (pBtLinkInfo->bA2dpExist && pBtLinkInfo->bPanExist) {
1788 			halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 22);
1789 			halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4);
1790 		} else {
1791 			halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 20);
1792 			halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4);
1793 		}
1794 	} else if (
1795 		(pCoexDm->btStatus == BT_8723B_1ANT_BT_STATUS_SCO_BUSY) ||
1796 		(pCoexDm->btStatus == BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY)
1797 	) {
1798 		halbtc8723b1ant_ActionBtScoHidOnlyBusy(
1799 			pBtCoexist, BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN
1800 		);
1801 	} else {
1802 		/* Bryant Add */
1803 		halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, false, 8);
1804 		halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2);
1805 	}
1806 }
1807 
halbtc8723b1ant_ActionWifiConnectedSpecialPacket(struct btc_coexist * pBtCoexist)1808 static void halbtc8723b1ant_ActionWifiConnectedSpecialPacket(
1809 	struct btc_coexist *pBtCoexist
1810 )
1811 {
1812 	struct btc_bt_link_info *pBtLinkInfo = &pBtCoexist->btLinkInfo;
1813 
1814 	halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
1815 
1816 	/*  tdma and coex table */
1817 	if (
1818 		(pBtLinkInfo->bScoExist) ||
1819 		(pBtLinkInfo->bHidExist) ||
1820 		(pBtLinkInfo->bA2dpExist)
1821 	) {
1822 		halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 32);
1823 		halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4);
1824 	} else if (pBtLinkInfo->bPanExist) {
1825 		halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 20);
1826 		halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4);
1827 	} else {
1828 		halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, false, 8);
1829 		halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2);
1830 	}
1831 }
1832 
halbtc8723b1ant_ActionWifiConnected(struct btc_coexist * pBtCoexist)1833 static void halbtc8723b1ant_ActionWifiConnected(struct btc_coexist *pBtCoexist)
1834 {
1835 	bool bWifiBusy = false;
1836 	bool bScan = false, bLink = false, bRoam = false;
1837 	bool bUnder4way = false, bApEnable = false;
1838 
1839 	pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &bUnder4way);
1840 	if (bUnder4way) {
1841 		halbtc8723b1ant_ActionWifiConnectedSpecialPacket(pBtCoexist);
1842 		return;
1843 	}
1844 
1845 	pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_SCAN, &bScan);
1846 	pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_LINK, &bLink);
1847 	pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_ROAM, &bRoam);
1848 	if (bScan || bLink || bRoam) {
1849 		if (bScan)
1850 			halbtc8723b1ant_ActionWifiConnectedScan(pBtCoexist);
1851 		else
1852 			halbtc8723b1ant_ActionWifiConnectedSpecialPacket(pBtCoexist);
1853 		return;
1854 	}
1855 
1856 	pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable);
1857 	pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy);
1858 
1859 	/*  power save state */
1860 	if (
1861 		!bApEnable &&
1862 		pCoexDm->btStatus == BT_8723B_1ANT_BT_STATUS_ACL_BUSY &&
1863 		!pBtCoexist->btLinkInfo.bHidOnly
1864 	) {
1865 		if (pBtCoexist->btLinkInfo.bA2dpOnly) { /* A2DP */
1866 			if (!bWifiBusy)
1867 				halbtc8723b1ant_PowerSaveState(
1868 					pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0
1869 				);
1870 			else { /* busy */
1871 				if  (pCoexSta->nScanAPNum >= BT_8723B_1ANT_WIFI_NOISY_THRESH)  /* no force LPS, no PS-TDMA, use pure TDMA */
1872 					halbtc8723b1ant_PowerSaveState(
1873 						pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0
1874 					);
1875 				else
1876 					halbtc8723b1ant_PowerSaveState(
1877 						pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4
1878 					);
1879 			}
1880 		} else if (
1881 			(!pCoexSta->bPanExist) &&
1882 			(!pCoexSta->bA2dpExist) &&
1883 			(!pCoexSta->bHidExist)
1884 		)
1885 			halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
1886 		else
1887 			halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4);
1888 	} else
1889 		halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
1890 
1891 	/*  tdma and coex table */
1892 	if (!bWifiBusy) {
1893 		if (pCoexDm->btStatus == BT_8723B_1ANT_BT_STATUS_ACL_BUSY) {
1894 			halbtc8723b1ant_ActionWifiConnectedBtAclBusy(
1895 				pBtCoexist,
1896 				BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE
1897 			);
1898 		} else if (
1899 			(pCoexDm->btStatus == BT_8723B_1ANT_BT_STATUS_SCO_BUSY) ||
1900 			(pCoexDm->btStatus == BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY)
1901 		) {
1902 			halbtc8723b1ant_ActionBtScoHidOnlyBusy(pBtCoexist,
1903 				BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE);
1904 		} else {
1905 			halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, false, 8);
1906 
1907 			if ((pCoexSta->highPriorityTx) + (pCoexSta->highPriorityRx) <= 60)
1908 				halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2);
1909 			else
1910 				halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7);
1911 		}
1912 	} else {
1913 		if (pCoexDm->btStatus == BT_8723B_1ANT_BT_STATUS_ACL_BUSY) {
1914 			halbtc8723b1ant_ActionWifiConnectedBtAclBusy(
1915 				pBtCoexist,
1916 				BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY
1917 			);
1918 		} else if (
1919 			(pCoexDm->btStatus == BT_8723B_1ANT_BT_STATUS_SCO_BUSY) ||
1920 			(pCoexDm->btStatus == BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY)
1921 		) {
1922 			halbtc8723b1ant_ActionBtScoHidOnlyBusy(
1923 				pBtCoexist,
1924 				BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY
1925 			);
1926 		} else {
1927 			halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, false, 8);
1928 
1929 			if ((pCoexSta->highPriorityTx) + (pCoexSta->highPriorityRx) <= 60)
1930 				halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2);
1931 			else
1932 				halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7);
1933 		}
1934 	}
1935 }
1936 
halbtc8723b1ant_RunSwCoexistMechanism(struct btc_coexist * pBtCoexist)1937 static void halbtc8723b1ant_RunSwCoexistMechanism(struct btc_coexist *pBtCoexist)
1938 {
1939 	u8 algorithm = 0;
1940 
1941 	algorithm = halbtc8723b1ant_ActionAlgorithm(pBtCoexist);
1942 	pCoexDm->curAlgorithm = algorithm;
1943 
1944 	if (halbtc8723b1ant_IsCommonAction(pBtCoexist)) {
1945 
1946 	} else {
1947 		switch (pCoexDm->curAlgorithm) {
1948 		case BT_8723B_1ANT_COEX_ALGO_SCO:
1949 			/* halbtc8723b1ant_ActionSco(pBtCoexist); */
1950 			break;
1951 		case BT_8723B_1ANT_COEX_ALGO_HID:
1952 			/* halbtc8723b1ant_ActionHid(pBtCoexist); */
1953 			break;
1954 		case BT_8723B_1ANT_COEX_ALGO_A2DP:
1955 			/* halbtc8723b1ant_ActionA2dp(pBtCoexist); */
1956 			break;
1957 		case BT_8723B_1ANT_COEX_ALGO_A2DP_PANHS:
1958 			/* halbtc8723b1ant_ActionA2dpPanHs(pBtCoexist); */
1959 			break;
1960 		case BT_8723B_1ANT_COEX_ALGO_PANEDR:
1961 			/* halbtc8723b1ant_ActionPanEdr(pBtCoexist); */
1962 			break;
1963 		case BT_8723B_1ANT_COEX_ALGO_PANHS:
1964 			/* halbtc8723b1ant_ActionPanHs(pBtCoexist); */
1965 			break;
1966 		case BT_8723B_1ANT_COEX_ALGO_PANEDR_A2DP:
1967 			/* halbtc8723b1ant_ActionPanEdrA2dp(pBtCoexist); */
1968 			break;
1969 		case BT_8723B_1ANT_COEX_ALGO_PANEDR_HID:
1970 			/* halbtc8723b1ant_ActionPanEdrHid(pBtCoexist); */
1971 			break;
1972 		case BT_8723B_1ANT_COEX_ALGO_HID_A2DP_PANEDR:
1973 			/* halbtc8723b1ant_ActionHidA2dpPanEdr(pBtCoexist); */
1974 			break;
1975 		case BT_8723B_1ANT_COEX_ALGO_HID_A2DP:
1976 			/* halbtc8723b1ant_ActionHidA2dp(pBtCoexist); */
1977 			break;
1978 		default:
1979 			break;
1980 		}
1981 		pCoexDm->preAlgorithm = pCoexDm->curAlgorithm;
1982 	}
1983 }
1984 
halbtc8723b1ant_RunCoexistMechanism(struct btc_coexist * pBtCoexist)1985 static void halbtc8723b1ant_RunCoexistMechanism(struct btc_coexist *pBtCoexist)
1986 {
1987 	struct btc_bt_link_info *pBtLinkInfo = &pBtCoexist->btLinkInfo;
1988 	bool bWifiConnected = false, bBtHsOn = false;
1989 	bool bIncreaseScanDevNum = false;
1990 	bool bBtCtrlAggBufSize = false;
1991 	u8 aggBufSize = 5;
1992 	u32 wifiLinkStatus = 0;
1993 	u32 numOfWifiLink = 0;
1994 
1995 	if (pBtCoexist->bManualControl)
1996 		return;
1997 
1998 	if (pBtCoexist->bStopCoexDm)
1999 		return;
2000 
2001 	if (pCoexSta->bUnderIps)
2002 		return;
2003 
2004 	if (
2005 		(pCoexDm->btStatus == BT_8723B_1ANT_BT_STATUS_ACL_BUSY) ||
2006 		(pCoexDm->btStatus == BT_8723B_1ANT_BT_STATUS_SCO_BUSY) ||
2007 		(pCoexDm->btStatus == BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY)
2008 	){
2009 		bIncreaseScanDevNum = true;
2010 	}
2011 
2012 	pBtCoexist->fBtcSet(
2013 		pBtCoexist,
2014 		BTC_SET_BL_INC_SCAN_DEV_NUM,
2015 		&bIncreaseScanDevNum
2016 	);
2017 	pBtCoexist->fBtcGet(
2018 		pBtCoexist,
2019 		BTC_GET_BL_WIFI_CONNECTED,
2020 		&bWifiConnected
2021 	);
2022 
2023 	pBtCoexist->fBtcGet(
2024 		pBtCoexist,
2025 		BTC_GET_U4_WIFI_LINK_STATUS,
2026 		&wifiLinkStatus
2027 	);
2028 	numOfWifiLink = wifiLinkStatus >> 16;
2029 
2030 	if ((numOfWifiLink >= 2) || (wifiLinkStatus & WIFI_P2P_GO_CONNECTED)) {
2031 		halbtc8723b1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0);
2032 		halbtc8723b1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, false, bBtCtrlAggBufSize, aggBufSize);
2033 
2034 		if ((pBtLinkInfo->bA2dpExist) && (pCoexSta->bC2hBtInquiryPage))
2035 			halbtc8723b1ant_ActionBtInquiry(pBtCoexist);
2036 		else
2037 			halbtc8723b1ant_ActionWifiMultiPort(pBtCoexist);
2038 
2039 		return;
2040 	}
2041 
2042 	if ((pBtLinkInfo->bBtLinkExist) && (bWifiConnected)) {
2043 		halbtc8723b1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 1, 1, 0, 1);
2044 
2045 		if (pBtLinkInfo->bScoExist)
2046 			halbtc8723b1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, false, true, 0x5);
2047 		else
2048 			halbtc8723b1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, false, true, 0x8);
2049 
2050 		halbtc8723b1ant_SwMechanism(pBtCoexist, true);
2051 		halbtc8723b1ant_RunSwCoexistMechanism(pBtCoexist);  /* just print debug message */
2052 	} else {
2053 		halbtc8723b1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0);
2054 
2055 		halbtc8723b1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, false, false, 0x5);
2056 
2057 		halbtc8723b1ant_SwMechanism(pBtCoexist, false);
2058 		halbtc8723b1ant_RunSwCoexistMechanism(pBtCoexist); /* just print debug message */
2059 	}
2060 
2061 	pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn);
2062 	if (pCoexSta->bC2hBtInquiryPage) {
2063 		halbtc8723b1ant_ActionBtInquiry(pBtCoexist);
2064 		return;
2065 	} else if (bBtHsOn) {
2066 		halbtc8723b1ant_ActionHs(pBtCoexist);
2067 		return;
2068 	}
2069 
2070 
2071 	if (!bWifiConnected) {
2072 		bool bScan = false, bLink = false, bRoam = false;
2073 
2074 		pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_SCAN, &bScan);
2075 		pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_LINK, &bLink);
2076 		pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_ROAM, &bRoam);
2077 
2078 		if (bScan || bLink || bRoam) {
2079 			if (bScan)
2080 				halbtc8723b1ant_ActionWifiNotConnectedScan(pBtCoexist);
2081 			else
2082 				halbtc8723b1ant_ActionWifiNotConnectedAssoAuth(pBtCoexist);
2083 		} else
2084 			halbtc8723b1ant_ActionWifiNotConnected(pBtCoexist);
2085 	} else /*  wifi LPS/Busy */
2086 		halbtc8723b1ant_ActionWifiConnected(pBtCoexist);
2087 }
2088 
halbtc8723b1ant_InitCoexDm(struct btc_coexist * pBtCoexist)2089 static void halbtc8723b1ant_InitCoexDm(struct btc_coexist *pBtCoexist)
2090 {
2091 	/*  force to reset coex mechanism */
2092 
2093 	/*  sw all off */
2094 	halbtc8723b1ant_SwMechanism(pBtCoexist, false);
2095 
2096 	/* halbtc8723b1ant_PsTdma(pBtCoexist, FORCE_EXEC, false, 8); */
2097 	halbtc8723b1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 0);
2098 
2099 	pCoexSta->popEventCnt = 0;
2100 }
2101 
halbtc8723b1ant_InitHwConfig(struct btc_coexist * pBtCoexist,bool bBackUp,bool bWifiOnly)2102 static void halbtc8723b1ant_InitHwConfig(
2103 	struct btc_coexist *pBtCoexist,
2104 	bool bBackUp,
2105 	bool bWifiOnly
2106 )
2107 {
2108 	pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x550, 0x8, 0x1);  /* enable TBTT nterrupt */
2109 
2110 	/*  0x790[5:0]= 0x5 */
2111 	pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x790, 0x5);
2112 
2113 	/*  Enable counter statistics */
2114 	pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x778, 0x1);
2115 	pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x40, 0x20, 0x1);
2116 
2117 	/* Antenna config */
2118 	if (bWifiOnly) {
2119 		halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_WIFI, true, false);
2120 		halbtc8723b1ant_PsTdma(pBtCoexist, FORCE_EXEC, false, 9);
2121 	} else
2122 		halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, true, false);
2123 
2124 	/*  PTA parameter */
2125 	halbtc8723b1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 0);
2126 
2127 	pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x948);
2128 	pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x765);
2129 	pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x67);
2130 }
2131 
2132 /*  */
2133 /*  work around function start with wa_halbtc8723b1ant_ */
2134 /*  */
2135 /*  */
2136 /*  extern function start with EXhalbtc8723b1ant_ */
2137 /*  */
EXhalbtc8723b1ant_PowerOnSetting(struct btc_coexist * pBtCoexist)2138 void EXhalbtc8723b1ant_PowerOnSetting(struct btc_coexist *pBtCoexist)
2139 {
2140 	struct btc_board_info *pBoardInfo = &pBtCoexist->boardInfo;
2141 	u8 u1Tmp = 0x0;
2142 	u16 u2Tmp = 0x0;
2143 
2144 	pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x67, 0x20);
2145 
2146 	/*  enable BB, REG_SYS_FUNC_EN such that we can write 0x948 correctly. */
2147 	u2Tmp = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0x2);
2148 	pBtCoexist->fBtcWrite2Byte(pBtCoexist, 0x2, u2Tmp | BIT0 | BIT1);
2149 
2150 	/*  set GRAN_BT = 1 */
2151 	pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x765, 0x18);
2152 	/*  set WLAN_ACT = 0 */
2153 	pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0x4);
2154 
2155 	/*  */
2156 	/*  S0 or S1 setting and Local register setting(By the setting fw can get ant number, S0/S1, ... info) */
2157 	/*  Local setting bit define */
2158 	/*	BIT0: "0" for no antenna inverse; "1" for antenna inverse */
2159 	/*	BIT1: "0" for internal switch; "1" for external switch */
2160 	/*	BIT2: "0" for one antenna; "1" for two antenna */
2161 	/*  NOTE: here default all internal switch and 1-antenna ==> BIT1 = 0 and BIT2 = 0 */
2162 	if (pBtCoexist->chipInterface == BTC_INTF_USB) {
2163 		/*  fixed at S0 for USB interface */
2164 		pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x0);
2165 
2166 		u1Tmp |= 0x1;	/*  antenna inverse */
2167 		pBtCoexist->fBtcWriteLocalReg1Byte(pBtCoexist, 0xfe08, u1Tmp);
2168 
2169 		pBoardInfo->btdmAntPos = BTC_ANTENNA_AT_AUX_PORT;
2170 	} else {
2171 		/*  for PCIE and SDIO interface, we check efuse 0xc3[6] */
2172 		if (pBoardInfo->singleAntPath == 0) {
2173 			/*  set to S1 */
2174 			pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x280);
2175 			pBoardInfo->btdmAntPos = BTC_ANTENNA_AT_MAIN_PORT;
2176 		} else if (pBoardInfo->singleAntPath == 1) {
2177 			/*  set to S0 */
2178 			pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x0);
2179 			u1Tmp |= 0x1;	/*  antenna inverse */
2180 			pBoardInfo->btdmAntPos = BTC_ANTENNA_AT_AUX_PORT;
2181 		}
2182 
2183 		if (pBtCoexist->chipInterface == BTC_INTF_PCI)
2184 			pBtCoexist->fBtcWriteLocalReg1Byte(pBtCoexist, 0x384, u1Tmp);
2185 		else if (pBtCoexist->chipInterface == BTC_INTF_SDIO)
2186 			pBtCoexist->fBtcWriteLocalReg1Byte(pBtCoexist, 0x60, u1Tmp);
2187 	}
2188 }
2189 
EXhalbtc8723b1ant_InitHwConfig(struct btc_coexist * pBtCoexist,bool bWifiOnly)2190 void EXhalbtc8723b1ant_InitHwConfig(struct btc_coexist *pBtCoexist, bool bWifiOnly)
2191 {
2192 	halbtc8723b1ant_InitHwConfig(pBtCoexist, true, bWifiOnly);
2193 }
2194 
EXhalbtc8723b1ant_InitCoexDm(struct btc_coexist * pBtCoexist)2195 void EXhalbtc8723b1ant_InitCoexDm(struct btc_coexist *pBtCoexist)
2196 {
2197 	pBtCoexist->bStopCoexDm = false;
2198 
2199 	halbtc8723b1ant_InitCoexDm(pBtCoexist);
2200 
2201 	halbtc8723b1ant_QueryBtInfo(pBtCoexist);
2202 }
2203 
EXhalbtc8723b1ant_IpsNotify(struct btc_coexist * pBtCoexist,u8 type)2204 void EXhalbtc8723b1ant_IpsNotify(struct btc_coexist *pBtCoexist, u8 type)
2205 {
2206 	if (pBtCoexist->bManualControl ||	pBtCoexist->bStopCoexDm)
2207 		return;
2208 
2209 	if (type == BTC_IPS_ENTER) {
2210 		pCoexSta->bUnderIps = true;
2211 
2212 		halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, false, 0);
2213 		halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0);
2214 		halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, false, true);
2215 	} else if (type == BTC_IPS_LEAVE) {
2216 		pCoexSta->bUnderIps = false;
2217 
2218 		halbtc8723b1ant_InitHwConfig(pBtCoexist, false, false);
2219 		halbtc8723b1ant_InitCoexDm(pBtCoexist);
2220 		halbtc8723b1ant_QueryBtInfo(pBtCoexist);
2221 	}
2222 }
2223 
EXhalbtc8723b1ant_LpsNotify(struct btc_coexist * pBtCoexist,u8 type)2224 void EXhalbtc8723b1ant_LpsNotify(struct btc_coexist *pBtCoexist, u8 type)
2225 {
2226 	if (pBtCoexist->bManualControl || pBtCoexist->bStopCoexDm)
2227 		return;
2228 
2229 	if (type == BTC_LPS_ENABLE)
2230 		pCoexSta->bUnderLps = true;
2231 	else if (type == BTC_LPS_DISABLE)
2232 		pCoexSta->bUnderLps = false;
2233 }
2234 
EXhalbtc8723b1ant_ScanNotify(struct btc_coexist * pBtCoexist,u8 type)2235 void EXhalbtc8723b1ant_ScanNotify(struct btc_coexist *pBtCoexist, u8 type)
2236 {
2237 	bool bWifiConnected = false, bBtHsOn = false;
2238 	u32 wifiLinkStatus = 0;
2239 	u32 numOfWifiLink = 0;
2240 	bool bBtCtrlAggBufSize = false;
2241 	u8 aggBufSize = 5;
2242 
2243 	if (pBtCoexist->bManualControl || pBtCoexist->bStopCoexDm)
2244 		return;
2245 
2246 	if (type == BTC_SCAN_START) {
2247 		pCoexSta->bWiFiIsHighPriTask = true;
2248 
2249 		halbtc8723b1ant_PsTdma(pBtCoexist, FORCE_EXEC, false, 8);  /* Force antenna setup for no scan result issue */
2250 		pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x948);
2251 		pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x765);
2252 		pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x67);
2253 	} else {
2254 		pCoexSta->bWiFiIsHighPriTask = false;
2255 
2256 		pBtCoexist->fBtcGet(
2257 			pBtCoexist, BTC_GET_U1_AP_NUM, &pCoexSta->nScanAPNum
2258 		);
2259 	}
2260 
2261 	if (pBtCoexist->btInfo.bBtDisabled)
2262 		return;
2263 
2264 	pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn);
2265 	pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected);
2266 
2267 	halbtc8723b1ant_QueryBtInfo(pBtCoexist);
2268 
2269 	pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_LINK_STATUS, &wifiLinkStatus);
2270 	numOfWifiLink = wifiLinkStatus >> 16;
2271 
2272 	if (numOfWifiLink >= 2) {
2273 		halbtc8723b1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0);
2274 		halbtc8723b1ant_LimitedRx(
2275 			pBtCoexist, NORMAL_EXEC, false, bBtCtrlAggBufSize, aggBufSize
2276 		);
2277 		halbtc8723b1ant_ActionWifiMultiPort(pBtCoexist);
2278 		return;
2279 	}
2280 
2281 	if (pCoexSta->bC2hBtInquiryPage) {
2282 		halbtc8723b1ant_ActionBtInquiry(pBtCoexist);
2283 		return;
2284 	} else if (bBtHsOn) {
2285 		halbtc8723b1ant_ActionHs(pBtCoexist);
2286 		return;
2287 	}
2288 
2289 	if (type == BTC_SCAN_START) {
2290 		if (!bWifiConnected)	/*  non-connected scan */
2291 			halbtc8723b1ant_ActionWifiNotConnectedScan(pBtCoexist);
2292 		else	/*  wifi is connected */
2293 			halbtc8723b1ant_ActionWifiConnectedScan(pBtCoexist);
2294 	} else if (type == BTC_SCAN_FINISH) {
2295 		if (!bWifiConnected)	/*  non-connected scan */
2296 			halbtc8723b1ant_ActionWifiNotConnected(pBtCoexist);
2297 		else
2298 			halbtc8723b1ant_ActionWifiConnected(pBtCoexist);
2299 	}
2300 }
2301 
EXhalbtc8723b1ant_ConnectNotify(struct btc_coexist * pBtCoexist,u8 type)2302 void EXhalbtc8723b1ant_ConnectNotify(struct btc_coexist *pBtCoexist, u8 type)
2303 {
2304 	bool bWifiConnected = false, bBtHsOn = false;
2305 	u32 wifiLinkStatus = 0;
2306 	u32 numOfWifiLink = 0;
2307 	bool bBtCtrlAggBufSize = false;
2308 	u8 aggBufSize = 5;
2309 
2310 	if (
2311 		pBtCoexist->bManualControl ||
2312 		pBtCoexist->bStopCoexDm ||
2313 		pBtCoexist->btInfo.bBtDisabled
2314 	)
2315 		return;
2316 
2317 	if (type == BTC_ASSOCIATE_START) {
2318 		pCoexSta->bWiFiIsHighPriTask = true;
2319 		 pCoexDm->nArpCnt = 0;
2320 	} else {
2321 		pCoexSta->bWiFiIsHighPriTask = false;
2322 		/* pCoexDm->nArpCnt = 0; */
2323 	}
2324 
2325 	pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_LINK_STATUS, &wifiLinkStatus);
2326 	numOfWifiLink = wifiLinkStatus >> 16;
2327 	if (numOfWifiLink >= 2) {
2328 		halbtc8723b1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0);
2329 		halbtc8723b1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, false, bBtCtrlAggBufSize, aggBufSize);
2330 		halbtc8723b1ant_ActionWifiMultiPort(pBtCoexist);
2331 		return;
2332 	}
2333 
2334 	pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn);
2335 	if (pCoexSta->bC2hBtInquiryPage) {
2336 		halbtc8723b1ant_ActionBtInquiry(pBtCoexist);
2337 		return;
2338 	} else if (bBtHsOn) {
2339 		halbtc8723b1ant_ActionHs(pBtCoexist);
2340 		return;
2341 	}
2342 
2343 	if (type == BTC_ASSOCIATE_START) {
2344 		halbtc8723b1ant_ActionWifiNotConnectedAssoAuth(pBtCoexist);
2345 	} else if (type == BTC_ASSOCIATE_FINISH) {
2346 		pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected);
2347 		if (!bWifiConnected) /*  non-connected scan */
2348 			halbtc8723b1ant_ActionWifiNotConnected(pBtCoexist);
2349 		else
2350 			halbtc8723b1ant_ActionWifiConnected(pBtCoexist);
2351 	}
2352 }
2353 
EXhalbtc8723b1ant_MediaStatusNotify(struct btc_coexist * pBtCoexist,u8 type)2354 void EXhalbtc8723b1ant_MediaStatusNotify(struct btc_coexist *pBtCoexist, u8 type)
2355 {
2356 	u8 H2C_Parameter[3] = {0};
2357 	u32 wifiBw;
2358 	u8 wifiCentralChnl;
2359 	bool bWifiUnderBMode = false;
2360 
2361 	if (
2362 		pBtCoexist->bManualControl ||
2363 		pBtCoexist->bStopCoexDm ||
2364 		pBtCoexist->btInfo.bBtDisabled
2365 	)
2366 		return;
2367 
2368 	if (type == BTC_MEDIA_CONNECT) {
2369 		pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_B_MODE, &bWifiUnderBMode);
2370 
2371 		/* Set CCK Tx/Rx high Pri except 11b mode */
2372 		if (bWifiUnderBMode) {
2373 			pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cd, 0x00); /* CCK Tx */
2374 			pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cf, 0x00); /* CCK Rx */
2375 		} else {
2376 			pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cd, 0x10); /* CCK Tx */
2377 			pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cf, 0x10); /* CCK Rx */
2378 		}
2379 
2380 		pCoexDm->backupArfrCnt1 = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x430);
2381 		pCoexDm->backupArfrCnt2 = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x434);
2382 		pCoexDm->backupRetryLimit = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0x42a);
2383 		pCoexDm->backupAmpduMaxTime = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x456);
2384 	} else {
2385 		pCoexDm->nArpCnt = 0;
2386 
2387 		pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cd, 0x0); /* CCK Tx */
2388 		pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cf, 0x0); /* CCK Rx */
2389 	}
2390 
2391 	/*  only 2.4G we need to inform bt the chnl mask */
2392 	pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL, &wifiCentralChnl);
2393 	if ((type == BTC_MEDIA_CONNECT) && (wifiCentralChnl <= 14)) {
2394 		/* H2C_Parameter[0] = 0x1; */
2395 		H2C_Parameter[0] = 0x0;
2396 		H2C_Parameter[1] = wifiCentralChnl;
2397 		pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw);
2398 
2399 		if (wifiBw == BTC_WIFI_BW_HT40)
2400 			H2C_Parameter[2] = 0x30;
2401 		else
2402 			H2C_Parameter[2] = 0x20;
2403 	}
2404 
2405 	pCoexDm->wifiChnlInfo[0] = H2C_Parameter[0];
2406 	pCoexDm->wifiChnlInfo[1] = H2C_Parameter[1];
2407 	pCoexDm->wifiChnlInfo[2] = H2C_Parameter[2];
2408 
2409 	pBtCoexist->fBtcFillH2c(pBtCoexist, 0x66, 3, H2C_Parameter);
2410 }
2411 
EXhalbtc8723b1ant_SpecialPacketNotify(struct btc_coexist * pBtCoexist,u8 type)2412 void EXhalbtc8723b1ant_SpecialPacketNotify(struct btc_coexist *pBtCoexist, u8 type)
2413 {
2414 	bool bBtHsOn = false;
2415 	u32 wifiLinkStatus = 0;
2416 	u32 numOfWifiLink = 0;
2417 	bool bBtCtrlAggBufSize = false;
2418 	u8 aggBufSize = 5;
2419 
2420 	if (
2421 		pBtCoexist->bManualControl ||
2422 		pBtCoexist->bStopCoexDm ||
2423 		pBtCoexist->btInfo.bBtDisabled
2424 	)
2425 		return;
2426 
2427 	if (
2428 		type == BTC_PACKET_DHCP ||
2429 		type == BTC_PACKET_EAPOL ||
2430 		type == BTC_PACKET_ARP
2431 	) {
2432 		if (type == BTC_PACKET_ARP) {
2433 			pCoexDm->nArpCnt++;
2434 
2435 			if (pCoexDm->nArpCnt >= 10) /*  if APR PKT > 10 after connect, do not go to ActionWifiConnectedSpecialPacket(pBtCoexist) */
2436 				pCoexSta->bWiFiIsHighPriTask = false;
2437 			else
2438 				pCoexSta->bWiFiIsHighPriTask = true;
2439 		} else {
2440 			pCoexSta->bWiFiIsHighPriTask = true;
2441 		}
2442 	} else {
2443 		pCoexSta->bWiFiIsHighPriTask = false;
2444 	}
2445 
2446 	pCoexSta->specialPktPeriodCnt = 0;
2447 
2448 	pBtCoexist->fBtcGet(
2449 		pBtCoexist, BTC_GET_U4_WIFI_LINK_STATUS, &wifiLinkStatus
2450 	);
2451 	numOfWifiLink = wifiLinkStatus >> 16;
2452 
2453 	if (numOfWifiLink >= 2) {
2454 		halbtc8723b1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0);
2455 		halbtc8723b1ant_LimitedRx(
2456 			pBtCoexist, NORMAL_EXEC, false, bBtCtrlAggBufSize, aggBufSize
2457 		);
2458 		halbtc8723b1ant_ActionWifiMultiPort(pBtCoexist);
2459 		return;
2460 	}
2461 
2462 	pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn);
2463 	if (pCoexSta->bC2hBtInquiryPage) {
2464 		halbtc8723b1ant_ActionBtInquiry(pBtCoexist);
2465 		return;
2466 	} else if (bBtHsOn) {
2467 		halbtc8723b1ant_ActionHs(pBtCoexist);
2468 		return;
2469 	}
2470 
2471 	if (
2472 		type == BTC_PACKET_DHCP ||
2473 		type == BTC_PACKET_EAPOL ||
2474 		((type == BTC_PACKET_ARP) && (pCoexSta->bWiFiIsHighPriTask))
2475 	)
2476 		halbtc8723b1ant_ActionWifiConnectedSpecialPacket(pBtCoexist);
2477 }
2478 
EXhalbtc8723b1ant_BtInfoNotify(struct btc_coexist * pBtCoexist,u8 * tmpBuf,u8 length)2479 void EXhalbtc8723b1ant_BtInfoNotify(
2480 	struct btc_coexist *pBtCoexist, u8 *tmpBuf, u8 length
2481 )
2482 {
2483 	u8 btInfo = 0;
2484 	u8 i, rspSource = 0;
2485 	bool bWifiConnected = false;
2486 	bool bBtBusy = false;
2487 
2488 	pCoexSta->bC2hBtInfoReqSent = false;
2489 
2490 	rspSource = tmpBuf[0] & 0xf;
2491 	if (rspSource >= BT_INFO_SRC_8723B_1ANT_MAX)
2492 		rspSource = BT_INFO_SRC_8723B_1ANT_WIFI_FW;
2493 	pCoexSta->btInfoC2hCnt[rspSource]++;
2494 
2495 	for (i = 0; i < length; i++) {
2496 		pCoexSta->btInfoC2h[rspSource][i] = tmpBuf[i];
2497 		if (i == 1)
2498 			btInfo = tmpBuf[i];
2499 	}
2500 
2501 	if (rspSource != BT_INFO_SRC_8723B_1ANT_WIFI_FW) {
2502 		pCoexSta->btRetryCnt = pCoexSta->btInfoC2h[rspSource][2] & 0xf;
2503 
2504 		if (pCoexSta->btRetryCnt >= 1)
2505 			pCoexSta->popEventCnt++;
2506 
2507 		if (pCoexSta->btInfoC2h[rspSource][2] & 0x20)
2508 			pCoexSta->bC2hBtPage = true;
2509 		else
2510 			pCoexSta->bC2hBtPage = false;
2511 
2512 		pCoexSta->btRssi = pCoexSta->btInfoC2h[rspSource][3] * 2 - 90;
2513 		/* pCoexSta->btInfoC2h[rspSource][3]*2+10; */
2514 
2515 		pCoexSta->btInfoExt = pCoexSta->btInfoC2h[rspSource][4];
2516 
2517 		pCoexSta->bBtTxRxMask = (pCoexSta->btInfoC2h[rspSource][2] & 0x40);
2518 		pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_TX_RX_MASK, &pCoexSta->bBtTxRxMask);
2519 
2520 		if (!pCoexSta->bBtTxRxMask) {
2521 			/* BT into is responded by BT FW and BT RF REG 0x3C != 0x15 => Need to switch BT TRx Mask */
2522 			pBtCoexist->fBtcSetBtReg(pBtCoexist, BTC_BT_REG_RF, 0x3c, 0x15);
2523 		}
2524 
2525 		/*  Here we need to resend some wifi info to BT */
2526 		/*  because bt is reset and loss of the info. */
2527 		if (pCoexSta->btInfoExt & BIT1) {
2528 			pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected);
2529 			if (bWifiConnected)
2530 				EXhalbtc8723b1ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_CONNECT);
2531 			else
2532 				EXhalbtc8723b1ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT);
2533 		}
2534 
2535 		if (pCoexSta->btInfoExt & BIT3) {
2536 			if (!pBtCoexist->bManualControl && !pBtCoexist->bStopCoexDm)
2537 				halbtc8723b1ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, false);
2538 		} else {
2539 			/*  BT already NOT ignore Wlan active, do nothing here. */
2540 		}
2541 	}
2542 
2543 	/*  check BIT2 first ==> check if bt is under inquiry or page scan */
2544 	if (btInfo & BT_INFO_8723B_1ANT_B_INQ_PAGE)
2545 		pCoexSta->bC2hBtInquiryPage = true;
2546 	else
2547 		pCoexSta->bC2hBtInquiryPage = false;
2548 
2549 	/*  set link exist status */
2550 	if (!(btInfo & BT_INFO_8723B_1ANT_B_CONNECTION)) {
2551 		pCoexSta->bBtLinkExist = false;
2552 		pCoexSta->bPanExist = false;
2553 		pCoexSta->bA2dpExist = false;
2554 		pCoexSta->bHidExist = false;
2555 		pCoexSta->bScoExist = false;
2556 	} else {	/*  connection exists */
2557 		pCoexSta->bBtLinkExist = true;
2558 		if (btInfo & BT_INFO_8723B_1ANT_B_FTP)
2559 			pCoexSta->bPanExist = true;
2560 		else
2561 			pCoexSta->bPanExist = false;
2562 
2563 		if (btInfo & BT_INFO_8723B_1ANT_B_A2DP)
2564 			pCoexSta->bA2dpExist = true;
2565 		else
2566 			pCoexSta->bA2dpExist = false;
2567 
2568 		if (btInfo & BT_INFO_8723B_1ANT_B_HID)
2569 			pCoexSta->bHidExist = true;
2570 		else
2571 			pCoexSta->bHidExist = false;
2572 
2573 		if (btInfo & BT_INFO_8723B_1ANT_B_SCO_ESCO)
2574 			pCoexSta->bScoExist = true;
2575 		else
2576 			pCoexSta->bScoExist = false;
2577 	}
2578 
2579 	halbtc8723b1ant_UpdateBtLinkInfo(pBtCoexist);
2580 
2581 	btInfo = btInfo & 0x1f;  /* mask profile bit for connect-ilde identification (for CSR case: A2DP idle --> 0x41) */
2582 
2583 	if (!(btInfo & BT_INFO_8723B_1ANT_B_CONNECTION)) {
2584 		pCoexDm->btStatus = BT_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE;
2585 	} else if (btInfo == BT_INFO_8723B_1ANT_B_CONNECTION)	{
2586 		/*  connection exists but no busy */
2587 		pCoexDm->btStatus = BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE;
2588 	} else if (
2589 		(btInfo & BT_INFO_8723B_1ANT_B_SCO_ESCO) ||
2590 		(btInfo & BT_INFO_8723B_1ANT_B_SCO_BUSY)
2591 	) {
2592 		pCoexDm->btStatus = BT_8723B_1ANT_BT_STATUS_SCO_BUSY;
2593 	} else if (btInfo & BT_INFO_8723B_1ANT_B_ACL_BUSY) {
2594 		if (pCoexDm->btStatus != BT_8723B_1ANT_BT_STATUS_ACL_BUSY)
2595 			pCoexDm->bAutoTdmaAdjust = false;
2596 
2597 		pCoexDm->btStatus = BT_8723B_1ANT_BT_STATUS_ACL_BUSY;
2598 	} else {
2599 		pCoexDm->btStatus = BT_8723B_1ANT_BT_STATUS_MAX;
2600 	}
2601 
2602 	if (
2603 		(pCoexDm->btStatus == BT_8723B_1ANT_BT_STATUS_ACL_BUSY) ||
2604 		(pCoexDm->btStatus == BT_8723B_1ANT_BT_STATUS_SCO_BUSY) ||
2605 		(pCoexDm->btStatus == BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY)
2606 	)
2607 		bBtBusy = true;
2608 	else
2609 		bBtBusy = false;
2610 	pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bBtBusy);
2611 
2612 	halbtc8723b1ant_RunCoexistMechanism(pBtCoexist);
2613 }
2614 
EXhalbtc8723b1ant_HaltNotify(struct btc_coexist * pBtCoexist)2615 void EXhalbtc8723b1ant_HaltNotify(struct btc_coexist *pBtCoexist)
2616 {
2617 	halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
2618 	halbtc8723b1ant_PsTdma(pBtCoexist, FORCE_EXEC, false, 0);
2619 	halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, false, true);
2620 
2621 	halbtc8723b1ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, true);
2622 
2623 	EXhalbtc8723b1ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT);
2624 
2625 	pBtCoexist->bStopCoexDm = true;
2626 }
2627 
EXhalbtc8723b1ant_PnpNotify(struct btc_coexist * pBtCoexist,u8 pnpState)2628 void EXhalbtc8723b1ant_PnpNotify(struct btc_coexist *pBtCoexist, u8 pnpState)
2629 {
2630 	if (pnpState == BTC_WIFI_PNP_SLEEP) {
2631 		halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
2632 		halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, false, 0);
2633 		halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2);
2634 		halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, false, true);
2635 
2636 		pBtCoexist->bStopCoexDm = true;
2637 	} else if (pnpState == BTC_WIFI_PNP_WAKE_UP) {
2638 		pBtCoexist->bStopCoexDm = false;
2639 		halbtc8723b1ant_InitHwConfig(pBtCoexist, false, false);
2640 		halbtc8723b1ant_InitCoexDm(pBtCoexist);
2641 		halbtc8723b1ant_QueryBtInfo(pBtCoexist);
2642 	}
2643 }
2644 
EXhalbtc8723b1ant_Periodical(struct btc_coexist * pBtCoexist)2645 void EXhalbtc8723b1ant_Periodical(struct btc_coexist *pBtCoexist)
2646 {
2647 	static u8 disVerInfoCnt;
2648 	u32 fwVer = 0, btPatchVer = 0;
2649 
2650 	if (disVerInfoCnt <= 5) {
2651 		disVerInfoCnt += 1;
2652 		pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_BT_PATCH_VER, &btPatchVer);
2653 		pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer);
2654 	}
2655 
2656 	halbtc8723b1ant_MonitorBtCtr(pBtCoexist);
2657 	halbtc8723b1ant_MonitorWiFiCtr(pBtCoexist);
2658 
2659 	if (
2660 		halbtc8723b1ant_IsWifiStatusChanged(pBtCoexist) ||
2661 		pCoexDm->bAutoTdmaAdjust
2662 	)
2663 		halbtc8723b1ant_RunCoexistMechanism(pBtCoexist);
2664 
2665 	pCoexSta->specialPktPeriodCnt++;
2666 }
2667