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 <hal_data.h> 11#include <linux/kernel.h> 12 13u8 PHY_GetTxPowerByRateBase(struct adapter *Adapter, u8 RfPath, 14 enum rate_section RateSection) 15{ 16 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter); 17 u8 value = 0; 18 19 if (RfPath >= RF_PATH_MAX) 20 return 0; 21 22 switch (RateSection) { 23 case CCK: 24 value = pHalData->TxPwrByRateBase2_4G[RfPath][0]; 25 break; 26 case OFDM: 27 value = pHalData->TxPwrByRateBase2_4G[RfPath][1]; 28 break; 29 case HT_MCS0_MCS7: 30 value = pHalData->TxPwrByRateBase2_4G[RfPath][2]; 31 break; 32 default: 33 break; 34 } 35 36 return value; 37} 38 39static void 40phy_SetTxPowerByRateBase(struct adapter *Adapter, u8 RfPath, 41 enum rate_section RateSection, u8 Value) 42{ 43 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter); 44 45 if (RfPath >= RF_PATH_MAX) 46 return; 47 48 switch (RateSection) { 49 case CCK: 50 pHalData->TxPwrByRateBase2_4G[RfPath][0] = Value; 51 break; 52 case OFDM: 53 pHalData->TxPwrByRateBase2_4G[RfPath][1] = Value; 54 break; 55 case HT_MCS0_MCS7: 56 pHalData->TxPwrByRateBase2_4G[RfPath][2] = Value; 57 break; 58 default: 59 break; 60 } 61} 62 63static void 64phy_StoreTxPowerByRateBase( 65struct adapter *padapter 66 ) 67{ 68 u8 path, base; 69 70 for (path = RF_PATH_A; path <= RF_PATH_B; ++path) { 71 base = PHY_GetTxPowerByRate(padapter, path, MGN_11M); 72 phy_SetTxPowerByRateBase(padapter, path, CCK, base); 73 74 base = PHY_GetTxPowerByRate(padapter, path, MGN_54M); 75 phy_SetTxPowerByRateBase(padapter, path, OFDM, base); 76 77 base = PHY_GetTxPowerByRate(padapter, path, MGN_MCS7); 78 phy_SetTxPowerByRateBase(padapter, path, HT_MCS0_MCS7, base); 79 } 80} 81 82u8 PHY_GetRateSectionIndexOfTxPowerByRate( 83 struct adapter *padapter, u32 RegAddr, u32 BitMask 84) 85{ 86 struct hal_com_data *pHalData = GET_HAL_DATA(padapter); 87 struct dm_odm_t *pDM_Odm = &pHalData->odmpriv; 88 u8 index = 0; 89 90 if (pDM_Odm->PhyRegPgVersion == 0) { 91 switch (RegAddr) { 92 case rTxAGC_A_Rate18_06: 93 index = 0; 94 break; 95 case rTxAGC_A_Rate54_24: 96 index = 1; 97 break; 98 case rTxAGC_A_CCK1_Mcs32: 99 index = 6; 100 break; 101 case rTxAGC_B_CCK11_A_CCK2_11: 102 if (BitMask == bMaskH3Bytes) 103 index = 7; 104 else if (BitMask == 0x000000ff) 105 index = 15; 106 break; 107 108 case rTxAGC_A_Mcs03_Mcs00: 109 index = 2; 110 break; 111 case rTxAGC_A_Mcs07_Mcs04: 112 index = 3; 113 break; 114 case rTxAGC_B_Rate18_06: 115 index = 8; 116 break; 117 case rTxAGC_B_Rate54_24: 118 index = 9; 119 break; 120 case rTxAGC_B_CCK1_55_Mcs32: 121 index = 14; 122 break; 123 case rTxAGC_B_Mcs03_Mcs00: 124 index = 10; 125 break; 126 case rTxAGC_B_Mcs07_Mcs04: 127 index = 11; 128 break; 129 default: 130 break; 131 } 132 } 133 134 return index; 135} 136 137void 138PHY_GetRateValuesOfTxPowerByRate( 139 struct adapter *padapter, 140 u32 RegAddr, 141 u32 BitMask, 142 u32 Value, 143 u8 *RateIndex, 144 s8 *PwrByRateVal, 145 u8 *RateNum 146) 147{ 148 u8 i = 0; 149 150 switch (RegAddr) { 151 case rTxAGC_A_Rate18_06: 152 case rTxAGC_B_Rate18_06: 153 RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_6M); 154 RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_9M); 155 RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_12M); 156 RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_18M); 157 for (i = 0; i < 4; ++i) { 158 PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 + 159 ((Value >> (i * 8)) & 0xF)); 160 } 161 *RateNum = 4; 162 break; 163 164 case rTxAGC_A_Rate54_24: 165 case rTxAGC_B_Rate54_24: 166 RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_24M); 167 RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_36M); 168 RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_48M); 169 RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_54M); 170 for (i = 0; i < 4; ++i) { 171 PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 + 172 ((Value >> (i * 8)) & 0xF)); 173 } 174 *RateNum = 4; 175 break; 176 177 case rTxAGC_A_CCK1_Mcs32: 178 RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_1M); 179 PwrByRateVal[0] = (s8) ((((Value >> (8 + 4)) & 0xF)) * 10 + 180 ((Value >> 8) & 0xF)); 181 *RateNum = 1; 182 break; 183 184 case rTxAGC_B_CCK11_A_CCK2_11: 185 if (BitMask == 0xffffff00) { 186 RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_2M); 187 RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_5_5M); 188 RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_11M); 189 for (i = 1; i < 4; ++i) { 190 PwrByRateVal[i - 1] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 + 191 ((Value >> (i * 8)) & 0xF)); 192 } 193 *RateNum = 3; 194 } else if (BitMask == 0x000000ff) { 195 RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_11M); 196 PwrByRateVal[0] = (s8) ((((Value >> 4) & 0xF)) * 10 + (Value & 0xF)); 197 *RateNum = 1; 198 } 199 break; 200 201 case rTxAGC_A_Mcs03_Mcs00: 202 case rTxAGC_B_Mcs03_Mcs00: 203 RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS0); 204 RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS1); 205 RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS2); 206 RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS3); 207 for (i = 0; i < 4; ++i) { 208 PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 + 209 ((Value >> (i * 8)) & 0xF)); 210 } 211 *RateNum = 4; 212 break; 213 214 case rTxAGC_A_Mcs07_Mcs04: 215 case rTxAGC_B_Mcs07_Mcs04: 216 RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS4); 217 RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS5); 218 RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS6); 219 RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS7); 220 for (i = 0; i < 4; ++i) { 221 PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 + 222 ((Value >> (i * 8)) & 0xF)); 223 } 224 *RateNum = 4; 225 break; 226 227 case rTxAGC_B_CCK1_55_Mcs32: 228 RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_1M); 229 RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_2M); 230 RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_5_5M); 231 for (i = 1; i < 4; ++i) { 232 PwrByRateVal[i - 1] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 + 233 ((Value >> (i * 8)) & 0xF)); 234 } 235 *RateNum = 3; 236 break; 237 238 case 0xC20: 239 case 0xE20: 240 case 0x1820: 241 case 0x1a20: 242 RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_1M); 243 RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_2M); 244 RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_5_5M); 245 RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_11M); 246 for (i = 0; i < 4; ++i) { 247 PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 + 248 ((Value >> (i * 8)) & 0xF)); 249 } 250 *RateNum = 4; 251 break; 252 253 case 0xC24: 254 case 0xE24: 255 case 0x1824: 256 case 0x1a24: 257 RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_6M); 258 RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_9M); 259 RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_12M); 260 RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_18M); 261 for (i = 0; i < 4; ++i) { 262 PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 + 263 ((Value >> (i * 8)) & 0xF)); 264 } 265 *RateNum = 4; 266 break; 267 268 case 0xC28: 269 case 0xE28: 270 case 0x1828: 271 case 0x1a28: 272 RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_24M); 273 RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_36M); 274 RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_48M); 275 RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_54M); 276 for (i = 0; i < 4; ++i) { 277 PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 + 278 ((Value >> (i * 8)) & 0xF)); 279 } 280 *RateNum = 4; 281 break; 282 283 case 0xC2C: 284 case 0xE2C: 285 case 0x182C: 286 case 0x1a2C: 287 RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS0); 288 RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS1); 289 RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS2); 290 RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS3); 291 for (i = 0; i < 4; ++i) { 292 PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 + 293 ((Value >> (i * 8)) & 0xF)); 294 } 295 *RateNum = 4; 296 break; 297 298 case 0xC30: 299 case 0xE30: 300 case 0x1830: 301 case 0x1a30: 302 RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS4); 303 RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS5); 304 RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS6); 305 RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS7); 306 for (i = 0; i < 4; ++i) { 307 PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 + 308 ((Value >> (i * 8)) & 0xF)); 309 } 310 *RateNum = 4; 311 break; 312 313 default: 314 break; 315 } 316} 317 318static void PHY_StoreTxPowerByRateNew(struct adapter *padapter, u32 RfPath, 319 u32 RegAddr, u32 BitMask, u32 Data) 320{ 321 struct hal_com_data *pHalData = GET_HAL_DATA(padapter); 322 u8 i = 0, rateIndex[4] = {0}, rateNum = 0; 323 s8 PwrByRateVal[4] = {0}; 324 325 PHY_GetRateValuesOfTxPowerByRate(padapter, RegAddr, BitMask, Data, rateIndex, PwrByRateVal, &rateNum); 326 327 if (RfPath >= RF_PATH_MAX) 328 return; 329 330 for (i = 0; i < rateNum; ++i) { 331 pHalData->TxPwrByRateOffset[RfPath][rateIndex[i]] = PwrByRateVal[i]; 332 } 333} 334 335static void PHY_StoreTxPowerByRateOld( 336 struct adapter *padapter, u32 RegAddr, u32 BitMask, u32 Data 337) 338{ 339 struct hal_com_data *pHalData = GET_HAL_DATA(padapter); 340 u8 index = PHY_GetRateSectionIndexOfTxPowerByRate(padapter, RegAddr, BitMask); 341 342 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][index] = Data; 343} 344 345void PHY_InitTxPowerByRate(struct adapter *padapter) 346{ 347 struct hal_com_data *pHalData = GET_HAL_DATA(padapter); 348 u8 rfPath, rate; 349 350 for (rfPath = RF_PATH_A; rfPath < MAX_RF_PATH_NUM; ++rfPath) 351 for (rate = 0; rate < TX_PWR_BY_RATE_NUM_RATE; ++rate) 352 pHalData->TxPwrByRateOffset[rfPath][rate] = 0; 353} 354 355void PHY_StoreTxPowerByRate( 356 struct adapter *padapter, 357 u32 RfPath, 358 u32 RegAddr, 359 u32 BitMask, 360 u32 Data 361) 362{ 363 struct hal_com_data *pHalData = GET_HAL_DATA(padapter); 364 struct dm_odm_t *pDM_Odm = &pHalData->odmpriv; 365 366 if (pDM_Odm->PhyRegPgVersion > 0) 367 PHY_StoreTxPowerByRateNew(padapter, RfPath, RegAddr, BitMask, Data); 368 else if (pDM_Odm->PhyRegPgVersion == 0) { 369 PHY_StoreTxPowerByRateOld(padapter, RegAddr, BitMask, Data); 370 } 371} 372 373static void 374phy_ConvertTxPowerByRateInDbmToRelativeValues( 375struct adapter *padapter 376 ) 377{ 378 u8 base = 0, i = 0, value = 0, path = 0; 379 u8 cckRates[4] = { 380 MGN_1M, MGN_2M, MGN_5_5M, MGN_11M 381 }; 382 u8 ofdmRates[8] = { 383 MGN_6M, MGN_9M, MGN_12M, MGN_18M, MGN_24M, MGN_36M, MGN_48M, MGN_54M 384 }; 385 u8 mcs0_7Rates[8] = { 386 MGN_MCS0, MGN_MCS1, MGN_MCS2, MGN_MCS3, MGN_MCS4, MGN_MCS5, MGN_MCS6, MGN_MCS7 387 }; 388 for (path = RF_PATH_A; path < RF_PATH_MAX; ++path) { 389 /* CCK */ 390 base = PHY_GetTxPowerByRate(padapter, path, MGN_11M); 391 for (i = 0; i < ARRAY_SIZE(cckRates); ++i) { 392 value = PHY_GetTxPowerByRate(padapter, path, cckRates[i]); 393 PHY_SetTxPowerByRate(padapter, path, cckRates[i], value - base); 394 } 395 396 /* OFDM */ 397 base = PHY_GetTxPowerByRate(padapter, path, MGN_54M); 398 for (i = 0; i < sizeof(ofdmRates); ++i) { 399 value = PHY_GetTxPowerByRate(padapter, path, ofdmRates[i]); 400 PHY_SetTxPowerByRate(padapter, path, ofdmRates[i], value - base); 401 } 402 403 /* HT MCS0~7 */ 404 base = PHY_GetTxPowerByRate(padapter, path, MGN_MCS7); 405 for (i = 0; i < sizeof(mcs0_7Rates); ++i) { 406 value = PHY_GetTxPowerByRate(padapter, path, mcs0_7Rates[i]); 407 PHY_SetTxPowerByRate(padapter, path, mcs0_7Rates[i], value - base); 408 } 409 } 410} 411 412/* 413 * This function must be called if the value in the PHY_REG_PG.txt(or header) 414 * is exact dBm values 415 */ 416void PHY_TxPowerByRateConfiguration(struct adapter *padapter) 417{ 418 phy_StoreTxPowerByRateBase(padapter); 419 phy_ConvertTxPowerByRateInDbmToRelativeValues(padapter); 420} 421 422void PHY_SetTxPowerIndexByRateSection( 423 struct adapter *padapter, u8 RFPath, u8 Channel, u8 RateSection 424) 425{ 426 struct hal_com_data *pHalData = GET_HAL_DATA(padapter); 427 428 if (RateSection == CCK) { 429 u8 cckRates[] = {MGN_1M, MGN_2M, MGN_5_5M, MGN_11M}; 430 PHY_SetTxPowerIndexByRateArray(padapter, RFPath, 431 pHalData->CurrentChannelBW, 432 Channel, cckRates, 433 ARRAY_SIZE(cckRates)); 434 435 } else if (RateSection == OFDM) { 436 u8 ofdmRates[] = {MGN_6M, MGN_9M, MGN_12M, MGN_18M, MGN_24M, MGN_36M, MGN_48M, MGN_54M}; 437 PHY_SetTxPowerIndexByRateArray(padapter, RFPath, 438 pHalData->CurrentChannelBW, 439 Channel, ofdmRates, 440 ARRAY_SIZE(ofdmRates)); 441 442 } else if (RateSection == HT_MCS0_MCS7) { 443 u8 htRates1T[] = {MGN_MCS0, MGN_MCS1, MGN_MCS2, MGN_MCS3, MGN_MCS4, MGN_MCS5, MGN_MCS6, MGN_MCS7}; 444 PHY_SetTxPowerIndexByRateArray(padapter, RFPath, 445 pHalData->CurrentChannelBW, 446 Channel, htRates1T, 447 ARRAY_SIZE(htRates1T)); 448 449 } 450} 451 452u8 PHY_GetTxPowerIndexBase( 453 struct adapter *padapter, 454 u8 RFPath, 455 u8 Rate, 456 enum channel_width BandWidth, 457 u8 Channel 458) 459{ 460 struct hal_com_data *pHalData = GET_HAL_DATA(padapter); 461 u8 txPower = 0; 462 u8 chnlIdx = (Channel-1); 463 464 if (HAL_IsLegalChannel(padapter, Channel) == false) 465 chnlIdx = 0; 466 467 if (IS_CCK_RATE(Rate)) 468 txPower = pHalData->Index24G_CCK_Base[RFPath][chnlIdx]; 469 else if (MGN_6M <= Rate) 470 txPower = pHalData->Index24G_BW40_Base[RFPath][chnlIdx]; 471 472 /* OFDM-1T */ 473 if ((MGN_6M <= Rate && Rate <= MGN_54M) && !IS_CCK_RATE(Rate)) 474 txPower += pHalData->OFDM_24G_Diff[RFPath][TX_1S]; 475 476 if (BandWidth == CHANNEL_WIDTH_20) { /* BW20-1S, BW20-2S */ 477 if (MGN_MCS0 <= Rate && Rate <= MGN_MCS7) 478 txPower += pHalData->BW20_24G_Diff[RFPath][TX_1S]; 479 } else if (BandWidth == CHANNEL_WIDTH_40) { /* BW40-1S, BW40-2S */ 480 if (MGN_MCS0 <= Rate && Rate <= MGN_MCS7) 481 txPower += pHalData->BW40_24G_Diff[RFPath][TX_1S]; 482 } 483 484 return txPower; 485} 486 487s8 PHY_GetTxPowerTrackingOffset(struct adapter *padapter, u8 RFPath, u8 Rate) 488{ 489 struct hal_com_data *pHalData = GET_HAL_DATA(padapter); 490 struct dm_odm_t *pDM_Odm = &pHalData->odmpriv; 491 s8 offset = 0; 492 493 if (pDM_Odm->RFCalibrateInfo.TxPowerTrackControl == false) 494 return offset; 495 496 if ((Rate == MGN_1M) || (Rate == MGN_2M) || (Rate == MGN_5_5M) || (Rate == MGN_11M)) 497 offset = pDM_Odm->Remnant_CCKSwingIdx; 498 else 499 offset = pDM_Odm->Remnant_OFDMSwingIdx[RFPath]; 500 501 return offset; 502} 503 504u8 PHY_GetRateIndexOfTxPowerByRate(u8 Rate) 505{ 506 u8 index = 0; 507 switch (Rate) { 508 case MGN_1M: 509 index = 0; 510 break; 511 case MGN_2M: 512 index = 1; 513 break; 514 case MGN_5_5M: 515 index = 2; 516 break; 517 case MGN_11M: 518 index = 3; 519 break; 520 case MGN_6M: 521 index = 4; 522 break; 523 case MGN_9M: 524 index = 5; 525 break; 526 case MGN_12M: 527 index = 6; 528 break; 529 case MGN_18M: 530 index = 7; 531 break; 532 case MGN_24M: 533 index = 8; 534 break; 535 case MGN_36M: 536 index = 9; 537 break; 538 case MGN_48M: 539 index = 10; 540 break; 541 case MGN_54M: 542 index = 11; 543 break; 544 case MGN_MCS0: 545 index = 12; 546 break; 547 case MGN_MCS1: 548 index = 13; 549 break; 550 case MGN_MCS2: 551 index = 14; 552 break; 553 case MGN_MCS3: 554 index = 15; 555 break; 556 case MGN_MCS4: 557 index = 16; 558 break; 559 case MGN_MCS5: 560 index = 17; 561 break; 562 case MGN_MCS6: 563 index = 18; 564 break; 565 case MGN_MCS7: 566 index = 19; 567 break; 568 default: 569 break; 570 } 571 return index; 572} 573 574s8 PHY_GetTxPowerByRate(struct adapter *padapter, u8 RFPath, u8 Rate) 575{ 576 struct hal_com_data *pHalData = GET_HAL_DATA(padapter); 577 s8 value = 0; 578 u8 rateIndex = PHY_GetRateIndexOfTxPowerByRate(Rate); 579 580 if ((padapter->registrypriv.RegEnableTxPowerByRate == 2 && pHalData->EEPROMRegulatory == 2) || 581 padapter->registrypriv.RegEnableTxPowerByRate == 0) 582 return 0; 583 584 if (RFPath >= RF_PATH_MAX) 585 return value; 586 587 if (rateIndex >= TX_PWR_BY_RATE_NUM_RATE) 588 return value; 589 590 return pHalData->TxPwrByRateOffset[RFPath][rateIndex]; 591 592} 593 594void PHY_SetTxPowerByRate( 595 struct adapter *padapter, 596 u8 RFPath, 597 u8 Rate, 598 s8 Value 599) 600{ 601 struct hal_com_data *pHalData = GET_HAL_DATA(padapter); 602 u8 rateIndex = PHY_GetRateIndexOfTxPowerByRate(Rate); 603 604 if (RFPath >= RF_PATH_MAX) 605 return; 606 607 if (rateIndex >= TX_PWR_BY_RATE_NUM_RATE) 608 return; 609 610 pHalData->TxPwrByRateOffset[RFPath][rateIndex] = Value; 611} 612 613void PHY_SetTxPowerLevelByPath(struct adapter *Adapter, u8 channel, u8 path) 614{ 615 PHY_SetTxPowerIndexByRateSection(Adapter, path, channel, CCK); 616 617 PHY_SetTxPowerIndexByRateSection(Adapter, path, channel, OFDM); 618 PHY_SetTxPowerIndexByRateSection(Adapter, path, channel, HT_MCS0_MCS7); 619} 620 621void PHY_SetTxPowerIndexByRateArray( 622 struct adapter *padapter, 623 u8 RFPath, 624 enum channel_width BandWidth, 625 u8 Channel, 626 u8 *Rates, 627 u8 RateArraySize 628) 629{ 630 u32 powerIndex = 0; 631 int i = 0; 632 633 for (i = 0; i < RateArraySize; ++i) { 634 powerIndex = PHY_GetTxPowerIndex(padapter, RFPath, Rates[i], BandWidth, Channel); 635 PHY_SetTxPowerIndex(padapter, powerIndex, RFPath, Rates[i]); 636 } 637} 638 639static s8 phy_GetWorldWideLimit(s8 *LimitTable) 640{ 641 s8 min = LimitTable[0]; 642 u8 i = 0; 643 644 for (i = 0; i < MAX_REGULATION_NUM; ++i) { 645 if (LimitTable[i] < min) 646 min = LimitTable[i]; 647 } 648 649 return min; 650} 651 652static s8 phy_GetChannelIndexOfTxPowerLimit(u8 Channel) 653{ 654 return Channel - 1; 655} 656 657static s16 get_bandwidth_idx(const enum channel_width bandwidth) 658{ 659 switch (bandwidth) { 660 case CHANNEL_WIDTH_20: 661 return 0; 662 case CHANNEL_WIDTH_40: 663 return 1; 664 default: 665 return -1; 666 } 667} 668 669static s16 get_rate_sctn_idx(const u8 rate) 670{ 671 switch (rate) { 672 case MGN_1M: case MGN_2M: case MGN_5_5M: case MGN_11M: 673 return 0; 674 case MGN_6M: case MGN_9M: case MGN_12M: case MGN_18M: 675 case MGN_24M: case MGN_36M: case MGN_48M: case MGN_54M: 676 return 1; 677 case MGN_MCS0: case MGN_MCS1: case MGN_MCS2: case MGN_MCS3: 678 case MGN_MCS4: case MGN_MCS5: case MGN_MCS6: case MGN_MCS7: 679 return 2; 680 default: 681 return -1; 682 } 683} 684 685s8 phy_get_tx_pwr_lmt(struct adapter *adapter, u32 reg_pwr_tbl_sel, 686 enum channel_width bandwidth, 687 u8 rf_path, u8 data_rate, u8 channel) 688{ 689 s16 idx_regulation = -1; 690 s16 idx_bandwidth = -1; 691 s16 idx_rate_sctn = -1; 692 s16 idx_channel = -1; 693 s8 pwr_lmt = MAX_POWER_INDEX; 694 struct hal_com_data *hal_data = GET_HAL_DATA(adapter); 695 s8 limits[10] = {0}; u8 i = 0; 696 697 if (((adapter->registrypriv.RegEnableTxPowerLimit == 2) && 698 (hal_data->EEPROMRegulatory != 1)) || 699 (adapter->registrypriv.RegEnableTxPowerLimit == 0)) 700 return MAX_POWER_INDEX; 701 702 switch (adapter->registrypriv.RegPwrTblSel) { 703 case 1: 704 idx_regulation = TXPWR_LMT_ETSI; 705 break; 706 case 2: 707 idx_regulation = TXPWR_LMT_MKK; 708 break; 709 case 3: 710 idx_regulation = TXPWR_LMT_FCC; 711 break; 712 case 4: 713 idx_regulation = TXPWR_LMT_WW; 714 break; 715 default: 716 idx_regulation = hal_data->Regulation2_4G; 717 break; 718 } 719 720 idx_bandwidth = get_bandwidth_idx(bandwidth); 721 idx_rate_sctn = get_rate_sctn_idx(data_rate); 722 723 /* workaround for wrong index combination to obtain tx power limit, */ 724 /* OFDM only exists in BW 20M */ 725 /* CCK table will only be given in BW 20M */ 726 /* HT on 80M will reference to HT on 40M */ 727 if (idx_rate_sctn == 0 || idx_rate_sctn == 1) 728 idx_bandwidth = 0; 729 730 channel = phy_GetChannelIndexOfTxPowerLimit(channel); 731 732 if (idx_regulation == -1 || idx_bandwidth == -1 || 733 idx_rate_sctn == -1 || idx_channel == -1) 734 return MAX_POWER_INDEX; 735 736 737 for (i = 0; i < MAX_REGULATION_NUM; i++) 738 limits[i] = hal_data->TxPwrLimit_2_4G[i] 739 [idx_bandwidth] 740 [idx_rate_sctn] 741 [idx_channel] 742 [rf_path]; 743 744 pwr_lmt = (idx_regulation == TXPWR_LMT_WW) ? 745 phy_GetWorldWideLimit(limits) : 746 hal_data->TxPwrLimit_2_4G[idx_regulation] 747 [idx_bandwidth] 748 [idx_rate_sctn] 749 [idx_channel] 750 [rf_path]; 751 752 return pwr_lmt; 753} 754 755void PHY_ConvertTxPowerLimitToPowerIndex(struct adapter *Adapter) 756{ 757 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter); 758 u8 BW40PwrBasedBm2_4G = 0x2E; 759 u8 regulation, bw, channel, rateSection; 760 s8 tempValue = 0, tempPwrLmt = 0; 761 u8 rfPath = 0; 762 763 for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) { 764 for (bw = 0; bw < MAX_2_4G_BANDWIDTH_NUM; ++bw) { 765 for (channel = 0; channel < CHANNEL_MAX_NUMBER_2G; ++channel) { 766 for (rateSection = 0; rateSection < MAX_RATE_SECTION_NUM; ++rateSection) { 767 tempPwrLmt = pHalData->TxPwrLimit_2_4G[regulation][bw][rateSection][channel][RF_PATH_A]; 768 769 for (rfPath = RF_PATH_A; rfPath < MAX_RF_PATH_NUM; ++rfPath) { 770 if (pHalData->odmpriv.PhyRegPgValueType == PHY_REG_PG_EXACT_VALUE) { 771 if (rateSection == 2) /* HT 1T */ 772 BW40PwrBasedBm2_4G = PHY_GetTxPowerByRateBase(Adapter, rfPath, HT_MCS0_MCS7); 773 else if (rateSection == 1) /* OFDM */ 774 BW40PwrBasedBm2_4G = PHY_GetTxPowerByRateBase(Adapter, rfPath, OFDM); 775 else if (rateSection == 0) /* CCK */ 776 BW40PwrBasedBm2_4G = PHY_GetTxPowerByRateBase(Adapter, rfPath, CCK); 777 } else 778 BW40PwrBasedBm2_4G = Adapter->registrypriv.RegPowerBase * 2; 779 780 if (tempPwrLmt != MAX_POWER_INDEX) { 781 tempValue = tempPwrLmt - BW40PwrBasedBm2_4G; 782 pHalData->TxPwrLimit_2_4G[regulation][bw][rateSection][channel][rfPath] = tempValue; 783 } 784 } 785 } 786 } 787 } 788 } 789} 790 791void PHY_InitTxPowerLimit(struct adapter *Adapter) 792{ 793 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter); 794 u8 i, j, k, l, m; 795 796 for (i = 0; i < MAX_REGULATION_NUM; ++i) { 797 for (j = 0; j < MAX_2_4G_BANDWIDTH_NUM; ++j) 798 for (k = 0; k < MAX_RATE_SECTION_NUM; ++k) 799 for (m = 0; m < CHANNEL_MAX_NUMBER_2G; ++m) 800 for (l = 0; l < MAX_RF_PATH_NUM; ++l) 801 pHalData->TxPwrLimit_2_4G[i][j][k][m][l] = MAX_POWER_INDEX; 802 } 803} 804 805void PHY_SetTxPowerLimit( 806 struct adapter *Adapter, 807 u8 *Regulation, 808 u8 *Bandwidth, 809 u8 *RateSection, 810 u8 *RfPath, 811 u8 *Channel, 812 u8 *PowerLimit 813) 814{ 815 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter); 816 u8 regulation = 0, bandwidth = 0, rateSection = 0, channel; 817 s8 powerLimit = 0, prevPowerLimit, channelIndex; 818 819 GetU1ByteIntegerFromStringInDecimal((s8 *)Channel, &channel); 820 GetU1ByteIntegerFromStringInDecimal((s8 *)PowerLimit, &powerLimit); 821 822 powerLimit = powerLimit > MAX_POWER_INDEX ? MAX_POWER_INDEX : powerLimit; 823 824 if (eqNByte(Regulation, (u8 *)("FCC"), 3)) 825 regulation = 0; 826 else if (eqNByte(Regulation, (u8 *)("MKK"), 3)) 827 regulation = 1; 828 else if (eqNByte(Regulation, (u8 *)("ETSI"), 4)) 829 regulation = 2; 830 else if (eqNByte(Regulation, (u8 *)("WW13"), 4)) 831 regulation = 3; 832 833 if (eqNByte(RateSection, (u8 *)("CCK"), 3) && eqNByte(RfPath, (u8 *)("1T"), 2)) 834 rateSection = 0; 835 else if (eqNByte(RateSection, (u8 *)("OFDM"), 4) && eqNByte(RfPath, (u8 *)("1T"), 2)) 836 rateSection = 1; 837 else if (eqNByte(RateSection, (u8 *)("HT"), 2) && eqNByte(RfPath, (u8 *)("1T"), 2)) 838 rateSection = 2; 839 else 840 return; 841 842 if (eqNByte(Bandwidth, (u8 *)("20M"), 3)) 843 bandwidth = 0; 844 else if (eqNByte(Bandwidth, (u8 *)("40M"), 3)) 845 bandwidth = 1; 846 847 channelIndex = phy_GetChannelIndexOfTxPowerLimit(channel); 848 849 if (channelIndex == -1) 850 return; 851 852 prevPowerLimit = pHalData->TxPwrLimit_2_4G[regulation][bandwidth][rateSection][channelIndex][RF_PATH_A]; 853 854 if (powerLimit < prevPowerLimit) 855 pHalData->TxPwrLimit_2_4G[regulation][bandwidth][rateSection][channelIndex][RF_PATH_A] = powerLimit; 856} 857 858void Hal_ChannelPlanToRegulation(struct adapter *Adapter, u16 ChannelPlan) 859{ 860 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter); 861 pHalData->Regulation2_4G = TXPWR_LMT_WW; 862 863 switch (ChannelPlan) { 864 case RT_CHANNEL_DOMAIN_WORLD_NULL: 865 pHalData->Regulation2_4G = TXPWR_LMT_WW; 866 break; 867 case RT_CHANNEL_DOMAIN_ETSI1_NULL: 868 pHalData->Regulation2_4G = TXPWR_LMT_ETSI; 869 break; 870 case RT_CHANNEL_DOMAIN_FCC1_NULL: 871 pHalData->Regulation2_4G = TXPWR_LMT_FCC; 872 break; 873 case RT_CHANNEL_DOMAIN_MKK1_NULL: 874 pHalData->Regulation2_4G = TXPWR_LMT_MKK; 875 break; 876 case RT_CHANNEL_DOMAIN_ETSI2_NULL: 877 pHalData->Regulation2_4G = TXPWR_LMT_ETSI; 878 break; 879 case RT_CHANNEL_DOMAIN_FCC1_FCC1: 880 pHalData->Regulation2_4G = TXPWR_LMT_FCC; 881 break; 882 case RT_CHANNEL_DOMAIN_WORLD_ETSI1: 883 pHalData->Regulation2_4G = TXPWR_LMT_FCC; 884 break; 885 case RT_CHANNEL_DOMAIN_MKK1_MKK1: 886 pHalData->Regulation2_4G = TXPWR_LMT_MKK; 887 break; 888 case RT_CHANNEL_DOMAIN_WORLD_KCC1: 889 pHalData->Regulation2_4G = TXPWR_LMT_FCC; 890 break; 891 case RT_CHANNEL_DOMAIN_WORLD_FCC2: 892 pHalData->Regulation2_4G = TXPWR_LMT_FCC; 893 break; 894 case RT_CHANNEL_DOMAIN_WORLD_FCC3: 895 pHalData->Regulation2_4G = TXPWR_LMT_FCC; 896 break; 897 case RT_CHANNEL_DOMAIN_WORLD_FCC4: 898 pHalData->Regulation2_4G = TXPWR_LMT_FCC; 899 break; 900 case RT_CHANNEL_DOMAIN_WORLD_FCC5: 901 pHalData->Regulation2_4G = TXPWR_LMT_FCC; 902 break; 903 case RT_CHANNEL_DOMAIN_WORLD_FCC6: 904 pHalData->Regulation2_4G = TXPWR_LMT_FCC; 905 break; 906 case RT_CHANNEL_DOMAIN_FCC1_FCC7: 907 pHalData->Regulation2_4G = TXPWR_LMT_FCC; 908 break; 909 case RT_CHANNEL_DOMAIN_WORLD_ETSI2: 910 pHalData->Regulation2_4G = TXPWR_LMT_FCC; 911 break; 912 case RT_CHANNEL_DOMAIN_WORLD_ETSI3: 913 pHalData->Regulation2_4G = TXPWR_LMT_FCC; 914 break; 915 case RT_CHANNEL_DOMAIN_MKK1_MKK2: 916 pHalData->Regulation2_4G = TXPWR_LMT_MKK; 917 break; 918 case RT_CHANNEL_DOMAIN_MKK1_MKK3: 919 pHalData->Regulation2_4G = TXPWR_LMT_MKK; 920 break; 921 case RT_CHANNEL_DOMAIN_FCC1_NCC1: 922 pHalData->Regulation2_4G = TXPWR_LMT_FCC; 923 break; 924 case RT_CHANNEL_DOMAIN_FCC1_NCC2: 925 pHalData->Regulation2_4G = TXPWR_LMT_FCC; 926 break; 927 case RT_CHANNEL_DOMAIN_GLOBAL_NULL: 928 pHalData->Regulation2_4G = TXPWR_LMT_WW; 929 break; 930 case RT_CHANNEL_DOMAIN_ETSI1_ETSI4: 931 pHalData->Regulation2_4G = TXPWR_LMT_ETSI; 932 break; 933 case RT_CHANNEL_DOMAIN_FCC1_FCC2: 934 pHalData->Regulation2_4G = TXPWR_LMT_FCC; 935 break; 936 case RT_CHANNEL_DOMAIN_FCC1_NCC3: 937 pHalData->Regulation2_4G = TXPWR_LMT_FCC; 938 break; 939 case RT_CHANNEL_DOMAIN_WORLD_ETSI5: 940 pHalData->Regulation2_4G = TXPWR_LMT_ETSI; 941 break; 942 case RT_CHANNEL_DOMAIN_FCC1_FCC8: 943 pHalData->Regulation2_4G = TXPWR_LMT_FCC; 944 break; 945 case RT_CHANNEL_DOMAIN_WORLD_ETSI6: 946 pHalData->Regulation2_4G = TXPWR_LMT_ETSI; 947 break; 948 case RT_CHANNEL_DOMAIN_WORLD_ETSI7: 949 pHalData->Regulation2_4G = TXPWR_LMT_ETSI; 950 break; 951 case RT_CHANNEL_DOMAIN_WORLD_ETSI8: 952 pHalData->Regulation2_4G = TXPWR_LMT_ETSI; 953 break; 954 case RT_CHANNEL_DOMAIN_WORLD_ETSI9: 955 pHalData->Regulation2_4G = TXPWR_LMT_ETSI; 956 break; 957 case RT_CHANNEL_DOMAIN_WORLD_ETSI10: 958 pHalData->Regulation2_4G = TXPWR_LMT_ETSI; 959 break; 960 case RT_CHANNEL_DOMAIN_WORLD_ETSI11: 961 pHalData->Regulation2_4G = TXPWR_LMT_ETSI; 962 break; 963 case RT_CHANNEL_DOMAIN_FCC1_NCC4: 964 pHalData->Regulation2_4G = TXPWR_LMT_FCC; 965 break; 966 case RT_CHANNEL_DOMAIN_WORLD_ETSI12: 967 pHalData->Regulation2_4G = TXPWR_LMT_ETSI; 968 break; 969 case RT_CHANNEL_DOMAIN_FCC1_FCC9: 970 pHalData->Regulation2_4G = TXPWR_LMT_FCC; 971 break; 972 case RT_CHANNEL_DOMAIN_WORLD_ETSI13: 973 pHalData->Regulation2_4G = TXPWR_LMT_ETSI; 974 break; 975 case RT_CHANNEL_DOMAIN_FCC1_FCC10: 976 pHalData->Regulation2_4G = TXPWR_LMT_FCC; 977 break; 978 case RT_CHANNEL_DOMAIN_REALTEK_DEFINE: /* Realtek Reserve */ 979 pHalData->Regulation2_4G = TXPWR_LMT_WW; 980 break; 981 default: 982 break; 983 } 984} 985