• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  ******************************************************************************/
15 #define _RTL8723A_PHYCFG_C_
16 
17 #include <osdep_service.h>
18 #include <drv_types.h>
19 
20 #include <rtl8723a_hal.h>
21 #include <usb_ops_linux.h>
22 
23 /*---------------------------Define Local Constant---------------------------*/
24 /* Channel switch:The size of command tables for switch channel*/
25 #define MAX_PRECMD_CNT 16
26 #define MAX_RFDEPENDCMD_CNT 16
27 #define MAX_POSTCMD_CNT 16
28 
29 #define MAX_DOZE_WAITING_TIMES_9x 64
30 
31 /*---------------------------Define Local Constant---------------------------*/
32 
33 /*------------------------Define global variable-----------------------------*/
34 
35 /*------------------------Define local variable------------------------------*/
36 
37 /*--------------------Define export function prototype-----------------------*/
38 /*  Please refer to header file */
39 /*--------------------Define export function prototype-----------------------*/
40 
41 /*----------------------------Function Body----------------------------------*/
42 /*  */
43 /*  1. BB register R/W API */
44 /*  */
45 
46 /**
47 * Function:	phy_CalculateBitShift
48 *
49 * OverView:	Get shifted position of the BitMask
50 *
51 * Input:
52 *			u32		BitMask,
53 *
54 * Output:	none
55 * Return:		u32		Return the shift bit bit position of the mask
56 */
phy_CalculateBitShift(u32 BitMask)57 static	u32 phy_CalculateBitShift(u32 BitMask)
58 {
59 	u32 i;
60 
61 	for (i = 0; i <= 31; i++) {
62 		if (((BitMask>>i) & 0x1) == 1)
63 			break;
64 	}
65 
66 	return i;
67 }
68 
69 /**
70 * Function:	PHY_QueryBBReg
71 *
72 * OverView:	Read "sepcific bits" from BB register
73 *
74 * Input:
75 *	struct rtw_adapter *	Adapter,
76 *	u32			RegAddr,	Target address to be readback
77 *	u32			BitMask		Target bit position in the
78 *						target address to be readback
79 * Output:
80 *	None
81 * Return:
82 *	u32			Data		The readback register value
83 * Note:
84 *	This function is equal to "GetRegSetting" in PHY programming guide
85 */
86 u32
PHY_QueryBBReg(struct rtw_adapter * Adapter,u32 RegAddr,u32 BitMask)87 PHY_QueryBBReg(struct rtw_adapter *Adapter, u32 RegAddr, u32 BitMask)
88 {
89 	u32	ReturnValue = 0, OriginalValue, BitShift;
90 
91 	OriginalValue = rtl8723au_read32(Adapter, RegAddr);
92 	BitShift = phy_CalculateBitShift(BitMask);
93 	ReturnValue = (OriginalValue & BitMask) >> BitShift;
94 	return ReturnValue;
95 }
96 
97 /**
98 * Function:	PHY_SetBBReg
99 *
100 * OverView:	Write "Specific bits" to BB register (page 8~)
101 *
102 * Input:
103 *	struct rtw_adapter *	Adapter,
104 *	u32			RegAddr,	Target address to be modified
105 *	u32			BitMask		Target bit position in the
106 *						target address to be modified
107 *	u32			Data		The new register value in the
108 *						target bit position of the
109 *						 target address
110 *
111 * Output:
112 *	None
113 * Return:
114 *	None
115 * Note:
116 *	This function is equal to "PutRegSetting" in PHY programming guide
117 */
118 
119 void
PHY_SetBBReg(struct rtw_adapter * Adapter,u32 RegAddr,u32 BitMask,u32 Data)120 PHY_SetBBReg(struct rtw_adapter *Adapter, u32 RegAddr, u32 BitMask, u32	Data)
121 {
122 	u32 OriginalValue, BitShift;
123 
124 	if (BitMask != bMaskDWord) {/* if not "double word" write */
125 		OriginalValue = rtl8723au_read32(Adapter, RegAddr);
126 		BitShift = phy_CalculateBitShift(BitMask);
127 		Data = (OriginalValue & (~BitMask)) | (Data << BitShift);
128 	}
129 
130 	rtl8723au_write32(Adapter, RegAddr, Data);
131 
132 	/* RTPRINT(FPHY, PHY_BBW, ("BBW MASK = 0x%lx Addr[0x%lx]= 0x%lx\n", BitMask, RegAddr, Data)); */
133 }
134 
135 /*  */
136 /*  2. RF register R/W API */
137 /*  */
138 
139 /**
140 * Function:	phy_RFSerialRead
141 *
142 * OverView:	Read regster from RF chips
143 *
144 * Input:
145 *		struct rtw_adapter *		Adapter,
146 *		enum RF_RADIO_PATH	eRFPath,	Radio path of A/B/C/D
147 *		u32 Offset,			The target address to be read
148 *
149 * Output:	None
150 * Return:	u32			reback value
151 * Note:		Threre are three types of serial operations:
152 *		1. Software serial write
153 *		2. Hardware LSSI-Low Speed Serial Interface
154 *		3. Hardware HSSI-High speed
155 *		serial write. Driver need to implement (1) and (2).
156 *		This function is equal to the combination of RF_ReadReg() and
157 *		RFLSSIRead()
158 */
159 static u32
phy_RFSerialRead(struct rtw_adapter * Adapter,enum RF_RADIO_PATH eRFPath,u32 Offset)160 phy_RFSerialRead(struct rtw_adapter *Adapter, enum RF_RADIO_PATH eRFPath,
161 		 u32 Offset)
162 {
163 	u32 retValue = 0;
164 	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
165 	struct bb_reg_define *pPhyReg = &pHalData->PHYRegDef[eRFPath];
166 	u32 NewOffset;
167 	u32 tmplong, tmplong2;
168 	u8 RfPiEnable = 0;
169 	/*  */
170 	/*  Make sure RF register offset is correct */
171 	/*  */
172 	Offset &= 0x3f;
173 
174 	/*  */
175 	/*  Switch page for 8256 RF IC */
176 	/*  */
177 	NewOffset = Offset;
178 
179 	/*  2009/06/17 MH We can not execute IO for power save or
180 	    other accident mode. */
181 	/* if (RT_CANNOT_IO(Adapter)) */
182 	/*  */
183 	/*	RTPRINT(FPHY, PHY_RFR, ("phy_RFSerialRead return all one\n")); */
184 	/*	return	0xFFFFFFFF; */
185 	/*  */
186 
187 	/*  For 92S LSSI Read RFLSSIRead */
188 	/*  For RF A/B write 0x824/82c(does not work in the future) */
189 	/*  We must use 0x824 for RF A and B to execute read trigger */
190 	tmplong = rtl8723au_read32(Adapter, rFPGA0_XA_HSSIParameter2);
191 	if (eRFPath == RF_PATH_A)
192 		tmplong2 = tmplong;
193 	else
194 		tmplong2 = rtl8723au_read32(Adapter, pPhyReg->rfHSSIPara2);
195 
196 	tmplong2 = (tmplong2 & ~bLSSIReadAddress) |
197 		(NewOffset << 23) | bLSSIReadEdge;	/* T65 RF */
198 
199 	rtl8723au_write32(Adapter, rFPGA0_XA_HSSIParameter2,
200 			  tmplong & (~bLSSIReadEdge));
201 	udelay(10);/*  PlatformStallExecution(10); */
202 
203 	rtl8723au_write32(Adapter, pPhyReg->rfHSSIPara2, tmplong2);
204 	udelay(100);/* PlatformStallExecution(100); */
205 
206 	rtl8723au_write32(Adapter, rFPGA0_XA_HSSIParameter2,
207 			  tmplong | bLSSIReadEdge);
208 	udelay(10);/* PlatformStallExecution(10); */
209 
210 	if (eRFPath == RF_PATH_A)
211 		RfPiEnable = (u8)PHY_QueryBBReg(Adapter,
212 						rFPGA0_XA_HSSIParameter1,
213 						BIT(8));
214 	else if (eRFPath == RF_PATH_B)
215 		RfPiEnable = (u8)PHY_QueryBBReg(Adapter,
216 						rFPGA0_XB_HSSIParameter1,
217 						BIT(8));
218 
219 	if (RfPiEnable)	{
220 		/* Read from BBreg8b8, 12 bits for 8190, 20bits for T65 RF */
221 		retValue = PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBackPi,
222 					  bLSSIReadBackData);
223 		/* DBG_8723A("Readback from RF-PI : 0x%x\n", retValue); */
224 	} else {
225 		/* Read from BBreg8a0, 12 bits for 8190, 20 bits for T65 RF */
226 		retValue = PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBack,
227 					  bLSSIReadBackData);
228 		/* DBG_8723A("Readback from RF-SI : 0x%x\n", retValue); */
229 	}
230 	/* DBG_8723A("RFR-%d Addr[0x%x]= 0x%x\n", eRFPath, pPhyReg->rfLSSIReadBack, retValue); */
231 
232 	return retValue;
233 }
234 
235 /**
236 * Function:	phy_RFSerialWrite
237 *
238 * OverView:	Write data to RF register (page 8~)
239 *
240 * Input:
241 *	struct rtw_adapter *		Adapter,
242 *	enum RF_RADIO_PATH	eRFPath,	Radio path of A/B/C/D
243 *	u32 Offset,			The target address to be read
244 *	u32 Data			The new register Data in the target
245 *					bit position of the target to be read
246 *
247 * Output:
248 *	None
249 * Return:
250 *	None
251 * Note:
252 *	Threre are three types of serial operations:
253 *		1. Software serial write
254 *		2. Hardware LSSI-Low Speed Serial Interface
255 *		3. Hardware HSSI-High speed
256 *		serial write. Driver need to implement (1) and (2).
257 *		This function is equal to the combination of RF_ReadReg() and
258 *		RFLSSIRead()
259 *
260 * Note:	  For RF8256 only
261 * The total count of RTL8256(Zebra4) register is around 36 bit it only employs
262 * 4-bit RF address. RTL8256 uses "register mode control bit"
263 * (Reg00[12], Reg00[10]) to access register address bigger than 0xf.
264 * See "Appendix-4 in PHY Configuration programming guide" for more details.
265 * Thus, we define a sub-finction for RTL8526 register address conversion
266 * ===========================================================
267 * Register Mode:	RegCTL[1]	RegCTL[0]	Note
268 *			(Reg00[12])	(Reg00[10])
269 * ===========================================================
270 * Reg_Mode0		0		x		Reg 0 ~15(0x0 ~ 0xf)
271 * ------------------------------------------------------------------
272 * Reg_Mode1		1		0		Reg 16 ~30(0x1 ~ 0xf)
273 * ------------------------------------------------------------------
274 * Reg_Mode2		1		1		Reg 31 ~ 45(0x1 ~ 0xf)
275 * ------------------------------------------------------------------
276 *
277 *	2008/09/02	MH	Add 92S RF definition
278 */
279 static	void
phy_RFSerialWrite(struct rtw_adapter * Adapter,enum RF_RADIO_PATH eRFPath,u32 Offset,u32 Data)280 phy_RFSerialWrite(struct rtw_adapter *Adapter, enum RF_RADIO_PATH eRFPath,
281 		  u32 Offset, u32 Data)
282 {
283 	u32 DataAndAddr = 0;
284 	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
285 	struct bb_reg_define *pPhyReg = &pHalData->PHYRegDef[eRFPath];
286 	u32 NewOffset;
287 
288 	/*  2009/06/17 MH We can not execute IO for power save or
289 	    other accident mode. */
290 	/* if (RT_CANNOT_IO(Adapter)) */
291 	/*  */
292 	/*	RTPRINT(FPHY, PHY_RFW, ("phy_RFSerialWrite stop\n")); */
293 	/*	return; */
294 	/*  */
295 
296 	Offset &= 0x3f;
297 
298 	/*  */
299 	/*  Shadow Update */
300 	/*  */
301 	/* PHY_RFShadowWrite(Adapter, eRFPath, Offset, Data); */
302 
303 	/*  */
304 	/*  Switch page for 8256 RF IC */
305 	/*  */
306 	NewOffset = Offset;
307 
308 	/*  */
309 	/*  Put write addr in [5:0]  and write data in [31:16] */
310 	/*  */
311 	/* DataAndAddr = (Data<<16) | (NewOffset&0x3f); */
312 	/*  T65 RF */
313 	DataAndAddr = ((NewOffset<<20) | (Data&0x000fffff)) & 0x0fffffff;
314 
315 	/*  */
316 	/*  Write Operation */
317 	/*  */
318 	rtl8723au_write32(Adapter, pPhyReg->rf3wireOffset, DataAndAddr);
319 }
320 
321 /**
322 * Function:	PHY_QueryRFReg
323 *
324 * OverView:	Query "Specific bits" to RF register (page 8~)
325 *
326 * Input:
327 *	struct rtw_adapter *		Adapter,
328 *	enum RF_RADIO_PATH	eRFPath,	Radio path of A/B/C/D
329 *	u32 RegAddr,			The target address to be read
330 *	u32BitMask			The target bit position in the target
331 *					address	to be read
332 *
333 * Output:
334 *	None
335 * Return:
336 *	u32				Readback value
337 * Note:
338 *	This function is equal to "GetRFRegSetting" in PHY programming guide
339 */
340 u32
PHY_QueryRFReg(struct rtw_adapter * Adapter,enum RF_RADIO_PATH eRFPath,u32 RegAddr,u32 BitMask)341 PHY_QueryRFReg(struct rtw_adapter *Adapter, enum RF_RADIO_PATH eRFPath,
342 	       u32 RegAddr, u32 BitMask)
343 {
344 	u32 Original_Value, Readback_Value, BitShift;
345 	/* struct hal_data_8723a	*pHalData = GET_HAL_DATA(Adapter); */
346 	/* u8	RFWaitCounter = 0; */
347 	/* _irqL	irqL; */
348 
349 	Original_Value = phy_RFSerialRead(Adapter, eRFPath, RegAddr);
350 
351 	BitShift =  phy_CalculateBitShift(BitMask);
352 	Readback_Value = (Original_Value & BitMask) >> BitShift;
353 
354 	return Readback_Value;
355 }
356 
357 /**
358 * Function:	PHY_SetRFReg
359 *
360 * OverView:	Write "Specific bits" to RF register (page 8~)
361 *
362 * Input:
363 *	struct rtw_adapter *		Adapter,
364 *	enum RF_RADIO_PATH	eRFPath,	Radio path of A/B/C/D
365 *	u32 RegAddr,			The target address to be modified
366 *	u32 BitMask			The target bit position in the target
367 *					address to be modified
368 *	u32 Data			The new register Data in the target
369 *					bit position of the target address
370 *
371 * Output:
372 *	None
373 * Return:
374 *	None
375 * Note:	This function is equal to "PutRFRegSetting" in PHY programming guide
376 */
377 void
PHY_SetRFReg(struct rtw_adapter * Adapter,enum RF_RADIO_PATH eRFPath,u32 RegAddr,u32 BitMask,u32 Data)378 PHY_SetRFReg(struct rtw_adapter *Adapter, enum RF_RADIO_PATH eRFPath,
379 	     u32 RegAddr, u32 BitMask, u32 Data)
380 {
381 	/* struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); */
382 	/* u8 RFWaitCounter	= 0; */
383 	u32 Original_Value, BitShift;
384 
385 	/*  RF data is 12 bits only */
386 	if (BitMask != bRFRegOffsetMask) {
387 		Original_Value = phy_RFSerialRead(Adapter, eRFPath, RegAddr);
388 		BitShift =  phy_CalculateBitShift(BitMask);
389 		Data = (Original_Value & (~BitMask)) | (Data << BitShift);
390 	}
391 
392 	phy_RFSerialWrite(Adapter, eRFPath, RegAddr, Data);
393 }
394 
395 /*  3. Initial MAC/BB/RF config by reading MAC/BB/RF txt. */
396 
397 /*-----------------------------------------------------------------------------
398  * Function:    PHY_MACConfig8723A
399  *
400  * Overview:	Condig MAC by header file or parameter file.
401  *
402  * Input:       NONE
403  *
404  * Output:      NONE
405  *
406  * Return:      NONE
407  *
408  * Revised History:
409  *  When		Who		Remark
410  *  08/12/2008	MHC		Create Version 0.
411  *
412  *---------------------------------------------------------------------------*/
PHY_MACConfig8723A(struct rtw_adapter * Adapter)413 int PHY_MACConfig8723A(struct rtw_adapter *Adapter)
414 {
415 	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
416 
417 	/*  */
418 	/*  Config MAC */
419 	/*  */
420 	ODM_ReadAndConfig_MAC_REG_8723A(&pHalData->odmpriv);
421 
422 	/*  2010.07.13 AMPDU aggregation number 9 */
423 	rtl8723au_write8(Adapter, REG_MAX_AGGR_NUM, 0x0A);
424 	if (pHalData->rf_type == RF_2T2R &&
425 	    BOARD_USB_DONGLE == pHalData->BoardType)
426 		rtl8723au_write8(Adapter, 0x40, 0x04);
427 
428 	return _SUCCESS;
429 }
430 
431 /**
432 * Function:	phy_InitBBRFRegisterDefinition
433 *
434 * OverView:	Initialize Register definition offset for Radio Path A/B/C/D
435 *
436 * Input:
437 *			struct rtw_adapter *		Adapter,
438 *
439 * Output:	None
440 * Return:		None
441 * Note:
442 *	The initialization value is constant and it should never be changes
443 */
444 static	void
phy_InitBBRFRegisterDefinition(struct rtw_adapter * Adapter)445 phy_InitBBRFRegisterDefinition(struct rtw_adapter *Adapter)
446 {
447 	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
448 
449 	/*  RF Interface Sowrtware Control */
450 	 /*  16 LSBs if read 32-bit from 0x870 */
451 	pHalData->PHYRegDef[RF_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW;
452 	 /*  16 MSBs if read 32-bit from 0x870 (16-bit for 0x872) */
453 	pHalData->PHYRegDef[RF_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW;
454 
455 	/*  RF Interface Readback Value */
456 	/*  16 LSBs if read 32-bit from 0x8E0 */
457 	pHalData->PHYRegDef[RF_PATH_A].rfintfi = rFPGA0_XAB_RFInterfaceRB;
458 	/*  16 MSBs if read 32-bit from 0x8E0 (16-bit for 0x8E2) */
459 	pHalData->PHYRegDef[RF_PATH_B].rfintfi = rFPGA0_XAB_RFInterfaceRB;
460 
461 	/*  RF Interface Output (and Enable) */
462 	/*  16 LSBs if read 32-bit from 0x860 */
463 	pHalData->PHYRegDef[RF_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE;
464 	 /*  16 LSBs if read 32-bit from 0x864 */
465 	pHalData->PHYRegDef[RF_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE;
466 
467 	/*  RF Interface (Output and)  Enable */
468 	 /*  16 MSBs if read 32-bit from 0x860 (16-bit for 0x862) */
469 	pHalData->PHYRegDef[RF_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE;
470 	/*  16 MSBs if read 32-bit from 0x864 (16-bit for 0x866) */
471 	pHalData->PHYRegDef[RF_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE;
472 
473 	/* Addr of LSSI. Wirte RF register by driver */
474 	pHalData->PHYRegDef[RF_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter;
475 	pHalData->PHYRegDef[RF_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter;
476 
477 	/*  RF parameter */
478 	/* BB Band Select */
479 	pHalData->PHYRegDef[RF_PATH_A].rfLSSI_Select = rFPGA0_XAB_RFParameter;
480 	pHalData->PHYRegDef[RF_PATH_B].rfLSSI_Select = rFPGA0_XAB_RFParameter;
481 
482 	/*  Tx AGC Gain Stage (same for all path. Should we remove this?) */
483 	pHalData->PHYRegDef[RF_PATH_A].rfTxGainStage = rFPGA0_TxGainStage;
484 	pHalData->PHYRegDef[RF_PATH_B].rfTxGainStage = rFPGA0_TxGainStage;
485 
486 	/*  Tranceiver A~D HSSI Parameter-1 */
487 	/* wire control parameter1 */
488 	pHalData->PHYRegDef[RF_PATH_A].rfHSSIPara1 = rFPGA0_XA_HSSIParameter1;
489 	/* wire control parameter1 */
490 	pHalData->PHYRegDef[RF_PATH_B].rfHSSIPara1 = rFPGA0_XB_HSSIParameter1;
491 
492 	/*  Tranceiver A~D HSSI Parameter-2 */
493 	/* wire control parameter2 */
494 	pHalData->PHYRegDef[RF_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2;
495 	/* wire control parameter2 */
496 	pHalData->PHYRegDef[RF_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2;
497 
498 	/*  RF switch Control */
499 	pHalData->PHYRegDef[RF_PATH_A].rfSwitchControl =
500 		rFPGA0_XAB_SwitchControl; /* TR/Ant switch control */
501 	pHalData->PHYRegDef[RF_PATH_B].rfSwitchControl =
502 		rFPGA0_XAB_SwitchControl;
503 
504 	/*  AGC control 1 */
505 	pHalData->PHYRegDef[RF_PATH_A].rfAGCControl1 = rOFDM0_XAAGCCore1;
506 	pHalData->PHYRegDef[RF_PATH_B].rfAGCControl1 = rOFDM0_XBAGCCore1;
507 
508 	/*  AGC control 2 */
509 	pHalData->PHYRegDef[RF_PATH_A].rfAGCControl2 = rOFDM0_XAAGCCore2;
510 	pHalData->PHYRegDef[RF_PATH_B].rfAGCControl2 = rOFDM0_XBAGCCore2;
511 
512 	/*  RX AFE control 1 */
513 	pHalData->PHYRegDef[RF_PATH_A].rfRxIQImbalance = rOFDM0_XARxIQImbalance;
514 	pHalData->PHYRegDef[RF_PATH_B].rfRxIQImbalance = rOFDM0_XBRxIQImbalance;
515 
516 	/*  RX AFE control 1 */
517 	pHalData->PHYRegDef[RF_PATH_A].rfRxAFE = rOFDM0_XARxAFE;
518 	pHalData->PHYRegDef[RF_PATH_B].rfRxAFE = rOFDM0_XBRxAFE;
519 
520 	/*  Tx AFE control 1 */
521 	pHalData->PHYRegDef[RF_PATH_A].rfTxIQImbalance = rOFDM0_XATxIQImbalance;
522 	pHalData->PHYRegDef[RF_PATH_B].rfTxIQImbalance = rOFDM0_XBTxIQImbalance;
523 
524 	/*  Tx AFE control 2 */
525 	pHalData->PHYRegDef[RF_PATH_A].rfTxAFE = rOFDM0_XATxAFE;
526 	pHalData->PHYRegDef[RF_PATH_B].rfTxAFE = rOFDM0_XBTxAFE;
527 
528 	/*  Tranceiver LSSI Readback SI mode */
529 	pHalData->PHYRegDef[RF_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack;
530 	pHalData->PHYRegDef[RF_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack;
531 
532 	/*  Tranceiver LSSI Readback PI mode */
533 	pHalData->PHYRegDef[RF_PATH_A].rfLSSIReadBackPi =
534 		TransceiverA_HSPI_Readback;
535 	pHalData->PHYRegDef[RF_PATH_B].rfLSSIReadBackPi =
536 		TransceiverB_HSPI_Readback;
537 }
538 
539 /*  The following is for High Power PA */
540 static void
storePwrIndexDiffRateOffset(struct rtw_adapter * Adapter,u32 RegAddr,u32 BitMask,u32 Data)541 storePwrIndexDiffRateOffset(struct rtw_adapter *Adapter, u32 RegAddr,
542 			    u32 BitMask, u32 Data)
543 {
544 	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
545 
546 	if (RegAddr == rTxAGC_A_Rate18_06) {
547 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][0] = Data;
548 	}
549 	if (RegAddr == rTxAGC_A_Rate54_24) {
550 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][1] = Data;
551 	}
552 	if (RegAddr == rTxAGC_A_CCK1_Mcs32) {
553 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][6] = Data;
554 	}
555 	if (RegAddr == rTxAGC_B_CCK11_A_CCK2_11 && BitMask == 0xffffff00) {
556 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][7] = Data;
557 	}
558 	if (RegAddr == rTxAGC_A_Mcs03_Mcs00) {
559 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][2] = Data;
560 	}
561 	if (RegAddr == rTxAGC_A_Mcs07_Mcs04) {
562 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][3] = Data;
563 	}
564 	if (RegAddr == rTxAGC_A_Mcs11_Mcs08) {
565 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][4] = Data;
566 	}
567 	if (RegAddr == rTxAGC_A_Mcs15_Mcs12) {
568 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][5] = Data;
569 	}
570 	if (RegAddr == rTxAGC_B_Rate18_06) {
571 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][8] = Data;
572 	}
573 	if (RegAddr == rTxAGC_B_Rate54_24) {
574 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][9] = Data;
575 	}
576 	if (RegAddr == rTxAGC_B_CCK1_55_Mcs32) {
577 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][14] = Data;
578 	}
579 	if (RegAddr == rTxAGC_B_CCK11_A_CCK2_11 && BitMask == 0x000000ff) {
580 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][15] = Data;
581 	}
582 	if (RegAddr == rTxAGC_B_Mcs03_Mcs00) {
583 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][10] = Data;
584 	}
585 	if (RegAddr == rTxAGC_B_Mcs07_Mcs04) {
586 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][11] = Data;
587 	}
588 	if (RegAddr == rTxAGC_B_Mcs11_Mcs08) {
589 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][12] = Data;
590 	}
591 	if (RegAddr == rTxAGC_B_Mcs15_Mcs12) {
592 		pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][13] = Data;
593 		pHalData->pwrGroupCnt++;
594 	}
595 }
596 
597 /*-----------------------------------------------------------------------------
598  * Function:	phy_ConfigBBWithPgHeaderFile
599  *
600  * Overview:	Config PHY_REG_PG array
601  *
602  * Input:       NONE
603  *
604  * Output:      NONE
605  *
606  * Return:      NONE
607  *
608  * Revised History:
609  * When		Who	Remark
610  * 11/06/2008	MHC	Add later!!!!!!.. Please modify for new files!!!!
611  * 11/10/2008	tynli	Modify to mew files.
612  *---------------------------------------------------------------------------*/
613 static	int
phy_ConfigBBWithPgHeaderFile(struct rtw_adapter * Adapter)614 phy_ConfigBBWithPgHeaderFile(struct rtw_adapter *Adapter)
615 {
616 	int i;
617 	u32 *Rtl819XPHY_REGArray_Table_PG;
618 	u16 PHY_REGArrayPGLen;
619 
620 	PHY_REGArrayPGLen = Rtl8723_PHY_REG_Array_PGLength;
621 	Rtl819XPHY_REGArray_Table_PG = (u32 *)Rtl8723_PHY_REG_Array_PG;
622 
623 	for (i = 0; i < PHY_REGArrayPGLen; i = i + 3) {
624 		storePwrIndexDiffRateOffset(Adapter,
625 					    Rtl819XPHY_REGArray_Table_PG[i],
626 					    Rtl819XPHY_REGArray_Table_PG[i+1],
627 					    Rtl819XPHY_REGArray_Table_PG[i+2]);
628 	}
629 
630 	return _SUCCESS;
631 }
632 
633 static void
phy_BB8192C_Config_1T(struct rtw_adapter * Adapter)634 phy_BB8192C_Config_1T(struct rtw_adapter *Adapter)
635 {
636 	/* for path - B */
637 	PHY_SetBBReg(Adapter, rFPGA0_TxInfo, 0x3, 0x2);
638 	PHY_SetBBReg(Adapter, rFPGA1_TxInfo, 0x300033, 0x200022);
639 
640 	/*  20100519 Joseph: Add for 1T2R config. Suggested by Kevin,
641 	    Jenyu and Yunan. */
642 	PHY_SetBBReg(Adapter, rCCK0_AFESetting, bMaskByte3, 0x45);
643 	PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, bMaskByte0, 0x23);
644 	/*  B path first AGC */
645 	PHY_SetBBReg(Adapter, rOFDM0_AGCParameter1, 0x30, 0x1);
646 
647 	PHY_SetBBReg(Adapter, 0xe74, 0x0c000000, 0x2);
648 	PHY_SetBBReg(Adapter, 0xe78, 0x0c000000, 0x2);
649 	PHY_SetBBReg(Adapter, 0xe7c, 0x0c000000, 0x2);
650 	PHY_SetBBReg(Adapter, 0xe80, 0x0c000000, 0x2);
651 	PHY_SetBBReg(Adapter, 0xe88, 0x0c000000, 0x2);
652 }
653 
654 static int
phy_BB8723a_Config_ParaFile(struct rtw_adapter * Adapter)655 phy_BB8723a_Config_ParaFile(struct rtw_adapter *Adapter)
656 {
657 	struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(Adapter);
658 	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
659 	int rtStatus = _SUCCESS;
660 
661 	/*  */
662 	/*  1. Read PHY_REG.TXT BB INIT!! */
663 	/*  We will separate as 88C / 92C according to chip version */
664 	/*  */
665 	ODM_ReadAndConfig_PHY_REG_1T_8723A(&pHalData->odmpriv);
666 
667 	/*  */
668 	/*  20100318 Joseph: Config 2T2R to 1T2R if necessary. */
669 	/*  */
670 	if (pHalData->rf_type == RF_1T2R) {
671 		phy_BB8192C_Config_1T(Adapter);
672 		DBG_8723A("phy_BB8723a_Config_ParaFile():Config to 1T!!\n");
673 	}
674 
675 	/*  */
676 	/*  2. If EEPROM or EFUSE autoload OK, We must config by
677 	    PHY_REG_PG.txt */
678 	/*  */
679 	if (pEEPROM->bautoload_fail_flag == false) {
680 		pHalData->pwrGroupCnt = 0;
681 
682 		rtStatus = phy_ConfigBBWithPgHeaderFile(Adapter);
683 	}
684 
685 	if (rtStatus != _SUCCESS)
686 		goto phy_BB8190_Config_ParaFile_Fail;
687 
688 	/*  */
689 	/*  3. BB AGC table Initialization */
690 	/*  */
691 	ODM_ReadAndConfig_AGC_TAB_1T_8723A(&pHalData->odmpriv);
692 
693 phy_BB8190_Config_ParaFile_Fail:
694 
695 	return rtStatus;
696 }
697 
698 int
PHY_BBConfig8723A(struct rtw_adapter * Adapter)699 PHY_BBConfig8723A(struct rtw_adapter *Adapter)
700 {
701 	int rtStatus = _SUCCESS;
702 	struct hal_data_8723a	*pHalData = GET_HAL_DATA(Adapter);
703 	u8 TmpU1B = 0;
704 	u8 CrystalCap;
705 
706 	phy_InitBBRFRegisterDefinition(Adapter);
707 
708 	/*  Suggested by Scott. tynli_test. 2010.12.30. */
709 	/* 1. 0x28[1] = 1 */
710 	TmpU1B = rtl8723au_read8(Adapter, REG_AFE_PLL_CTRL);
711 	udelay(2);
712 	rtl8723au_write8(Adapter, REG_AFE_PLL_CTRL, TmpU1B | BIT(1));
713 	udelay(2);
714 
715 	/* 2. 0x29[7:0] = 0xFF */
716 	rtl8723au_write8(Adapter, REG_AFE_PLL_CTRL+1, 0xff);
717 	udelay(2);
718 
719 	/* 3. 0x02[1:0] = 2b'11 */
720 	TmpU1B = rtl8723au_read8(Adapter, REG_SYS_FUNC_EN);
721 	rtl8723au_write8(Adapter, REG_SYS_FUNC_EN,
722 			 (TmpU1B | FEN_BB_GLB_RSTn | FEN_BBRSTB));
723 
724 	/* 4. 0x25[6] = 0 */
725 	TmpU1B = rtl8723au_read8(Adapter, REG_AFE_XTAL_CTRL + 1);
726 	rtl8723au_write8(Adapter, REG_AFE_XTAL_CTRL+1, TmpU1B & ~BIT(6));
727 
728 	/* 5. 0x24[20] = 0	Advised by SD3 Alex Wang. 2011.02.09. */
729 	TmpU1B = rtl8723au_read8(Adapter, REG_AFE_XTAL_CTRL+2);
730 	rtl8723au_write8(Adapter, REG_AFE_XTAL_CTRL+2, TmpU1B & ~BIT(4));
731 
732 	/* 6. 0x1f[7:0] = 0x07 */
733 	rtl8723au_write8(Adapter, REG_RF_CTRL, 0x07);
734 
735 	/*  */
736 	/*  Config BB and AGC */
737 	/*  */
738 	rtStatus = phy_BB8723a_Config_ParaFile(Adapter);
739 
740 /* only for B-cut */
741 	if (pHalData->EEPROMVersion >= 0x01) {
742 		CrystalCap = pHalData->CrystalCap & 0x3F;
743 		PHY_SetBBReg(Adapter, REG_MAC_PHY_CTRL, 0xFFF000,
744 			     (CrystalCap | (CrystalCap << 6)));
745 	}
746 
747 	rtl8723au_write32(Adapter, REG_LDOA15_CTRL, 0x01572505);
748 	return rtStatus;
749 }
750 
751 /*-----------------------------------------------------------------------------
752  * Function:    SetTxPowerLevel8723A()
753  *
754  * Overview:    This function is export to "HalCommon" moudule
755  *			We must consider RF path later!!!!!!!
756  *
757  * Input:       struct rtw_adapter *		Adapter
758  *			u8		channel
759  *
760  * Output:      NONE
761  *
762  * Return:      NONE
763  *
764  *---------------------------------------------------------------------------*/
PHY_SetTxPowerLevel8723A(struct rtw_adapter * Adapter,u8 channel)765 void PHY_SetTxPowerLevel8723A(struct rtw_adapter *Adapter, u8 channel)
766 {
767 	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
768 	u8 cckpwr[2], ofdmpwr[2];	/*  [0]:RF-A, [1]:RF-B */
769 	int i = channel - 1;
770 
771 	if (pHalData->bTXPowerDataReadFromEEPORM == false)
772 		return;
773 
774 	/*  1. CCK */
775 	cckpwr[RF_PATH_A] = pHalData->TxPwrLevelCck[RF_PATH_A][i];
776 	cckpwr[RF_PATH_B] = pHalData->TxPwrLevelCck[RF_PATH_B][i];
777 
778 	/*  2. OFDM for 1S or 2S */
779 	if (GET_RF_TYPE(Adapter) == RF_1T2R ||
780 	    GET_RF_TYPE(Adapter) == RF_1T1R) {
781 		/*  Read HT 40 OFDM TX power */
782 		ofdmpwr[RF_PATH_A] = pHalData->TxPwrLevelHT40_1S[RF_PATH_A][i];
783 		ofdmpwr[RF_PATH_B] = pHalData->TxPwrLevelHT40_1S[RF_PATH_B][i];
784 	} else if (GET_RF_TYPE(Adapter) == RF_2T2R) {
785 		/*  Read HT 40 OFDM TX power */
786 		ofdmpwr[RF_PATH_A] = pHalData->TxPwrLevelHT40_2S[RF_PATH_A][i];
787 		ofdmpwr[RF_PATH_B] = pHalData->TxPwrLevelHT40_2S[RF_PATH_B][i];
788 	}
789 
790 	rtl823a_phy_rf6052setccktxpower(Adapter, &cckpwr[0]);
791 	rtl8723a_PHY_RF6052SetOFDMTxPower(Adapter, &ofdmpwr[0], channel);
792 }
793 
794 /*-----------------------------------------------------------------------------
795  * Function:    PHY_SetBWMode23aCallback8192C()
796  *
797  * Overview:    Timer callback function for SetSetBWMode23a
798  *
799  * Input:		PRT_TIMER		pTimer
800  *
801  * Output:      NONE
802  *
803  * Return:      NONE
804  *
805  * Note:
806  *	(1) We do not take j mode into consideration now
807  *	(2) Will two workitem of "switch channel" and
808  *	    "switch channel bandwidth" run concurrently?
809  *---------------------------------------------------------------------------*/
810 static void
_PHY_SetBWMode23a92C(struct rtw_adapter * Adapter)811 _PHY_SetBWMode23a92C(struct rtw_adapter *Adapter)
812 {
813 	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
814 	u8 regBwOpMode;
815 	u8 regRRSR_RSC;
816 
817 	if (Adapter->bDriverStopped)
818 		return;
819 
820 	/* 3 */
821 	/* 3<1>Set MAC register */
822 	/* 3 */
823 
824 	regBwOpMode = rtl8723au_read8(Adapter, REG_BWOPMODE);
825 	regRRSR_RSC = rtl8723au_read8(Adapter, REG_RRSR+2);
826 
827 	switch (pHalData->CurrentChannelBW) {
828 	case HT_CHANNEL_WIDTH_20:
829 		regBwOpMode |= BW_OPMODE_20MHZ;
830 		rtl8723au_write8(Adapter, REG_BWOPMODE, regBwOpMode);
831 		break;
832 	case HT_CHANNEL_WIDTH_40:
833 		regBwOpMode &= ~BW_OPMODE_20MHZ;
834 		rtl8723au_write8(Adapter, REG_BWOPMODE, regBwOpMode);
835 		regRRSR_RSC = (regRRSR_RSC & 0x90) |
836 			(pHalData->nCur40MhzPrimeSC << 5);
837 		rtl8723au_write8(Adapter, REG_RRSR+2, regRRSR_RSC);
838 		break;
839 
840 	default:
841 		break;
842 	}
843 
844 	/* 3 */
845 	/* 3<2>Set PHY related register */
846 	/* 3 */
847 	switch (pHalData->CurrentChannelBW) {
848 		/* 20 MHz channel*/
849 	case HT_CHANNEL_WIDTH_20:
850 		PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x0);
851 		PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x0);
852 		PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter2, BIT(10), 1);
853 
854 		break;
855 
856 		/* 40 MHz channel*/
857 	case HT_CHANNEL_WIDTH_40:
858 		PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x1);
859 		PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x1);
860 
861 		/*  Set Control channel to upper or lower. These settings
862 		    are required only for 40MHz */
863 		PHY_SetBBReg(Adapter, rCCK0_System, bCCKSideBand,
864 			     (pHalData->nCur40MhzPrimeSC >> 1));
865 		PHY_SetBBReg(Adapter, rOFDM1_LSTF, 0xC00,
866 			     pHalData->nCur40MhzPrimeSC);
867 		PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter2, BIT(10), 0);
868 
869 		PHY_SetBBReg(Adapter, 0x818, BIT(26) | BIT(27),
870 			     (pHalData->nCur40MhzPrimeSC ==
871 			      HAL_PRIME_CHNL_OFFSET_LOWER) ? 2:1);
872 		break;
873 
874 	default:
875 		break;
876 	}
877 	/* Skip over setting of J-mode in BB register here. Default value
878 	   is "None J mode". Emily 20070315 */
879 
880 	/*  Added it for 20/40 mhz switch time evaluation by guangan 070531 */
881 	/* NowL = PlatformEFIORead4Byte(Adapter, TSFR); */
882 	/* NowH = PlatformEFIORead4Byte(Adapter, TSFR+4); */
883 	/* EndTime = ((u64)NowH << 32) + NowL; */
884 
885 	rtl8723a_phy_rf6052set_bw(Adapter, pHalData->CurrentChannelBW);
886 }
887 
888  /*-----------------------------------------------------------------------------
889  * Function:   SetBWMode23a8190Pci()
890  *
891  * Overview:  This function is export to "HalCommon" moudule
892  *
893  * Input:		struct rtw_adapter *			Adapter
894  *			enum ht_channel_width	Bandwidth	20M or 40M
895  *
896  * Output:      NONE
897  *
898  * Return:      NONE
899  *
900  * Note:		We do not take j mode into consideration now
901  *---------------------------------------------------------------------------*/
902 void
PHY_SetBWMode23a8723A(struct rtw_adapter * Adapter,enum ht_channel_width Bandwidth,unsigned char Offset)903 PHY_SetBWMode23a8723A(struct rtw_adapter *Adapter,
904 		   enum ht_channel_width Bandwidth, unsigned char Offset)
905 {
906 	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
907 	enum ht_channel_width tmpBW = pHalData->CurrentChannelBW;
908 
909 	pHalData->CurrentChannelBW = Bandwidth;
910 
911 	pHalData->nCur40MhzPrimeSC = Offset;
912 
913 	if ((!Adapter->bDriverStopped) && (!Adapter->bSurpriseRemoved))
914 		_PHY_SetBWMode23a92C(Adapter);
915 	else
916 		pHalData->CurrentChannelBW = tmpBW;
917 }
918 
_PHY_SwChnl8723A(struct rtw_adapter * Adapter,u8 channel)919 static void _PHY_SwChnl8723A(struct rtw_adapter *Adapter, u8 channel)
920 {
921 	enum RF_RADIO_PATH eRFPath;
922 	u32 param1, param2;
923 	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
924 
925 	/* s1. pre common command - CmdID_SetTxPowerLevel */
926 	PHY_SetTxPowerLevel8723A(Adapter, channel);
927 
928 	/* s2. RF dependent command - CmdID_RF_WriteReg,
929 	   param1 = RF_CHNLBW, param2 = channel */
930 	param1 = RF_CHNLBW;
931 	param2 = channel;
932 	for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++) {
933 		pHalData->RfRegChnlVal[eRFPath] =
934 			(pHalData->RfRegChnlVal[eRFPath] & 0xfffffc00) | param2;
935 		PHY_SetRFReg(Adapter, eRFPath, param1,
936 			     bRFRegOffsetMask, pHalData->RfRegChnlVal[eRFPath]);
937 	}
938 
939 	/* s3. post common command - CmdID_End, None */
940 }
941 
PHY_SwChnl8723A(struct rtw_adapter * Adapter,u8 channel)942 void PHY_SwChnl8723A(struct rtw_adapter *Adapter, u8 channel)
943 {
944 	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
945 	u8 tmpchannel = pHalData->CurrentChannel;
946 	bool  result = true;
947 
948 	if (channel == 0)
949 		channel = 1;
950 
951 	pHalData->CurrentChannel = channel;
952 
953 	if ((!Adapter->bDriverStopped) && (!Adapter->bSurpriseRemoved)) {
954 		_PHY_SwChnl8723A(Adapter, channel);
955 
956 		if (!result)
957 			pHalData->CurrentChannel = tmpchannel;
958 	} else {
959 		pHalData->CurrentChannel = tmpchannel;
960 	}
961 }
962