1 /******************************************************************************
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
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.
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
14 ******************************************************************************/
15 #define _RTL8723A_PHYCFG_C_
17 #include <osdep_service.h>
18 #include <drv_types.h>
20 #include <rtl8723a_hal.h>
21 #include <usb_ops_linux.h>
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
29 #define MAX_DOZE_WAITING_TIMES_9x 64
31 /*---------------------------Define Local Constant---------------------------*/
33 /*------------------------Define global variable-----------------------------*/
35 /*------------------------Define local variable------------------------------*/
37 /*--------------------Define export function prototype-----------------------*/
38 /* Please refer to header file */
39 /*--------------------Define export function prototype-----------------------*/
41 /*----------------------------Function Body----------------------------------*/
43 /* 1. BB register R/W API */
47 * Function: phy_CalculateBitShift
49 * OverView: Get shifted position of the BitMask
55 * Return: u32 Return the shift bit bit position of the mask
57 static u32 phy_CalculateBitShift(u32 BitMask)
61 for (i = 0; i <= 31; i++) {
62 if (((BitMask>>i) & 0x1) == 1)
70 * Function: PHY_QueryBBReg
72 * OverView: Read "sepcific bits" from BB register
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
82 * u32 Data The readback register value
84 * This function is equal to "GetRegSetting" in PHY programming guide
87 PHY_QueryBBReg(struct rtw_adapter *Adapter, u32 RegAddr, u32 BitMask)
89 u32 ReturnValue = 0, OriginalValue, BitShift;
91 OriginalValue = rtl8723au_read32(Adapter, RegAddr);
92 BitShift = phy_CalculateBitShift(BitMask);
93 ReturnValue = (OriginalValue & BitMask) >> BitShift;
98 * Function: PHY_SetBBReg
100 * OverView: Write "Specific bits" to BB register (page 8~)
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
116 * This function is equal to "PutRegSetting" in PHY programming guide
120 PHY_SetBBReg(struct rtw_adapter *Adapter, u32 RegAddr, u32 BitMask, u32 Data)
122 u32 OriginalValue, BitShift;
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);
130 rtl8723au_write32(Adapter, RegAddr, Data);
132 /* RTPRINT(FPHY, PHY_BBW, ("BBW MASK = 0x%lx Addr[0x%lx]= 0x%lx\n", BitMask, RegAddr, Data)); */
136 /* 2. RF register R/W API */
140 * Function: phy_RFSerialRead
142 * OverView: Read regster from RF chips
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
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
160 phy_RFSerialRead(struct rtw_adapter *Adapter, enum RF_RADIO_PATH eRFPath,
164 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
165 struct bb_reg_define *pPhyReg = &pHalData->PHYRegDef[eRFPath];
167 u32 tmplong, tmplong2;
170 /* Make sure RF register offset is correct */
175 /* Switch page for 8256 RF IC */
179 /* 2009/06/17 MH We can not execute IO for power save or
180 other accident mode. */
181 /* if (RT_CANNOT_IO(Adapter)) */
183 /* RTPRINT(FPHY, PHY_RFR, ("phy_RFSerialRead return all one\n")); */
184 /* return 0xFFFFFFFF; */
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)
194 tmplong2 = rtl8723au_read32(Adapter, pPhyReg->rfHSSIPara2);
196 tmplong2 = (tmplong2 & ~bLSSIReadAddress) |
197 (NewOffset << 23) | bLSSIReadEdge; /* T65 RF */
199 rtl8723au_write32(Adapter, rFPGA0_XA_HSSIParameter2,
200 tmplong & (~bLSSIReadEdge));
201 udelay(10);/* PlatformStallExecution(10); */
203 rtl8723au_write32(Adapter, pPhyReg->rfHSSIPara2, tmplong2);
204 udelay(100);/* PlatformStallExecution(100); */
206 rtl8723au_write32(Adapter, rFPGA0_XA_HSSIParameter2,
207 tmplong | bLSSIReadEdge);
208 udelay(10);/* PlatformStallExecution(10); */
210 if (eRFPath == RF_PATH_A)
211 RfPiEnable = (u8)PHY_QueryBBReg(Adapter,
212 rFPGA0_XA_HSSIParameter1,
214 else if (eRFPath == RF_PATH_B)
215 RfPiEnable = (u8)PHY_QueryBBReg(Adapter,
216 rFPGA0_XB_HSSIParameter1,
220 /* Read from BBreg8b8, 12 bits for 8190, 20bits for T65 RF */
221 retValue = PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBackPi,
223 /* DBG_8723A("Readback from RF-PI : 0x%x\n", retValue); */
225 /* Read from BBreg8a0, 12 bits for 8190, 20 bits for T65 RF */
226 retValue = PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBack,
228 /* DBG_8723A("Readback from RF-SI : 0x%x\n", retValue); */
230 /* DBG_8723A("RFR-%d Addr[0x%x]= 0x%x\n", eRFPath, pPhyReg->rfLSSIReadBack, retValue); */
236 * Function: phy_RFSerialWrite
238 * OverView: Write data to RF register (page 8~)
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
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
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 * ------------------------------------------------------------------
277 * 2008/09/02 MH Add 92S RF definition
280 phy_RFSerialWrite(struct rtw_adapter *Adapter, enum RF_RADIO_PATH eRFPath,
281 u32 Offset, u32 Data)
284 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
285 struct bb_reg_define *pPhyReg = &pHalData->PHYRegDef[eRFPath];
288 /* 2009/06/17 MH We can not execute IO for power save or
289 other accident mode. */
290 /* if (RT_CANNOT_IO(Adapter)) */
292 /* RTPRINT(FPHY, PHY_RFW, ("phy_RFSerialWrite stop\n")); */
301 /* PHY_RFShadowWrite(Adapter, eRFPath, Offset, Data); */
304 /* Switch page for 8256 RF IC */
309 /* Put write addr in [5:0] and write data in [31:16] */
311 /* DataAndAddr = (Data<<16) | (NewOffset&0x3f); */
313 DataAndAddr = ((NewOffset<<20) | (Data&0x000fffff)) & 0x0fffffff;
316 /* Write Operation */
318 rtl8723au_write32(Adapter, pPhyReg->rf3wireOffset, DataAndAddr);
322 * Function: PHY_QueryRFReg
324 * OverView: Query "Specific bits" to RF register (page 8~)
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
338 * This function is equal to "GetRFRegSetting" in PHY programming guide
341 PHY_QueryRFReg(struct rtw_adapter *Adapter, enum RF_RADIO_PATH eRFPath,
342 u32 RegAddr, u32 BitMask)
344 u32 Original_Value, Readback_Value, BitShift;
345 /* struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); */
346 /* u8 RFWaitCounter = 0; */
349 Original_Value = phy_RFSerialRead(Adapter, eRFPath, RegAddr);
351 BitShift = phy_CalculateBitShift(BitMask);
352 Readback_Value = (Original_Value & BitMask) >> BitShift;
354 return Readback_Value;
358 * Function: PHY_SetRFReg
360 * OverView: Write "Specific bits" to RF register (page 8~)
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
375 * Note: This function is equal to "PutRFRegSetting" in PHY programming guide
378 PHY_SetRFReg(struct rtw_adapter *Adapter, enum RF_RADIO_PATH eRFPath,
379 u32 RegAddr, u32 BitMask, u32 Data)
381 /* struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); */
382 /* u8 RFWaitCounter = 0; */
383 u32 Original_Value, BitShift;
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);
392 phy_RFSerialWrite(Adapter, eRFPath, RegAddr, Data);
395 /* 3. Initial MAC/BB/RF config by reading MAC/BB/RF txt. */
397 /*-----------------------------------------------------------------------------
398 * Function: PHY_MACConfig8723A
400 * Overview: Condig MAC by header file or parameter file.
410 * 08/12/2008 MHC Create Version 0.
412 *---------------------------------------------------------------------------*/
413 int PHY_MACConfig8723A(struct rtw_adapter *Adapter)
415 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
420 ODM_ReadAndConfig_MAC_REG_8723A(&pHalData->odmpriv);
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);
432 * Function: phy_InitBBRFRegisterDefinition
434 * OverView: Initialize Register definition offset for Radio Path A/B/C/D
437 * struct rtw_adapter * Adapter,
442 * The initialization value is constant and it should never be changes
445 phy_InitBBRFRegisterDefinition(struct rtw_adapter *Adapter)
447 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
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;
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;
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;
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;
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;
479 pHalData->PHYRegDef[RF_PATH_A].rfLSSI_Select = rFPGA0_XAB_RFParameter;
480 pHalData->PHYRegDef[RF_PATH_B].rfLSSI_Select = rFPGA0_XAB_RFParameter;
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;
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;
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;
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;
505 pHalData->PHYRegDef[RF_PATH_A].rfAGCControl1 = rOFDM0_XAAGCCore1;
506 pHalData->PHYRegDef[RF_PATH_B].rfAGCControl1 = rOFDM0_XBAGCCore1;
509 pHalData->PHYRegDef[RF_PATH_A].rfAGCControl2 = rOFDM0_XAAGCCore2;
510 pHalData->PHYRegDef[RF_PATH_B].rfAGCControl2 = rOFDM0_XBAGCCore2;
512 /* RX AFE control 1 */
513 pHalData->PHYRegDef[RF_PATH_A].rfRxIQImbalance = rOFDM0_XARxIQImbalance;
514 pHalData->PHYRegDef[RF_PATH_B].rfRxIQImbalance = rOFDM0_XBRxIQImbalance;
516 /* RX AFE control 1 */
517 pHalData->PHYRegDef[RF_PATH_A].rfRxAFE = rOFDM0_XARxAFE;
518 pHalData->PHYRegDef[RF_PATH_B].rfRxAFE = rOFDM0_XBRxAFE;
520 /* Tx AFE control 1 */
521 pHalData->PHYRegDef[RF_PATH_A].rfTxIQImbalance = rOFDM0_XATxIQImbalance;
522 pHalData->PHYRegDef[RF_PATH_B].rfTxIQImbalance = rOFDM0_XBTxIQImbalance;
524 /* Tx AFE control 2 */
525 pHalData->PHYRegDef[RF_PATH_A].rfTxAFE = rOFDM0_XATxAFE;
526 pHalData->PHYRegDef[RF_PATH_B].rfTxAFE = rOFDM0_XBTxAFE;
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;
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;
539 /* The following is for High Power PA */
541 storePwrIndexDiffRateOffset(struct rtw_adapter *Adapter, u32 RegAddr,
542 u32 BitMask, u32 Data)
544 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
546 if (RegAddr == rTxAGC_A_Rate18_06) {
547 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][0] = Data;
549 if (RegAddr == rTxAGC_A_Rate54_24) {
550 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][1] = Data;
552 if (RegAddr == rTxAGC_A_CCK1_Mcs32) {
553 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][6] = Data;
555 if (RegAddr == rTxAGC_B_CCK11_A_CCK2_11 && BitMask == 0xffffff00) {
556 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][7] = Data;
558 if (RegAddr == rTxAGC_A_Mcs03_Mcs00) {
559 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][2] = Data;
561 if (RegAddr == rTxAGC_A_Mcs07_Mcs04) {
562 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][3] = Data;
564 if (RegAddr == rTxAGC_A_Mcs11_Mcs08) {
565 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][4] = Data;
567 if (RegAddr == rTxAGC_A_Mcs15_Mcs12) {
568 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][5] = Data;
570 if (RegAddr == rTxAGC_B_Rate18_06) {
571 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][8] = Data;
573 if (RegAddr == rTxAGC_B_Rate54_24) {
574 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][9] = Data;
576 if (RegAddr == rTxAGC_B_CCK1_55_Mcs32) {
577 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][14] = Data;
579 if (RegAddr == rTxAGC_B_CCK11_A_CCK2_11 && BitMask == 0x000000ff) {
580 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][15] = Data;
582 if (RegAddr == rTxAGC_B_Mcs03_Mcs00) {
583 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][10] = Data;
585 if (RegAddr == rTxAGC_B_Mcs07_Mcs04) {
586 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][11] = Data;
588 if (RegAddr == rTxAGC_B_Mcs11_Mcs08) {
589 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][12] = Data;
591 if (RegAddr == rTxAGC_B_Mcs15_Mcs12) {
592 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][13] = Data;
593 pHalData->pwrGroupCnt++;
597 /*-----------------------------------------------------------------------------
598 * Function: phy_ConfigBBWithPgHeaderFile
600 * Overview: Config PHY_REG_PG array
610 * 11/06/2008 MHC Add later!!!!!!.. Please modify for new files!!!!
611 * 11/10/2008 tynli Modify to mew files.
612 *---------------------------------------------------------------------------*/
614 phy_ConfigBBWithPgHeaderFile(struct rtw_adapter *Adapter)
617 u32 *Rtl819XPHY_REGArray_Table_PG;
618 u16 PHY_REGArrayPGLen;
620 PHY_REGArrayPGLen = Rtl8723_PHY_REG_Array_PGLength;
621 Rtl819XPHY_REGArray_Table_PG = (u32 *)Rtl8723_PHY_REG_Array_PG;
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]);
634 phy_BB8192C_Config_1T(struct rtw_adapter *Adapter)
637 PHY_SetBBReg(Adapter, rFPGA0_TxInfo, 0x3, 0x2);
638 PHY_SetBBReg(Adapter, rFPGA1_TxInfo, 0x300033, 0x200022);
640 /* 20100519 Joseph: Add for 1T2R config. Suggested by Kevin,
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);
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);
655 phy_BB8723a_Config_ParaFile(struct rtw_adapter *Adapter)
657 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(Adapter);
658 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
659 int rtStatus = _SUCCESS;
662 /* 1. Read PHY_REG.TXT BB INIT!! */
663 /* We will seperate as 88C / 92C according to chip version */
665 ODM_ReadAndConfig_PHY_REG_1T_8723A(&pHalData->odmpriv);
668 /* 20100318 Joseph: Config 2T2R to 1T2R if necessary. */
670 if (pHalData->rf_type == RF_1T2R) {
671 phy_BB8192C_Config_1T(Adapter);
672 DBG_8723A("phy_BB8723a_Config_ParaFile():Config to 1T!!\n");
676 /* 2. If EEPROM or EFUSE autoload OK, We must config by
679 if (pEEPROM->bautoload_fail_flag == false) {
680 pHalData->pwrGroupCnt = 0;
682 rtStatus = phy_ConfigBBWithPgHeaderFile(Adapter);
685 if (rtStatus != _SUCCESS)
686 goto phy_BB8190_Config_ParaFile_Fail;
689 /* 3. BB AGC table Initialization */
691 ODM_ReadAndConfig_AGC_TAB_1T_8723A(&pHalData->odmpriv);
693 phy_BB8190_Config_ParaFile_Fail:
699 PHY_BBConfig8723A(struct rtw_adapter *Adapter)
701 int rtStatus = _SUCCESS;
702 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
706 phy_InitBBRFRegisterDefinition(Adapter);
708 /* Suggested by Scott. tynli_test. 2010.12.30. */
710 TmpU1B = rtl8723au_read8(Adapter, REG_AFE_PLL_CTRL);
712 rtl8723au_write8(Adapter, REG_AFE_PLL_CTRL, TmpU1B | BIT(1));
715 /* 2. 0x29[7:0] = 0xFF */
716 rtl8723au_write8(Adapter, REG_AFE_PLL_CTRL+1, 0xff);
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));
725 TmpU1B = rtl8723au_read8(Adapter, REG_AFE_XTAL_CTRL + 1);
726 rtl8723au_write8(Adapter, REG_AFE_XTAL_CTRL+1, TmpU1B & ~BIT(6));
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));
732 /* 6. 0x1f[7:0] = 0x07 */
733 rtl8723au_write8(Adapter, REG_RF_CTRL, 0x07);
736 /* Config BB and AGC */
738 rtStatus = phy_BB8723a_Config_ParaFile(Adapter);
741 if (pHalData->EEPROMVersion >= 0x01) {
742 CrystalCap = pHalData->CrystalCap & 0x3F;
743 PHY_SetBBReg(Adapter, REG_MAC_PHY_CTRL, 0xFFF000,
744 (CrystalCap | (CrystalCap << 6)));
747 rtl8723au_write32(Adapter, REG_LDOA15_CTRL, 0x01572505);
751 static void getTxPowerIndex(struct rtw_adapter *Adapter,
752 u8 channel, u8 *cckPowerLevel, u8 *ofdmPowerLevel)
754 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
755 u8 index = (channel - 1);
757 cckPowerLevel[RF_PATH_A] = pHalData->TxPwrLevelCck[RF_PATH_A][index];
758 cckPowerLevel[RF_PATH_B] = pHalData->TxPwrLevelCck[RF_PATH_B][index];
760 /* 2. OFDM for 1S or 2S */
761 if (GET_RF_TYPE(Adapter) == RF_1T2R || GET_RF_TYPE(Adapter) == RF_1T1R) {
762 /* Read HT 40 OFDM TX power */
763 ofdmPowerLevel[RF_PATH_A] =
764 pHalData->TxPwrLevelHT40_1S[RF_PATH_A][index];
765 ofdmPowerLevel[RF_PATH_B] =
766 pHalData->TxPwrLevelHT40_1S[RF_PATH_B][index];
767 } else if (GET_RF_TYPE(Adapter) == RF_2T2R) {
768 /* Read HT 40 OFDM TX power */
769 ofdmPowerLevel[RF_PATH_A] =
770 pHalData->TxPwrLevelHT40_2S[RF_PATH_A][index];
771 ofdmPowerLevel[RF_PATH_B] =
772 pHalData->TxPwrLevelHT40_2S[RF_PATH_B][index];
776 static void ccxPowerIndexCheck(struct rtw_adapter *Adapter, u8 channel,
777 u8 *cckPowerLevel, u8 *ofdmPowerLevel)
781 /*-----------------------------------------------------------------------------
782 * Function: SetTxPowerLevel8723A()
784 * Overview: This function is export to "HalCommon" moudule
785 * We must consider RF path later!!!!!!!
787 * Input: struct rtw_adapter * Adapter
794 *---------------------------------------------------------------------------*/
795 void PHY_SetTxPowerLevel8723A(struct rtw_adapter *Adapter, u8 channel)
797 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
798 u8 cckPowerLevel[2], ofdmPowerLevel[2]; /* [0]:RF-A, [1]:RF-B */
800 if (pHalData->bTXPowerDataReadFromEEPORM == false)
803 getTxPowerIndex(Adapter, channel, &cckPowerLevel[0],
806 ccxPowerIndexCheck(Adapter, channel, &cckPowerLevel[0],
809 rtl823a_phy_rf6052setccktxpower(Adapter, &cckPowerLevel[0]);
810 rtl8723a_PHY_RF6052SetOFDMTxPower(Adapter, &ofdmPowerLevel[0], channel);
813 /*-----------------------------------------------------------------------------
814 * Function: PHY_SetBWMode23aCallback8192C()
816 * Overview: Timer callback function for SetSetBWMode23a
818 * Input: PRT_TIMER pTimer
825 * (1) We do not take j mode into consideration now
826 * (2) Will two workitem of "switch channel" and
827 * "switch channel bandwidth" run concurrently?
828 *---------------------------------------------------------------------------*/
830 _PHY_SetBWMode23a92C(struct rtw_adapter *Adapter)
832 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
836 if (Adapter->bDriverStopped)
840 /* 3<1>Set MAC register */
843 regBwOpMode = rtl8723au_read8(Adapter, REG_BWOPMODE);
844 regRRSR_RSC = rtl8723au_read8(Adapter, REG_RRSR+2);
846 switch (pHalData->CurrentChannelBW) {
847 case HT_CHANNEL_WIDTH_20:
848 regBwOpMode |= BW_OPMODE_20MHZ;
849 rtl8723au_write8(Adapter, REG_BWOPMODE, regBwOpMode);
851 case HT_CHANNEL_WIDTH_40:
852 regBwOpMode &= ~BW_OPMODE_20MHZ;
853 rtl8723au_write8(Adapter, REG_BWOPMODE, regBwOpMode);
854 regRRSR_RSC = (regRRSR_RSC & 0x90) |
855 (pHalData->nCur40MhzPrimeSC << 5);
856 rtl8723au_write8(Adapter, REG_RRSR+2, regRRSR_RSC);
864 /* 3<2>Set PHY related register */
866 switch (pHalData->CurrentChannelBW) {
868 case HT_CHANNEL_WIDTH_20:
869 PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x0);
870 PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x0);
871 PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter2, BIT(10), 1);
876 case HT_CHANNEL_WIDTH_40:
877 PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x1);
878 PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x1);
880 /* Set Control channel to upper or lower. These settings
881 are required only for 40MHz */
882 PHY_SetBBReg(Adapter, rCCK0_System, bCCKSideBand,
883 (pHalData->nCur40MhzPrimeSC >> 1));
884 PHY_SetBBReg(Adapter, rOFDM1_LSTF, 0xC00,
885 pHalData->nCur40MhzPrimeSC);
886 PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter2, BIT(10), 0);
888 PHY_SetBBReg(Adapter, 0x818, BIT(26) | BIT(27),
889 (pHalData->nCur40MhzPrimeSC ==
890 HAL_PRIME_CHNL_OFFSET_LOWER) ? 2:1);
896 /* Skip over setting of J-mode in BB register here. Default value
897 is "None J mode". Emily 20070315 */
899 /* Added it for 20/40 mhz switch time evaluation by guangan 070531 */
900 /* NowL = PlatformEFIORead4Byte(Adapter, TSFR); */
901 /* NowH = PlatformEFIORead4Byte(Adapter, TSFR+4); */
902 /* EndTime = ((u64)NowH << 32) + NowL; */
904 rtl8723a_phy_rf6052set_bw(Adapter, pHalData->CurrentChannelBW);
907 /*-----------------------------------------------------------------------------
908 * Function: SetBWMode23a8190Pci()
910 * Overview: This function is export to "HalCommon" moudule
912 * Input: struct rtw_adapter * Adapter
913 * enum ht_channel_width Bandwidth 20M or 40M
919 * Note: We do not take j mode into consideration now
920 *---------------------------------------------------------------------------*/
922 PHY_SetBWMode23a8723A(struct rtw_adapter *Adapter,
923 enum ht_channel_width Bandwidth, unsigned char Offset)
925 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
926 enum ht_channel_width tmpBW = pHalData->CurrentChannelBW;
928 pHalData->CurrentChannelBW = Bandwidth;
930 pHalData->nCur40MhzPrimeSC = Offset;
932 if ((!Adapter->bDriverStopped) && (!Adapter->bSurpriseRemoved))
933 _PHY_SetBWMode23a92C(Adapter);
935 pHalData->CurrentChannelBW = tmpBW;
938 static void _PHY_SwChnl8723A(struct rtw_adapter *Adapter, u8 channel)
940 enum RF_RADIO_PATH eRFPath;
942 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
944 /* s1. pre common command - CmdID_SetTxPowerLevel */
945 PHY_SetTxPowerLevel8723A(Adapter, channel);
947 /* s2. RF dependent command - CmdID_RF_WriteReg,
948 param1 = RF_CHNLBW, param2 = channel */
951 for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++) {
952 pHalData->RfRegChnlVal[eRFPath] =
953 (pHalData->RfRegChnlVal[eRFPath] & 0xfffffc00) | param2;
954 PHY_SetRFReg(Adapter, eRFPath, param1,
955 bRFRegOffsetMask, pHalData->RfRegChnlVal[eRFPath]);
958 /* s3. post common command - CmdID_End, None */
961 void PHY_SwChnl8723A(struct rtw_adapter *Adapter, u8 channel)
963 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
964 u8 tmpchannel = pHalData->CurrentChannel;
970 pHalData->CurrentChannel = channel;
972 if ((!Adapter->bDriverStopped) && (!Adapter->bSurpriseRemoved)) {
973 _PHY_SwChnl8723A(Adapter, channel);
976 pHalData->CurrentChannel = tmpchannel;
978 pHalData->CurrentChannel = tmpchannel;