xref: /linux/drivers/staging/rtl8723bs/hal/rtl8723b_phycfg.c (revision a5f22b9b139762685810aa5a41fd0181488aea13)
1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
5  *
6  ******************************************************************************/
7 
8 #include <drv_types.h>
9 #include <rtl8723b_hal.h>
10 
11 /**
12  * phy_CalculateBitShift - Get shifted position of the BitMask.
13  * @BitMask: Bitmask.
14  *
15  * Return:	Return the shift bit position of the mask
16  */
phy_CalculateBitShift(u32 BitMask)17 static	u32 phy_CalculateBitShift(u32 BitMask)
18 {
19 	u32 i;
20 
21 	for (i = 0; i <= 31; i++) {
22 		if (((BitMask>>i) &  0x1) == 1)
23 			break;
24 	}
25 	return i;
26 }
27 
28 
29 /**
30  * PHY_QueryBBReg_8723B - Read "specific bits" from BB register.
31  * @Adapter:
32  * @RegAddr:	The target address to be readback
33  * @BitMask:	The target bit position in the target address
34  *				to be readback
35  *
36  * Return:	The readback register value
37  *
38  * .. Note::	This function is equal to "GetRegSetting" in PHY programming
39  *			guide
40  */
PHY_QueryBBReg_8723B(struct adapter * Adapter,u32 RegAddr,u32 BitMask)41 u32 PHY_QueryBBReg_8723B(struct adapter *Adapter, u32 RegAddr, u32 BitMask)
42 {
43 	u32 OriginalValue, BitShift;
44 
45 	OriginalValue = rtw_read32(Adapter, RegAddr);
46 	BitShift = phy_CalculateBitShift(BitMask);
47 
48 	return (OriginalValue & BitMask) >> BitShift;
49 
50 }
51 
52 
53 /**
54  * PHY_SetBBReg_8723B - Write "Specific bits" to BB register (page 8~).
55  * @Adapter:
56  * @RegAddr:	The target address to be modified
57  * @BitMask:	The target bit position in the target address
58  *				to be modified
59  * @Data:		The new register value in the target bit position
60  *				of the target address
61  *
62  * .. Note::	This function is equal to "PutRegSetting" in PHY programming
63  *			guide
64  */
65 
PHY_SetBBReg_8723B(struct adapter * Adapter,u32 RegAddr,u32 BitMask,u32 Data)66 void PHY_SetBBReg_8723B(
67 	struct adapter *Adapter,
68 	u32 RegAddr,
69 	u32 BitMask,
70 	u32 Data
71 )
72 {
73 	/* u16 BBWaitCounter	= 0; */
74 	u32 OriginalValue, BitShift;
75 
76 	if (BitMask != bMaskDWord) { /* if not "double word" write */
77 		OriginalValue = rtw_read32(Adapter, RegAddr);
78 		BitShift = phy_CalculateBitShift(BitMask);
79 		Data = ((OriginalValue & (~BitMask)) | ((Data << BitShift) & BitMask));
80 	}
81 
82 	rtw_write32(Adapter, RegAddr, Data);
83 
84 }
85 
86 
87 /*  */
88 /*  2. RF register R/W API */
89 /*  */
90 
phy_RFSerialRead_8723B(struct adapter * Adapter,enum rf_path eRFPath,u32 Offset)91 static u32 phy_RFSerialRead_8723B(
92 	struct adapter *Adapter, enum rf_path eRFPath, u32 Offset
93 )
94 {
95 	u32 retValue = 0;
96 	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
97 	struct bb_register_def *pPhyReg = &pHalData->PHYRegDef[eRFPath];
98 	u32 NewOffset;
99 	u32 tmplong2;
100 	u8 RfPiEnable = 0;
101 	u32 MaskforPhySet = 0;
102 	int i = 0;
103 
104 	/*  */
105 	/*  Make sure RF register offset is correct */
106 	/*  */
107 	Offset &= 0xff;
108 
109 	NewOffset = Offset;
110 
111 	if (eRFPath == RF_PATH_A) {
112 		tmplong2 = PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter2|MaskforPhySet, bMaskDWord);
113 		tmplong2 = (tmplong2 & (~bLSSIReadAddress)) | (NewOffset<<23) | bLSSIReadEdge;	/* T65 RF */
114 		PHY_SetBBReg(Adapter, rFPGA0_XA_HSSIParameter2|MaskforPhySet, bMaskDWord, tmplong2&(~bLSSIReadEdge));
115 	} else {
116 		tmplong2 = PHY_QueryBBReg(Adapter, rFPGA0_XB_HSSIParameter2|MaskforPhySet, bMaskDWord);
117 		tmplong2 = (tmplong2 & (~bLSSIReadAddress)) | (NewOffset<<23) | bLSSIReadEdge;	/* T65 RF */
118 		PHY_SetBBReg(Adapter, rFPGA0_XB_HSSIParameter2|MaskforPhySet, bMaskDWord, tmplong2&(~bLSSIReadEdge));
119 	}
120 
121 	tmplong2 = PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter2|MaskforPhySet, bMaskDWord);
122 	PHY_SetBBReg(Adapter, rFPGA0_XA_HSSIParameter2|MaskforPhySet, bMaskDWord, tmplong2 & (~bLSSIReadEdge));
123 	PHY_SetBBReg(Adapter, rFPGA0_XA_HSSIParameter2|MaskforPhySet, bMaskDWord, tmplong2 | bLSSIReadEdge);
124 
125 	udelay(10);
126 
127 	for (i = 0; i < 2; i++)
128 		udelay(MAX_STALL_TIME);
129 	udelay(10);
130 
131 	if (eRFPath == RF_PATH_A)
132 		RfPiEnable = (u8)PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter1|MaskforPhySet, BIT8);
133 	else if (eRFPath == RF_PATH_B)
134 		RfPiEnable = (u8)PHY_QueryBBReg(Adapter, rFPGA0_XB_HSSIParameter1|MaskforPhySet, BIT8);
135 
136 	if (RfPiEnable) {
137 		/*  Read from BBreg8b8, 12 bits for 8190, 20bits for T65 RF */
138 		retValue = PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBackPi|MaskforPhySet, bLSSIReadBackData);
139 	} else {
140 		/* Read from BBreg8a0, 12 bits for 8190, 20 bits for T65 RF */
141 		retValue = PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBack|MaskforPhySet, bLSSIReadBackData);
142 	}
143 	return retValue;
144 
145 }
146 
147 /**
148  * phy_RFSerialWrite_8723B - Write data to RF register (page 8~).
149  * @Adapter:
150  * @eRFPath:	Radio path of A/B/C/D
151  * @Offset:	The target address to be read
152  * @Data:	The new register Data in the target bit position
153  *			of the target to be read
154  *
155  * .. Note::	There are three types of serial operations:
156  *		1. Software serial write
157  *		2. Hardware LSSI-Low Speed Serial Interface
158  *		3. Hardware HSSI-High speed
159  *		serial write. Driver need to implement (1) and (2).
160  *		This function is equal to the combination of RF_ReadReg() and  RFLSSIRead()
161  *
162  * .. Note::		  For RF8256 only
163  *		 The total count of RTL8256(Zebra4) register is around 36 bit it only employs
164  *		 4-bit RF address. RTL8256 uses "register mode control bit" (Reg00[12], Reg00[10])
165  *		 to access register address bigger than 0xf. See "Appendix-4 in PHY Configuration
166  *		 programming guide" for more details.
167  *		 Thus, we define a sub-finction for RTL8526 register address conversion
168  *	       ===========================================================
169  *		 Register Mode		RegCTL[1]		RegCTL[0]		Note
170  *							(Reg00[12])		(Reg00[10])
171  *	       ===========================================================
172  *		 Reg_Mode0				0				x			Reg 0 ~15(0x0 ~ 0xf)
173  *	       ------------------------------------------------------------------
174  *		 Reg_Mode1				1				0			Reg 16 ~30(0x1 ~ 0xf)
175  *	       ------------------------------------------------------------------
176  *		 Reg_Mode2				1				1			Reg 31 ~ 45(0x1 ~ 0xf)
177  *	       ------------------------------------------------------------------
178  *
179  *2008/09/02	MH	Add 92S RF definition
180  *
181  *
182  *
183  */
phy_RFSerialWrite_8723B(struct adapter * Adapter,enum rf_path eRFPath,u32 Offset,u32 Data)184 static void phy_RFSerialWrite_8723B(
185 	struct adapter *Adapter,
186 	enum rf_path eRFPath,
187 	u32 Offset,
188 	u32 Data
189 )
190 {
191 	u32 DataAndAddr = 0;
192 	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
193 	struct bb_register_def *pPhyReg = &pHalData->PHYRegDef[eRFPath];
194 	u32 NewOffset;
195 
196 	Offset &= 0xff;
197 
198 	/*  */
199 	/*  Switch page for 8256 RF IC */
200 	/*  */
201 	NewOffset = Offset;
202 
203 	/*  */
204 	/*  Put write addr in [5:0]  and write data in [31:16] */
205 	/*  */
206 	DataAndAddr = ((NewOffset<<20) | (Data&0x000fffff)) & 0x0fffffff;	/*  T65 RF */
207 	/*  */
208 	/*  Write Operation */
209 	/*  */
210 	PHY_SetBBReg(Adapter, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr);
211 }
212 
213 
214 /**
215  * PHY_QueryRFReg_8723B - Query "Specific bits" to RF register (page 8~).
216  * @Adapter:
217  * @eRFPath:	Radio path of A/B/C/D
218  * @RegAddr:	The target address to be read
219  * @BitMask:	The target bit position in the target address
220  *				to be read
221  *
222  * Return:	Readback value
223  *
224  * .. Note::	This function is equal to "GetRFRegSetting" in PHY
225  *			programming guide
226  */
PHY_QueryRFReg_8723B(struct adapter * Adapter,u8 eRFPath,u32 RegAddr,u32 BitMask)227 u32 PHY_QueryRFReg_8723B(
228 	struct adapter *Adapter,
229 	u8 eRFPath,
230 	u32 RegAddr,
231 	u32 BitMask
232 )
233 {
234 	u32 Original_Value, BitShift;
235 
236 	Original_Value = phy_RFSerialRead_8723B(Adapter, eRFPath, RegAddr);
237 	BitShift =  phy_CalculateBitShift(BitMask);
238 
239 	return (Original_Value & BitMask) >> BitShift;
240 }
241 
242 /**
243  * PHY_SetRFReg_8723B - Write "Specific bits" to RF register (page 8~).
244  * @Adapter:
245  * @eRFPath:	Radio path of A/B/C/D
246  * @RegAddr:	The target address to be modified
247  * @BitMask:	The target bit position in the target address
248  *				to be modified
249  * @Data:	The new register Data in the target bit position
250  *								of the target address
251  *
252  * .. Note::	This function is equal to "PutRFRegSetting" in PHY
253  *			programming guide.
254  */
PHY_SetRFReg_8723B(struct adapter * Adapter,u8 eRFPath,u32 RegAddr,u32 BitMask,u32 Data)255 void PHY_SetRFReg_8723B(
256 	struct adapter *Adapter,
257 	u8 eRFPath,
258 	u32 RegAddr,
259 	u32 BitMask,
260 	u32 Data
261 )
262 {
263 	u32 Original_Value, BitShift;
264 
265 	/*  RF data is 12 bits only */
266 	if (BitMask != bRFRegOffsetMask) {
267 		Original_Value = phy_RFSerialRead_8723B(Adapter, eRFPath, RegAddr);
268 		BitShift =  phy_CalculateBitShift(BitMask);
269 		Data = ((Original_Value & (~BitMask)) | (Data<<BitShift));
270 	}
271 
272 	phy_RFSerialWrite_8723B(Adapter, eRFPath, RegAddr, Data);
273 }
274 
275 
276 /*  */
277 /*  3. Initial MAC/BB/RF config by reading MAC/BB/RF txt. */
278 /*  */
279 
280 
281 /*-----------------------------------------------------------------------------
282  * PHY_MACConfig8192C - Config MAC by header file or parameter file.
283  *
284  * Revised History:
285  *  When		Who		Remark
286  *  08/12/2008	MHC		Create Version 0.
287  *
288  *---------------------------------------------------------------------------
289  */
PHY_MACConfig8723B(struct adapter * Adapter)290 s32 PHY_MACConfig8723B(struct adapter *Adapter)
291 {
292 	struct hal_com_data	*pHalData = GET_HAL_DATA(Adapter);
293 
294 	ODM_ReadAndConfig_MP_8723B_MAC_REG(&pHalData->odmpriv);
295 	return _SUCCESS;
296 }
297 
298 /**
299  * phy_InitBBRFRegisterDefinition - Initialize Register definition offset for
300  *									Radio Path A/B/C/D
301  * @Adapter:
302  *
303  * .. Note::		The initialization value is constant and it should never be changes
304  */
phy_InitBBRFRegisterDefinition(struct adapter * Adapter)305 static void phy_InitBBRFRegisterDefinition(struct adapter *Adapter)
306 {
307 	struct hal_com_data		*pHalData = GET_HAL_DATA(Adapter);
308 
309 	/*  RF Interface Sowrtware Control */
310 	pHalData->PHYRegDef[RF_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW; /*  16 LSBs if read 32-bit from 0x870 */
311 	pHalData->PHYRegDef[RF_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW; /*  16 MSBs if read 32-bit from 0x870 (16-bit for 0x872) */
312 
313 	/*  RF Interface Output (and Enable) */
314 	pHalData->PHYRegDef[RF_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE; /*  16 LSBs if read 32-bit from 0x860 */
315 	pHalData->PHYRegDef[RF_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE; /*  16 LSBs if read 32-bit from 0x864 */
316 
317 	/*  RF Interface (Output and)  Enable */
318 	pHalData->PHYRegDef[RF_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE; /*  16 MSBs if read 32-bit from 0x860 (16-bit for 0x862) */
319 	pHalData->PHYRegDef[RF_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE; /*  16 MSBs if read 32-bit from 0x864 (16-bit for 0x866) */
320 
321 	pHalData->PHYRegDef[RF_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter; /* LSSI Parameter */
322 	pHalData->PHYRegDef[RF_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter;
323 
324 	pHalData->PHYRegDef[RF_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2;  /* wire control parameter2 */
325 	pHalData->PHYRegDef[RF_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2;  /* wire control parameter2 */
326 
327 	/*  Transceiver Readback LSSI/HSPI mode */
328 	pHalData->PHYRegDef[RF_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack;
329 	pHalData->PHYRegDef[RF_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack;
330 	pHalData->PHYRegDef[RF_PATH_A].rfLSSIReadBackPi = TransceiverA_HSPI_Readback;
331 	pHalData->PHYRegDef[RF_PATH_B].rfLSSIReadBackPi = TransceiverB_HSPI_Readback;
332 
333 }
334 
phy_BB8723b_Config_ParaFile(struct adapter * Adapter)335 static int phy_BB8723b_Config_ParaFile(struct adapter *Adapter)
336 {
337 	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
338 
339 	/*  Read Tx Power Limit File */
340 	PHY_InitTxPowerLimit(Adapter);
341 	if (Adapter->registrypriv.reg_enable_tx_power_limit == 1 ||
342 	    (Adapter->registrypriv.reg_enable_tx_power_limit == 2 &&
343 	   pHalData->EEPROMRegulatory == 1))
344 		ODM_ConfigRFWithHeaderFile(&pHalData->odmpriv, CONFIG_RF_TXPWR_LMT, 0);
345 
346 	/*  */
347 	/*  1. Read PHY_REG.TXT BB INIT!! */
348 	/*  */
349 	ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv, CONFIG_BB_PHY_REG);
350 
351 	/*  If EEPROM or EFUSE autoload OK, We must config by PHY_REG_PG.txt */
352 	PHY_InitTxPowerByRate(Adapter);
353 
354 	if (Adapter->registrypriv.reg_enable_tx_power_by_rate == 1 ||
355 	    (Adapter->registrypriv.reg_enable_tx_power_by_rate == 2 &&
356 	   pHalData->EEPROMRegulatory != 2)) {
357 		ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv, CONFIG_BB_PHY_REG_PG);
358 
359 		if (pHalData->odmpriv.PhyRegPgValueType == PHY_REG_PG_EXACT_VALUE)
360 			PHY_TxPowerByRateConfiguration(Adapter);
361 
362 		if (Adapter->registrypriv.reg_enable_tx_power_limit == 1 ||
363 		    (Adapter->registrypriv.reg_enable_tx_power_limit == 2 &&
364 		   pHalData->EEPROMRegulatory == 1))
365 			PHY_ConvertTxPowerLimitToPowerIndex(Adapter);
366 	}
367 
368 	/*  */
369 	/*  2. Read BB AGC table Initialization */
370 	/*  */
371 	ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv, CONFIG_BB_AGC_TAB);
372 
373 	return _SUCCESS;
374 }
375 
376 
PHY_BBConfig8723B(struct adapter * Adapter)377 int PHY_BBConfig8723B(struct adapter *Adapter)
378 {
379 	int	rtStatus = _SUCCESS;
380 	struct hal_com_data	*pHalData = GET_HAL_DATA(Adapter);
381 	u32 RegVal;
382 	u8 CrystalCap;
383 
384 	phy_InitBBRFRegisterDefinition(Adapter);
385 
386 	/*  Enable BB and RF */
387 	RegVal = rtw_read16(Adapter, REG_SYS_FUNC_EN);
388 	rtw_write16(Adapter, REG_SYS_FUNC_EN, (u16)(RegVal|BIT13|BIT0|BIT1));
389 
390 	rtw_write32(Adapter, 0x948, 0x280);	/*  Others use Antenna S1 */
391 
392 	rtw_write8(Adapter, REG_RF_CTRL, RF_EN|RF_RSTB|RF_SDMRSTB);
393 
394 	msleep(1);
395 
396 	PHY_SetRFReg(Adapter, RF_PATH_A, 0x1, 0xfffff, 0x780);
397 
398 	rtw_write8(Adapter, REG_SYS_FUNC_EN, FEN_PPLL|FEN_PCIEA|FEN_DIO_PCIE|FEN_BB_GLB_RSTn|FEN_BBRSTB);
399 
400 	rtw_write8(Adapter, REG_AFE_XTAL_CTRL+1, 0x80);
401 
402 	/*  */
403 	/*  Config BB and AGC */
404 	/*  */
405 	rtStatus = phy_BB8723b_Config_ParaFile(Adapter);
406 
407 	/*  0x2C[23:18] = 0x2C[17:12] = CrystalCap */
408 	CrystalCap = pHalData->CrystalCap & 0x3F;
409 	PHY_SetBBReg(Adapter, REG_MAC_PHY_CTRL, 0xFFF000, (CrystalCap | (CrystalCap << 6)));
410 
411 	return rtStatus;
412 }
413 
phy_LCK_8723B(struct adapter * Adapter)414 static void phy_LCK_8723B(struct adapter *Adapter)
415 {
416 	PHY_SetRFReg(Adapter, RF_PATH_A, 0xB0, bRFRegOffsetMask, 0xDFBE0);
417 	PHY_SetRFReg(Adapter, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, 0x8C01);
418 	mdelay(200);
419 	PHY_SetRFReg(Adapter, RF_PATH_A, 0xB0, bRFRegOffsetMask, 0xDFFE0);
420 }
421 
PHY_RFConfig8723B(struct adapter * Adapter)422 int PHY_RFConfig8723B(struct adapter *Adapter)
423 {
424 	int rtStatus = _SUCCESS;
425 
426 	/*  */
427 	/*  RF config */
428 	/*  */
429 	rtStatus = PHY_RF6052_Config8723B(Adapter);
430 
431 	phy_LCK_8723B(Adapter);
432 
433 	return rtStatus;
434 }
435 
436 /**************************************************************************************************************
437  *   Description:
438  *       The low-level interface to set TxAGC , called by both MP and Normal Driver.
439  *
440  *                                                                                    <20120830, Kordan>
441  **************************************************************************************************************/
442 
PHY_SetTxPowerIndex(struct adapter * Adapter,u32 PowerIndex,u8 RFPath,u8 Rate)443 void PHY_SetTxPowerIndex(
444 	struct adapter *Adapter,
445 	u32 PowerIndex,
446 	u8 RFPath,
447 	u8 Rate
448 )
449 {
450 	if (RFPath == RF_PATH_A || RFPath == RF_PATH_B) {
451 		switch (Rate) {
452 		case MGN_1M:
453 			PHY_SetBBReg(Adapter, rTxAGC_A_CCK1_Mcs32, bMaskByte1, PowerIndex);
454 			break;
455 		case MGN_2M:
456 			PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte1, PowerIndex);
457 			break;
458 		case MGN_5_5M:
459 			PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte2, PowerIndex);
460 			break;
461 		case MGN_11M:
462 			PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte3, PowerIndex);
463 			break;
464 
465 		case MGN_6M:
466 			PHY_SetBBReg(Adapter, rTxAGC_A_Rate18_06, bMaskByte0, PowerIndex);
467 			break;
468 		case MGN_9M:
469 			PHY_SetBBReg(Adapter, rTxAGC_A_Rate18_06, bMaskByte1, PowerIndex);
470 			break;
471 		case MGN_12M:
472 			PHY_SetBBReg(Adapter, rTxAGC_A_Rate18_06, bMaskByte2, PowerIndex);
473 			break;
474 		case MGN_18M:
475 			PHY_SetBBReg(Adapter, rTxAGC_A_Rate18_06, bMaskByte3, PowerIndex);
476 			break;
477 
478 		case MGN_24M:
479 			PHY_SetBBReg(Adapter, rTxAGC_A_Rate54_24, bMaskByte0, PowerIndex);
480 			break;
481 		case MGN_36M:
482 			PHY_SetBBReg(Adapter, rTxAGC_A_Rate54_24, bMaskByte1, PowerIndex);
483 			break;
484 		case MGN_48M:
485 			PHY_SetBBReg(Adapter, rTxAGC_A_Rate54_24, bMaskByte2, PowerIndex);
486 			break;
487 		case MGN_54M:
488 			PHY_SetBBReg(Adapter, rTxAGC_A_Rate54_24, bMaskByte3, PowerIndex);
489 			break;
490 
491 		case MGN_MCS0:
492 			PHY_SetBBReg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte0, PowerIndex);
493 			break;
494 		case MGN_MCS1:
495 			PHY_SetBBReg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte1, PowerIndex);
496 			break;
497 		case MGN_MCS2:
498 			PHY_SetBBReg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte2, PowerIndex);
499 			break;
500 		case MGN_MCS3:
501 			PHY_SetBBReg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte3, PowerIndex);
502 			break;
503 
504 		case MGN_MCS4:
505 			PHY_SetBBReg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte0, PowerIndex);
506 			break;
507 		case MGN_MCS5:
508 			PHY_SetBBReg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte1, PowerIndex);
509 			break;
510 		case MGN_MCS6:
511 			PHY_SetBBReg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte2, PowerIndex);
512 			break;
513 		case MGN_MCS7:
514 			PHY_SetBBReg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte3, PowerIndex);
515 			break;
516 
517 		default:
518 			break;
519 		}
520 	}
521 }
522 
PHY_GetTxPowerIndex(struct adapter * padapter,u8 RFPath,u8 Rate,enum channel_width BandWidth,u8 Channel)523 u8 PHY_GetTxPowerIndex(
524 	struct adapter *padapter,
525 	u8 RFPath,
526 	u8 Rate,
527 	enum channel_width BandWidth,
528 	u8 Channel
529 )
530 {
531 	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
532 	s8 txPower = 0, powerDiffByRate = 0, limit = 0;
533 
534 	txPower = (s8) PHY_GetTxPowerIndexBase(padapter, RFPath, Rate, BandWidth, Channel);
535 	powerDiffByRate = PHY_GetTxPowerByRate(padapter, RF_PATH_A, Rate);
536 
537 	limit = phy_get_tx_pwr_lmt(
538 		padapter,
539 		padapter->registrypriv.reg_pwr_tbl_sel,
540 		pHalData->CurrentChannelBW,
541 		RFPath,
542 		Rate,
543 		pHalData->CurrentChannel
544 	);
545 
546 	powerDiffByRate = powerDiffByRate > limit ? limit : powerDiffByRate;
547 	txPower += powerDiffByRate;
548 
549 	txPower += PHY_GetTxPowerTrackingOffset(padapter, RFPath, Rate);
550 
551 	if (txPower > MAX_POWER_INDEX)
552 		txPower = MAX_POWER_INDEX;
553 
554 	return (u8) txPower;
555 }
556 
PHY_SetTxPowerLevel8723B(struct adapter * Adapter,u8 Channel)557 void PHY_SetTxPowerLevel8723B(struct adapter *Adapter, u8 Channel)
558 {
559 	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
560 	struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
561 	struct fat_t *pDM_FatTable = &pDM_Odm->DM_FatTable;
562 	u8 RFPath = RF_PATH_A;
563 
564 	if (pHalData->AntDivCfg) {/*  antenna diversity Enable */
565 		RFPath = ((pDM_FatTable->RxIdleAnt == MAIN_ANT) ? RF_PATH_A : RF_PATH_B);
566 	} else { /*  antenna diversity disable */
567 		RFPath = pHalData->ant_path;
568 	}
569 
570 	PHY_SetTxPowerLevelByPath(Adapter, Channel, RFPath);
571 }
572 
phy_SetRegBW_8723B(struct adapter * Adapter,enum channel_width CurrentBW)573 static void phy_SetRegBW_8723B(
574 	struct adapter *Adapter, enum channel_width CurrentBW
575 )
576 {
577 	u16 RegRfMod_BW, u2tmp = 0;
578 	RegRfMod_BW = rtw_read16(Adapter, REG_TRXPTCL_CTL_8723B);
579 
580 	switch (CurrentBW) {
581 	case CHANNEL_WIDTH_20:
582 		rtw_write16(Adapter, REG_TRXPTCL_CTL_8723B, (RegRfMod_BW & 0xFE7F)); /*  BIT 7 = 0, BIT 8 = 0 */
583 		break;
584 
585 	case CHANNEL_WIDTH_40:
586 		u2tmp = RegRfMod_BW | BIT7;
587 		rtw_write16(Adapter, REG_TRXPTCL_CTL_8723B, (u2tmp & 0xFEFF)); /*  BIT 7 = 1, BIT 8 = 0 */
588 		break;
589 
590 	default:
591 		break;
592 	}
593 }
594 
phy_GetSecondaryChnl_8723B(struct adapter * Adapter)595 static u8 phy_GetSecondaryChnl_8723B(struct adapter *Adapter)
596 {
597 	u8 SCSettingOf40 = 0, SCSettingOf20 = 0;
598 	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
599 
600 	if (pHalData->CurrentChannelBW == CHANNEL_WIDTH_40) {
601 		if (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
602 			SCSettingOf20 = HT_DATA_SC_20_UPPER_OF_40MHZ;
603 		else if (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
604 			SCSettingOf20 = HT_DATA_SC_20_LOWER_OF_40MHZ;
605 	}
606 
607 	return  (SCSettingOf40 << 4) | SCSettingOf20;
608 }
609 
phy_PostSetBwMode8723B(struct adapter * Adapter)610 static void phy_PostSetBwMode8723B(struct adapter *Adapter)
611 {
612 	u8 SubChnlNum = 0;
613 	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
614 
615 
616 	/* 3 Set Reg668 Reg440 BW */
617 	phy_SetRegBW_8723B(Adapter, pHalData->CurrentChannelBW);
618 
619 	/* 3 Set Reg483 */
620 	SubChnlNum = phy_GetSecondaryChnl_8723B(Adapter);
621 	rtw_write8(Adapter, REG_DATA_SC_8723B, SubChnlNum);
622 
623 	/* 3 */
624 	/* 3<2>Set PHY related register */
625 	/* 3 */
626 	switch (pHalData->CurrentChannelBW) {
627 	/* 20 MHz channel*/
628 	case CHANNEL_WIDTH_20:
629 		PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x0);
630 
631 		PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x0);
632 
633 		PHY_SetBBReg(Adapter, rOFDM0_TxPseudoNoiseWgt, (BIT31|BIT30), 0x0);
634 		break;
635 
636 	/* 40 MHz channel*/
637 	case CHANNEL_WIDTH_40:
638 		PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x1);
639 
640 		PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x1);
641 
642 		/*  Set Control channel to upper or lower. These settings are required only for 40MHz */
643 		PHY_SetBBReg(Adapter, rCCK0_System, bCCKSideBand, (pHalData->nCur40MhzPrimeSC>>1));
644 
645 		PHY_SetBBReg(Adapter, rOFDM1_LSTF, 0xC00, pHalData->nCur40MhzPrimeSC);
646 
647 		PHY_SetBBReg(Adapter, 0x818, (BIT26|BIT27), (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
648 		break;
649 	default:
650 		break;
651 	}
652 
653 	/* 3<3>Set RF related register */
654 	PHY_RF6052SetBandwidth8723B(Adapter, pHalData->CurrentChannelBW);
655 }
656 
phy_SwChnl8723B(struct adapter * padapter)657 static void phy_SwChnl8723B(struct adapter *padapter)
658 {
659 	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
660 	u8 channelToSW = pHalData->CurrentChannel;
661 
662 	if (pHalData->rf_chip == RF_PSEUDO_11N)
663 		return;
664 	pHalData->RfRegChnlVal[0] = ((pHalData->RfRegChnlVal[0] & 0xfffff00) | channelToSW);
665 	PHY_SetRFReg(padapter, RF_PATH_A, RF_CHNLBW, 0x3FF, pHalData->RfRegChnlVal[0]);
666 	PHY_SetRFReg(padapter, RF_PATH_B, RF_CHNLBW, 0x3FF, pHalData->RfRegChnlVal[0]);
667 }
668 
phy_SwChnlAndSetBwMode8723B(struct adapter * Adapter)669 static void phy_SwChnlAndSetBwMode8723B(struct adapter *Adapter)
670 {
671 	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
672 
673 	if (Adapter->bDriverStopped || Adapter->bSurpriseRemoved)
674 		return;
675 
676 	if (pHalData->bSwChnl) {
677 		phy_SwChnl8723B(Adapter);
678 		pHalData->bSwChnl = false;
679 	}
680 
681 	if (pHalData->bSetChnlBW) {
682 		phy_PostSetBwMode8723B(Adapter);
683 		pHalData->bSetChnlBW = false;
684 	}
685 
686 	PHY_SetTxPowerLevel8723B(Adapter, pHalData->CurrentChannel);
687 }
688 
PHY_HandleSwChnlAndSetBW8723B(struct adapter * Adapter,bool bSwitchChannel,bool bSetBandWidth,u8 ChannelNum,enum channel_width ChnlWidth,enum extchnl_offset ExtChnlOffsetOf40MHz,enum extchnl_offset ExtChnlOffsetOf80MHz,u8 CenterFrequencyIndex1)689 static void PHY_HandleSwChnlAndSetBW8723B(
690 	struct adapter *Adapter,
691 	bool bSwitchChannel,
692 	bool bSetBandWidth,
693 	u8 ChannelNum,
694 	enum channel_width ChnlWidth,
695 	enum extchnl_offset ExtChnlOffsetOf40MHz,
696 	enum extchnl_offset ExtChnlOffsetOf80MHz,
697 	u8 CenterFrequencyIndex1
698 )
699 {
700 	/* static bool		bInitialzed = false; */
701 	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
702 	u8 tmpChannel = pHalData->CurrentChannel;
703 	enum channel_width tmpBW = pHalData->CurrentChannelBW;
704 	u8 tmpnCur40MhzPrimeSC = pHalData->nCur40MhzPrimeSC;
705 	u8 tmpnCur80MhzPrimeSC = pHalData->nCur80MhzPrimeSC;
706 	u8 tmpCenterFrequencyIndex1 = pHalData->CurrentCenterFrequencyIndex1;
707 
708 	/* check is swchnl or setbw */
709 	if (!bSwitchChannel && !bSetBandWidth)
710 		return;
711 
712 	/* skip change for channel or bandwidth is the same */
713 	if (bSwitchChannel) {
714 		{
715 			if (HAL_IsLegalChannel(Adapter, ChannelNum))
716 				pHalData->bSwChnl = true;
717 		}
718 	}
719 
720 	if (bSetBandWidth)
721 		pHalData->bSetChnlBW = true;
722 
723 	if (!pHalData->bSetChnlBW && !pHalData->bSwChnl)
724 		return;
725 
726 
727 	if (pHalData->bSwChnl) {
728 		pHalData->CurrentChannel = ChannelNum;
729 		pHalData->CurrentCenterFrequencyIndex1 = ChannelNum;
730 	}
731 
732 
733 	if (pHalData->bSetChnlBW) {
734 		pHalData->CurrentChannelBW = ChnlWidth;
735 		pHalData->nCur40MhzPrimeSC = ExtChnlOffsetOf40MHz;
736 		pHalData->nCur80MhzPrimeSC = ExtChnlOffsetOf80MHz;
737 		pHalData->CurrentCenterFrequencyIndex1 = CenterFrequencyIndex1;
738 	}
739 
740 	/* Switch workitem or set timer to do switch channel or setbandwidth operation */
741 	if ((!Adapter->bDriverStopped) && (!Adapter->bSurpriseRemoved)) {
742 		phy_SwChnlAndSetBwMode8723B(Adapter);
743 	} else {
744 		if (pHalData->bSwChnl) {
745 			pHalData->CurrentChannel = tmpChannel;
746 			pHalData->CurrentCenterFrequencyIndex1 = tmpChannel;
747 		}
748 
749 		if (pHalData->bSetChnlBW) {
750 			pHalData->CurrentChannelBW = tmpBW;
751 			pHalData->nCur40MhzPrimeSC = tmpnCur40MhzPrimeSC;
752 			pHalData->nCur80MhzPrimeSC = tmpnCur80MhzPrimeSC;
753 			pHalData->CurrentCenterFrequencyIndex1 = tmpCenterFrequencyIndex1;
754 		}
755 	}
756 }
757 
758 /*  Call after initialization */
PHY_SwChnl8723B(struct adapter * Adapter,u8 channel)759 void PHY_SwChnl8723B(struct adapter *Adapter, u8 channel)
760 {
761 	PHY_HandleSwChnlAndSetBW8723B(Adapter, true, false, channel, 0, 0, 0, channel);
762 }
763 
PHY_SetSwChnlBWMode8723B(struct adapter * Adapter,u8 channel,enum channel_width Bandwidth,u8 Offset40,u8 Offset80)764 void PHY_SetSwChnlBWMode8723B(
765 	struct adapter *Adapter,
766 	u8 channel,
767 	enum channel_width Bandwidth,
768 	u8 Offset40,
769 	u8 Offset80
770 )
771 {
772 	PHY_HandleSwChnlAndSetBW8723B(Adapter, true, true, channel, Bandwidth, Offset40, Offset80, channel);
773 }
774