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 (
342 		Adapter->registrypriv.RegEnableTxPowerLimit == 1 ||
343 		(Adapter->registrypriv.RegEnableTxPowerLimit == 2 && pHalData->EEPROMRegulatory == 1)
344 	) {
345 		ODM_ConfigRFWithHeaderFile(&pHalData->odmpriv,
346 					   CONFIG_RF_TXPWR_LMT, 0);
347 	}
348 
349 	/*  */
350 	/*  1. Read PHY_REG.TXT BB INIT!! */
351 	/*  */
352 	ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv, CONFIG_BB_PHY_REG);
353 
354 	/*  If EEPROM or EFUSE autoload OK, We must config by PHY_REG_PG.txt */
355 	PHY_InitTxPowerByRate(Adapter);
356 	if (
357 		Adapter->registrypriv.RegEnableTxPowerByRate == 1 ||
358 		(Adapter->registrypriv.RegEnableTxPowerByRate == 2 && pHalData->EEPROMRegulatory != 2)
359 	) {
360 		ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv,
361 					   CONFIG_BB_PHY_REG_PG);
362 
363 		if (pHalData->odmpriv.PhyRegPgValueType == PHY_REG_PG_EXACT_VALUE)
364 			PHY_TxPowerByRateConfiguration(Adapter);
365 
366 		if (
367 			Adapter->registrypriv.RegEnableTxPowerLimit == 1 ||
368 			(Adapter->registrypriv.RegEnableTxPowerLimit == 2 && pHalData->EEPROMRegulatory == 1)
369 		)
370 			PHY_ConvertTxPowerLimitToPowerIndex(Adapter);
371 	}
372 
373 	/*  */
374 	/*  2. Read BB AGC table Initialization */
375 	/*  */
376 	ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv, CONFIG_BB_AGC_TAB);
377 
378 	return _SUCCESS;
379 }
380 
381 
PHY_BBConfig8723B(struct adapter * Adapter)382 int PHY_BBConfig8723B(struct adapter *Adapter)
383 {
384 	int	rtStatus = _SUCCESS;
385 	struct hal_com_data	*pHalData = GET_HAL_DATA(Adapter);
386 	u32 RegVal;
387 	u8 CrystalCap;
388 
389 	phy_InitBBRFRegisterDefinition(Adapter);
390 
391 	/*  Enable BB and RF */
392 	RegVal = rtw_read16(Adapter, REG_SYS_FUNC_EN);
393 	rtw_write16(Adapter, REG_SYS_FUNC_EN, (u16)(RegVal|BIT13|BIT0|BIT1));
394 
395 	rtw_write32(Adapter, 0x948, 0x280);	/*  Others use Antenna S1 */
396 
397 	rtw_write8(Adapter, REG_RF_CTRL, RF_EN|RF_RSTB|RF_SDMRSTB);
398 
399 	msleep(1);
400 
401 	PHY_SetRFReg(Adapter, RF_PATH_A, 0x1, 0xfffff, 0x780);
402 
403 	rtw_write8(Adapter, REG_SYS_FUNC_EN, FEN_PPLL|FEN_PCIEA|FEN_DIO_PCIE|FEN_BB_GLB_RSTn|FEN_BBRSTB);
404 
405 	rtw_write8(Adapter, REG_AFE_XTAL_CTRL+1, 0x80);
406 
407 	/*  */
408 	/*  Config BB and AGC */
409 	/*  */
410 	rtStatus = phy_BB8723b_Config_ParaFile(Adapter);
411 
412 	/*  0x2C[23:18] = 0x2C[17:12] = CrystalCap */
413 	CrystalCap = pHalData->CrystalCap & 0x3F;
414 	PHY_SetBBReg(Adapter, REG_MAC_PHY_CTRL, 0xFFF000, (CrystalCap | (CrystalCap << 6)));
415 
416 	return rtStatus;
417 }
418 
phy_LCK_8723B(struct adapter * Adapter)419 static void phy_LCK_8723B(struct adapter *Adapter)
420 {
421 	PHY_SetRFReg(Adapter, RF_PATH_A, 0xB0, bRFRegOffsetMask, 0xDFBE0);
422 	PHY_SetRFReg(Adapter, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, 0x8C01);
423 	mdelay(200);
424 	PHY_SetRFReg(Adapter, RF_PATH_A, 0xB0, bRFRegOffsetMask, 0xDFFE0);
425 }
426 
PHY_RFConfig8723B(struct adapter * Adapter)427 int PHY_RFConfig8723B(struct adapter *Adapter)
428 {
429 	int rtStatus = _SUCCESS;
430 
431 	/*  */
432 	/*  RF config */
433 	/*  */
434 	rtStatus = PHY_RF6052_Config8723B(Adapter);
435 
436 	phy_LCK_8723B(Adapter);
437 
438 	return rtStatus;
439 }
440 
441 /**************************************************************************************************************
442  *   Description:
443  *       The low-level interface to set TxAGC , called by both MP and Normal Driver.
444  *
445  *                                                                                    <20120830, Kordan>
446  **************************************************************************************************************/
447 
PHY_SetTxPowerIndex(struct adapter * Adapter,u32 PowerIndex,u8 RFPath,u8 Rate)448 void PHY_SetTxPowerIndex(
449 	struct adapter *Adapter,
450 	u32 PowerIndex,
451 	u8 RFPath,
452 	u8 Rate
453 )
454 {
455 	if (RFPath == RF_PATH_A || RFPath == RF_PATH_B) {
456 		switch (Rate) {
457 		case MGN_1M:
458 			PHY_SetBBReg(Adapter, rTxAGC_A_CCK1_Mcs32, bMaskByte1, PowerIndex);
459 			break;
460 		case MGN_2M:
461 			PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte1, PowerIndex);
462 			break;
463 		case MGN_5_5M:
464 			PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte2, PowerIndex);
465 			break;
466 		case MGN_11M:
467 			PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte3, PowerIndex);
468 			break;
469 
470 		case MGN_6M:
471 			PHY_SetBBReg(Adapter, rTxAGC_A_Rate18_06, bMaskByte0, PowerIndex);
472 			break;
473 		case MGN_9M:
474 			PHY_SetBBReg(Adapter, rTxAGC_A_Rate18_06, bMaskByte1, PowerIndex);
475 			break;
476 		case MGN_12M:
477 			PHY_SetBBReg(Adapter, rTxAGC_A_Rate18_06, bMaskByte2, PowerIndex);
478 			break;
479 		case MGN_18M:
480 			PHY_SetBBReg(Adapter, rTxAGC_A_Rate18_06, bMaskByte3, PowerIndex);
481 			break;
482 
483 		case MGN_24M:
484 			PHY_SetBBReg(Adapter, rTxAGC_A_Rate54_24, bMaskByte0, PowerIndex);
485 			break;
486 		case MGN_36M:
487 			PHY_SetBBReg(Adapter, rTxAGC_A_Rate54_24, bMaskByte1, PowerIndex);
488 			break;
489 		case MGN_48M:
490 			PHY_SetBBReg(Adapter, rTxAGC_A_Rate54_24, bMaskByte2, PowerIndex);
491 			break;
492 		case MGN_54M:
493 			PHY_SetBBReg(Adapter, rTxAGC_A_Rate54_24, bMaskByte3, PowerIndex);
494 			break;
495 
496 		case MGN_MCS0:
497 			PHY_SetBBReg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte0, PowerIndex);
498 			break;
499 		case MGN_MCS1:
500 			PHY_SetBBReg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte1, PowerIndex);
501 			break;
502 		case MGN_MCS2:
503 			PHY_SetBBReg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte2, PowerIndex);
504 			break;
505 		case MGN_MCS3:
506 			PHY_SetBBReg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte3, PowerIndex);
507 			break;
508 
509 		case MGN_MCS4:
510 			PHY_SetBBReg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte0, PowerIndex);
511 			break;
512 		case MGN_MCS5:
513 			PHY_SetBBReg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte1, PowerIndex);
514 			break;
515 		case MGN_MCS6:
516 			PHY_SetBBReg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte2, PowerIndex);
517 			break;
518 		case MGN_MCS7:
519 			PHY_SetBBReg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte3, PowerIndex);
520 			break;
521 
522 		default:
523 			break;
524 		}
525 	}
526 }
527 
PHY_GetTxPowerIndex(struct adapter * padapter,u8 RFPath,u8 Rate,enum channel_width BandWidth,u8 Channel)528 u8 PHY_GetTxPowerIndex(
529 	struct adapter *padapter,
530 	u8 RFPath,
531 	u8 Rate,
532 	enum channel_width BandWidth,
533 	u8 Channel
534 )
535 {
536 	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
537 	s8 txPower = 0, powerDiffByRate = 0, limit = 0;
538 
539 	txPower = (s8) PHY_GetTxPowerIndexBase(padapter, RFPath, Rate, BandWidth, Channel);
540 	powerDiffByRate = PHY_GetTxPowerByRate(padapter, RF_PATH_A, Rate);
541 
542 	limit = phy_get_tx_pwr_lmt(
543 		padapter,
544 		padapter->registrypriv.RegPwrTblSel,
545 		pHalData->CurrentChannelBW,
546 		RFPath,
547 		Rate,
548 		pHalData->CurrentChannel
549 	);
550 
551 	powerDiffByRate = powerDiffByRate > limit ? limit : powerDiffByRate;
552 	txPower += powerDiffByRate;
553 
554 	txPower += PHY_GetTxPowerTrackingOffset(padapter, RFPath, Rate);
555 
556 	if (txPower > MAX_POWER_INDEX)
557 		txPower = MAX_POWER_INDEX;
558 
559 	return (u8) txPower;
560 }
561 
PHY_SetTxPowerLevel8723B(struct adapter * Adapter,u8 Channel)562 void PHY_SetTxPowerLevel8723B(struct adapter *Adapter, u8 Channel)
563 {
564 	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
565 	struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
566 	struct fat_t *pDM_FatTable = &pDM_Odm->DM_FatTable;
567 	u8 RFPath = RF_PATH_A;
568 
569 	if (pHalData->AntDivCfg) {/*  antenna diversity Enable */
570 		RFPath = ((pDM_FatTable->RxIdleAnt == MAIN_ANT) ? RF_PATH_A : RF_PATH_B);
571 	} else { /*  antenna diversity disable */
572 		RFPath = pHalData->ant_path;
573 	}
574 
575 	PHY_SetTxPowerLevelByPath(Adapter, Channel, RFPath);
576 }
577 
PHY_GetTxPowerLevel8723B(struct adapter * Adapter,s32 * powerlevel)578 void PHY_GetTxPowerLevel8723B(struct adapter *Adapter, s32 *powerlevel)
579 {
580 }
581 
phy_SetRegBW_8723B(struct adapter * Adapter,enum channel_width CurrentBW)582 static void phy_SetRegBW_8723B(
583 	struct adapter *Adapter, enum channel_width CurrentBW
584 )
585 {
586 	u16 RegRfMod_BW, u2tmp = 0;
587 	RegRfMod_BW = rtw_read16(Adapter, REG_TRXPTCL_CTL_8723B);
588 
589 	switch (CurrentBW) {
590 	case CHANNEL_WIDTH_20:
591 		rtw_write16(Adapter, REG_TRXPTCL_CTL_8723B, (RegRfMod_BW & 0xFE7F)); /*  BIT 7 = 0, BIT 8 = 0 */
592 		break;
593 
594 	case CHANNEL_WIDTH_40:
595 		u2tmp = RegRfMod_BW | BIT7;
596 		rtw_write16(Adapter, REG_TRXPTCL_CTL_8723B, (u2tmp & 0xFEFF)); /*  BIT 7 = 1, BIT 8 = 0 */
597 		break;
598 
599 	default:
600 		break;
601 	}
602 }
603 
phy_GetSecondaryChnl_8723B(struct adapter * Adapter)604 static u8 phy_GetSecondaryChnl_8723B(struct adapter *Adapter)
605 {
606 	u8 SCSettingOf40 = 0, SCSettingOf20 = 0;
607 	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
608 
609 	if (pHalData->CurrentChannelBW == CHANNEL_WIDTH_40) {
610 		if (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
611 			SCSettingOf20 = HT_DATA_SC_20_UPPER_OF_40MHZ;
612 		else if (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
613 			SCSettingOf20 = HT_DATA_SC_20_LOWER_OF_40MHZ;
614 	}
615 
616 	return  (SCSettingOf40 << 4) | SCSettingOf20;
617 }
618 
phy_PostSetBwMode8723B(struct adapter * Adapter)619 static void phy_PostSetBwMode8723B(struct adapter *Adapter)
620 {
621 	u8 SubChnlNum = 0;
622 	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
623 
624 
625 	/* 3 Set Reg668 Reg440 BW */
626 	phy_SetRegBW_8723B(Adapter, pHalData->CurrentChannelBW);
627 
628 	/* 3 Set Reg483 */
629 	SubChnlNum = phy_GetSecondaryChnl_8723B(Adapter);
630 	rtw_write8(Adapter, REG_DATA_SC_8723B, SubChnlNum);
631 
632 	/* 3 */
633 	/* 3<2>Set PHY related register */
634 	/* 3 */
635 	switch (pHalData->CurrentChannelBW) {
636 	/* 20 MHz channel*/
637 	case CHANNEL_WIDTH_20:
638 		PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x0);
639 
640 		PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x0);
641 
642 		PHY_SetBBReg(Adapter, rOFDM0_TxPseudoNoiseWgt, (BIT31|BIT30), 0x0);
643 		break;
644 
645 	/* 40 MHz channel*/
646 	case CHANNEL_WIDTH_40:
647 		PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x1);
648 
649 		PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x1);
650 
651 		/*  Set Control channel to upper or lower. These settings are required only for 40MHz */
652 		PHY_SetBBReg(Adapter, rCCK0_System, bCCKSideBand, (pHalData->nCur40MhzPrimeSC>>1));
653 
654 		PHY_SetBBReg(Adapter, rOFDM1_LSTF, 0xC00, pHalData->nCur40MhzPrimeSC);
655 
656 		PHY_SetBBReg(Adapter, 0x818, (BIT26|BIT27), (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
657 		break;
658 	default:
659 		break;
660 	}
661 
662 	/* 3<3>Set RF related register */
663 	PHY_RF6052SetBandwidth8723B(Adapter, pHalData->CurrentChannelBW);
664 }
665 
phy_SwChnl8723B(struct adapter * padapter)666 static void phy_SwChnl8723B(struct adapter *padapter)
667 {
668 	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
669 	u8 channelToSW = pHalData->CurrentChannel;
670 
671 	if (pHalData->rf_chip == RF_PSEUDO_11N)
672 		return;
673 	pHalData->RfRegChnlVal[0] = ((pHalData->RfRegChnlVal[0] & 0xfffff00) | channelToSW);
674 	PHY_SetRFReg(padapter, RF_PATH_A, RF_CHNLBW, 0x3FF, pHalData->RfRegChnlVal[0]);
675 	PHY_SetRFReg(padapter, RF_PATH_B, RF_CHNLBW, 0x3FF, pHalData->RfRegChnlVal[0]);
676 }
677 
phy_SwChnlAndSetBwMode8723B(struct adapter * Adapter)678 static void phy_SwChnlAndSetBwMode8723B(struct adapter *Adapter)
679 {
680 	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
681 
682 	if (Adapter->bDriverStopped || Adapter->bSurpriseRemoved)
683 		return;
684 
685 	if (pHalData->bSwChnl) {
686 		phy_SwChnl8723B(Adapter);
687 		pHalData->bSwChnl = false;
688 	}
689 
690 	if (pHalData->bSetChnlBW) {
691 		phy_PostSetBwMode8723B(Adapter);
692 		pHalData->bSetChnlBW = false;
693 	}
694 
695 	PHY_SetTxPowerLevel8723B(Adapter, pHalData->CurrentChannel);
696 }
697 
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)698 static void PHY_HandleSwChnlAndSetBW8723B(
699 	struct adapter *Adapter,
700 	bool bSwitchChannel,
701 	bool bSetBandWidth,
702 	u8 ChannelNum,
703 	enum channel_width ChnlWidth,
704 	enum extchnl_offset ExtChnlOffsetOf40MHz,
705 	enum extchnl_offset ExtChnlOffsetOf80MHz,
706 	u8 CenterFrequencyIndex1
707 )
708 {
709 	/* static bool		bInitialzed = false; */
710 	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
711 	u8 tmpChannel = pHalData->CurrentChannel;
712 	enum channel_width tmpBW = pHalData->CurrentChannelBW;
713 	u8 tmpnCur40MhzPrimeSC = pHalData->nCur40MhzPrimeSC;
714 	u8 tmpnCur80MhzPrimeSC = pHalData->nCur80MhzPrimeSC;
715 	u8 tmpCenterFrequencyIndex1 = pHalData->CurrentCenterFrequencyIndex1;
716 
717 	/* check is swchnl or setbw */
718 	if (!bSwitchChannel && !bSetBandWidth)
719 		return;
720 
721 	/* skip change for channel or bandwidth is the same */
722 	if (bSwitchChannel) {
723 		{
724 			if (HAL_IsLegalChannel(Adapter, ChannelNum))
725 				pHalData->bSwChnl = true;
726 		}
727 	}
728 
729 	if (bSetBandWidth)
730 		pHalData->bSetChnlBW = true;
731 
732 	if (!pHalData->bSetChnlBW && !pHalData->bSwChnl)
733 		return;
734 
735 
736 	if (pHalData->bSwChnl) {
737 		pHalData->CurrentChannel = ChannelNum;
738 		pHalData->CurrentCenterFrequencyIndex1 = ChannelNum;
739 	}
740 
741 
742 	if (pHalData->bSetChnlBW) {
743 		pHalData->CurrentChannelBW = ChnlWidth;
744 		pHalData->nCur40MhzPrimeSC = ExtChnlOffsetOf40MHz;
745 		pHalData->nCur80MhzPrimeSC = ExtChnlOffsetOf80MHz;
746 		pHalData->CurrentCenterFrequencyIndex1 = CenterFrequencyIndex1;
747 	}
748 
749 	/* Switch workitem or set timer to do switch channel or setbandwidth operation */
750 	if ((!Adapter->bDriverStopped) && (!Adapter->bSurpriseRemoved)) {
751 		phy_SwChnlAndSetBwMode8723B(Adapter);
752 	} else {
753 		if (pHalData->bSwChnl) {
754 			pHalData->CurrentChannel = tmpChannel;
755 			pHalData->CurrentCenterFrequencyIndex1 = tmpChannel;
756 		}
757 
758 		if (pHalData->bSetChnlBW) {
759 			pHalData->CurrentChannelBW = tmpBW;
760 			pHalData->nCur40MhzPrimeSC = tmpnCur40MhzPrimeSC;
761 			pHalData->nCur80MhzPrimeSC = tmpnCur80MhzPrimeSC;
762 			pHalData->CurrentCenterFrequencyIndex1 = tmpCenterFrequencyIndex1;
763 		}
764 	}
765 }
766 
PHY_SetBWMode8723B(struct adapter * Adapter,enum channel_width Bandwidth,unsigned char Offset)767 void PHY_SetBWMode8723B(
768 	struct adapter *Adapter,
769 	enum channel_width Bandwidth, /*  20M or 40M */
770 	unsigned char Offset /*  Upper, Lower, or Don't care */
771 )
772 {
773 	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
774 
775 	PHY_HandleSwChnlAndSetBW8723B(Adapter, false, true, pHalData->CurrentChannel, Bandwidth, Offset, Offset, pHalData->CurrentChannel);
776 }
777 
778 /*  Call after initialization */
PHY_SwChnl8723B(struct adapter * Adapter,u8 channel)779 void PHY_SwChnl8723B(struct adapter *Adapter, u8 channel)
780 {
781 	PHY_HandleSwChnlAndSetBW8723B(Adapter, true, false, channel, 0, 0, 0, channel);
782 }
783 
PHY_SetSwChnlBWMode8723B(struct adapter * Adapter,u8 channel,enum channel_width Bandwidth,u8 Offset40,u8 Offset80)784 void PHY_SetSwChnlBWMode8723B(
785 	struct adapter *Adapter,
786 	u8 channel,
787 	enum channel_width Bandwidth,
788 	u8 Offset40,
789 	u8 Offset80
790 )
791 {
792 	PHY_HandleSwChnlAndSetBW8723B(Adapter, true, true, channel, Bandwidth, Offset40, Offset80, channel);
793 }
794