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