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