1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2007 - 2011 Realtek Corporation. */
3 
4 #define _RTL8188E_PHYCFG_C_
5 
6 #include "../include/osdep_service.h"
7 #include "../include/drv_types.h"
8 #include "../include/rtw_iol.h"
9 #include "../include/rtl8188e_hal.h"
10 
11 /*  */
12 /*  1. BB register R/W API */
13 /*  */
14 
15 /**
16 * Function:	phy_CalculateBitShift
17 *
18 * OverView:	Get shifted position of the BitMask
19 *
20 * Input:
21 *			u32		BitMask,
22 *
23 * Output:	none
24 * Return:		u32		Return the shift bit bit position of the mask
25 */
phy_CalculateBitShift(u32 BitMask)26 static	u32 phy_CalculateBitShift(u32 BitMask)
27 {
28 	u32 i;
29 
30 	for (i = 0; i <= 31; i++) {
31 		if (((BitMask >> i) & 0x1) == 1)
32 			break;
33 	}
34 	return i;
35 }
36 
37 /**
38 * Function:	PHY_QueryBBReg
39 *
40 * OverView:	Read "sepcific bits" from BB register
41 *
42 * Input:
43 *			struct adapter *Adapter,
44 *			u32			RegAddr,	The target address to be readback
45 *			u32			BitMask		The target bit position in the target address
46 *								to be readback
47 * Output:	None
48 * Return:		u32			Data		The readback register value
49 * Note:		This function is equal to "GetRegSetting" in PHY programming guide
50 */
51 u32
rtl8188e_PHY_QueryBBReg(struct adapter * Adapter,u32 RegAddr,u32 BitMask)52 rtl8188e_PHY_QueryBBReg(
53 		struct adapter *Adapter,
54 		u32 RegAddr,
55 		u32 BitMask
56 	)
57 {
58 	u32 ReturnValue = 0, OriginalValue, BitShift;
59 	int res;
60 
61 	res = rtw_read32(Adapter, RegAddr, &OriginalValue);
62 	if (res)
63 		return 0;
64 
65 	BitShift = phy_CalculateBitShift(BitMask);
66 	ReturnValue = (OriginalValue & BitMask) >> BitShift;
67 	return ReturnValue;
68 }
69 
70 /**
71 * Function:	PHY_SetBBReg
72 *
73 * OverView:	Write "Specific bits" to BB register (page 8~)
74 *
75 * Input:
76 *			struct adapter *Adapter,
77 *			u32			RegAddr,	The target address to be modified
78 *			u32			BitMask		The target bit position in the target address
79 *									to be modified
80 *			u32			Data		The new register value in the target bit position
81 *									of the target address
82 *
83 * Output:	None
84 * Return:		None
85 * Note:		This function is equal to "PutRegSetting" in PHY programming guide
86 */
87 
rtl8188e_PHY_SetBBReg(struct adapter * Adapter,u32 RegAddr,u32 BitMask,u32 Data)88 void rtl8188e_PHY_SetBBReg(struct adapter *Adapter, u32 RegAddr, u32 BitMask, u32 Data)
89 {
90 	u32 OriginalValue, BitShift;
91 	int res;
92 
93 	if (BitMask != bMaskDWord) { /* if not "double word" write */
94 		res = rtw_read32(Adapter, RegAddr, &OriginalValue);
95 		if (res)
96 			return;
97 
98 		BitShift = phy_CalculateBitShift(BitMask);
99 		Data = ((OriginalValue & (~BitMask)) | (Data << BitShift));
100 	}
101 
102 	rtw_write32(Adapter, RegAddr, Data);
103 }
104 
105 /*  */
106 /*  2. RF register R/W API */
107 /*  */
108 /**
109 * Function:	phy_RFSerialRead
110 *
111 * OverView:	Read regster from RF chips
112 *
113 * Input:
114 *			struct adapter *Adapter,
115 *			u32			Offset,		The target address to be read
116 *
117 * Output:	None
118 * Return:		u32			reback value
119 * Note:		Threre are three types of serial operations:
120 *			1. Software serial write
121 *			2. Hardware LSSI-Low Speed Serial Interface
122 *			3. Hardware HSSI-High speed
123 *			serial write. Driver need to implement (1) and (2).
124 *			This function is equal to the combination of RF_ReadReg() and  RFLSSIRead()
125 */
126 static	u32
phy_RFSerialRead(struct adapter * Adapter,u32 Offset)127 phy_RFSerialRead(
128 		struct adapter *Adapter,
129 		u32 Offset
130 	)
131 {
132 	u32 retValue = 0;
133 	struct hal_data_8188e *pHalData = &Adapter->haldata;
134 	struct bb_reg_def *pPhyReg = &pHalData->PHYRegDef;
135 	u32 NewOffset;
136 	u32 tmplong, tmplong2;
137 	u8 	RfPiEnable = 0;
138 	/*  */
139 	/*  Make sure RF register offset is correct */
140 	/*  */
141 	Offset &= 0xff;
142 
143 	/*  */
144 	/*  Switch page for 8256 RF IC */
145 	/*  */
146 	NewOffset = Offset;
147 
148 	/*  For 92S LSSI Read RFLSSIRead */
149 	/*  For RF A/B write 0x824/82c(does not work in the future) */
150 	/*  We must use 0x824 for RF A and B to execute read trigger */
151 	tmplong = rtl8188e_PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter2, bMaskDWord);
152 	tmplong2 = tmplong;
153 
154 	tmplong2 = (tmplong2 & (~bLSSIReadAddress)) | (NewOffset << 23) | bLSSIReadEdge;	/* T65 RF */
155 
156 	rtl8188e_PHY_SetBBReg(Adapter, rFPGA0_XA_HSSIParameter2, bMaskDWord, tmplong & (~bLSSIReadEdge));
157 	udelay(10);/*  PlatformStallExecution(10); */
158 
159 	rtl8188e_PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, bMaskDWord, tmplong2);
160 	udelay(100);/* PlatformStallExecution(100); */
161 
162 	udelay(10);/* PlatformStallExecution(10); */
163 
164 	RfPiEnable = (u8)rtl8188e_PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter1, BIT(8));
165 
166 	if (RfPiEnable) {	/*  Read from BBreg8b8, 12 bits for 8190, 20bits for T65 RF */
167 		retValue = rtl8188e_PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBackPi, bLSSIReadBackData);
168 	} else {	/* Read from BBreg8a0, 12 bits for 8190, 20 bits for T65 RF */
169 		retValue = rtl8188e_PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBack, bLSSIReadBackData);
170 	}
171 	return retValue;
172 }
173 
174 /**
175 * Function:	phy_RFSerialWrite
176 *
177 * OverView:	Write data to RF register (page 8~)
178 *
179 * Input:
180 *			struct adapter *Adapter,
181 *			enum rf_radio_path eRFPath,	Radio path of A/B/C/D
182 *			u32			Offset,		The target address to be read
183 *			u32			Data		The new register Data in the target bit position
184 *									of the target to be read
185 *
186 * Output:	None
187 * Return:		None
188 * Note:		Threre are three types of serial operations:
189 *			1. Software serial write
190 *			2. Hardware LSSI-Low Speed Serial Interface
191 *			3. Hardware HSSI-High speed
192 *			serial write. Driver need to implement (1) and (2).
193 *			This function is equal to the combination of RF_ReadReg() and  RFLSSIRead()
194  *
195  * Note:		  For RF8256 only
196  *			 The total count of RTL8256(Zebra4) register is around 36 bit it only employs
197  *			 4-bit RF address. RTL8256 uses "register mode control bit" (Reg00[12], Reg00[10])
198  *			 to access register address bigger than 0xf. See "Appendix-4 in PHY Configuration
199  *			 programming guide" for more details.
200  *			 Thus, we define a sub-finction for RTL8526 register address conversion
201  *		       ===========================================================
202  *			 Register Mode		RegCTL[1]		RegCTL[0]		Note
203  *								(Reg00[12])		(Reg00[10])
204  *		       ===========================================================
205  *			 Reg_Mode0				0				x			Reg 0 ~15(0x0 ~ 0xf)
206  *		       ------------------------------------------------------------------
207  *			 Reg_Mode1				1				0			Reg 16 ~30(0x1 ~ 0xf)
208  *		       ------------------------------------------------------------------
209  *			 Reg_Mode2				1				1			Reg 31 ~ 45(0x1 ~ 0xf)
210  *		       ------------------------------------------------------------------
211  *
212  *	2008/09/02	MH	Add 92S RF definition
213  *
214  *
215  *
216 */
217 static	void
phy_RFSerialWrite(struct adapter * Adapter,u32 Offset,u32 Data)218 phy_RFSerialWrite(
219 		struct adapter *Adapter,
220 		u32 Offset,
221 		u32 Data
222 	)
223 {
224 	u32 DataAndAddr = 0;
225 	struct hal_data_8188e *pHalData = &Adapter->haldata;
226 	struct bb_reg_def *pPhyReg = &pHalData->PHYRegDef;
227 	u32 NewOffset;
228 
229 	/*  2009/06/17 MH We can not execute IO for power save or other accident mode. */
230 
231 	Offset &= 0xff;
232 
233 	/*  */
234 	/*  Switch page for 8256 RF IC */
235 	/*  */
236 	NewOffset = Offset;
237 
238 	/*  */
239 	/*  Put write addr in [5:0]  and write data in [31:16] */
240 	/*  */
241 	DataAndAddr = ((NewOffset << 20) | (Data & 0x000fffff)) & 0x0fffffff;	/*  T65 RF */
242 
243 	/*  */
244 	/*  Write Operation */
245 	/*  */
246 	rtl8188e_PHY_SetBBReg(Adapter, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr);
247 }
248 
249 /**
250 * Function:	PHY_QueryRFReg
251 *
252 * OverView:	Query "Specific bits" to RF register (page 8~)
253 *
254 * Input:
255 *			struct adapter *Adapter,
256 *			u32			RegAddr,	The target address to be read
257 *			u32			BitMask		The target bit position in the target address
258 *									to be read
259 *
260 * Output:	None
261 * Return:		u32			Readback value
262 * Note:		This function is equal to "GetRFRegSetting" in PHY programming guide
263 */
rtl8188e_PHY_QueryRFReg(struct adapter * Adapter,u32 RegAddr,u32 BitMask)264 u32 rtl8188e_PHY_QueryRFReg(struct adapter *Adapter, u32 RegAddr, u32 BitMask)
265 {
266 	u32 Original_Value, Readback_Value, BitShift;
267 
268 	Original_Value = phy_RFSerialRead(Adapter, RegAddr);
269 
270 	BitShift =  phy_CalculateBitShift(BitMask);
271 	Readback_Value = (Original_Value & BitMask) >> BitShift;
272 	return Readback_Value;
273 }
274 
275 /**
276 * Function:	PHY_SetRFReg
277 *
278 * OverView:	Write "Specific bits" to RF register (page 8~)
279 *
280 * Input:
281 *			struct adapter *Adapter,
282 *			u32			RegAddr,	The target address to be modified
283 *			u32			BitMask		The target bit position in the target address
284 *									to be modified
285 *			u32			Data		The new register Data in the target bit position
286 *									of the target address
287 *
288 * Output:	None
289 * Return:		None
290 * Note:		This function is equal to "PutRFRegSetting" in PHY programming guide
291 */
292 void
rtl8188e_PHY_SetRFReg(struct adapter * Adapter,u32 RegAddr,u32 BitMask,u32 Data)293 rtl8188e_PHY_SetRFReg(
294 		struct adapter *Adapter,
295 		u32 RegAddr,
296 		u32 BitMask,
297 		u32 Data
298 	)
299 {
300 	u32 Original_Value, BitShift;
301 
302 	/*  RF data is 12 bits only */
303 	if (BitMask != bRFRegOffsetMask) {
304 		Original_Value = phy_RFSerialRead(Adapter, RegAddr);
305 		BitShift =  phy_CalculateBitShift(BitMask);
306 		Data = ((Original_Value & (~BitMask)) | (Data << BitShift));
307 	}
308 
309 	phy_RFSerialWrite(Adapter, RegAddr, Data);
310 }
311 
312 /*  */
313 /*  3. Initial MAC/BB/RF config by reading MAC/BB/RF txt. */
314 /*  */
315 
316 /*-----------------------------------------------------------------------------
317  * Function:    PHY_MACConfig8192C
318  *
319  * Overview:	Condig MAC by header file or parameter file.
320  *
321  * Input:       NONE
322  *
323  * Output:      NONE
324  *
325  * Return:      NONE
326  *
327  * Revised History:
328  *  When		Who		Remark
329  *  08/12/2008	MHC		Create Version 0.
330  *
331  *---------------------------------------------------------------------------*/
PHY_MACConfig8188E(struct adapter * Adapter)332 s32 PHY_MACConfig8188E(struct adapter *Adapter)
333 {
334 	struct hal_data_8188e *pHalData = &Adapter->haldata;
335 	int rtStatus = _SUCCESS;
336 
337 	/*  */
338 	/*  Config MAC */
339 	/*  */
340 	if (HAL_STATUS_FAILURE == ODM_ReadAndConfig_MAC_REG_8188E(&pHalData->odmpriv))
341 		rtStatus = _FAIL;
342 
343 	/*  2010.07.13 AMPDU aggregation number B */
344 	rtw_write16(Adapter, REG_MAX_AGGR_NUM, MAX_AGGR_NUM);
345 
346 	return rtStatus;
347 }
348 
349 /**
350 * Function:	phy_InitBBRFRegisterDefinition
351 *
352 * OverView:	Initialize Register definition offset for Radio Path A/B/C/D
353 *
354 * Input:
355 *			struct adapter *Adapter,
356 *
357 * Output:	None
358 * Return:		None
359 * Note:		The initialization value is constant and it should never be changes
360 */
361 static	void
phy_InitBBRFRegisterDefinition(struct adapter * Adapter)362 phy_InitBBRFRegisterDefinition(
363 		struct adapter *Adapter
364 )
365 {
366 	struct hal_data_8188e *pHalData = &Adapter->haldata;
367 
368 	/*  RF Interface Sowrtware Control */
369 	pHalData->PHYRegDef.rfintfs = rFPGA0_XAB_RFInterfaceSW; /*  16 LSBs if read 32-bit from 0x870 */
370 
371 	/*  RF Interface Readback Value */
372 	pHalData->PHYRegDef.rfintfi = rFPGA0_XAB_RFInterfaceRB; /*  16 LSBs if read 32-bit from 0x8E0 */
373 
374 	/*  RF Interface Output (and Enable) */
375 	pHalData->PHYRegDef.rfintfo = rFPGA0_XA_RFInterfaceOE; /*  16 LSBs if read 32-bit from 0x860 */
376 
377 	/*  RF Interface (Output and)  Enable */
378 	pHalData->PHYRegDef.rfintfe = rFPGA0_XA_RFInterfaceOE; /*  16 MSBs if read 32-bit from 0x860 (16-bit for 0x862) */
379 
380 	/* Addr of LSSI. Wirte RF register by driver */
381 	pHalData->PHYRegDef.rf3wireOffset = rFPGA0_XA_LSSIParameter; /* LSSI Parameter */
382 
383 	/*  RF parameter */
384 	pHalData->PHYRegDef.rfLSSI_Select = rFPGA0_XAB_RFParameter;  /* BB Band Select */
385 
386 	/*  Tx AGC Gain Stage (same for all path. Should we remove this?) */
387 	pHalData->PHYRegDef.rfTxGainStage = rFPGA0_TxGainStage; /* Tx gain stage */
388 
389 	/*  Transceiver A~D HSSI Parameter-1 */
390 	pHalData->PHYRegDef.rfHSSIPara1 = rFPGA0_XA_HSSIParameter1;  /* wire control parameter1 */
391 
392 	/*  Transceiver A~D HSSI Parameter-2 */
393 	pHalData->PHYRegDef.rfHSSIPara2 = rFPGA0_XA_HSSIParameter2;  /* wire control parameter2 */
394 
395 	/*  RF switch Control */
396 	pHalData->PHYRegDef.rfSwitchControl = rFPGA0_XAB_SwitchControl; /* TR/Ant switch control */
397 
398 	/*  AGC control 1 */
399 	pHalData->PHYRegDef.rfAGCControl1 = rOFDM0_XAAGCCore1;
400 
401 	/*  AGC control 2 */
402 	pHalData->PHYRegDef.rfAGCControl2 = rOFDM0_XAAGCCore2;
403 
404 	/*  RX AFE control 1 */
405 	pHalData->PHYRegDef.rfRxIQImbalance = rOFDM0_XARxIQImbalance;
406 
407 	/*  RX AFE control 1 */
408 	pHalData->PHYRegDef.rfRxAFE = rOFDM0_XARxAFE;
409 
410 	/*  Tx AFE control 1 */
411 	pHalData->PHYRegDef.rfTxIQImbalance = rOFDM0_XATxIQImbalance;
412 
413 	/*  Tx AFE control 2 */
414 	pHalData->PHYRegDef.rfTxAFE = rOFDM0_XATxAFE;
415 
416 	/*  Transceiver LSSI Readback SI mode */
417 	pHalData->PHYRegDef.rfLSSIReadBack = rFPGA0_XA_LSSIReadBack;
418 
419 	/*  Transceiver LSSI Readback PI mode */
420 	pHalData->PHYRegDef.rfLSSIReadBackPi = TransceiverA_HSPI_Readback;
421 }
422 
storePwrIndexDiffRateOffset(struct adapter * Adapter,u32 RegAddr,u32 BitMask,u32 Data)423 void storePwrIndexDiffRateOffset(struct adapter *Adapter, u32 RegAddr, u32 BitMask, u32 Data)
424 {
425 	struct hal_data_8188e *pHalData = &Adapter->haldata;
426 
427 	if (RegAddr == rTxAGC_A_Rate18_06)
428 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][0] = Data;
429 	if (RegAddr == rTxAGC_A_Rate54_24)
430 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][1] = Data;
431 	if (RegAddr == rTxAGC_A_CCK1_Mcs32)
432 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][6] = Data;
433 	if (RegAddr == rTxAGC_B_CCK11_A_CCK2_11 && BitMask == 0xffffff00)
434 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][7] = Data;
435 	if (RegAddr == rTxAGC_A_Mcs03_Mcs00)
436 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][2] = Data;
437 	if (RegAddr == rTxAGC_A_Mcs07_Mcs04)
438 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][3] = Data;
439 	if (RegAddr == rTxAGC_A_Mcs11_Mcs08)
440 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][4] = Data;
441 	if (RegAddr == rTxAGC_A_Mcs15_Mcs12) {
442 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][5] = Data;
443 		pHalData->pwrGroupCnt++;
444 	}
445 	if (RegAddr == rTxAGC_B_Rate18_06)
446 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][8] = Data;
447 	if (RegAddr == rTxAGC_B_Rate54_24)
448 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][9] = Data;
449 	if (RegAddr == rTxAGC_B_CCK1_55_Mcs32)
450 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][14] = Data;
451 	if (RegAddr == rTxAGC_B_CCK11_A_CCK2_11 && BitMask == 0x000000ff)
452 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][15] = Data;
453 	if (RegAddr == rTxAGC_B_Mcs03_Mcs00)
454 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][10] = Data;
455 	if (RegAddr == rTxAGC_B_Mcs07_Mcs04)
456 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][11] = Data;
457 	if (RegAddr == rTxAGC_B_Mcs11_Mcs08)
458 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][12] = Data;
459 	if (RegAddr == rTxAGC_B_Mcs15_Mcs12)
460 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][13] = Data;
461 }
462 
phy_BB8188E_Config_ParaFile(struct adapter * Adapter)463 static	int phy_BB8188E_Config_ParaFile(struct adapter *Adapter)
464 {
465 	struct eeprom_priv *pEEPROM = &Adapter->eeprompriv;
466 	struct hal_data_8188e *pHalData = &Adapter->haldata;
467 
468 	/*  */
469 	/*  1. Read PHY_REG.TXT BB INIT!! */
470 	/*  We will separate as 88C / 92C according to chip version */
471 	/*  */
472 	if (HAL_STATUS_FAILURE == ODM_ReadAndConfig_PHY_REG_1T_8188E(&pHalData->odmpriv))
473 		return _FAIL;
474 
475 	/*  2. If EEPROM or EFUSE autoload OK, We must config by PHY_REG_PG.txt */
476 	if (!pEEPROM->bautoload_fail_flag) {
477 		pHalData->pwrGroupCnt = 0;
478 		ODM_ReadAndConfig_PHY_REG_PG_8188E(&pHalData->odmpriv);
479 	}
480 
481 	/*  3. BB AGC table Initialization */
482 	if (HAL_STATUS_FAILURE == ODM_ReadAndConfig_AGC_TAB_1T_8188E(&pHalData->odmpriv))
483 		return _FAIL;
484 
485 	return _SUCCESS;
486 }
487 
488 int
PHY_BBConfig8188E(struct adapter * Adapter)489 PHY_BBConfig8188E(
490 		struct adapter *Adapter
491 	)
492 {
493 	int	rtStatus = _SUCCESS;
494 	struct hal_data_8188e *pHalData = &Adapter->haldata;
495 	u16 RegVal;
496 	u8 CrystalCap;
497 	int res;
498 
499 	phy_InitBBRFRegisterDefinition(Adapter);
500 
501 	/*  Enable BB and RF */
502 	res = rtw_read16(Adapter, REG_SYS_FUNC_EN, &RegVal);
503 	if (res)
504 		return _FAIL;
505 
506 	rtw_write16(Adapter, REG_SYS_FUNC_EN, (u16)(RegVal | BIT(13) | BIT(0) | BIT(1)));
507 
508 	/*  20090923 Joseph: Advised by Steven and Jenyu. Power sequence before init RF. */
509 
510 	rtw_write8(Adapter, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
511 
512 	rtw_write8(Adapter, REG_SYS_FUNC_EN, FEN_USBA | FEN_USBD | FEN_BB_GLB_RSTn | FEN_BBRSTB);
513 
514 	/*  Config BB and AGC */
515 	rtStatus = phy_BB8188E_Config_ParaFile(Adapter);
516 
517 	/*  write 0x24[16:11] = 0x24[22:17] = CrystalCap */
518 	CrystalCap = pHalData->CrystalCap & 0x3F;
519 	rtl8188e_PHY_SetBBReg(Adapter, REG_AFE_XTAL_CTRL, 0x7ff800, (CrystalCap | (CrystalCap << 6)));
520 
521 	return rtStatus;
522 }
523 
PHY_RFConfig8188E(struct adapter * Adapter)524 int PHY_RFConfig8188E(struct adapter *Adapter)
525 {
526 	int		rtStatus = _SUCCESS;
527 
528 	/*  RF config */
529 	rtStatus = PHY_RF6052_Config8188E(Adapter);
530 	return rtStatus;
531 }
532 
getTxPowerIndex88E(struct adapter * Adapter,u8 channel,u8 * cckPowerLevel,u8 * ofdmPowerLevel,u8 * BW20PowerLevel,u8 * BW40PowerLevel)533 static void getTxPowerIndex88E(struct adapter *Adapter, u8 channel, u8 *cckPowerLevel,
534 			       u8 *ofdmPowerLevel, u8 *BW20PowerLevel,
535 			       u8 *BW40PowerLevel)
536 {
537 	struct hal_data_8188e *pHalData = &Adapter->haldata;
538 	u8 index = (channel - 1);
539 
540 	/*  1. CCK */
541 	cckPowerLevel[RF_PATH_A] = pHalData->Index24G_CCK_Base[index];
542 	/* 2. OFDM */
543 	ofdmPowerLevel[RF_PATH_A] = pHalData->Index24G_BW40_Base[index] +
544 		pHalData->OFDM_24G_Diff[RF_PATH_A];
545 	/*  1. BW20 */
546 	BW20PowerLevel[RF_PATH_A] = pHalData->Index24G_BW40_Base[index] +
547 		pHalData->BW20_24G_Diff[RF_PATH_A];
548 	/* 2. BW40 */
549 	BW40PowerLevel[RF_PATH_A] = pHalData->Index24G_BW40_Base[index];
550 }
551 
552 /*-----------------------------------------------------------------------------
553  * Function:    SetTxPowerLevel8190()
554  *
555  * Overview:    This function is export to "HalCommon" moudule
556  *			We must consider RF path later!!!!!!!
557  *
558  * Input:       struct adapter *Adapter
559  *			u8		channel
560  *
561  * Output:      NONE
562  *
563  * Return:      NONE
564  *	2008/11/04	MHC		We remove EEPROM_93C56.
565  *						We need to move CCX relative code to independet file.
566  *	2009/01/21	MHC		Support new EEPROM format from SD3 requirement.
567  *
568  *---------------------------------------------------------------------------*/
569 void
PHY_SetTxPowerLevel8188E(struct adapter * Adapter,u8 channel)570 PHY_SetTxPowerLevel8188E(
571 		struct adapter *Adapter,
572 		u8 channel
573 	)
574 {
575 	u8 cckPowerLevel[MAX_TX_COUNT] = {0};
576 	u8 ofdmPowerLevel[MAX_TX_COUNT] = {0};/*  [0]:RF-A, [1]:RF-B */
577 	u8 BW20PowerLevel[MAX_TX_COUNT] = {0};
578 	u8 BW40PowerLevel[MAX_TX_COUNT] = {0};
579 
580 	getTxPowerIndex88E(Adapter, channel, &cckPowerLevel[0], &ofdmPowerLevel[0], &BW20PowerLevel[0], &BW40PowerLevel[0]);
581 
582 	rtl8188e_PHY_RF6052SetCckTxPower(Adapter, &cckPowerLevel[0]);
583 	rtl8188e_PHY_RF6052SetOFDMTxPower(Adapter, &ofdmPowerLevel[0], &BW20PowerLevel[0], &BW40PowerLevel[0], channel);
584 }
585 
586 /*-----------------------------------------------------------------------------
587  * Function:    PHY_SetBWModeCallback8192C()
588  *
589  * Overview:    Timer callback function for SetSetBWMode
590  *
591  * Input:		PRT_TIMER		pTimer
592  *
593  * Output:      NONE
594  *
595  * Return:      NONE
596  *
597  * Note:		(1) We do not take j mode into consideration now
598  *			(2) Will two workitem of "switch channel" and "switch channel bandwidth" run
599  *			     concurrently?
600  *---------------------------------------------------------------------------*/
601 static void
_PHY_SetBWMode92C(struct adapter * Adapter)602 _PHY_SetBWMode92C(
603 		struct adapter *Adapter
604 )
605 {
606 	struct hal_data_8188e *pHalData = &Adapter->haldata;
607 	u8 regBwOpMode;
608 	u8 regRRSR_RSC;
609 	int res;
610 
611 	if (Adapter->bDriverStopped)
612 		return;
613 
614 	/* 3 */
615 	/* 3<1>Set MAC register */
616 	/* 3 */
617 
618 	res = rtw_read8(Adapter, REG_BWOPMODE, &regBwOpMode);
619 	if (res)
620 		return;
621 
622 	res = rtw_read8(Adapter, REG_RRSR + 2, &regRRSR_RSC);
623 	if (res)
624 		return;
625 
626 	switch (pHalData->CurrentChannelBW) {
627 	case HT_CHANNEL_WIDTH_20:
628 		regBwOpMode |= BW_OPMODE_20MHZ;
629 		/*  2007/02/07 Mark by Emily because we have not verify whether this register works */
630 		rtw_write8(Adapter, REG_BWOPMODE, regBwOpMode);
631 		break;
632 	case HT_CHANNEL_WIDTH_40:
633 		regBwOpMode &= ~BW_OPMODE_20MHZ;
634 		/*  2007/02/07 Mark by Emily because we have not verify whether this register works */
635 		rtw_write8(Adapter, REG_BWOPMODE, regBwOpMode);
636 		regRRSR_RSC = (regRRSR_RSC & 0x90) | (pHalData->nCur40MhzPrimeSC << 5);
637 		rtw_write8(Adapter, REG_RRSR + 2, regRRSR_RSC);
638 		break;
639 	default:
640 		break;
641 	}
642 
643 	/* 3  */
644 	/* 3 <2>Set PHY related register */
645 	/* 3 */
646 	switch (pHalData->CurrentChannelBW) {
647 	/* 20 MHz channel*/
648 	case HT_CHANNEL_WIDTH_20:
649 		rtl8188e_PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x0);
650 		rtl8188e_PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x0);
651 		break;
652 	/* 40 MHz channel*/
653 	case HT_CHANNEL_WIDTH_40:
654 		rtl8188e_PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x1);
655 		rtl8188e_PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x1);
656 		/*  Set Control channel to upper or lower. These settings are required only for 40MHz */
657 		rtl8188e_PHY_SetBBReg(Adapter, rCCK0_System, bCCKSideBand, (pHalData->nCur40MhzPrimeSC >> 1));
658 		rtl8188e_PHY_SetBBReg(Adapter, rOFDM1_LSTF, 0xC00, pHalData->nCur40MhzPrimeSC);
659 		rtl8188e_PHY_SetBBReg(Adapter, 0x818, (BIT(26) | BIT(27)),
660 			     (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
661 		break;
662 	default:
663 		break;
664 	}
665 	/* Skip over setting of J-mode in BB register here. Default value is "None J mode". Emily 20070315 */
666 
667 	rtl8188e_PHY_RF6052SetBandwidth(Adapter, pHalData->CurrentChannelBW);
668 }
669 
670  /*-----------------------------------------------------------------------------
671  * Function:   SetBWMode8190Pci()
672  *
673  * Overview:  This function is export to "HalCommon" moudule
674  *
675  * Input:		struct adapter *Adapter
676  *			enum ht_channel_width Bandwidth	20M or 40M
677  *
678  * Output:      NONE
679  *
680  * Return:      NONE
681  *
682  * Note:		We do not take j mode into consideration now
683  *---------------------------------------------------------------------------*/
PHY_SetBWMode8188E(struct adapter * Adapter,enum ht_channel_width Bandwidth,unsigned char Offset)684 void PHY_SetBWMode8188E(struct adapter *Adapter, enum ht_channel_width Bandwidth,	/*  20M or 40M */
685 			unsigned char	Offset)		/*  Upper, Lower, or Don't care */
686 {
687 	struct hal_data_8188e *pHalData = &Adapter->haldata;
688 	enum ht_channel_width tmpBW = pHalData->CurrentChannelBW;
689 
690 	pHalData->CurrentChannelBW = Bandwidth;
691 
692 	pHalData->nCur40MhzPrimeSC = Offset;
693 
694 	if ((!Adapter->bDriverStopped) && (!Adapter->bSurpriseRemoved))
695 		_PHY_SetBWMode92C(Adapter);
696 	else
697 		pHalData->CurrentChannelBW = tmpBW;
698 }
699 
_PHY_SwChnl8192C(struct adapter * Adapter,u8 channel)700 static void _PHY_SwChnl8192C(struct adapter *Adapter, u8 channel)
701 {
702 	u32 param1, param2;
703 	struct hal_data_8188e *pHalData = &Adapter->haldata;
704 
705 	/* s1. pre common command - CmdID_SetTxPowerLevel */
706 	PHY_SetTxPowerLevel8188E(Adapter, channel);
707 
708 	/* s2. RF dependent command - CmdID_RF_WriteReg, param1=RF_CHNLBW, param2=channel */
709 	param1 = RF_CHNLBW;
710 	param2 = channel;
711 	pHalData->RfRegChnlVal = ((pHalData->RfRegChnlVal & 0xfffffc00) | param2);
712 	rtl8188e_PHY_SetRFReg(Adapter, param1, bRFRegOffsetMask, pHalData->RfRegChnlVal);
713 }
714 
PHY_SwChnl8188E(struct adapter * Adapter,u8 channel)715 void PHY_SwChnl8188E(struct adapter *Adapter, u8 channel)
716 {
717 	/*  Call after initialization */
718 	struct hal_data_8188e *pHalData = &Adapter->haldata;
719 
720 	if (channel == 0)
721 		channel = 1;
722 
723 	if ((!Adapter->bDriverStopped) && (!Adapter->bSurpriseRemoved)) {
724 		pHalData->CurrentChannel = channel;
725 		_PHY_SwChnl8192C(Adapter, channel);
726 	}
727 }
728