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