1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
5  *
6  ******************************************************************************/
7 #define _RTL8723B_PHYCFG_C_
8 
9 #include <drv_types.h>
10 #include <rtw_debug.h>
11 #include <rtl8723b_hal.h>
12 
13 
14 /*---------------------------Define Local Constant---------------------------*/
15 /* Channel switch:The size of command tables for switch channel*/
16 #define MAX_PRECMD_CNT 16
17 #define MAX_RFDEPENDCMD_CNT 16
18 #define MAX_POSTCMD_CNT 16
19 
20 #define MAX_DOZE_WAITING_TIMES_9x 64
21 
22 /**
23 * Function:	phy_CalculateBitShift
24 *
25 * OverView:	Get shifted position of the BitMask
26 *
27 * Input:
28 *		u32 	BitMask,
29 *
30 * Output:	none
31 * Return:		u32 	Return the shift bit bit position of the mask
32 */
33 static	u32 phy_CalculateBitShift(u32 BitMask)
34 {
35 	u32 i;
36 
37 	for (i = 0; i <= 31; i++) {
38 		if (((BitMask>>i) &  0x1) == 1)
39 			break;
40 	}
41 	return i;
42 }
43 
44 
45 /**
46 * Function:	PHY_QueryBBReg
47 *
48 * OverView:	Read "sepcific bits" from BB register
49 *
50 * Input:
51 *		struct adapter *	Adapter,
52 *		u32 		RegAddr,	The target address to be readback
53 *		u32 		BitMask		The target bit position in the target address
54 *							to be readback
55 * Output:	None
56 * Return:		u32 		Data		The readback register value
57 * Note:		This function is equal to "GetRegSetting" in PHY programming guide
58 */
59 u32 PHY_QueryBBReg_8723B(struct adapter *Adapter, u32 RegAddr, u32 BitMask)
60 {
61 	u32 ReturnValue = 0, OriginalValue, BitShift;
62 
63 #if (DISABLE_BB_RF == 1)
64 	return 0;
65 #endif
66 
67 	/* RT_TRACE(COMP_RF, DBG_TRACE, ("--->PHY_QueryBBReg(): RegAddr(%#lx), BitMask(%#lx)\n", RegAddr, BitMask)); */
68 
69 	OriginalValue = rtw_read32(Adapter, RegAddr);
70 	BitShift = phy_CalculateBitShift(BitMask);
71 	ReturnValue = (OriginalValue & BitMask) >> BitShift;
72 
73 	return ReturnValue;
74 
75 }
76 
77 
78 /**
79 * Function:	PHY_SetBBReg
80 *
81 * OverView:	Write "Specific bits" to BB register (page 8~)
82 *
83 * Input:
84 *		struct adapter *	Adapter,
85 *		u32 		RegAddr,	The target address to be modified
86 *		u32 		BitMask		The target bit position in the target address
87 *								to be modified
88 *		u32 		Data		The new register value in the target bit position
89 *								of the target address
90 *
91 * Output:	None
92 * Return:		None
93 * Note:		This function is equal to "PutRegSetting" in PHY programming guide
94 */
95 
96 void PHY_SetBBReg_8723B(
97 	struct adapter *Adapter,
98 	u32 RegAddr,
99 	u32 BitMask,
100 	u32 Data
101 )
102 {
103 	/* u16 BBWaitCounter	= 0; */
104 	u32 OriginalValue, BitShift;
105 
106 #if (DISABLE_BB_RF == 1)
107 	return;
108 #endif
109 
110 	/* RT_TRACE(COMP_RF, DBG_TRACE, ("--->PHY_SetBBReg(): RegAddr(%#lx), BitMask(%#lx), Data(%#lx)\n", RegAddr, BitMask, Data)); */
111 
112 	if (BitMask != bMaskDWord) { /* if not "double word" write */
113 		OriginalValue = rtw_read32(Adapter, RegAddr);
114 		BitShift = phy_CalculateBitShift(BitMask);
115 		Data = ((OriginalValue & (~BitMask)) | ((Data << BitShift) & BitMask));
116 	}
117 
118 	rtw_write32(Adapter, RegAddr, Data);
119 
120 }
121 
122 
123 /*  */
124 /*  2. RF register R/W API */
125 /*  */
126 
127 static u32 phy_RFSerialRead_8723B(
128 	struct adapter *Adapter, enum RF_PATH eRFPath, u32 Offset
129 )
130 {
131 	u32 retValue = 0;
132 	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
133 	struct bb_register_def *pPhyReg = &pHalData->PHYRegDef[eRFPath];
134 	u32 NewOffset;
135 	u32 tmplong2;
136 	u8 RfPiEnable = 0;
137 	u32 MaskforPhySet = 0;
138 	int i = 0;
139 
140 	/*  */
141 	/*  Make sure RF register offset is correct */
142 	/*  */
143 	Offset &= 0xff;
144 
145 	NewOffset = Offset;
146 
147 	if (eRFPath == RF_PATH_A) {
148 		tmplong2 = PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter2|MaskforPhySet, bMaskDWord);
149 		tmplong2 = (tmplong2 & (~bLSSIReadAddress)) | (NewOffset<<23) | bLSSIReadEdge;	/* T65 RF */
150 		PHY_SetBBReg(Adapter, rFPGA0_XA_HSSIParameter2|MaskforPhySet, bMaskDWord, tmplong2&(~bLSSIReadEdge));
151 	} else {
152 		tmplong2 = PHY_QueryBBReg(Adapter, rFPGA0_XB_HSSIParameter2|MaskforPhySet, bMaskDWord);
153 		tmplong2 = (tmplong2 & (~bLSSIReadAddress)) | (NewOffset<<23) | bLSSIReadEdge;	/* T65 RF */
154 		PHY_SetBBReg(Adapter, rFPGA0_XB_HSSIParameter2|MaskforPhySet, bMaskDWord, tmplong2&(~bLSSIReadEdge));
155 	}
156 
157 	tmplong2 = PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter2|MaskforPhySet, bMaskDWord);
158 	PHY_SetBBReg(Adapter, rFPGA0_XA_HSSIParameter2|MaskforPhySet, bMaskDWord, tmplong2 & (~bLSSIReadEdge));
159 	PHY_SetBBReg(Adapter, rFPGA0_XA_HSSIParameter2|MaskforPhySet, bMaskDWord, tmplong2 | bLSSIReadEdge);
160 
161 	udelay(10);
162 
163 	for (i = 0; i < 2; i++)
164 		udelay(MAX_STALL_TIME);
165 	udelay(10);
166 
167 	if (eRFPath == RF_PATH_A)
168 		RfPiEnable = (u8)PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter1|MaskforPhySet, BIT8);
169 	else if (eRFPath == RF_PATH_B)
170 		RfPiEnable = (u8)PHY_QueryBBReg(Adapter, rFPGA0_XB_HSSIParameter1|MaskforPhySet, BIT8);
171 
172 	if (RfPiEnable) {
173 		/*  Read from BBreg8b8, 12 bits for 8190, 20bits for T65 RF */
174 		retValue = PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBackPi|MaskforPhySet, bLSSIReadBackData);
175 
176 		/* RT_DISP(FINIT, INIT_RF, ("Readback from RF-PI : 0x%x\n", retValue)); */
177 	} else {
178 		/* Read from BBreg8a0, 12 bits for 8190, 20 bits for T65 RF */
179 		retValue = PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBack|MaskforPhySet, bLSSIReadBackData);
180 
181 		/* RT_DISP(FINIT, INIT_RF, ("Readback from RF-SI : 0x%x\n", retValue)); */
182 	}
183 	return retValue;
184 
185 }
186 
187 /**
188 * Function:	phy_RFSerialWrite_8723B
189 *
190 * OverView:	Write data to RF register (page 8~)
191 *
192 * Input:
193 *		struct adapter *	Adapter,
194 *		RF_PATH			eRFPath,	Radio path of A/B/C/D
195 *		u32 		Offset,		The target address to be read
196 *		u32 		Data		The new register Data in the target bit position
197 *								of the target to be read
198 *
199 * Output:	None
200 * Return:		None
201 * Note:		Threre are three types of serial operations:
202 *		1. Software serial write
203 *		2. Hardware LSSI-Low Speed Serial Interface
204 *		3. Hardware HSSI-High speed
205 *		serial write. Driver need to implement (1) and (2).
206 *		This function is equal to the combination of RF_ReadReg() and  RFLSSIRead()
207  *
208  * Note:		  For RF8256 only
209  *		 The total count of RTL8256(Zebra4) register is around 36 bit it only employs
210  *		 4-bit RF address. RTL8256 uses "register mode control bit" (Reg00[12], Reg00[10])
211  *		 to access register address bigger than 0xf. See "Appendix-4 in PHY Configuration
212  *		 programming guide" for more details.
213  *		 Thus, we define a sub-finction for RTL8526 register address conversion
214  *	       ===========================================================
215  *		 Register Mode		RegCTL[1]		RegCTL[0]		Note
216  *							(Reg00[12])		(Reg00[10])
217  *	       ===========================================================
218  *		 Reg_Mode0				0				x			Reg 0 ~15(0x0 ~ 0xf)
219  *	       ------------------------------------------------------------------
220  *		 Reg_Mode1				1				0			Reg 16 ~30(0x1 ~ 0xf)
221  *	       ------------------------------------------------------------------
222  *		 Reg_Mode2				1				1			Reg 31 ~ 45(0x1 ~ 0xf)
223  *	       ------------------------------------------------------------------
224  *
225  *2008/09/02	MH	Add 92S RF definition
226  *
227  *
228  *
229 */
230 static void phy_RFSerialWrite_8723B(
231 	struct adapter *Adapter,
232 	enum RF_PATH eRFPath,
233 	u32 Offset,
234 	u32 Data
235 )
236 {
237 	u32 DataAndAddr = 0;
238 	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
239 	struct bb_register_def *pPhyReg = &pHalData->PHYRegDef[eRFPath];
240 	u32 NewOffset;
241 
242 	Offset &= 0xff;
243 
244 	/*  */
245 	/*  Switch page for 8256 RF IC */
246 	/*  */
247 	NewOffset = Offset;
248 
249 	/*  */
250 	/*  Put write addr in [5:0]  and write data in [31:16] */
251 	/*  */
252 	/* DataAndAddr = (Data<<16) | (NewOffset&0x3f); */
253 	DataAndAddr = ((NewOffset<<20) | (Data&0x000fffff)) & 0x0fffffff;	/*  T65 RF */
254 
255 	/*  */
256 	/*  Write Operation */
257 	/*  */
258 	PHY_SetBBReg(Adapter, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr);
259 	/* RTPRINT(FPHY, PHY_RFW, ("RFW-%d Addr[0x%lx]= 0x%lx\n", eRFPath, pPhyReg->rf3wireOffset, DataAndAddr)); */
260 
261 }
262 
263 
264 /**
265 * Function:	PHY_QueryRFReg
266 *
267 * OverView:	Query "Specific bits" to RF register (page 8~)
268 *
269 * Input:
270 *		struct adapter *	Adapter,
271 *		RF_PATH			eRFPath,	Radio path of A/B/C/D
272 *		u32 		RegAddr,	The target address to be read
273 *		u32 		BitMask		The target bit position in the target address
274 *								to be read
275 *
276 * Output:	None
277 * Return:		u32 		Readback value
278 * Note:		This function is equal to "GetRFRegSetting" in PHY programming guide
279 */
280 u32 PHY_QueryRFReg_8723B(
281 	struct adapter *Adapter,
282 	u8 eRFPath,
283 	u32 RegAddr,
284 	u32 BitMask
285 )
286 {
287 	u32 Original_Value, Readback_Value, BitShift;
288 
289 #if (DISABLE_BB_RF == 1)
290 	return 0;
291 #endif
292 
293 	Original_Value = phy_RFSerialRead_8723B(Adapter, eRFPath, RegAddr);
294 
295 	BitShift =  phy_CalculateBitShift(BitMask);
296 	Readback_Value = (Original_Value & BitMask) >> BitShift;
297 
298 	return Readback_Value;
299 }
300 
301 /**
302 * Function:	PHY_SetRFReg
303 *
304 * OverView:	Write "Specific bits" to RF register (page 8~)
305 *
306 * Input:
307 *		struct adapter *	Adapter,
308 *		RF_PATH			eRFPath,	Radio path of A/B/C/D
309 *		u32 		RegAddr,	The target address to be modified
310 *		u32 		BitMask		The target bit position in the target address
311 *								to be modified
312 *		u32 		Data		The new register Data in the target bit position
313 *								of the target address
314 *
315 * Output:	None
316 * Return:		None
317 * Note:		This function is equal to "PutRFRegSetting" in PHY programming guide
318 */
319 void PHY_SetRFReg_8723B(
320 	struct adapter *Adapter,
321 	u8 eRFPath,
322 	u32 RegAddr,
323 	u32 BitMask,
324 	u32 Data
325 )
326 {
327 	u32 Original_Value, BitShift;
328 
329 #if (DISABLE_BB_RF == 1)
330 	return;
331 #endif
332 
333 	/*  RF data is 12 bits only */
334 	if (BitMask != bRFRegOffsetMask) {
335 		Original_Value = phy_RFSerialRead_8723B(Adapter, eRFPath, RegAddr);
336 		BitShift =  phy_CalculateBitShift(BitMask);
337 		Data = ((Original_Value & (~BitMask)) | (Data<<BitShift));
338 	}
339 
340 	phy_RFSerialWrite_8723B(Adapter, eRFPath, RegAddr, Data);
341 }
342 
343 
344 /*  */
345 /*  3. Initial MAC/BB/RF config by reading MAC/BB/RF txt. */
346 /*  */
347 
348 
349 /*-----------------------------------------------------------------------------
350  * Function:    PHY_MACConfig8192C
351  *
352  * Overview:	Condig MAC by header file or parameter file.
353  *
354  * Input:       NONE
355  *
356  * Output:      NONE
357  *
358  * Return:      NONE
359  *
360  * Revised History:
361  *  When		Who		Remark
362  *  08/12/2008	MHC		Create Version 0.
363  *
364  *---------------------------------------------------------------------------
365  */
366 s32 PHY_MACConfig8723B(struct adapter *Adapter)
367 {
368 	int rtStatus = _SUCCESS;
369 	struct hal_com_data	*pHalData = GET_HAL_DATA(Adapter);
370 	s8 *pszMACRegFile;
371 	s8 sz8723MACRegFile[] = RTL8723B_PHY_MACREG;
372 
373 
374 	pszMACRegFile = sz8723MACRegFile;
375 
376 	/*  */
377 	/*  Config MAC */
378 	/*  */
379 	rtStatus = phy_ConfigMACWithParaFile(Adapter, pszMACRegFile);
380 	if (rtStatus == _FAIL) {
381 		ODM_ConfigMACWithHeaderFile(&pHalData->odmpriv);
382 		rtStatus = _SUCCESS;
383 	}
384 
385 	return rtStatus;
386 }
387 
388 /**
389 * Function:	phy_InitBBRFRegisterDefinition
390 *
391 * OverView:	Initialize Register definition offset for Radio Path A/B/C/D
392 *
393 * Input:
394 *		struct adapter *	Adapter,
395 *
396 * Output:	None
397 * Return:		None
398 * Note:		The initialization value is constant and it should never be changes
399 */
400 static void phy_InitBBRFRegisterDefinition(struct adapter *Adapter)
401 {
402 	struct hal_com_data		*pHalData = GET_HAL_DATA(Adapter);
403 
404 	/*  RF Interface Sowrtware Control */
405 	pHalData->PHYRegDef[ODM_RF_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW; /*  16 LSBs if read 32-bit from 0x870 */
406 	pHalData->PHYRegDef[ODM_RF_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW; /*  16 MSBs if read 32-bit from 0x870 (16-bit for 0x872) */
407 
408 	/*  RF Interface Output (and Enable) */
409 	pHalData->PHYRegDef[ODM_RF_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE; /*  16 LSBs if read 32-bit from 0x860 */
410 	pHalData->PHYRegDef[ODM_RF_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE; /*  16 LSBs if read 32-bit from 0x864 */
411 
412 	/*  RF Interface (Output and)  Enable */
413 	pHalData->PHYRegDef[ODM_RF_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE; /*  16 MSBs if read 32-bit from 0x860 (16-bit for 0x862) */
414 	pHalData->PHYRegDef[ODM_RF_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE; /*  16 MSBs if read 32-bit from 0x864 (16-bit for 0x866) */
415 
416 	pHalData->PHYRegDef[ODM_RF_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter; /* LSSI Parameter */
417 	pHalData->PHYRegDef[ODM_RF_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter;
418 
419 	pHalData->PHYRegDef[ODM_RF_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2;  /* wire control parameter2 */
420 	pHalData->PHYRegDef[ODM_RF_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2;  /* wire control parameter2 */
421 
422 	/*  Tranceiver Readback LSSI/HSPI mode */
423 	pHalData->PHYRegDef[ODM_RF_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack;
424 	pHalData->PHYRegDef[ODM_RF_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack;
425 	pHalData->PHYRegDef[ODM_RF_PATH_A].rfLSSIReadBackPi = TransceiverA_HSPI_Readback;
426 	pHalData->PHYRegDef[ODM_RF_PATH_B].rfLSSIReadBackPi = TransceiverB_HSPI_Readback;
427 
428 }
429 
430 static int phy_BB8723b_Config_ParaFile(struct adapter *Adapter)
431 {
432 	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
433 	int rtStatus = _SUCCESS;
434 	u8 sz8723BBRegFile[] = RTL8723B_PHY_REG;
435 	u8 sz8723AGCTableFile[] = RTL8723B_AGC_TAB;
436 	u8 sz8723BBBRegPgFile[] = RTL8723B_PHY_REG_PG;
437 	u8 sz8723BBRegMpFile[] = RTL8723B_PHY_REG_MP;
438 	u8 sz8723BRFTxPwrLmtFile[] = RTL8723B_TXPWR_LMT;
439 	u8 *pszBBRegFile = NULL, *pszAGCTableFile = NULL, *pszBBRegPgFile = NULL, *pszBBRegMpFile = NULL, *pszRFTxPwrLmtFile = NULL;
440 
441 	pszBBRegFile = sz8723BBRegFile;
442 	pszAGCTableFile = sz8723AGCTableFile;
443 	pszBBRegPgFile = sz8723BBBRegPgFile;
444 	pszBBRegMpFile = sz8723BBRegMpFile;
445 	pszRFTxPwrLmtFile = sz8723BRFTxPwrLmtFile;
446 
447 	/*  Read Tx Power Limit File */
448 	PHY_InitTxPowerLimit(Adapter);
449 	if (
450 		Adapter->registrypriv.RegEnableTxPowerLimit == 1 ||
451 		(Adapter->registrypriv.RegEnableTxPowerLimit == 2 && pHalData->EEPROMRegulatory == 1)
452 	) {
453 		if (PHY_ConfigRFWithPowerLimitTableParaFile(Adapter, pszRFTxPwrLmtFile) == _FAIL) {
454 			if (HAL_STATUS_SUCCESS != ODM_ConfigRFWithHeaderFile(&pHalData->odmpriv, CONFIG_RF_TXPWR_LMT, (ODM_RF_RADIO_PATH_E)0))
455 				rtStatus = _FAIL;
456 		}
457 
458 		if (rtStatus != _SUCCESS) {
459 			DBG_871X("%s():Read Tx power limit fail\n", __func__);
460 			goto phy_BB8190_Config_ParaFile_Fail;
461 		}
462 	}
463 
464 	/*  */
465 	/*  1. Read PHY_REG.TXT BB INIT!! */
466 	/*  */
467 	if (phy_ConfigBBWithParaFile(Adapter, pszBBRegFile, CONFIG_BB_PHY_REG) ==
468 		_FAIL) {
469 		if (HAL_STATUS_SUCCESS != ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv, CONFIG_BB_PHY_REG))
470 			rtStatus = _FAIL;
471 	}
472 
473 	if (rtStatus != _SUCCESS) {
474 		DBG_8192C("%s():Write BB Reg Fail!!", __func__);
475 		goto phy_BB8190_Config_ParaFile_Fail;
476 	}
477 
478 	/*  If EEPROM or EFUSE autoload OK, We must config by PHY_REG_PG.txt */
479 	PHY_InitTxPowerByRate(Adapter);
480 	if (
481 		Adapter->registrypriv.RegEnableTxPowerByRate == 1 ||
482 		(Adapter->registrypriv.RegEnableTxPowerByRate == 2 && pHalData->EEPROMRegulatory != 2)
483 	) {
484 		if (phy_ConfigBBWithPgParaFile(Adapter, pszBBRegPgFile) ==
485 			_FAIL) {
486 			if (HAL_STATUS_SUCCESS != ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv, CONFIG_BB_PHY_REG_PG))
487 				rtStatus = _FAIL;
488 		}
489 
490 		if (pHalData->odmpriv.PhyRegPgValueType == PHY_REG_PG_EXACT_VALUE)
491 			PHY_TxPowerByRateConfiguration(Adapter);
492 
493 		if (
494 			Adapter->registrypriv.RegEnableTxPowerLimit == 1 ||
495 			(Adapter->registrypriv.RegEnableTxPowerLimit == 2 && pHalData->EEPROMRegulatory == 1)
496 		)
497 			PHY_ConvertTxPowerLimitToPowerIndex(Adapter);
498 
499 		if (rtStatus != _SUCCESS) {
500 			DBG_8192C("%s():BB_PG Reg Fail!!\n", __func__);
501 		}
502 	}
503 
504 	/*  */
505 	/*  2. Read BB AGC table Initialization */
506 	/*  */
507 	if (phy_ConfigBBWithParaFile(Adapter, pszAGCTableFile,
508 				     CONFIG_BB_AGC_TAB) == _FAIL) {
509 		if (HAL_STATUS_SUCCESS != ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv, CONFIG_BB_AGC_TAB))
510 			rtStatus = _FAIL;
511 	}
512 
513 	if (rtStatus != _SUCCESS) {
514 		DBG_8192C("%s():AGC Table Fail\n", __func__);
515 		goto phy_BB8190_Config_ParaFile_Fail;
516 	}
517 
518 phy_BB8190_Config_ParaFile_Fail:
519 
520 	return rtStatus;
521 }
522 
523 
524 int PHY_BBConfig8723B(struct adapter *Adapter)
525 {
526 	int	rtStatus = _SUCCESS;
527 	struct hal_com_data	*pHalData = GET_HAL_DATA(Adapter);
528 	u32 RegVal;
529 	u8 CrystalCap;
530 
531 	phy_InitBBRFRegisterDefinition(Adapter);
532 
533 	/*  Enable BB and RF */
534 	RegVal = rtw_read16(Adapter, REG_SYS_FUNC_EN);
535 	rtw_write16(Adapter, REG_SYS_FUNC_EN, (u16)(RegVal|BIT13|BIT0|BIT1));
536 
537 	rtw_write32(Adapter, 0x948, 0x280);	/*  Others use Antenna S1 */
538 
539 	rtw_write8(Adapter, REG_RF_CTRL, RF_EN|RF_RSTB|RF_SDMRSTB);
540 
541 	msleep(1);
542 
543 	PHY_SetRFReg(Adapter, ODM_RF_PATH_A, 0x1, 0xfffff, 0x780);
544 
545 	rtw_write8(Adapter, REG_SYS_FUNC_EN, FEN_PPLL|FEN_PCIEA|FEN_DIO_PCIE|FEN_BB_GLB_RSTn|FEN_BBRSTB);
546 
547 	rtw_write8(Adapter, REG_AFE_XTAL_CTRL+1, 0x80);
548 
549 	/*  */
550 	/*  Config BB and AGC */
551 	/*  */
552 	rtStatus = phy_BB8723b_Config_ParaFile(Adapter);
553 
554 	/*  0x2C[23:18] = 0x2C[17:12] = CrystalCap */
555 	CrystalCap = pHalData->CrystalCap & 0x3F;
556 	PHY_SetBBReg(Adapter, REG_MAC_PHY_CTRL, 0xFFF000, (CrystalCap | (CrystalCap << 6)));
557 
558 	return rtStatus;
559 }
560 
561 static void phy_LCK_8723B(struct adapter *Adapter)
562 {
563 	PHY_SetRFReg(Adapter, RF_PATH_A, 0xB0, bRFRegOffsetMask, 0xDFBE0);
564 	PHY_SetRFReg(Adapter, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, 0x8C01);
565 	mdelay(200);
566 	PHY_SetRFReg(Adapter, RF_PATH_A, 0xB0, bRFRegOffsetMask, 0xDFFE0);
567 }
568 
569 int PHY_RFConfig8723B(struct adapter *Adapter)
570 {
571 	int rtStatus = _SUCCESS;
572 
573 	/*  */
574 	/*  RF config */
575 	/*  */
576 	rtStatus = PHY_RF6052_Config8723B(Adapter);
577 
578 	phy_LCK_8723B(Adapter);
579 	/* PHY_BB8723B_Config_1T(Adapter); */
580 
581 	return rtStatus;
582 }
583 
584 /**************************************************************************************************************
585  *   Description:
586  *       The low-level interface to set TxAGC , called by both MP and Normal Driver.
587  *
588  *                                                                                    <20120830, Kordan>
589  **************************************************************************************************************/
590 
591 void PHY_SetTxPowerIndex_8723B(
592 	struct adapter *Adapter,
593 	u32 PowerIndex,
594 	u8 RFPath,
595 	u8 Rate
596 )
597 {
598 	if (RFPath == ODM_RF_PATH_A || RFPath == ODM_RF_PATH_B) {
599 		switch (Rate) {
600 		case MGN_1M:
601 			PHY_SetBBReg(Adapter, rTxAGC_A_CCK1_Mcs32, bMaskByte1, PowerIndex);
602 			break;
603 		case MGN_2M:
604 			PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte1, PowerIndex);
605 			break;
606 		case MGN_5_5M:
607 			PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte2, PowerIndex);
608 			break;
609 		case MGN_11M:
610 			PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte3, PowerIndex);
611 			break;
612 
613 		case MGN_6M:
614 			PHY_SetBBReg(Adapter, rTxAGC_A_Rate18_06, bMaskByte0, PowerIndex);
615 			break;
616 		case MGN_9M:
617 			PHY_SetBBReg(Adapter, rTxAGC_A_Rate18_06, bMaskByte1, PowerIndex);
618 			break;
619 		case MGN_12M:
620 			PHY_SetBBReg(Adapter, rTxAGC_A_Rate18_06, bMaskByte2, PowerIndex);
621 			break;
622 		case MGN_18M:
623 			PHY_SetBBReg(Adapter, rTxAGC_A_Rate18_06, bMaskByte3, PowerIndex);
624 			break;
625 
626 		case MGN_24M:
627 			PHY_SetBBReg(Adapter, rTxAGC_A_Rate54_24, bMaskByte0, PowerIndex);
628 			break;
629 		case MGN_36M:
630 			PHY_SetBBReg(Adapter, rTxAGC_A_Rate54_24, bMaskByte1, PowerIndex);
631 			break;
632 		case MGN_48M:
633 			PHY_SetBBReg(Adapter, rTxAGC_A_Rate54_24, bMaskByte2, PowerIndex);
634 			break;
635 		case MGN_54M:
636 			PHY_SetBBReg(Adapter, rTxAGC_A_Rate54_24, bMaskByte3, PowerIndex);
637 			break;
638 
639 		case MGN_MCS0:
640 			PHY_SetBBReg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte0, PowerIndex);
641 			break;
642 		case MGN_MCS1:
643 			PHY_SetBBReg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte1, PowerIndex);
644 			break;
645 		case MGN_MCS2:
646 			PHY_SetBBReg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte2, PowerIndex);
647 			break;
648 		case MGN_MCS3:
649 			PHY_SetBBReg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte3, PowerIndex);
650 			break;
651 
652 		case MGN_MCS4:
653 			PHY_SetBBReg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte0, PowerIndex);
654 			break;
655 		case MGN_MCS5:
656 			PHY_SetBBReg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte1, PowerIndex);
657 			break;
658 		case MGN_MCS6:
659 			PHY_SetBBReg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte2, PowerIndex);
660 			break;
661 		case MGN_MCS7:
662 			PHY_SetBBReg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte3, PowerIndex);
663 			break;
664 
665 		default:
666 			DBG_871X("Invalid Rate!!\n");
667 			break;
668 		}
669 	} else {
670 		RT_TRACE(_module_hal_init_c_, _drv_err_, ("Invalid RFPath!!\n"));
671 	}
672 }
673 
674 u8 PHY_GetTxPowerIndex_8723B(
675 	struct adapter *padapter,
676 	u8 RFPath,
677 	u8 Rate,
678 	enum CHANNEL_WIDTH BandWidth,
679 	u8 Channel
680 )
681 {
682 	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
683 	s8 txPower = 0, powerDiffByRate = 0, limit = 0;
684 	bool bIn24G = false;
685 
686 	/* DBG_871X("===>%s\n", __func__); */
687 
688 	txPower = (s8) PHY_GetTxPowerIndexBase(padapter, RFPath, Rate, BandWidth, Channel, &bIn24G);
689 	powerDiffByRate = PHY_GetTxPowerByRate(padapter, BAND_ON_2_4G, ODM_RF_PATH_A, RF_1TX, Rate);
690 
691 	limit = phy_get_tx_pwr_lmt(
692 		padapter,
693 		padapter->registrypriv.RegPwrTblSel,
694 		(u8)(!bIn24G),
695 		pHalData->CurrentChannelBW,
696 		RFPath,
697 		Rate,
698 		pHalData->CurrentChannel
699 	);
700 
701 	powerDiffByRate = powerDiffByRate > limit ? limit : powerDiffByRate;
702 	txPower += powerDiffByRate;
703 
704 	txPower += PHY_GetTxPowerTrackingOffset(padapter, RFPath, Rate);
705 
706 	if (txPower > MAX_POWER_INDEX)
707 		txPower = MAX_POWER_INDEX;
708 
709 	/* DBG_871X("Final Tx Power(RF-%c, Channel: %d) = %d(0x%X)\n", ((RFPath == 0)?'A':'B'), Channel, txPower, txPower)); */
710 	return (u8) txPower;
711 }
712 
713 void PHY_SetTxPowerLevel8723B(struct adapter *Adapter, u8 Channel)
714 {
715 	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
716 	PDM_ODM_T pDM_Odm = &pHalData->odmpriv;
717 	pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable;
718 	u8 RFPath = ODM_RF_PATH_A;
719 
720 	if (pHalData->AntDivCfg) {/*  antenna diversity Enable */
721 		RFPath = ((pDM_FatTable->RxIdleAnt == MAIN_ANT) ? ODM_RF_PATH_A : ODM_RF_PATH_B);
722 	} else { /*  antenna diversity disable */
723 		RFPath = pHalData->ant_path;
724 	}
725 
726 	RT_TRACE(_module_hal_init_c_, _drv_info_, ("==>PHY_SetTxPowerLevel8723B()\n"));
727 
728 	PHY_SetTxPowerLevelByPath(Adapter, Channel, RFPath);
729 
730 	RT_TRACE(_module_hal_init_c_, _drv_info_, ("<==PHY_SetTxPowerLevel8723B()\n"));
731 }
732 
733 void PHY_GetTxPowerLevel8723B(struct adapter *Adapter, s32 *powerlevel)
734 {
735 }
736 
737 static void phy_SetRegBW_8723B(
738 	struct adapter *Adapter, enum CHANNEL_WIDTH CurrentBW
739 )
740 {
741 	u16 RegRfMod_BW, u2tmp = 0;
742 	RegRfMod_BW = rtw_read16(Adapter, REG_TRXPTCL_CTL_8723B);
743 
744 	switch (CurrentBW) {
745 	case CHANNEL_WIDTH_20:
746 		rtw_write16(Adapter, REG_TRXPTCL_CTL_8723B, (RegRfMod_BW & 0xFE7F)); /*  BIT 7 = 0, BIT 8 = 0 */
747 		break;
748 
749 	case CHANNEL_WIDTH_40:
750 		u2tmp = RegRfMod_BW | BIT7;
751 		rtw_write16(Adapter, REG_TRXPTCL_CTL_8723B, (u2tmp & 0xFEFF)); /*  BIT 7 = 1, BIT 8 = 0 */
752 		break;
753 
754 	case CHANNEL_WIDTH_80:
755 		u2tmp = RegRfMod_BW | BIT8;
756 		rtw_write16(Adapter, REG_TRXPTCL_CTL_8723B, (u2tmp & 0xFF7F)); /*  BIT 7 = 0, BIT 8 = 1 */
757 		break;
758 
759 	default:
760 		DBG_871X("phy_PostSetBWMode8723B():	unknown Bandwidth: %#X\n", CurrentBW);
761 		break;
762 	}
763 }
764 
765 static u8 phy_GetSecondaryChnl_8723B(struct adapter *Adapter)
766 {
767 	u8 SCSettingOf40 = 0, SCSettingOf20 = 0;
768 	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
769 
770 	RT_TRACE(
771 		_module_hal_init_c_,
772 		_drv_info_,
773 		(
774 			"SCMapping: VHT Case: pHalData->CurrentChannelBW %d, pHalData->nCur80MhzPrimeSC %d, pHalData->nCur40MhzPrimeSC %d\n",
775 			pHalData->CurrentChannelBW,
776 			pHalData->nCur80MhzPrimeSC,
777 			pHalData->nCur40MhzPrimeSC
778 		)
779 	);
780 	if (pHalData->CurrentChannelBW == CHANNEL_WIDTH_80) {
781 		if (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
782 			SCSettingOf40 = VHT_DATA_SC_40_LOWER_OF_80MHZ;
783 		else if (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
784 			SCSettingOf40 = VHT_DATA_SC_40_UPPER_OF_80MHZ;
785 		else
786 			RT_TRACE(_module_hal_init_c_, _drv_err_, ("SCMapping: Not Correct Primary40MHz Setting\n"));
787 
788 		if (
789 			(pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) &&
790 			(pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
791 		)
792 			SCSettingOf20 = VHT_DATA_SC_20_LOWEST_OF_80MHZ;
793 		else if (
794 			(pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) &&
795 			(pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
796 		)
797 			SCSettingOf20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
798 		else if (
799 			(pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) &&
800 			(pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
801 		)
802 			SCSettingOf20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
803 		else if (
804 			(pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) &&
805 			(pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
806 		)
807 			SCSettingOf20 = VHT_DATA_SC_20_UPPERST_OF_80MHZ;
808 		else
809 			RT_TRACE(_module_hal_init_c_, _drv_err_, ("SCMapping: Not Correct Primary40MHz Setting\n"));
810 	} else if (pHalData->CurrentChannelBW == CHANNEL_WIDTH_40) {
811 		RT_TRACE(
812 			_module_hal_init_c_,
813 			_drv_info_,
814 			(
815 				"SCMapping: VHT Case: pHalData->CurrentChannelBW %d, pHalData->nCur40MhzPrimeSC %d\n",
816 				pHalData->CurrentChannelBW,
817 				pHalData->nCur40MhzPrimeSC
818 			)
819 		);
820 
821 		if (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
822 			SCSettingOf20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
823 		else if (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
824 			SCSettingOf20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
825 		else
826 			RT_TRACE(_module_hal_init_c_, _drv_err_, ("SCMapping: Not Correct Primary40MHz Setting\n"));
827 	}
828 
829 	RT_TRACE(_module_hal_init_c_, _drv_info_, ("SCMapping: SC Value %x\n", ((SCSettingOf40 << 4) | SCSettingOf20)));
830 	return  ((SCSettingOf40 << 4) | SCSettingOf20);
831 }
832 
833 static void phy_PostSetBwMode8723B(struct adapter *Adapter)
834 {
835 	u8 SubChnlNum = 0;
836 	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
837 
838 
839 	/* 3 Set Reg668 Reg440 BW */
840 	phy_SetRegBW_8723B(Adapter, pHalData->CurrentChannelBW);
841 
842 	/* 3 Set Reg483 */
843 	SubChnlNum = phy_GetSecondaryChnl_8723B(Adapter);
844 	rtw_write8(Adapter, REG_DATA_SC_8723B, SubChnlNum);
845 
846 	/* 3 */
847 	/* 3<2>Set PHY related register */
848 	/* 3 */
849 	switch (pHalData->CurrentChannelBW) {
850 	/* 20 MHz channel*/
851 	case CHANNEL_WIDTH_20:
852 		PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x0);
853 
854 		PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x0);
855 
856 /* 			PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter2, BIT10, 1); */
857 
858 		PHY_SetBBReg(Adapter, rOFDM0_TxPseudoNoiseWgt, (BIT31|BIT30), 0x0);
859 		break;
860 
861 	/* 40 MHz channel*/
862 	case CHANNEL_WIDTH_40:
863 		PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x1);
864 
865 		PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x1);
866 
867 		/*  Set Control channel to upper or lower. These settings are required only for 40MHz */
868 		PHY_SetBBReg(Adapter, rCCK0_System, bCCKSideBand, (pHalData->nCur40MhzPrimeSC>>1));
869 
870 		PHY_SetBBReg(Adapter, rOFDM1_LSTF, 0xC00, pHalData->nCur40MhzPrimeSC);
871 
872 /* PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter2, BIT10, 0); */
873 
874 		PHY_SetBBReg(Adapter, 0x818, (BIT26|BIT27), (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
875 
876 		break;
877 
878 	default:
879 		/*RT_TRACE(COMP_DBG, DBG_LOUD, ("phy_SetBWMode8723B(): unknown Bandwidth: %#X\n"\
880 					, pHalData->CurrentChannelBW));*/
881 		break;
882 	}
883 
884 	/* 3<3>Set RF related register */
885 	PHY_RF6052SetBandwidth8723B(Adapter, pHalData->CurrentChannelBW);
886 }
887 
888 static void phy_SwChnl8723B(struct adapter *padapter)
889 {
890 	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
891 	u8 channelToSW = pHalData->CurrentChannel;
892 
893 	if (pHalData->rf_chip == RF_PSEUDO_11N) {
894 		/* RT_TRACE(COMP_MLME, DBG_LOUD, ("phy_SwChnl8723B: return for PSEUDO\n")); */
895 		return;
896 	}
897 	pHalData->RfRegChnlVal[0] = ((pHalData->RfRegChnlVal[0] & 0xfffff00) | channelToSW);
898 	PHY_SetRFReg(padapter, ODM_RF_PATH_A, RF_CHNLBW, 0x3FF, pHalData->RfRegChnlVal[0]);
899 	PHY_SetRFReg(padapter, ODM_RF_PATH_B, RF_CHNLBW, 0x3FF, pHalData->RfRegChnlVal[0]);
900 
901 	DBG_8192C("===>phy_SwChnl8723B: Channel = %d\n", channelToSW);
902 }
903 
904 static void phy_SwChnlAndSetBwMode8723B(struct adapter *Adapter)
905 {
906 	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
907 
908 	/* RT_TRACE(COMP_SCAN, DBG_LOUD, ("phy_SwChnlAndSetBwMode8723B(): bSwChnl %d, bSetChnlBW %d\n", pHalData->bSwChnl, pHalData->bSetChnlBW)); */
909 	if (Adapter->bNotifyChannelChange) {
910 		DBG_871X("[%s] bSwChnl =%d, ch =%d, bSetChnlBW =%d, bw =%d\n",
911 			__func__,
912 			pHalData->bSwChnl,
913 			pHalData->CurrentChannel,
914 			pHalData->bSetChnlBW,
915 			pHalData->CurrentChannelBW);
916 	}
917 
918 	if (Adapter->bDriverStopped || Adapter->bSurpriseRemoved)
919 		return;
920 
921 	if (pHalData->bSwChnl) {
922 		phy_SwChnl8723B(Adapter);
923 		pHalData->bSwChnl = false;
924 	}
925 
926 	if (pHalData->bSetChnlBW) {
927 		phy_PostSetBwMode8723B(Adapter);
928 		pHalData->bSetChnlBW = false;
929 	}
930 
931 	PHY_SetTxPowerLevel8723B(Adapter, pHalData->CurrentChannel);
932 }
933 
934 static void PHY_HandleSwChnlAndSetBW8723B(
935 	struct adapter *Adapter,
936 	bool bSwitchChannel,
937 	bool bSetBandWidth,
938 	u8 ChannelNum,
939 	enum CHANNEL_WIDTH ChnlWidth,
940 	enum EXTCHNL_OFFSET ExtChnlOffsetOf40MHz,
941 	enum EXTCHNL_OFFSET ExtChnlOffsetOf80MHz,
942 	u8 CenterFrequencyIndex1
943 )
944 {
945 	/* static bool		bInitialzed = false; */
946 	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
947 	u8 tmpChannel = pHalData->CurrentChannel;
948 	enum CHANNEL_WIDTH tmpBW = pHalData->CurrentChannelBW;
949 	u8 tmpnCur40MhzPrimeSC = pHalData->nCur40MhzPrimeSC;
950 	u8 tmpnCur80MhzPrimeSC = pHalData->nCur80MhzPrimeSC;
951 	u8 tmpCenterFrequencyIndex1 = pHalData->CurrentCenterFrequencyIndex1;
952 
953 	/* DBG_871X("=> PHY_HandleSwChnlAndSetBW8812: bSwitchChannel %d, bSetBandWidth %d\n", bSwitchChannel, bSetBandWidth); */
954 
955 	/* check is swchnl or setbw */
956 	if (!bSwitchChannel && !bSetBandWidth) {
957 		DBG_871X("PHY_HandleSwChnlAndSetBW8812:  not switch channel and not set bandwidth\n");
958 		return;
959 	}
960 
961 	/* skip change for channel or bandwidth is the same */
962 	if (bSwitchChannel) {
963 		/* if (pHalData->CurrentChannel != ChannelNum) */
964 		{
965 			if (HAL_IsLegalChannel(Adapter, ChannelNum))
966 				pHalData->bSwChnl = true;
967 		}
968 	}
969 
970 	if (bSetBandWidth)
971 		pHalData->bSetChnlBW = true;
972 
973 	if (!pHalData->bSetChnlBW && !pHalData->bSwChnl) {
974 		/* DBG_871X("<= PHY_HandleSwChnlAndSetBW8812: bSwChnl %d, bSetChnlBW %d\n", pHalData->bSwChnl, pHalData->bSetChnlBW); */
975 		return;
976 	}
977 
978 
979 	if (pHalData->bSwChnl) {
980 		pHalData->CurrentChannel = ChannelNum;
981 		pHalData->CurrentCenterFrequencyIndex1 = ChannelNum;
982 	}
983 
984 
985 	if (pHalData->bSetChnlBW) {
986 		pHalData->CurrentChannelBW = ChnlWidth;
987 		pHalData->nCur40MhzPrimeSC = ExtChnlOffsetOf40MHz;
988 		pHalData->nCur80MhzPrimeSC = ExtChnlOffsetOf80MHz;
989 		pHalData->CurrentCenterFrequencyIndex1 = CenterFrequencyIndex1;
990 	}
991 
992 	/* Switch workitem or set timer to do switch channel or setbandwidth operation */
993 	if ((!Adapter->bDriverStopped) && (!Adapter->bSurpriseRemoved)) {
994 		phy_SwChnlAndSetBwMode8723B(Adapter);
995 	} else {
996 		if (pHalData->bSwChnl) {
997 			pHalData->CurrentChannel = tmpChannel;
998 			pHalData->CurrentCenterFrequencyIndex1 = tmpChannel;
999 		}
1000 
1001 		if (pHalData->bSetChnlBW) {
1002 			pHalData->CurrentChannelBW = tmpBW;
1003 			pHalData->nCur40MhzPrimeSC = tmpnCur40MhzPrimeSC;
1004 			pHalData->nCur80MhzPrimeSC = tmpnCur80MhzPrimeSC;
1005 			pHalData->CurrentCenterFrequencyIndex1 = tmpCenterFrequencyIndex1;
1006 		}
1007 	}
1008 }
1009 
1010 void PHY_SetBWMode8723B(
1011 	struct adapter *Adapter,
1012 	enum CHANNEL_WIDTH Bandwidth, /*  20M or 40M */
1013 	unsigned char Offset /*  Upper, Lower, or Don't care */
1014 )
1015 {
1016 	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
1017 
1018 	PHY_HandleSwChnlAndSetBW8723B(Adapter, false, true, pHalData->CurrentChannel, Bandwidth, Offset, Offset, pHalData->CurrentChannel);
1019 }
1020 
1021 /*  Call after initialization */
1022 void PHY_SwChnl8723B(struct adapter *Adapter, u8 channel)
1023 {
1024 	PHY_HandleSwChnlAndSetBW8723B(Adapter, true, false, channel, 0, 0, 0, channel);
1025 }
1026 
1027 void PHY_SetSwChnlBWMode8723B(
1028 	struct adapter *Adapter,
1029 	u8 channel,
1030 	enum CHANNEL_WIDTH Bandwidth,
1031 	u8 Offset40,
1032 	u8 Offset80
1033 )
1034 {
1035 	/* DBG_871X("%s() ===>\n", __func__); */
1036 
1037 	PHY_HandleSwChnlAndSetBW8723B(Adapter, true, true, channel, Bandwidth, Offset40, Offset80, channel);
1038 
1039 	/* DBG_871X("<==%s()\n", __func__); */
1040 }
1041