linux/drivers/staging/rtl8723bs/hal/hal_com_phycfg.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/******************************************************************************
   3 *
   4 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
   5 *
   6 ******************************************************************************/
   7#define _HAL_COM_PHYCFG_C_
   8
   9#include <drv_types.h>
  10#include <rtw_debug.h>
  11#include <hal_data.h>
  12#include <linux/kernel.h>
  13
  14u8 PHY_GetTxPowerByRateBase(struct adapter *Adapter, u8 Band, u8 RfPath,
  15                            u8 TxNum, enum RATE_SECTION RateSection)
  16{
  17        struct hal_com_data     *pHalData = GET_HAL_DATA(Adapter);
  18        u8      value = 0;
  19
  20        if (RfPath > ODM_RF_PATH_D) {
  21                DBG_871X("Invalid Rf Path %d in PHY_GetTxPowerByRateBase()\n", RfPath);
  22                return 0;
  23        }
  24
  25        if (Band == BAND_ON_2_4G) {
  26                switch (RateSection) {
  27                case CCK:
  28                        value = pHalData->TxPwrByRateBase2_4G[RfPath][TxNum][0];
  29                        break;
  30                case OFDM:
  31                        value = pHalData->TxPwrByRateBase2_4G[RfPath][TxNum][1];
  32                        break;
  33                case HT_MCS0_MCS7:
  34                        value = pHalData->TxPwrByRateBase2_4G[RfPath][TxNum][2];
  35                        break;
  36                case HT_MCS8_MCS15:
  37                        value = pHalData->TxPwrByRateBase2_4G[RfPath][TxNum][3];
  38                        break;
  39                case HT_MCS16_MCS23:
  40                        value = pHalData->TxPwrByRateBase2_4G[RfPath][TxNum][4];
  41                        break;
  42                case HT_MCS24_MCS31:
  43                        value = pHalData->TxPwrByRateBase2_4G[RfPath][TxNum][5];
  44                        break;
  45                case VHT_1SSMCS0_1SSMCS9:
  46                        value = pHalData->TxPwrByRateBase2_4G[RfPath][TxNum][6];
  47                        break;
  48                case VHT_2SSMCS0_2SSMCS9:
  49                        value = pHalData->TxPwrByRateBase2_4G[RfPath][TxNum][7];
  50                        break;
  51                case VHT_3SSMCS0_3SSMCS9:
  52                        value = pHalData->TxPwrByRateBase2_4G[RfPath][TxNum][8];
  53                        break;
  54                case VHT_4SSMCS0_4SSMCS9:
  55                        value = pHalData->TxPwrByRateBase2_4G[RfPath][TxNum][9];
  56                        break;
  57                default:
  58                        DBG_871X("Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n",
  59                                         RateSection, RfPath, TxNum);
  60                        break;
  61                }
  62        } else if (Band == BAND_ON_5G) {
  63                switch (RateSection) {
  64                case OFDM:
  65                        value = pHalData->TxPwrByRateBase5G[RfPath][TxNum][0];
  66                        break;
  67                case HT_MCS0_MCS7:
  68                        value = pHalData->TxPwrByRateBase5G[RfPath][TxNum][1];
  69                        break;
  70                case HT_MCS8_MCS15:
  71                        value = pHalData->TxPwrByRateBase5G[RfPath][TxNum][2];
  72                        break;
  73                case HT_MCS16_MCS23:
  74                        value = pHalData->TxPwrByRateBase5G[RfPath][TxNum][3];
  75                        break;
  76                case HT_MCS24_MCS31:
  77                        value = pHalData->TxPwrByRateBase5G[RfPath][TxNum][4];
  78                        break;
  79                case VHT_1SSMCS0_1SSMCS9:
  80                        value = pHalData->TxPwrByRateBase5G[RfPath][TxNum][5];
  81                        break;
  82                case VHT_2SSMCS0_2SSMCS9:
  83                        value = pHalData->TxPwrByRateBase5G[RfPath][TxNum][6];
  84                        break;
  85                case VHT_3SSMCS0_3SSMCS9:
  86                        value = pHalData->TxPwrByRateBase5G[RfPath][TxNum][7];
  87                        break;
  88                case VHT_4SSMCS0_4SSMCS9:
  89                        value = pHalData->TxPwrByRateBase5G[RfPath][TxNum][8];
  90                        break;
  91                default:
  92                        DBG_871X("Invalid RateSection %d in Band 5G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n",
  93                                         RateSection, RfPath, TxNum);
  94                        break;
  95                }
  96        } else
  97                DBG_871X("Invalid Band %d in PHY_GetTxPowerByRateBase()\n", Band);
  98
  99        return value;
 100}
 101
 102static void
 103phy_SetTxPowerByRateBase(
 104        struct adapter *Adapter,
 105        u8 Band,
 106        u8 RfPath,
 107        enum RATE_SECTION       RateSection,
 108        u8 TxNum,
 109        u8 Value
 110)
 111{
 112        struct hal_com_data     *pHalData = GET_HAL_DATA(Adapter);
 113
 114        if (RfPath > ODM_RF_PATH_D) {
 115                DBG_871X("Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n", RfPath);
 116                return;
 117        }
 118
 119        if (Band == BAND_ON_2_4G) {
 120                switch (RateSection) {
 121                case CCK:
 122                        pHalData->TxPwrByRateBase2_4G[RfPath][TxNum][0] = Value;
 123                        break;
 124                case OFDM:
 125                        pHalData->TxPwrByRateBase2_4G[RfPath][TxNum][1] = Value;
 126                        break;
 127                case HT_MCS0_MCS7:
 128                        pHalData->TxPwrByRateBase2_4G[RfPath][TxNum][2] = Value;
 129                        break;
 130                case HT_MCS8_MCS15:
 131                        pHalData->TxPwrByRateBase2_4G[RfPath][TxNum][3] = Value;
 132                        break;
 133                case HT_MCS16_MCS23:
 134                        pHalData->TxPwrByRateBase2_4G[RfPath][TxNum][4] = Value;
 135                        break;
 136                case HT_MCS24_MCS31:
 137                        pHalData->TxPwrByRateBase2_4G[RfPath][TxNum][5] = Value;
 138                        break;
 139                case VHT_1SSMCS0_1SSMCS9:
 140                        pHalData->TxPwrByRateBase2_4G[RfPath][TxNum][6] = Value;
 141                        break;
 142                case VHT_2SSMCS0_2SSMCS9:
 143                        pHalData->TxPwrByRateBase2_4G[RfPath][TxNum][7] = Value;
 144                        break;
 145                case VHT_3SSMCS0_3SSMCS9:
 146                        pHalData->TxPwrByRateBase2_4G[RfPath][TxNum][8] = Value;
 147                        break;
 148                case VHT_4SSMCS0_4SSMCS9:
 149                        pHalData->TxPwrByRateBase2_4G[RfPath][TxNum][9] = Value;
 150                        break;
 151                default:
 152                        DBG_871X("Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in phy_SetTxPowerByRateBase()\n",
 153                                         RateSection, RfPath, TxNum);
 154                        break;
 155                }
 156        } else if (Band == BAND_ON_5G) {
 157                switch (RateSection) {
 158                case OFDM:
 159                        pHalData->TxPwrByRateBase5G[RfPath][TxNum][0] = Value;
 160                        break;
 161                case HT_MCS0_MCS7:
 162                        pHalData->TxPwrByRateBase5G[RfPath][TxNum][1] = Value;
 163                        break;
 164                case HT_MCS8_MCS15:
 165                        pHalData->TxPwrByRateBase5G[RfPath][TxNum][2] = Value;
 166                        break;
 167                case HT_MCS16_MCS23:
 168                        pHalData->TxPwrByRateBase5G[RfPath][TxNum][3] = Value;
 169                        break;
 170                case HT_MCS24_MCS31:
 171                        pHalData->TxPwrByRateBase5G[RfPath][TxNum][4] = Value;
 172                        break;
 173                case VHT_1SSMCS0_1SSMCS9:
 174                        pHalData->TxPwrByRateBase5G[RfPath][TxNum][5] = Value;
 175                        break;
 176                case VHT_2SSMCS0_2SSMCS9:
 177                        pHalData->TxPwrByRateBase5G[RfPath][TxNum][6] = Value;
 178                        break;
 179                case VHT_3SSMCS0_3SSMCS9:
 180                        pHalData->TxPwrByRateBase5G[RfPath][TxNum][7] = Value;
 181                        break;
 182                case VHT_4SSMCS0_4SSMCS9:
 183                        pHalData->TxPwrByRateBase5G[RfPath][TxNum][8] = Value;
 184                        break;
 185                default:
 186                        DBG_871X("Invalid RateSection %d in Band 5G, Rf Path %d, %dTx in phy_SetTxPowerByRateBase()\n",
 187                                         RateSection, RfPath, TxNum);
 188                        break;
 189                }
 190        } else
 191                DBG_871X("Invalid Band %d in phy_SetTxPowerByRateBase()\n", Band);
 192}
 193
 194static void
 195phy_StoreTxPowerByRateBase(
 196struct adapter *padapter
 197        )
 198{
 199        u8 path, base;
 200
 201        /* DBG_871X("===>%s\n", __func__); */
 202
 203        for (path = ODM_RF_PATH_A; path <= ODM_RF_PATH_B; ++path) {
 204                base = PHY_GetTxPowerByRate(padapter, BAND_ON_2_4G, path, RF_1TX, MGN_11M);
 205                phy_SetTxPowerByRateBase(padapter, BAND_ON_2_4G, path, CCK, RF_1TX, base);
 206                /* DBG_871X("Power index base of 2.4G path %d 1Tx CCK = > 0x%x\n", path, base); */
 207
 208                base = PHY_GetTxPowerByRate(padapter, BAND_ON_2_4G, path, RF_1TX, MGN_54M);
 209                phy_SetTxPowerByRateBase(padapter, BAND_ON_2_4G, path, OFDM, RF_1TX, base);
 210                /* DBG_871X("Power index base of 2.4G path %d 1Tx OFDM = > 0x%x\n", path, base); */
 211
 212                base = PHY_GetTxPowerByRate(padapter, BAND_ON_2_4G, path, RF_1TX, MGN_MCS7);
 213                phy_SetTxPowerByRateBase(padapter, BAND_ON_2_4G, path, HT_MCS0_MCS7, RF_1TX, base);
 214                /* DBG_871X("Power index base of 2.4G path %d 1Tx MCS0-7 = > 0x%x\n", path, base); */
 215
 216                base = PHY_GetTxPowerByRate(padapter, BAND_ON_2_4G, path, RF_2TX, MGN_MCS15);
 217                phy_SetTxPowerByRateBase(padapter, BAND_ON_2_4G, path, HT_MCS8_MCS15, RF_2TX, base);
 218                /* DBG_871X("Power index base of 2.4G path %d 2Tx MCS8-15 = > 0x%x\n", path, base); */
 219
 220                base = PHY_GetTxPowerByRate(padapter, BAND_ON_2_4G, path, RF_3TX, MGN_MCS23);
 221                phy_SetTxPowerByRateBase(padapter, BAND_ON_2_4G, path, HT_MCS16_MCS23, RF_3TX, base);
 222                /* DBG_871X("Power index base of 2.4G path %d 3Tx MCS16-23 = > 0x%x\n", path, base); */
 223
 224                base = PHY_GetTxPowerByRate(padapter, BAND_ON_2_4G, path, RF_1TX, MGN_VHT1SS_MCS7);
 225                phy_SetTxPowerByRateBase(padapter, BAND_ON_2_4G, path, VHT_1SSMCS0_1SSMCS9, RF_1TX, base);
 226                /* DBG_871X("Power index base of 2.4G path %d 1Tx VHT1SS = > 0x%x\n", path, base); */
 227
 228                base = PHY_GetTxPowerByRate(padapter, BAND_ON_2_4G, path, RF_2TX, MGN_VHT2SS_MCS7);
 229                phy_SetTxPowerByRateBase(padapter, BAND_ON_2_4G, path, VHT_2SSMCS0_2SSMCS9, RF_2TX, base);
 230                /* DBG_871X("Power index base of 2.4G path %d 2Tx VHT2SS = > 0x%x\n", path, base); */
 231
 232                base = PHY_GetTxPowerByRate(padapter, BAND_ON_2_4G, path, RF_3TX, MGN_VHT3SS_MCS7);
 233                phy_SetTxPowerByRateBase(padapter, BAND_ON_2_4G, path, VHT_3SSMCS0_3SSMCS9, RF_3TX, base);
 234                /* DBG_871X("Power index base of 2.4G path %d 3Tx VHT3SS = > 0x%x\n", path, base); */
 235
 236                base = PHY_GetTxPowerByRate(padapter, BAND_ON_5G, path, RF_1TX, MGN_54M);
 237                phy_SetTxPowerByRateBase(padapter, BAND_ON_5G, path, OFDM, RF_1TX, base);
 238                /* DBG_871X("Power index base of 5G path %d 1Tx OFDM = > 0x%x\n", path, base); */
 239
 240                base = PHY_GetTxPowerByRate(padapter, BAND_ON_5G, path, RF_1TX, MGN_MCS7);
 241                phy_SetTxPowerByRateBase(padapter, BAND_ON_5G, path, HT_MCS0_MCS7, RF_1TX, base);
 242                /* DBG_871X("Power index base of 5G path %d 1Tx MCS0~7 = > 0x%x\n", path, base); */
 243
 244                base = PHY_GetTxPowerByRate(padapter, BAND_ON_5G, path, RF_2TX, MGN_MCS15);
 245                phy_SetTxPowerByRateBase(padapter, BAND_ON_5G, path, HT_MCS8_MCS15, RF_2TX, base);
 246                /* DBG_871X("Power index base of 5G path %d 2Tx MCS8~15 = > 0x%x\n", path, base); */
 247
 248                base = PHY_GetTxPowerByRate(padapter, BAND_ON_5G, path, RF_3TX, MGN_MCS23);
 249                phy_SetTxPowerByRateBase(padapter, BAND_ON_5G, path, HT_MCS16_MCS23, RF_3TX, base);
 250                /* DBG_871X("Power index base of 5G path %d 3Tx MCS16~23 = > 0x%x\n", path, base); */
 251
 252                base = PHY_GetTxPowerByRate(padapter, BAND_ON_5G, path, RF_1TX, MGN_VHT1SS_MCS7);
 253                phy_SetTxPowerByRateBase(padapter, BAND_ON_5G, path, VHT_1SSMCS0_1SSMCS9, RF_1TX, base);
 254                /* DBG_871X("Power index base of 5G path %d 1Tx VHT1SS = > 0x%x\n", path, base); */
 255
 256                base = PHY_GetTxPowerByRate(padapter, BAND_ON_5G, path, RF_2TX, MGN_VHT2SS_MCS7);
 257                phy_SetTxPowerByRateBase(padapter, BAND_ON_5G, path, VHT_2SSMCS0_2SSMCS9, RF_2TX, base);
 258                /* DBG_871X("Power index base of 5G path %d 2Tx VHT2SS = > 0x%x\n", path, base); */
 259
 260                base = PHY_GetTxPowerByRate(padapter, BAND_ON_5G, path, RF_3TX, MGN_VHT2SS_MCS7);
 261                phy_SetTxPowerByRateBase(padapter, BAND_ON_5G, path, VHT_3SSMCS0_3SSMCS9, RF_3TX, base);
 262                /* DBG_871X("Power index base of 5G path %d 3Tx VHT3SS = > 0x%x\n", path, base); */
 263        }
 264
 265        /* DBG_871X("<===%s\n", __func__); */
 266}
 267
 268u8 PHY_GetRateSectionIndexOfTxPowerByRate(
 269        struct adapter *padapter, u32 RegAddr, u32 BitMask
 270)
 271{
 272        struct hal_com_data     *pHalData = GET_HAL_DATA(padapter);
 273        PDM_ODM_T pDM_Odm = &pHalData->odmpriv;
 274        u8      index = 0;
 275
 276        if (pDM_Odm->PhyRegPgVersion == 0) {
 277                switch (RegAddr) {
 278                case rTxAGC_A_Rate18_06:
 279                        index = 0;
 280                        break;
 281                case rTxAGC_A_Rate54_24:
 282                        index = 1;
 283                        break;
 284                case rTxAGC_A_CCK1_Mcs32:
 285                        index = 6;
 286                        break;
 287                case rTxAGC_B_CCK11_A_CCK2_11:
 288                        if (BitMask == bMaskH3Bytes)
 289                                index = 7;
 290                        else if (BitMask == 0x000000ff)
 291                                index = 15;
 292                        break;
 293
 294                case rTxAGC_A_Mcs03_Mcs00:
 295                        index = 2;
 296                        break;
 297                case rTxAGC_A_Mcs07_Mcs04:
 298                        index = 3;
 299                        break;
 300                case rTxAGC_A_Mcs11_Mcs08:
 301                        index = 4;
 302                        break;
 303                case rTxAGC_A_Mcs15_Mcs12:
 304                        index = 5;
 305                        break;
 306                case rTxAGC_B_Rate18_06:
 307                        index = 8;
 308                        break;
 309                case rTxAGC_B_Rate54_24:
 310                        index = 9;
 311                        break;
 312                case rTxAGC_B_CCK1_55_Mcs32:
 313                        index = 14;
 314                        break;
 315                case rTxAGC_B_Mcs03_Mcs00:
 316                        index = 10;
 317                        break;
 318                case rTxAGC_B_Mcs07_Mcs04:
 319                        index = 11;
 320                        break;
 321                case rTxAGC_B_Mcs11_Mcs08:
 322                        index = 12;
 323                        break;
 324                case rTxAGC_B_Mcs15_Mcs12:
 325                        index = 13;
 326                        break;
 327                default:
 328                        DBG_871X("Invalid RegAddr 0x3%x in PHY_GetRateSectionIndexOfTxPowerByRate()", RegAddr);
 329                        break;
 330                }
 331        }
 332
 333        return index;
 334}
 335
 336void
 337PHY_GetRateValuesOfTxPowerByRate(
 338        struct adapter *padapter,
 339        u32     RegAddr,
 340        u32     BitMask,
 341        u32     Value,
 342        u8 *RateIndex,
 343        s8 *PwrByRateVal,
 344        u8 *RateNum
 345)
 346{
 347        u8 i = 0;
 348
 349        switch (RegAddr) {
 350        case rTxAGC_A_Rate18_06:
 351        case rTxAGC_B_Rate18_06:
 352                RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_6M);
 353                RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_9M);
 354                RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_12M);
 355                RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_18M);
 356                for (i = 0; i < 4; ++i) {
 357                        PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
 358                                                                                        ((Value >> (i * 8)) & 0xF));
 359                }
 360                *RateNum = 4;
 361                break;
 362
 363        case rTxAGC_A_Rate54_24:
 364        case rTxAGC_B_Rate54_24:
 365                RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_24M);
 366                RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_36M);
 367                RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_48M);
 368                RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_54M);
 369                for (i = 0; i < 4; ++i) {
 370                        PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
 371                                                                                        ((Value >> (i * 8)) & 0xF));
 372                }
 373                *RateNum = 4;
 374                break;
 375
 376        case rTxAGC_A_CCK1_Mcs32:
 377                RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_1M);
 378                PwrByRateVal[0] = (s8) ((((Value >> (8 + 4)) & 0xF)) * 10 +
 379                                                                                ((Value >> 8) & 0xF));
 380                *RateNum = 1;
 381                break;
 382
 383        case rTxAGC_B_CCK11_A_CCK2_11:
 384                if (BitMask == 0xffffff00) {
 385                        RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_2M);
 386                        RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_5_5M);
 387                        RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_11M);
 388                        for (i = 1; i < 4; ++i) {
 389                                PwrByRateVal[i - 1] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
 390                                                                                                ((Value >> (i * 8)) & 0xF));
 391                        }
 392                        *RateNum = 3;
 393                } else if (BitMask == 0x000000ff) {
 394                        RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_11M);
 395                        PwrByRateVal[0] = (s8) ((((Value >> 4) & 0xF)) * 10 + (Value & 0xF));
 396                        *RateNum = 1;
 397                }
 398                break;
 399
 400        case rTxAGC_A_Mcs03_Mcs00:
 401        case rTxAGC_B_Mcs03_Mcs00:
 402                RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS0);
 403                RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS1);
 404                RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS2);
 405                RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS3);
 406                for (i = 0; i < 4; ++i) {
 407                        PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
 408                                                                                        ((Value >> (i * 8)) & 0xF));
 409                }
 410                *RateNum = 4;
 411                break;
 412
 413        case rTxAGC_A_Mcs07_Mcs04:
 414        case rTxAGC_B_Mcs07_Mcs04:
 415                RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS4);
 416                RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS5);
 417                RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS6);
 418                RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS7);
 419                for (i = 0; i < 4; ++i) {
 420                        PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
 421                                                                                        ((Value >> (i * 8)) & 0xF));
 422                }
 423                *RateNum = 4;
 424                break;
 425
 426        case rTxAGC_A_Mcs11_Mcs08:
 427        case rTxAGC_B_Mcs11_Mcs08:
 428                RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS8);
 429                RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS9);
 430                RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS10);
 431                RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS11);
 432                for (i = 0; i < 4; ++i) {
 433                        PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
 434                                                                                        ((Value >> (i * 8)) & 0xF));
 435                }
 436                *RateNum = 4;
 437                break;
 438
 439        case rTxAGC_A_Mcs15_Mcs12:
 440        case rTxAGC_B_Mcs15_Mcs12:
 441                RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS12);
 442                RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS13);
 443                RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS14);
 444                RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS15);
 445                for (i = 0; i < 4; ++i) {
 446                        PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
 447                                                                                        ((Value >> (i * 8)) & 0xF));
 448                }
 449                *RateNum = 4;
 450
 451                break;
 452
 453        case rTxAGC_B_CCK1_55_Mcs32:
 454                RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_1M);
 455                RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_2M);
 456                RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_5_5M);
 457                for (i = 1; i < 4; ++i) {
 458                        PwrByRateVal[i - 1] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
 459                                                                                        ((Value >> (i * 8)) & 0xF));
 460                }
 461                *RateNum = 3;
 462                break;
 463
 464        case 0xC20:
 465        case 0xE20:
 466        case 0x1820:
 467        case 0x1a20:
 468                RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_1M);
 469                RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_2M);
 470                RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_5_5M);
 471                RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_11M);
 472                for (i = 0; i < 4; ++i) {
 473                        PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
 474                                                                                        ((Value >> (i * 8)) & 0xF));
 475                }
 476                *RateNum = 4;
 477                break;
 478
 479        case 0xC24:
 480        case 0xE24:
 481        case 0x1824:
 482        case 0x1a24:
 483                RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_6M);
 484                RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_9M);
 485                RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_12M);
 486                RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_18M);
 487                for (i = 0; i < 4; ++i) {
 488                        PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
 489                                                                                        ((Value >> (i * 8)) & 0xF));
 490                }
 491                *RateNum = 4;
 492                break;
 493
 494        case 0xC28:
 495        case 0xE28:
 496        case 0x1828:
 497        case 0x1a28:
 498                RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_24M);
 499                RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_36M);
 500                RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_48M);
 501                RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_54M);
 502                for (i = 0; i < 4; ++i) {
 503                        PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
 504                                                                                        ((Value >> (i * 8)) & 0xF));
 505                }
 506                *RateNum = 4;
 507                break;
 508
 509        case 0xC2C:
 510        case 0xE2C:
 511        case 0x182C:
 512        case 0x1a2C:
 513                RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS0);
 514                RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS1);
 515                RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS2);
 516                RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS3);
 517                for (i = 0; i < 4; ++i) {
 518                        PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
 519                                                                                        ((Value >> (i * 8)) & 0xF));
 520                }
 521                *RateNum = 4;
 522                break;
 523
 524        case 0xC30:
 525        case 0xE30:
 526        case 0x1830:
 527        case 0x1a30:
 528                RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS4);
 529                RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS5);
 530                RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS6);
 531                RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS7);
 532                for (i = 0; i < 4; ++i) {
 533                        PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
 534                                                                                        ((Value >> (i * 8)) & 0xF));
 535                }
 536                *RateNum = 4;
 537                break;
 538
 539        case 0xC34:
 540        case 0xE34:
 541        case 0x1834:
 542        case 0x1a34:
 543                RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS8);
 544                RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS9);
 545                RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS10);
 546                RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS11);
 547                for (i = 0; i < 4; ++i) {
 548                        PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
 549                                                                                        ((Value >> (i * 8)) & 0xF));
 550                }
 551                *RateNum = 4;
 552                break;
 553
 554        case 0xC38:
 555        case 0xE38:
 556        case 0x1838:
 557        case 0x1a38:
 558                RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS12);
 559                RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS13);
 560                RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS14);
 561                RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS15);
 562                for (i = 0; i < 4; ++i) {
 563                        PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
 564                                                                                        ((Value >> (i * 8)) & 0xF));
 565                }
 566                *RateNum = 4;
 567                break;
 568
 569        case 0xC3C:
 570        case 0xE3C:
 571        case 0x183C:
 572        case 0x1a3C:
 573                RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_VHT1SS_MCS0);
 574                RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_VHT1SS_MCS1);
 575                RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_VHT1SS_MCS2);
 576                RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_VHT1SS_MCS3);
 577                for (i = 0; i < 4; ++i) {
 578                        PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
 579                                                                                        ((Value >> (i * 8)) & 0xF));
 580                }
 581                *RateNum = 4;
 582                break;
 583
 584        case 0xC40:
 585        case 0xE40:
 586        case 0x1840:
 587        case 0x1a40:
 588                RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_VHT1SS_MCS4);
 589                RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_VHT1SS_MCS5);
 590                RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_VHT1SS_MCS6);
 591                RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_VHT1SS_MCS7);
 592                for (i = 0; i < 4; ++i) {
 593                        PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
 594                                                                                        ((Value >> (i * 8)) & 0xF));
 595                }
 596                *RateNum = 4;
 597                break;
 598
 599        case 0xC44:
 600        case 0xE44:
 601        case 0x1844:
 602        case 0x1a44:
 603                RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_VHT1SS_MCS8);
 604                RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_VHT1SS_MCS9);
 605                RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_VHT2SS_MCS0);
 606                RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_VHT2SS_MCS1);
 607                for (i = 0; i < 4; ++i) {
 608                        PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
 609                                                                                        ((Value >> (i * 8)) & 0xF));
 610                }
 611                *RateNum = 4;
 612                break;
 613
 614        case 0xC48:
 615        case 0xE48:
 616        case 0x1848:
 617        case 0x1a48:
 618                RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_VHT2SS_MCS2);
 619                RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_VHT2SS_MCS3);
 620                RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_VHT2SS_MCS4);
 621                RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_VHT2SS_MCS5);
 622                for (i = 0; i < 4; ++i) {
 623                        PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
 624                                                                                        ((Value >> (i * 8)) & 0xF));
 625                }
 626                *RateNum = 4;
 627                break;
 628
 629        case 0xC4C:
 630        case 0xE4C:
 631        case 0x184C:
 632        case 0x1a4C:
 633                RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_VHT2SS_MCS6);
 634                RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_VHT2SS_MCS7);
 635                RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_VHT2SS_MCS8);
 636                RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_VHT2SS_MCS9);
 637                for (i = 0; i < 4; ++i) {
 638                        PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
 639                                                                                        ((Value >> (i * 8)) & 0xF));
 640                }
 641                *RateNum = 4;
 642                break;
 643
 644        case 0xCD8:
 645        case 0xED8:
 646        case 0x18D8:
 647        case 0x1aD8:
 648                RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS16);
 649                RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS17);
 650                RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS18);
 651                RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS19);
 652                for (i = 0; i < 4; ++i) {
 653                        PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
 654                                                                                        ((Value >> (i * 8)) & 0xF));
 655                }
 656                *RateNum = 4;
 657                break;
 658
 659        case 0xCDC:
 660        case 0xEDC:
 661        case 0x18DC:
 662        case 0x1aDC:
 663                RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS20);
 664                RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS21);
 665                RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS22);
 666                RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS23);
 667                for (i = 0; i < 4; ++i) {
 668                        PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
 669                                                                                        ((Value >> (i * 8)) & 0xF));
 670                }
 671                *RateNum = 4;
 672                break;
 673
 674        case 0xCE0:
 675        case 0xEE0:
 676        case 0x18E0:
 677        case 0x1aE0:
 678                RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_VHT3SS_MCS0);
 679                RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_VHT3SS_MCS1);
 680                RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_VHT3SS_MCS2);
 681                RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_VHT3SS_MCS3);
 682                for (i = 0; i < 4; ++i) {
 683                        PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
 684                                                                                        ((Value >> (i * 8)) & 0xF));
 685                }
 686                *RateNum = 4;
 687                break;
 688
 689        case 0xCE4:
 690        case 0xEE4:
 691        case 0x18E4:
 692        case 0x1aE4:
 693                RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_VHT3SS_MCS4);
 694                RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_VHT3SS_MCS5);
 695                RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_VHT3SS_MCS6);
 696                RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_VHT3SS_MCS7);
 697                for (i = 0; i < 4; ++i) {
 698                        PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
 699                                                                                        ((Value >> (i * 8)) & 0xF));
 700                }
 701                *RateNum = 4;
 702                break;
 703
 704        case 0xCE8:
 705        case 0xEE8:
 706        case 0x18E8:
 707        case 0x1aE8:
 708                RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_VHT3SS_MCS8);
 709                RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_VHT3SS_MCS9);
 710                for (i = 0; i < 2; ++i) {
 711                        PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
 712                                                                                        ((Value >> (i * 8)) & 0xF));
 713                }
 714                *RateNum = 4;
 715                break;
 716
 717        default:
 718                DBG_871X("Invalid RegAddr 0x%x in %s()\n", RegAddr, __func__);
 719                break;
 720        }
 721}
 722
 723static void PHY_StoreTxPowerByRateNew(
 724        struct adapter *padapter,
 725        u32     Band,
 726        u32     RfPath,
 727        u32     TxNum,
 728        u32     RegAddr,
 729        u32     BitMask,
 730        u32     Data
 731)
 732{
 733        struct hal_com_data     *pHalData = GET_HAL_DATA(padapter);
 734        u8 i = 0, rateIndex[4] = {0}, rateNum = 0;
 735        s8      PwrByRateVal[4] = {0};
 736
 737        PHY_GetRateValuesOfTxPowerByRate(padapter, RegAddr, BitMask, Data, rateIndex, PwrByRateVal, &rateNum);
 738
 739        if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) {
 740                DBG_871X("Invalid Band %d\n", Band);
 741                return;
 742        }
 743
 744        if (RfPath > ODM_RF_PATH_D) {
 745                DBG_871X("Invalid RfPath %d\n", RfPath);
 746                return;
 747        }
 748
 749        if (TxNum > ODM_RF_PATH_D) {
 750                DBG_871X("Invalid TxNum %d\n", TxNum);
 751                return;
 752        }
 753
 754        for (i = 0; i < rateNum; ++i) {
 755                if (rateIndex[i] == PHY_GetRateIndexOfTxPowerByRate(MGN_VHT2SS_MCS0) ||
 756                         rateIndex[i] == PHY_GetRateIndexOfTxPowerByRate(MGN_VHT2SS_MCS1))
 757                        TxNum = RF_2TX;
 758
 759                pHalData->TxPwrByRateOffset[Band][RfPath][TxNum][rateIndex[i]] = PwrByRateVal[i];
 760        }
 761}
 762
 763static void PHY_StoreTxPowerByRateOld(
 764        struct adapter *padapter, u32   RegAddr, u32 BitMask, u32 Data
 765)
 766{
 767        struct hal_com_data     *pHalData = GET_HAL_DATA(padapter);
 768        u8      index = PHY_GetRateSectionIndexOfTxPowerByRate(padapter, RegAddr, BitMask);
 769
 770        pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][index] = Data;
 771        /* DBG_871X("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n", pHalData->pwrGroupCnt, */
 772        /*      pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][0]); */
 773}
 774
 775void PHY_InitTxPowerByRate(struct adapter *padapter)
 776{
 777        struct hal_com_data     *pHalData = GET_HAL_DATA(padapter);
 778        u8 band, rfPath, TxNum, rate;
 779
 780        for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band)
 781                        for (rfPath = 0; rfPath < TX_PWR_BY_RATE_NUM_RF; ++rfPath)
 782                                for (TxNum = 0; TxNum < TX_PWR_BY_RATE_NUM_RF; ++TxNum)
 783                                        for (rate = 0; rate < TX_PWR_BY_RATE_NUM_RATE; ++rate)
 784                                                pHalData->TxPwrByRateOffset[band][rfPath][TxNum][rate] = 0;
 785}
 786
 787void PHY_StoreTxPowerByRate(
 788        struct adapter *padapter,
 789        u32     Band,
 790        u32     RfPath,
 791        u32     TxNum,
 792        u32     RegAddr,
 793        u32     BitMask,
 794        u32     Data
 795)
 796{
 797        struct hal_com_data     *pHalData = GET_HAL_DATA(padapter);
 798        PDM_ODM_T               pDM_Odm = &pHalData->odmpriv;
 799
 800        if (pDM_Odm->PhyRegPgVersion > 0)
 801                PHY_StoreTxPowerByRateNew(padapter, Band, RfPath, TxNum, RegAddr, BitMask, Data);
 802        else if (pDM_Odm->PhyRegPgVersion == 0) {
 803                PHY_StoreTxPowerByRateOld(padapter, RegAddr, BitMask, Data);
 804
 805                if (RegAddr == rTxAGC_A_Mcs15_Mcs12 && pHalData->rf_type == RF_1T1R)
 806                        pHalData->pwrGroupCnt++;
 807                else if (RegAddr == rTxAGC_B_Mcs15_Mcs12 && pHalData->rf_type != RF_1T1R)
 808                        pHalData->pwrGroupCnt++;
 809        } else
 810                DBG_871X("Invalid PHY_REG_PG.txt version %d\n",  pDM_Odm->PhyRegPgVersion);
 811
 812}
 813
 814static void
 815phy_ConvertTxPowerByRateInDbmToRelativeValues(
 816struct adapter *padapter
 817        )
 818{
 819        u8      base = 0, i = 0, value = 0, band = 0, path = 0, txNum = 0;
 820        u8      cckRates[4] = {
 821                MGN_1M, MGN_2M, MGN_5_5M, MGN_11M
 822        };
 823        u8      ofdmRates[8] = {
 824                MGN_6M, MGN_9M, MGN_12M, MGN_18M, MGN_24M, MGN_36M, MGN_48M, MGN_54M
 825        };
 826        u8 mcs0_7Rates[8] = {
 827                MGN_MCS0, MGN_MCS1, MGN_MCS2, MGN_MCS3, MGN_MCS4, MGN_MCS5, MGN_MCS6, MGN_MCS7
 828        };
 829        u8 mcs8_15Rates[8] = {
 830                MGN_MCS8, MGN_MCS9, MGN_MCS10, MGN_MCS11, MGN_MCS12, MGN_MCS13, MGN_MCS14, MGN_MCS15
 831        };
 832        u8 mcs16_23Rates[8] = {
 833                MGN_MCS16, MGN_MCS17, MGN_MCS18, MGN_MCS19, MGN_MCS20, MGN_MCS21, MGN_MCS22, MGN_MCS23
 834        };
 835        u8 vht1ssRates[10] = {
 836                MGN_VHT1SS_MCS0, MGN_VHT1SS_MCS1, MGN_VHT1SS_MCS2, MGN_VHT1SS_MCS3, MGN_VHT1SS_MCS4,
 837                MGN_VHT1SS_MCS5, MGN_VHT1SS_MCS6, MGN_VHT1SS_MCS7, MGN_VHT1SS_MCS8, MGN_VHT1SS_MCS9
 838        };
 839        u8 vht2ssRates[10] = {
 840                MGN_VHT2SS_MCS0, MGN_VHT2SS_MCS1, MGN_VHT2SS_MCS2, MGN_VHT2SS_MCS3, MGN_VHT2SS_MCS4,
 841                MGN_VHT2SS_MCS5, MGN_VHT2SS_MCS6, MGN_VHT2SS_MCS7, MGN_VHT2SS_MCS8, MGN_VHT2SS_MCS9
 842        };
 843        u8 vht3ssRates[10] = {
 844                MGN_VHT3SS_MCS0, MGN_VHT3SS_MCS1, MGN_VHT3SS_MCS2, MGN_VHT3SS_MCS3, MGN_VHT3SS_MCS4,
 845                MGN_VHT3SS_MCS5, MGN_VHT3SS_MCS6, MGN_VHT3SS_MCS7, MGN_VHT3SS_MCS8, MGN_VHT3SS_MCS9
 846        };
 847
 848        /* DBG_871X("===>PHY_ConvertTxPowerByRateInDbmToRelativeValues()\n"); */
 849
 850        for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band) {
 851                for (path = ODM_RF_PATH_A; path <= ODM_RF_PATH_D; ++path) {
 852                        for (txNum = RF_1TX; txNum < RF_MAX_TX_NUM; ++txNum) {
 853                                /*  CCK */
 854                                base = PHY_GetTxPowerByRate(padapter, band, path, txNum, MGN_11M);
 855                                for (i = 0; i < ARRAY_SIZE(cckRates); ++i) {
 856                                        value = PHY_GetTxPowerByRate(padapter, band, path, txNum, cckRates[i]);
 857                                        PHY_SetTxPowerByRate(padapter, band, path, txNum, cckRates[i], value - base);
 858                                }
 859
 860                                /*  OFDM */
 861                                base = PHY_GetTxPowerByRate(padapter, band, path, txNum, MGN_54M);
 862                                for (i = 0; i < sizeof(ofdmRates); ++i) {
 863                                        value = PHY_GetTxPowerByRate(padapter, band, path, txNum, ofdmRates[i]);
 864                                        PHY_SetTxPowerByRate(padapter, band, path, txNum, ofdmRates[i], value - base);
 865                                }
 866
 867                                /*  HT MCS0~7 */
 868                                base = PHY_GetTxPowerByRate(padapter, band, path, txNum, MGN_MCS7);
 869                                for (i = 0; i < sizeof(mcs0_7Rates); ++i) {
 870                                        value = PHY_GetTxPowerByRate(padapter, band, path, txNum, mcs0_7Rates[i]);
 871                                        PHY_SetTxPowerByRate(padapter, band, path, txNum, mcs0_7Rates[i], value - base);
 872                                }
 873
 874                                /*  HT MCS8~15 */
 875                                base = PHY_GetTxPowerByRate(padapter, band, path, txNum, MGN_MCS15);
 876                                for (i = 0; i < sizeof(mcs8_15Rates); ++i) {
 877                                        value = PHY_GetTxPowerByRate(padapter, band, path, txNum, mcs8_15Rates[i]);
 878                                        PHY_SetTxPowerByRate(padapter, band, path, txNum, mcs8_15Rates[i], value - base);
 879                                }
 880
 881                                /*  HT MCS16~23 */
 882                                base = PHY_GetTxPowerByRate(padapter, band, path, txNum, MGN_MCS23);
 883                                for (i = 0; i < sizeof(mcs16_23Rates); ++i) {
 884                                        value = PHY_GetTxPowerByRate(padapter, band, path, txNum, mcs16_23Rates[i]);
 885                                        PHY_SetTxPowerByRate(padapter, band, path, txNum, mcs16_23Rates[i], value - base);
 886                                }
 887
 888                                /*  VHT 1SS */
 889                                base = PHY_GetTxPowerByRate(padapter, band, path, txNum, MGN_VHT1SS_MCS7);
 890                                for (i = 0; i < sizeof(vht1ssRates); ++i) {
 891                                        value = PHY_GetTxPowerByRate(padapter, band, path, txNum, vht1ssRates[i]);
 892                                        PHY_SetTxPowerByRate(padapter, band, path, txNum, vht1ssRates[i], value - base);
 893                                }
 894
 895                                /*  VHT 2SS */
 896                                base = PHY_GetTxPowerByRate(padapter, band, path, txNum, MGN_VHT2SS_MCS7);
 897                                for (i = 0; i < sizeof(vht2ssRates); ++i) {
 898                                        value = PHY_GetTxPowerByRate(padapter, band, path, txNum, vht2ssRates[i]);
 899                                        PHY_SetTxPowerByRate(padapter, band, path, txNum, vht2ssRates[i], value - base);
 900                                }
 901
 902                                /*  VHT 3SS */
 903                                base = PHY_GetTxPowerByRate(padapter, band, path, txNum, MGN_VHT3SS_MCS7);
 904                                for (i = 0; i < sizeof(vht3ssRates); ++i) {
 905                                        value = PHY_GetTxPowerByRate(padapter, band, path, txNum, vht3ssRates[i]);
 906                                        PHY_SetTxPowerByRate(padapter, band, path, txNum, vht3ssRates[i], value - base);
 907                                }
 908                        }
 909                }
 910        }
 911
 912        /* DBG_871X("<===PHY_ConvertTxPowerByRateInDbmToRelativeValues()\n"); */
 913}
 914
 915/*
 916  * This function must be called if the value in the PHY_REG_PG.txt(or header)
 917  * is exact dBm values
 918  */
 919void PHY_TxPowerByRateConfiguration(struct adapter *padapter)
 920{
 921        phy_StoreTxPowerByRateBase(padapter);
 922        phy_ConvertTxPowerByRateInDbmToRelativeValues(padapter);
 923}
 924
 925void PHY_SetTxPowerIndexByRateSection(
 926        struct adapter *padapter, u8 RFPath, u8 Channel, u8 RateSection
 927)
 928{
 929        struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
 930
 931        if (RateSection == CCK) {
 932                u8 cckRates[]   = {MGN_1M, MGN_2M, MGN_5_5M, MGN_11M};
 933                if (pHalData->CurrentBandType == BAND_ON_2_4G)
 934                        PHY_SetTxPowerIndexByRateArray(padapter, RFPath,
 935                                                     pHalData->CurrentChannelBW,
 936                                                     Channel, cckRates,
 937                                                     ARRAY_SIZE(cckRates));
 938
 939        } else if (RateSection == OFDM) {
 940                u8 ofdmRates[]  = {MGN_6M, MGN_9M, MGN_12M, MGN_18M, MGN_24M, MGN_36M, MGN_48M, MGN_54M};
 941                PHY_SetTxPowerIndexByRateArray(padapter, RFPath,
 942                                               pHalData->CurrentChannelBW,
 943                                               Channel, ofdmRates,
 944                                               ARRAY_SIZE(ofdmRates));
 945
 946        } else if (RateSection == HT_MCS0_MCS7) {
 947                u8 htRates1T[]  = {MGN_MCS0, MGN_MCS1, MGN_MCS2, MGN_MCS3, MGN_MCS4, MGN_MCS5, MGN_MCS6, MGN_MCS7};
 948                PHY_SetTxPowerIndexByRateArray(padapter, RFPath,
 949                                               pHalData->CurrentChannelBW,
 950                                               Channel, htRates1T,
 951                                               ARRAY_SIZE(htRates1T));
 952
 953        } else if (RateSection == HT_MCS8_MCS15) {
 954                u8 htRates2T[]  = {MGN_MCS8, MGN_MCS9, MGN_MCS10, MGN_MCS11, MGN_MCS12, MGN_MCS13, MGN_MCS14, MGN_MCS15};
 955                PHY_SetTxPowerIndexByRateArray(padapter, RFPath,
 956                                               pHalData->CurrentChannelBW,
 957                                               Channel, htRates2T,
 958                                               ARRAY_SIZE(htRates2T));
 959
 960        } else if (RateSection == HT_MCS16_MCS23) {
 961                u8 htRates3T[]  = {MGN_MCS16, MGN_MCS17, MGN_MCS18, MGN_MCS19, MGN_MCS20, MGN_MCS21, MGN_MCS22, MGN_MCS23};
 962                PHY_SetTxPowerIndexByRateArray(padapter, RFPath,
 963                                               pHalData->CurrentChannelBW,
 964                                               Channel, htRates3T,
 965                                               ARRAY_SIZE(htRates3T));
 966
 967        } else if (RateSection == HT_MCS24_MCS31) {
 968                u8 htRates4T[]  = {MGN_MCS24, MGN_MCS25, MGN_MCS26, MGN_MCS27, MGN_MCS28, MGN_MCS29, MGN_MCS30, MGN_MCS31};
 969                PHY_SetTxPowerIndexByRateArray(padapter, RFPath,
 970                                               pHalData->CurrentChannelBW,
 971                                               Channel, htRates4T,
 972                                               ARRAY_SIZE(htRates4T));
 973
 974        } else if (RateSection == VHT_1SSMCS0_1SSMCS9) {
 975                u8 vhtRates1T[] = {MGN_VHT1SS_MCS0, MGN_VHT1SS_MCS1, MGN_VHT1SS_MCS2, MGN_VHT1SS_MCS3, MGN_VHT1SS_MCS4,
 976                                MGN_VHT1SS_MCS5, MGN_VHT1SS_MCS6, MGN_VHT1SS_MCS7, MGN_VHT1SS_MCS8, MGN_VHT1SS_MCS9};
 977                PHY_SetTxPowerIndexByRateArray(padapter, RFPath,
 978                                               pHalData->CurrentChannelBW,
 979                                               Channel, vhtRates1T,
 980                                               ARRAY_SIZE(vhtRates1T));
 981
 982        } else if (RateSection == VHT_2SSMCS0_2SSMCS9) {
 983                u8 vhtRates2T[] = {MGN_VHT2SS_MCS0, MGN_VHT2SS_MCS1, MGN_VHT2SS_MCS2, MGN_VHT2SS_MCS3, MGN_VHT2SS_MCS4,
 984                                MGN_VHT2SS_MCS5, MGN_VHT2SS_MCS6, MGN_VHT2SS_MCS7, MGN_VHT2SS_MCS8, MGN_VHT2SS_MCS9};
 985
 986                PHY_SetTxPowerIndexByRateArray(padapter, RFPath,
 987                                               pHalData->CurrentChannelBW,
 988                                               Channel, vhtRates2T,
 989                                               ARRAY_SIZE(vhtRates2T));
 990        } else if (RateSection == VHT_3SSMCS0_3SSMCS9) {
 991                u8 vhtRates3T[] = {MGN_VHT3SS_MCS0, MGN_VHT3SS_MCS1, MGN_VHT3SS_MCS2, MGN_VHT3SS_MCS3, MGN_VHT3SS_MCS4,
 992                                MGN_VHT3SS_MCS5, MGN_VHT3SS_MCS6, MGN_VHT3SS_MCS7, MGN_VHT3SS_MCS8, MGN_VHT3SS_MCS9};
 993
 994                PHY_SetTxPowerIndexByRateArray(padapter, RFPath,
 995                                               pHalData->CurrentChannelBW,
 996                                               Channel, vhtRates3T,
 997                                               ARRAY_SIZE(vhtRates3T));
 998        } else if (RateSection == VHT_4SSMCS0_4SSMCS9) {
 999                u8 vhtRates4T[] = {MGN_VHT4SS_MCS0, MGN_VHT4SS_MCS1, MGN_VHT4SS_MCS2, MGN_VHT4SS_MCS3, MGN_VHT4SS_MCS4,
1000                                MGN_VHT4SS_MCS5, MGN_VHT4SS_MCS6, MGN_VHT4SS_MCS7, MGN_VHT4SS_MCS8, MGN_VHT4SS_MCS9};
1001
1002                PHY_SetTxPowerIndexByRateArray(padapter, RFPath,
1003                                               pHalData->CurrentChannelBW,
1004                                               Channel, vhtRates4T,
1005                                               ARRAY_SIZE(vhtRates4T));
1006        } else
1007                DBG_871X("Invalid RateSection %d in %s", RateSection, __func__);
1008}
1009
1010static bool phy_GetChnlIndex(u8 Channel, u8 *ChannelIdx)
1011{
1012        u8 channel5G[CHANNEL_MAX_NUMBER_5G] = {
1013                36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 100, 102,
1014                104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130,
1015                132, 134, 136, 138, 140, 142, 144, 149, 151, 153, 155, 157, 159, 161,
1016                163, 165, 167, 168, 169, 171, 173, 175, 177
1017        };
1018        u8  i = 0;
1019        bool bIn24G = true;
1020
1021        if (Channel <= 14) {
1022                bIn24G = true;
1023                *ChannelIdx = Channel-1;
1024        } else {
1025                bIn24G = false;
1026
1027                for (i = 0; i < ARRAY_SIZE(channel5G); ++i) {
1028                        if (channel5G[i] == Channel) {
1029                                *ChannelIdx = i;
1030                                return bIn24G;
1031                        }
1032                }
1033        }
1034
1035        return bIn24G;
1036}
1037
1038u8 PHY_GetTxPowerIndexBase(
1039        struct adapter *padapter,
1040        u8 RFPath,
1041        u8 Rate,
1042        enum CHANNEL_WIDTH      BandWidth,
1043        u8 Channel,
1044        bool *bIn24G
1045)
1046{
1047        struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
1048        u8 i = 0;       /* default set to 1S */
1049        u8 txPower = 0;
1050        u8 chnlIdx = (Channel-1);
1051
1052        if (HAL_IsLegalChannel(padapter, Channel) == false) {
1053                chnlIdx = 0;
1054                DBG_871X("Illegal channel!!\n");
1055        }
1056
1057        *bIn24G = phy_GetChnlIndex(Channel, &chnlIdx);
1058
1059        /* DBG_871X("[%s] Channel Index: %d\n", (*bIn24G?"2.4G":"5G"), chnlIdx); */
1060
1061        if (*bIn24G) { /* 3 ============================== 2.4 G ============================== */
1062                if (IS_CCK_RATE(Rate))
1063                        txPower = pHalData->Index24G_CCK_Base[RFPath][chnlIdx];
1064                else if (MGN_6M <= Rate)
1065                        txPower = pHalData->Index24G_BW40_Base[RFPath][chnlIdx];
1066                else
1067                        DBG_871X("PHY_GetTxPowerIndexBase: INVALID Rate.\n");
1068
1069                /* DBG_871X("Base Tx power(RF-%c, Rate #%d, Channel Index %d) = 0x%X\n", */
1070                /*              ((RFPath == 0)?'A':'B'), Rate, chnlIdx, txPower); */
1071
1072                /*  OFDM-1T */
1073                if ((MGN_6M <= Rate && Rate <= MGN_54M) && !IS_CCK_RATE(Rate)) {
1074                        txPower += pHalData->OFDM_24G_Diff[RFPath][TX_1S];
1075                        /* DBG_871X("+PowerDiff 2.4G (RF-%c): (OFDM-1T) = (%d)\n", ((RFPath == 0)?'A':'B'), pHalData->OFDM_24G_Diff[RFPath][TX_1S]); */
1076                }
1077                if (BandWidth == CHANNEL_WIDTH_20) { /*  BW20-1S, BW20-2S */
1078                        if ((MGN_MCS0 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1079                                txPower += pHalData->BW20_24G_Diff[RFPath][TX_1S];
1080                        if ((MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1081                                txPower += pHalData->BW20_24G_Diff[RFPath][TX_2S];
1082                        if ((MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1083                                txPower += pHalData->BW20_24G_Diff[RFPath][TX_3S];
1084                        if ((MGN_MCS24 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1085                                txPower += pHalData->BW20_24G_Diff[RFPath][TX_4S];
1086
1087                        /* DBG_871X("+PowerDiff 2.4G (RF-%c): (BW20-1S, BW20-2S, BW20-3S, BW20-4S) = (%d, %d, %d, %d)\n", ((RFPath == 0)?'A':(RFPath == 1)?'B':(RFPath ==2)?'C':'D'), */
1088                        /*      pHalData->BW20_24G_Diff[RFPath][TX_1S], pHalData->BW20_24G_Diff[RFPath][TX_2S], */
1089                        /*      pHalData->BW20_24G_Diff[RFPath][TX_3S], pHalData->BW20_24G_Diff[RFPath][TX_4S]); */
1090                } else if (BandWidth == CHANNEL_WIDTH_40) { /*  BW40-1S, BW40-2S */
1091                        if ((MGN_MCS0 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1092                                txPower += pHalData->BW40_24G_Diff[RFPath][TX_1S];
1093                        if ((MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1094                                txPower += pHalData->BW40_24G_Diff[RFPath][TX_2S];
1095                        if ((MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1096                                txPower += pHalData->BW40_24G_Diff[RFPath][TX_3S];
1097                        if ((MGN_MCS24 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1098                                txPower += pHalData->BW40_24G_Diff[RFPath][TX_4S];
1099
1100                        /* DBG_871X("+PowerDiff 2.4G (RF-%c): (BW40-1S, BW40-2S, BW40-3S, BW40-4S) = (%d, %d, %d, %d)\n", ((RFPath == 0)?'A':(RFPath == 1)?'B':(RFPath ==2)?'C':'D'), */
1101                        /*      pHalData->BW40_24G_Diff[RFPath][TX_1S], pHalData->BW40_24G_Diff[RFPath][TX_2S], */
1102                        /*      pHalData->BW40_24G_Diff[RFPath][TX_3S], pHalData->BW40_24G_Diff[RFPath][TX_4S]); */
1103                }
1104                /*  Willis suggest adopt BW 40M power index while in BW 80 mode */
1105                else if (BandWidth == CHANNEL_WIDTH_80) {
1106                        if ((MGN_MCS0 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1107                                txPower += pHalData->BW40_24G_Diff[RFPath][TX_1S];
1108                        if ((MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1109                                txPower += pHalData->BW40_24G_Diff[RFPath][TX_2S];
1110                        if ((MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1111                                txPower += pHalData->BW40_24G_Diff[RFPath][TX_3S];
1112                        if ((MGN_MCS24 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1113                                txPower += pHalData->BW40_24G_Diff[RFPath][TX_4S];
1114
1115                        /* DBG_871X("+PowerDiff 2.4G (RF-%c): (BW40-1S, BW40-2S, BW40-3S, BW40-4T) = (%d, %d, %d, %d) P.S. Current is in BW 80MHz\n", ((RFPath == 0)?'A':(RFPath == 1)?'B':(RFPath ==2)?'C':'D'), */
1116                        /*      pHalData->BW40_24G_Diff[RFPath][TX_1S], pHalData->BW40_24G_Diff[RFPath][TX_2S], */
1117                        /*      pHalData->BW40_24G_Diff[RFPath][TX_3S], pHalData->BW40_24G_Diff[RFPath][TX_4S]); */
1118                }
1119        } else {/* 3 ============================== 5 G ============================== */
1120                if (MGN_6M <= Rate)
1121                        txPower = pHalData->Index5G_BW40_Base[RFPath][chnlIdx];
1122                else
1123                        DBG_871X("===> mpt_ProQueryCalTxPower_Jaguar: INVALID Rate.\n");
1124
1125                /* DBG_871X("Base Tx power(RF-%c, Rate #%d, Channel Index %d) = 0x%X\n", */
1126                /*      ((RFPath == 0)?'A':'B'), Rate, chnlIdx, txPower); */
1127
1128                /*  OFDM-1T */
1129                if ((MGN_6M <= Rate && Rate <= MGN_54M) && !IS_CCK_RATE(Rate)) {
1130                        txPower += pHalData->OFDM_5G_Diff[RFPath][TX_1S];
1131                        /* DBG_871X("+PowerDiff 5G (RF-%c): (OFDM-1T) = (%d)\n", ((RFPath == 0)?'A':'B'), pHalData->OFDM_5G_Diff[RFPath][TX_1S]); */
1132                }
1133
1134                /*  BW20-1S, BW20-2S */
1135                if (BandWidth == CHANNEL_WIDTH_20) {
1136                        if ((MGN_MCS0 <= Rate && Rate <= MGN_MCS31)  || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1137                                txPower += pHalData->BW20_5G_Diff[RFPath][TX_1S];
1138                        if ((MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1139                                txPower += pHalData->BW20_5G_Diff[RFPath][TX_2S];
1140                        if ((MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1141                                txPower += pHalData->BW20_5G_Diff[RFPath][TX_3S];
1142                        if ((MGN_MCS24 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1143                                txPower += pHalData->BW20_5G_Diff[RFPath][TX_4S];
1144
1145                        /* DBG_871X("+PowerDiff 5G (RF-%c): (BW20-1S, BW20-2S, BW20-3S, BW20-4S) = (%d, %d, %d, %d)\n", ((RFPath == 0)?'A':(RFPath == 1)?'B':(RFPath ==2)?'C':'D'), */
1146                        /*      pHalData->BW20_5G_Diff[RFPath][TX_1S], pHalData->BW20_5G_Diff[RFPath][TX_2S], */
1147                        /*      pHalData->BW20_5G_Diff[RFPath][TX_3S], pHalData->BW20_5G_Diff[RFPath][TX_4S]); */
1148                } else if (BandWidth == CHANNEL_WIDTH_40) { /*  BW40-1S, BW40-2S */
1149                        if ((MGN_MCS0 <= Rate && Rate <= MGN_MCS31)  || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1150                                txPower += pHalData->BW40_5G_Diff[RFPath][TX_1S];
1151                        if ((MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1152                                txPower += pHalData->BW40_5G_Diff[RFPath][TX_2S];
1153                        if ((MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1154                                txPower += pHalData->BW40_5G_Diff[RFPath][TX_3S];
1155                        if ((MGN_MCS24 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1156                                txPower += pHalData->BW40_5G_Diff[RFPath][TX_4S];
1157
1158                        /* DBG_871X("+PowerDiff 5G(RF-%c): (BW40-1S, BW40-2S) = (%d, %d, %d, %d)\n", ((RFPath == 0)?'A':(RFPath == 1)?'B':(RFPath ==2)?'C':'D'), */
1159                        /*      pHalData->BW40_5G_Diff[RFPath][TX_1S], pHalData->BW40_5G_Diff[RFPath][TX_2S], */
1160                        /*      pHalData->BW40_5G_Diff[RFPath][TX_3S], pHalData->BW40_5G_Diff[RFPath][TX_4S]); */
1161                } else if (BandWidth == CHANNEL_WIDTH_80) { /*  BW80-1S, BW80-2S */
1162                        /*  <20121220, Kordan> Get the index of array "Index5G_BW80_Base". */
1163                        u8 channel5G_80M[CHANNEL_MAX_NUMBER_5G_80M] = {42, 58, 106, 122, 138, 155, 171};
1164                        for (i = 0; i < ARRAY_SIZE(channel5G_80M); ++i)
1165                                if (channel5G_80M[i] == Channel)
1166                                        chnlIdx = i;
1167
1168                        txPower = pHalData->Index5G_BW80_Base[RFPath][chnlIdx];
1169
1170                        if ((MGN_MCS0 <= Rate && Rate <= MGN_MCS31)  || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1171                                txPower += + pHalData->BW80_5G_Diff[RFPath][TX_1S];
1172                        if ((MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1173                                txPower += pHalData->BW80_5G_Diff[RFPath][TX_2S];
1174                        if ((MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1175                                txPower += pHalData->BW80_5G_Diff[RFPath][TX_3S];
1176                        if ((MGN_MCS23 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1177                                txPower += pHalData->BW80_5G_Diff[RFPath][TX_4S];
1178
1179                        /* DBG_871X("+PowerDiff 5G(RF-%c): (BW80-1S, BW80-2S, BW80-3S, BW80-4S) = (%d, %d, %d, %d)\n", ((RFPath == 0)?'A':(RFPath == 1)?'B':(RFPath ==2)?'C':'D'), */
1180                        /*      pHalData->BW80_5G_Diff[RFPath][TX_1S], pHalData->BW80_5G_Diff[RFPath][TX_2S], */
1181                        /*      pHalData->BW80_5G_Diff[RFPath][TX_3S], pHalData->BW80_5G_Diff[RFPath][TX_4S]); */
1182                }
1183        }
1184
1185        return txPower;
1186}
1187
1188s8 PHY_GetTxPowerTrackingOffset(struct adapter *padapter, u8 RFPath, u8 Rate)
1189{
1190        struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
1191        PDM_ODM_T pDM_Odm = &pHalData->odmpriv;
1192        s8 offset = 0;
1193
1194        if (pDM_Odm->RFCalibrateInfo.TxPowerTrackControl  == false)
1195                return offset;
1196
1197        if ((Rate == MGN_1M) || (Rate == MGN_2M) || (Rate == MGN_5_5M) || (Rate == MGN_11M)) {
1198                offset = pDM_Odm->Remnant_CCKSwingIdx;
1199                /* DBG_871X("+Remnant_CCKSwingIdx = 0x%x\n", RFPath, Rate, pDM_Odm->Remnant_CCKSwingIdx); */
1200        } else {
1201                offset = pDM_Odm->Remnant_OFDMSwingIdx[RFPath];
1202                /* DBG_871X("+Remanant_OFDMSwingIdx[RFPath %u][Rate 0x%x] = 0x%x\n", RFPath, Rate, pDM_Odm->Remnant_OFDMSwingIdx[RFPath]); */
1203
1204        }
1205
1206        return offset;
1207}
1208
1209u8 PHY_GetRateIndexOfTxPowerByRate(u8 Rate)
1210{
1211        u8 index = 0;
1212        switch (Rate) {
1213        case MGN_1M:
1214                index = 0;
1215                break;
1216        case MGN_2M:
1217                index = 1;
1218                break;
1219        case MGN_5_5M:
1220                index = 2;
1221                break;
1222        case MGN_11M:
1223                index = 3;
1224                break;
1225        case MGN_6M:
1226                index = 4;
1227                break;
1228        case MGN_9M:
1229                index = 5;
1230                break;
1231        case MGN_12M:
1232                index = 6;
1233                break;
1234        case MGN_18M:
1235                index = 7;
1236                break;
1237        case MGN_24M:
1238                index = 8;
1239                break;
1240        case MGN_36M:
1241                index = 9;
1242                break;
1243        case MGN_48M:
1244                index = 10;
1245                break;
1246        case MGN_54M:
1247                index = 11;
1248                break;
1249        case MGN_MCS0:
1250                index = 12;
1251                break;
1252        case MGN_MCS1:
1253                index = 13;
1254                break;
1255        case MGN_MCS2:
1256                index = 14;
1257                break;
1258        case MGN_MCS3:
1259                index = 15;
1260                break;
1261        case MGN_MCS4:
1262                index = 16;
1263                break;
1264        case MGN_MCS5:
1265                index = 17;
1266                break;
1267        case MGN_MCS6:
1268                index = 18;
1269                break;
1270        case MGN_MCS7:
1271                index = 19;
1272                break;
1273        case MGN_MCS8:
1274                index = 20;
1275                break;
1276        case MGN_MCS9:
1277                index = 21;
1278                break;
1279        case MGN_MCS10:
1280                index = 22;
1281                break;
1282        case MGN_MCS11:
1283                index = 23;
1284                break;
1285        case MGN_MCS12:
1286                index = 24;
1287                break;
1288        case MGN_MCS13:
1289                index = 25;
1290                break;
1291        case MGN_MCS14:
1292                index = 26;
1293                break;
1294        case MGN_MCS15:
1295                index = 27;
1296                break;
1297        case MGN_MCS16:
1298                index = 28;
1299                break;
1300        case MGN_MCS17:
1301                index = 29;
1302                break;
1303        case MGN_MCS18:
1304                index = 30;
1305                break;
1306        case MGN_MCS19:
1307                index = 31;
1308                break;
1309        case MGN_MCS20:
1310                index = 32;
1311                break;
1312        case MGN_MCS21:
1313                index = 33;
1314                break;
1315        case MGN_MCS22:
1316                index = 34;
1317                break;
1318        case MGN_MCS23:
1319                index = 35;
1320                break;
1321        case MGN_MCS24:
1322                index = 36;
1323                break;
1324        case MGN_MCS25:
1325                index = 37;
1326                break;
1327        case MGN_MCS26:
1328                index = 38;
1329                break;
1330        case MGN_MCS27:
1331                index = 39;
1332                break;
1333        case MGN_MCS28:
1334                index = 40;
1335                break;
1336        case MGN_MCS29:
1337                index = 41;
1338                break;
1339        case MGN_MCS30:
1340                index = 42;
1341                break;
1342        case MGN_MCS31:
1343                index = 43;
1344                break;
1345        case MGN_VHT1SS_MCS0:
1346                index = 44;
1347                break;
1348        case MGN_VHT1SS_MCS1:
1349                index = 45;
1350                break;
1351        case MGN_VHT1SS_MCS2:
1352                index = 46;
1353                break;
1354        case MGN_VHT1SS_MCS3:
1355                index = 47;
1356                break;
1357        case MGN_VHT1SS_MCS4:
1358                index = 48;
1359                break;
1360        case MGN_VHT1SS_MCS5:
1361                index = 49;
1362                break;
1363        case MGN_VHT1SS_MCS6:
1364                index = 50;
1365                break;
1366        case MGN_VHT1SS_MCS7:
1367                index = 51;
1368                break;
1369        case MGN_VHT1SS_MCS8:
1370                index = 52;
1371                break;
1372        case MGN_VHT1SS_MCS9:
1373                index = 53;
1374                break;
1375        case MGN_VHT2SS_MCS0:
1376                index = 54;
1377                break;
1378        case MGN_VHT2SS_MCS1:
1379                index = 55;
1380                break;
1381        case MGN_VHT2SS_MCS2:
1382                index = 56;
1383                break;
1384        case MGN_VHT2SS_MCS3:
1385                index = 57;
1386                break;
1387        case MGN_VHT2SS_MCS4:
1388                index = 58;
1389                break;
1390        case MGN_VHT2SS_MCS5:
1391                index = 59;
1392                break;
1393        case MGN_VHT2SS_MCS6:
1394                index = 60;
1395                break;
1396        case MGN_VHT2SS_MCS7:
1397                index = 61;
1398                break;
1399        case MGN_VHT2SS_MCS8:
1400                index = 62;
1401                break;
1402        case MGN_VHT2SS_MCS9:
1403                index = 63;
1404                break;
1405        case MGN_VHT3SS_MCS0:
1406                index = 64;
1407                break;
1408        case MGN_VHT3SS_MCS1:
1409                index = 65;
1410                break;
1411        case MGN_VHT3SS_MCS2:
1412                index = 66;
1413                break;
1414        case MGN_VHT3SS_MCS3:
1415                index = 67;
1416                break;
1417        case MGN_VHT3SS_MCS4:
1418                index = 68;
1419                break;
1420        case MGN_VHT3SS_MCS5:
1421                index = 69;
1422                break;
1423        case MGN_VHT3SS_MCS6:
1424                index = 70;
1425                break;
1426        case MGN_VHT3SS_MCS7:
1427                index = 71;
1428                break;
1429        case MGN_VHT3SS_MCS8:
1430                index = 72;
1431                break;
1432        case MGN_VHT3SS_MCS9:
1433                index = 73;
1434                break;
1435        case MGN_VHT4SS_MCS0:
1436                index = 74;
1437                break;
1438        case MGN_VHT4SS_MCS1:
1439                index = 75;
1440                break;
1441        case MGN_VHT4SS_MCS2:
1442                index = 76;
1443                break;
1444        case MGN_VHT4SS_MCS3:
1445                index = 77;
1446                break;
1447        case MGN_VHT4SS_MCS4:
1448                index = 78;
1449                break;
1450        case MGN_VHT4SS_MCS5:
1451                index = 79;
1452                break;
1453        case MGN_VHT4SS_MCS6:
1454                index = 80;
1455                break;
1456        case MGN_VHT4SS_MCS7:
1457                index = 81;
1458                break;
1459        case MGN_VHT4SS_MCS8:
1460                index = 82;
1461                break;
1462        case MGN_VHT4SS_MCS9:
1463                index = 83;
1464                break;
1465        default:
1466                DBG_871X("Invalid rate 0x%x in %s\n", Rate, __func__);
1467                break;
1468        }
1469        return index;
1470}
1471
1472s8 PHY_GetTxPowerByRate(
1473        struct adapter *padapter, u8 Band, u8 RFPath, u8 TxNum, u8 Rate
1474)
1475{
1476        struct hal_com_data     *pHalData = GET_HAL_DATA(padapter);
1477        s8 value = 0;
1478        u8 rateIndex = PHY_GetRateIndexOfTxPowerByRate(Rate);
1479
1480        if ((padapter->registrypriv.RegEnableTxPowerByRate == 2 && pHalData->EEPROMRegulatory == 2) ||
1481                   padapter->registrypriv.RegEnableTxPowerByRate == 0)
1482                return 0;
1483
1484        if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) {
1485                DBG_871X("Invalid band %d in %s\n", Band, __func__);
1486                return value;
1487        }
1488        if (RFPath > ODM_RF_PATH_D) {
1489                DBG_871X("Invalid RfPath %d in %s\n", RFPath, __func__);
1490                return value;
1491        }
1492        if (TxNum >= RF_MAX_TX_NUM) {
1493                DBG_871X("Invalid TxNum %d in %s\n", TxNum, __func__);
1494                return value;
1495        }
1496        if (rateIndex >= TX_PWR_BY_RATE_NUM_RATE) {
1497                DBG_871X("Invalid RateIndex %d in %s\n", rateIndex, __func__);
1498                return value;
1499        }
1500
1501        value = pHalData->TxPwrByRateOffset[Band][RFPath][TxNum][rateIndex];
1502
1503        return value;
1504
1505}
1506
1507void PHY_SetTxPowerByRate(
1508        struct adapter *padapter,
1509        u8 Band,
1510        u8 RFPath,
1511        u8 TxNum,
1512        u8 Rate,
1513        s8 Value
1514)
1515{
1516        struct hal_com_data     *pHalData = GET_HAL_DATA(padapter);
1517        u8 rateIndex = PHY_GetRateIndexOfTxPowerByRate(Rate);
1518
1519        if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) {
1520                DBG_871X("Invalid band %d in %s\n", Band, __func__);
1521                return;
1522        }
1523        if (RFPath > ODM_RF_PATH_D) {
1524                DBG_871X("Invalid RfPath %d in %s\n", RFPath, __func__);
1525                return;
1526        }
1527        if (TxNum >= RF_MAX_TX_NUM) {
1528                DBG_871X("Invalid TxNum %d in %s\n", TxNum, __func__);
1529                return;
1530        }
1531        if (rateIndex >= TX_PWR_BY_RATE_NUM_RATE) {
1532                DBG_871X("Invalid RateIndex %d in %s\n", rateIndex, __func__);
1533                return;
1534        }
1535
1536        pHalData->TxPwrByRateOffset[Band][RFPath][TxNum][rateIndex] = Value;
1537}
1538
1539void PHY_SetTxPowerLevelByPath(struct adapter *Adapter, u8 channel, u8 path)
1540{
1541        struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
1542        bool bIsIn24G = (pHalData->CurrentBandType == BAND_ON_2_4G);
1543
1544        /* if (pMgntInfo->RegNByteAccess == 0) */
1545        {
1546                if (bIsIn24G)
1547                        PHY_SetTxPowerIndexByRateSection(Adapter, path, channel, CCK);
1548
1549                PHY_SetTxPowerIndexByRateSection(Adapter, path, channel, OFDM);
1550                PHY_SetTxPowerIndexByRateSection(Adapter, path, channel, HT_MCS0_MCS7);
1551
1552                if (pHalData->NumTotalRFPath >= 2)
1553                        PHY_SetTxPowerIndexByRateSection(Adapter, path, channel, HT_MCS8_MCS15);
1554
1555        }
1556}
1557
1558void PHY_SetTxPowerIndexByRateArray(
1559        struct adapter *padapter,
1560        u8 RFPath,
1561        enum CHANNEL_WIDTH BandWidth,
1562        u8 Channel,
1563        u8 *Rates,
1564        u8 RateArraySize
1565)
1566{
1567        u32 powerIndex = 0;
1568        int     i = 0;
1569
1570        for (i = 0; i < RateArraySize; ++i) {
1571                powerIndex = PHY_GetTxPowerIndex(padapter, RFPath, Rates[i], BandWidth, Channel);
1572                PHY_SetTxPowerIndex(padapter, powerIndex, RFPath, Rates[i]);
1573        }
1574}
1575
1576static s8 phy_GetWorldWideLimit(s8 *LimitTable)
1577{
1578        s8      min = LimitTable[0];
1579        u8 i = 0;
1580
1581        for (i = 0; i < MAX_REGULATION_NUM; ++i) {
1582                if (LimitTable[i] < min)
1583                        min = LimitTable[i];
1584        }
1585
1586        return min;
1587}
1588
1589static s8 phy_GetChannelIndexOfTxPowerLimit(u8 Band, u8 Channel)
1590{
1591        s8      channelIndex = -1;
1592        u8 channel5G[CHANNEL_MAX_NUMBER_5G] = {
1593                36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 100, 102,
1594                104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130,
1595                132, 134, 136, 138, 140, 142, 144, 149, 151, 153, 155, 157, 159, 161,
1596                163, 165, 167, 168, 169, 171, 173, 175, 177
1597        };
1598        u8 i = 0;
1599        if (Band == BAND_ON_2_4G)
1600                channelIndex = Channel - 1;
1601        else if (Band == BAND_ON_5G) {
1602                for (i = 0; i < ARRAY_SIZE(channel5G); ++i) {
1603                        if (channel5G[i] == Channel)
1604                                channelIndex = i;
1605                }
1606        } else
1607                DBG_871X("Invalid Band %d in %s", Band, __func__);
1608
1609        if (channelIndex == -1)
1610                DBG_871X("Invalid Channel %d of Band %d in %s", Channel, Band, __func__);
1611
1612        return channelIndex;
1613}
1614
1615s8 PHY_GetTxPowerLimit(
1616        struct adapter *Adapter,
1617        u32 RegPwrTblSel,
1618        enum BAND_TYPE Band,
1619        enum CHANNEL_WIDTH Bandwidth,
1620        u8 RfPath,
1621        u8 DataRate,
1622        u8 Channel
1623)
1624{
1625        struct hal_com_data     *pHalData = GET_HAL_DATA(Adapter);
1626        s16     band = -1, regulation = -1, bandwidth = -1, rateSection = -1, channel = -1;
1627        s8 powerLimit = MAX_POWER_INDEX;
1628
1629        if ((Adapter->registrypriv.RegEnableTxPowerLimit == 2 && pHalData->EEPROMRegulatory != 1) ||
1630                   Adapter->registrypriv.RegEnableTxPowerLimit == 0)
1631                return MAX_POWER_INDEX;
1632
1633        switch (Adapter->registrypriv.RegPwrTblSel) {
1634        case 1:
1635                        regulation = TXPWR_LMT_ETSI;
1636                        break;
1637        case 2:
1638                        regulation = TXPWR_LMT_MKK;
1639                        break;
1640        case 3:
1641                        regulation = TXPWR_LMT_FCC;
1642                        break;
1643
1644        case 4:
1645                        regulation = TXPWR_LMT_WW;
1646                        break;
1647
1648        default:
1649                        regulation = (Band == BAND_ON_2_4G) ? pHalData->Regulation2_4G : pHalData->Regulation5G;
1650                        break;
1651        }
1652
1653        /* DBG_871X("pMgntInfo->RegPwrTblSel %d, final regulation %d\n", Adapter->registrypriv.RegPwrTblSel, regulation); */
1654
1655
1656        if (Band == BAND_ON_2_4G)
1657                band = 0;
1658        else if (Band == BAND_ON_5G)
1659                band = 1;
1660
1661        if (Bandwidth == CHANNEL_WIDTH_20)
1662                bandwidth = 0;
1663        else if (Bandwidth == CHANNEL_WIDTH_40)
1664                bandwidth = 1;
1665        else if (Bandwidth == CHANNEL_WIDTH_80)
1666                bandwidth = 2;
1667        else if (Bandwidth == CHANNEL_WIDTH_160)
1668                bandwidth = 3;
1669
1670        switch (DataRate) {
1671        case MGN_1M: case MGN_2M: case MGN_5_5M: case MGN_11M:
1672                rateSection = 0;
1673                break;
1674
1675        case MGN_6M: case MGN_9M: case MGN_12M: case MGN_18M:
1676        case MGN_24M: case MGN_36M: case MGN_48M: case MGN_54M:
1677                rateSection = 1;
1678                break;
1679
1680        case MGN_MCS0: case MGN_MCS1: case MGN_MCS2: case MGN_MCS3:
1681        case MGN_MCS4: case MGN_MCS5: case MGN_MCS6: case MGN_MCS7:
1682                rateSection = 2;
1683                break;
1684
1685        case MGN_MCS8: case MGN_MCS9: case MGN_MCS10: case MGN_MCS11:
1686        case MGN_MCS12: case MGN_MCS13: case MGN_MCS14: case MGN_MCS15:
1687                rateSection = 3;
1688                break;
1689
1690        case MGN_MCS16: case MGN_MCS17: case MGN_MCS18: case MGN_MCS19:
1691        case MGN_MCS20: case MGN_MCS21: case MGN_MCS22: case MGN_MCS23:
1692                rateSection = 4;
1693                break;
1694
1695        case MGN_MCS24: case MGN_MCS25: case MGN_MCS26: case MGN_MCS27:
1696        case MGN_MCS28: case MGN_MCS29: case MGN_MCS30: case MGN_MCS31:
1697                rateSection = 5;
1698                break;
1699
1700        case MGN_VHT1SS_MCS0: case MGN_VHT1SS_MCS1: case MGN_VHT1SS_MCS2:
1701        case MGN_VHT1SS_MCS3: case MGN_VHT1SS_MCS4: case MGN_VHT1SS_MCS5:
1702        case MGN_VHT1SS_MCS6: case MGN_VHT1SS_MCS7: case MGN_VHT1SS_MCS8:
1703        case MGN_VHT1SS_MCS9:
1704                rateSection = 6;
1705                break;
1706
1707        case MGN_VHT2SS_MCS0: case MGN_VHT2SS_MCS1: case MGN_VHT2SS_MCS2:
1708        case MGN_VHT2SS_MCS3: case MGN_VHT2SS_MCS4: case MGN_VHT2SS_MCS5:
1709        case MGN_VHT2SS_MCS6: case MGN_VHT2SS_MCS7: case MGN_VHT2SS_MCS8:
1710        case MGN_VHT2SS_MCS9:
1711                rateSection = 7;
1712                break;
1713
1714        case MGN_VHT3SS_MCS0: case MGN_VHT3SS_MCS1: case MGN_VHT3SS_MCS2:
1715        case MGN_VHT3SS_MCS3: case MGN_VHT3SS_MCS4: case MGN_VHT3SS_MCS5:
1716        case MGN_VHT3SS_MCS6: case MGN_VHT3SS_MCS7: case MGN_VHT3SS_MCS8:
1717        case MGN_VHT3SS_MCS9:
1718                rateSection = 8;
1719                break;
1720
1721        case MGN_VHT4SS_MCS0: case MGN_VHT4SS_MCS1: case MGN_VHT4SS_MCS2:
1722        case MGN_VHT4SS_MCS3: case MGN_VHT4SS_MCS4: case MGN_VHT4SS_MCS5:
1723        case MGN_VHT4SS_MCS6: case MGN_VHT4SS_MCS7: case MGN_VHT4SS_MCS8:
1724        case MGN_VHT4SS_MCS9:
1725                rateSection = 9;
1726                break;
1727
1728        default:
1729                DBG_871X("Wrong rate 0x%x\n", DataRate);
1730                break;
1731        }
1732
1733        if (Band == BAND_ON_5G  && rateSection == 0)
1734                        DBG_871X("Wrong rate 0x%x: No CCK in 5G Band\n", DataRate);
1735
1736        /*  workaround for wrong index combination to obtain tx power limit, */
1737        /*  OFDM only exists in BW 20M */
1738        if (rateSection == 1)
1739                bandwidth = 0;
1740
1741        /*  workaround for wrong index combination to obtain tx power limit, */
1742        /*  CCK table will only be given in BW 20M */
1743        if (rateSection == 0)
1744                bandwidth = 0;
1745
1746        /*  workaround for wrong indxe combination to obtain tx power limit, */
1747        /*  HT on 80M will reference to HT on 40M */
1748        if ((rateSection == 2 || rateSection == 3) && Band == BAND_ON_5G && bandwidth == 2) {
1749                bandwidth = 1;
1750        }
1751
1752        if (Band == BAND_ON_2_4G)
1753                channel = phy_GetChannelIndexOfTxPowerLimit(BAND_ON_2_4G, Channel);
1754        else if (Band == BAND_ON_5G)
1755                channel = phy_GetChannelIndexOfTxPowerLimit(BAND_ON_5G, Channel);
1756        else if (Band == BAND_ON_BOTH) {
1757                /*  BAND_ON_BOTH don't care temporarily */
1758        }
1759
1760        if (band == -1 || regulation == -1 || bandwidth == -1 ||
1761             rateSection == -1 || channel == -1) {
1762                /* DBG_871X("Wrong index value to access power limit table [band %d][regulation %d][bandwidth %d][rf_path %d][rate_section %d][chnlGroup %d]\n", */
1763                /*        band, regulation, bandwidth, RfPath, rateSection, channelGroup); */
1764
1765                return MAX_POWER_INDEX;
1766        }
1767
1768        if (Band == BAND_ON_2_4G) {
1769                s8 limits[10] = {0}; u8 i = 0;
1770                for (i = 0; i < MAX_REGULATION_NUM; i++)
1771                        limits[i] = pHalData->TxPwrLimit_2_4G[i][bandwidth][rateSection][channel][RfPath];
1772
1773                powerLimit = (regulation == TXPWR_LMT_WW) ? phy_GetWorldWideLimit(limits) :
1774                        pHalData->TxPwrLimit_2_4G[regulation][bandwidth][rateSection][channel][RfPath];
1775
1776        } else if (Band == BAND_ON_5G) {
1777                s8 limits[10] = {0}; u8 i = 0;
1778                for (i = 0; i < MAX_REGULATION_NUM; ++i)
1779                        limits[i] = pHalData->TxPwrLimit_5G[i][bandwidth][rateSection][channel][RfPath];
1780
1781                powerLimit = (regulation == TXPWR_LMT_WW) ? phy_GetWorldWideLimit(limits) :
1782                        pHalData->TxPwrLimit_5G[regulation][bandwidth][rateSection][channel][RfPath];
1783        } else
1784                DBG_871X("No power limit table of the specified band\n");
1785
1786        /*  combine 5G VHT & HT rate */
1787        /*  5G 20M and 40M HT and VHT can cross reference */
1788        /*
1789        if (Band == BAND_ON_5G && powerLimit == MAX_POWER_INDEX) {
1790                if (bandwidth == 0 || bandwidth == 1) {
1791                        RT_TRACE(COMP_INIT, DBG_LOUD, ("No power limit table of the specified band %d, bandwidth %d, ratesection %d, rf path %d\n",
1792                                          band, bandwidth, rateSection, RfPath));
1793                        if (rateSection == 2)
1794                                powerLimit = pHalData->TxPwrLimit_5G[regulation]
1795                                                                                [bandwidth][4][channelGroup][RfPath];
1796                        else if (rateSection == 4)
1797                                powerLimit = pHalData->TxPwrLimit_5G[regulation]
1798                                                                                [bandwidth][2][channelGroup][RfPath];
1799                        else if (rateSection == 3)
1800                                powerLimit = pHalData->TxPwrLimit_5G[regulation]
1801                                                                                [bandwidth][5][channelGroup][RfPath];
1802                        else if (rateSection == 5)
1803                                powerLimit = pHalData->TxPwrLimit_5G[regulation]
1804                                                                                [bandwidth][3][channelGroup][RfPath];
1805                }
1806        }
1807        */
1808        /* DBG_871X("TxPwrLmt[Regulation %d][Band %d][BW %d][RFPath %d][Rate 0x%x][Chnl %d] = %d\n", */
1809        /*              regulation, pHalData->CurrentBandType, Bandwidth, RfPath, DataRate, Channel, powerLimit); */
1810        return powerLimit;
1811}
1812
1813static void phy_CrossReferenceHTAndVHTTxPowerLimit(struct adapter *padapter)
1814{
1815        struct hal_com_data     *pHalData = GET_HAL_DATA(padapter);
1816        u8 regulation, bw, channel, rateSection;
1817        s8 tempPwrLmt = 0;
1818
1819        for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
1820                for (bw = 0; bw < MAX_5G_BANDWITH_NUM; ++bw) {
1821                        for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G; ++channel) {
1822                                for (rateSection = 0; rateSection < MAX_RATE_SECTION_NUM; ++rateSection) {
1823                                        tempPwrLmt = pHalData->TxPwrLimit_5G[regulation][bw][rateSection][channel][ODM_RF_PATH_A];
1824                                        if (tempPwrLmt == MAX_POWER_INDEX) {
1825                                                u8 baseSection = 2, refSection = 6;
1826                                                if (bw == 0 || bw == 1) { /*  5G 20M 40M VHT and HT can cross reference */
1827                                                        /* DBG_871X("No power limit table of the specified band %d, bandwidth %d, ratesection %d, channel %d, rf path %d\n", */
1828                                                        /*                      1, bw, rateSection, channel, ODM_RF_PATH_A); */
1829                                                        if (rateSection >= 2 && rateSection <= 9) {
1830                                                                if (rateSection == 2) {
1831                                                                        baseSection = 2;
1832                                                                        refSection = 6;
1833                                                                } else if (rateSection == 3) {
1834                                                                        baseSection = 3;
1835                                                                        refSection = 7;
1836                                                                } else if (rateSection == 4) {
1837                                                                        baseSection = 4;
1838                                                                        refSection = 8;
1839                                                                } else if (rateSection == 5) {
1840                                                                        baseSection = 5;
1841                                                                        refSection = 9;
1842                                                                } else if (rateSection == 6) {
1843                                                                        baseSection = 6;
1844                                                                        refSection = 2;
1845                                                                } else if (rateSection == 7) {
1846                                                                        baseSection = 7;
1847                                                                        refSection = 3;
1848                                                                } else if (rateSection == 8) {
1849                                                                        baseSection = 8;
1850                                                                        refSection = 4;
1851                                                                } else if (rateSection == 9) {
1852                                                                        baseSection = 9;
1853                                                                        refSection = 5;
1854                                                                }
1855                                                                pHalData->TxPwrLimit_5G[regulation][bw][baseSection][channel][ODM_RF_PATH_A] =
1856                                                                        pHalData->TxPwrLimit_5G[regulation][bw][refSection][channel][ODM_RF_PATH_A];
1857                                                        }
1858
1859                                                        /* DBG_871X("use other value %d", tempPwrLmt); */
1860                                                }
1861                                        }
1862                                }
1863                        }
1864                }
1865        }
1866}
1867
1868void PHY_ConvertTxPowerLimitToPowerIndex(struct adapter *Adapter)
1869{
1870        struct hal_com_data     *pHalData = GET_HAL_DATA(Adapter);
1871        u8 BW40PwrBasedBm2_4G = 0x2E;
1872        u8 regulation, bw, channel, rateSection;
1873        s8 tempValue = 0, tempPwrLmt = 0;
1874        u8 rfPath = 0;
1875
1876        /* DBG_871X("=====> PHY_ConvertTxPowerLimitToPowerIndex()\n"); */
1877
1878        phy_CrossReferenceHTAndVHTTxPowerLimit(Adapter);
1879
1880        for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
1881                for (bw = 0; bw < MAX_2_4G_BANDWITH_NUM; ++bw) {
1882                        for (channel = 0; channel < CHANNEL_MAX_NUMBER_2G; ++channel) {
1883                                for (rateSection = 0; rateSection < MAX_RATE_SECTION_NUM; ++rateSection) {
1884                                        tempPwrLmt = pHalData->TxPwrLimit_2_4G[regulation][bw][rateSection][channel][ODM_RF_PATH_A];
1885
1886                                        for (rfPath = ODM_RF_PATH_A; rfPath < MAX_RF_PATH_NUM; ++rfPath) {
1887                                                if (pHalData->odmpriv.PhyRegPgValueType == PHY_REG_PG_EXACT_VALUE) {
1888                                                        if (rateSection == 5) /*  HT 4T */
1889                                                                BW40PwrBasedBm2_4G = PHY_GetTxPowerByRateBase(Adapter, BAND_ON_2_4G, rfPath, RF_4TX, HT_MCS24_MCS31);
1890                                                        else if (rateSection == 4) /*  HT 3T */
1891                                                                BW40PwrBasedBm2_4G = PHY_GetTxPowerByRateBase(Adapter, BAND_ON_2_4G, rfPath, RF_3TX, HT_MCS16_MCS23);
1892                                                        else if (rateSection == 3) /*  HT 2T */
1893                                                                BW40PwrBasedBm2_4G = PHY_GetTxPowerByRateBase(Adapter, BAND_ON_2_4G, rfPath, RF_2TX, HT_MCS8_MCS15);
1894                                                        else if (rateSection == 2) /*  HT 1T */
1895                                                                BW40PwrBasedBm2_4G = PHY_GetTxPowerByRateBase(Adapter, BAND_ON_2_4G, rfPath, RF_1TX, HT_MCS0_MCS7);
1896                                                        else if (rateSection == 1) /*  OFDM */
1897                                                                BW40PwrBasedBm2_4G = PHY_GetTxPowerByRateBase(Adapter, BAND_ON_2_4G, rfPath, RF_1TX, OFDM);
1898                                                        else if (rateSection == 0) /*  CCK */
1899                                                                BW40PwrBasedBm2_4G = PHY_GetTxPowerByRateBase(Adapter, BAND_ON_2_4G, rfPath, RF_1TX, CCK);
1900                                                } else
1901                                                        BW40PwrBasedBm2_4G = Adapter->registrypriv.RegPowerBase * 2;
1902
1903                                                if (tempPwrLmt != MAX_POWER_INDEX) {
1904                                                        tempValue = tempPwrLmt - BW40PwrBasedBm2_4G;
1905                                                        pHalData->TxPwrLimit_2_4G[regulation][bw][rateSection][channel][rfPath] = tempValue;
1906                                                }
1907                                        }
1908                                }
1909                        }
1910                }
1911        }
1912
1913        /* DBG_871X("<===== PHY_ConvertTxPowerLimitToPowerIndex()\n"); */
1914}
1915
1916void PHY_InitTxPowerLimit(struct adapter *Adapter)
1917{
1918        struct hal_com_data     *pHalData = GET_HAL_DATA(Adapter);
1919        u8 i, j, k, l, m;
1920
1921        /* DBG_871X("=====> PHY_InitTxPowerLimit()!\n"); */
1922
1923        for (i = 0; i < MAX_REGULATION_NUM; ++i) {
1924                for (j = 0; j < MAX_2_4G_BANDWITH_NUM; ++j)
1925                        for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
1926                                for (m = 0; m < CHANNEL_MAX_NUMBER_2G; ++m)
1927                                        for (l = 0; l < MAX_RF_PATH_NUM; ++l)
1928                                                pHalData->TxPwrLimit_2_4G[i][j][k][m][l] = MAX_POWER_INDEX;
1929        }
1930
1931        for (i = 0; i < MAX_REGULATION_NUM; ++i) {
1932                for (j = 0; j < MAX_5G_BANDWITH_NUM; ++j)
1933                        for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
1934                                for (m = 0; m < CHANNEL_MAX_NUMBER_5G; ++m)
1935                                        for (l = 0; l < MAX_RF_PATH_NUM; ++l)
1936                                                pHalData->TxPwrLimit_5G[i][j][k][m][l] = MAX_POWER_INDEX;
1937        }
1938
1939        /* DBG_871X("<===== PHY_InitTxPowerLimit()!\n"); */
1940}
1941
1942void PHY_SetTxPowerLimit(
1943        struct adapter *Adapter,
1944        u8 *Regulation,
1945        u8 *Band,
1946        u8 *Bandwidth,
1947        u8 *RateSection,
1948        u8 *RfPath,
1949        u8 *Channel,
1950        u8 *PowerLimit
1951)
1952{
1953        struct hal_com_data     *pHalData = GET_HAL_DATA(Adapter);
1954        u8 regulation = 0, bandwidth = 0, rateSection = 0, channel;
1955        s8 powerLimit = 0, prevPowerLimit, channelIndex;
1956
1957        /* DBG_871X("Index of power limit table [band %s][regulation %s][bw %s][rate section %s][rf path %s][chnl %s][val %s]\n", */
1958        /*        Band, Regulation, Bandwidth, RateSection, RfPath, Channel, PowerLimit); */
1959
1960        if (!GetU1ByteIntegerFromStringInDecimal((s8 *)Channel, &channel) ||
1961                 !GetU1ByteIntegerFromStringInDecimal((s8 *)PowerLimit, &powerLimit))
1962                DBG_871X("Illegal index of power limit table [chnl %s][val %s]\n", Channel, PowerLimit);
1963
1964        powerLimit = powerLimit > MAX_POWER_INDEX ? MAX_POWER_INDEX : powerLimit;
1965
1966        if (eqNByte(Regulation, (u8 *)("FCC"), 3))
1967                regulation = 0;
1968        else if (eqNByte(Regulation, (u8 *)("MKK"), 3))
1969                regulation = 1;
1970        else if (eqNByte(Regulation, (u8 *)("ETSI"), 4))
1971                regulation = 2;
1972        else if (eqNByte(Regulation, (u8 *)("WW13"), 4))
1973                regulation = 3;
1974
1975        if (eqNByte(RateSection, (u8 *)("CCK"), 3) && eqNByte(RfPath, (u8 *)("1T"), 2))
1976                rateSection = 0;
1977        else if (eqNByte(RateSection, (u8 *)("OFDM"), 4) && eqNByte(RfPath, (u8 *)("1T"), 2))
1978                rateSection = 1;
1979        else if (eqNByte(RateSection, (u8 *)("HT"), 2) && eqNByte(RfPath, (u8 *)("1T"), 2))
1980                rateSection = 2;
1981        else if (eqNByte(RateSection, (u8 *)("HT"), 2) && eqNByte(RfPath, (u8 *)("2T"), 2))
1982                rateSection = 3;
1983        else if (eqNByte(RateSection, (u8 *)("HT"), 2) && eqNByte(RfPath, (u8 *)("3T"), 2))
1984                rateSection = 4;
1985        else if (eqNByte(RateSection, (u8 *)("HT"), 2) && eqNByte(RfPath, (u8 *)("4T"), 2))
1986                rateSection = 5;
1987        else if (eqNByte(RateSection, (u8 *)("VHT"), 3) && eqNByte(RfPath, (u8 *)("1T"), 2))
1988                rateSection = 6;
1989        else if (eqNByte(RateSection, (u8 *)("VHT"), 3) && eqNByte(RfPath, (u8 *)("2T"), 2))
1990                rateSection = 7;
1991        else if (eqNByte(RateSection, (u8 *)("VHT"), 3) && eqNByte(RfPath, (u8 *)("3T"), 2))
1992                rateSection = 8;
1993        else if (eqNByte(RateSection, (u8 *)("VHT"), 3) && eqNByte(RfPath, (u8 *)("4T"), 2))
1994                rateSection = 9;
1995        else {
1996                DBG_871X("Wrong rate section!\n");
1997                return;
1998        }
1999
2000
2001        if (eqNByte(Bandwidth, (u8 *)("20M"), 3))
2002                bandwidth = 0;
2003        else if (eqNByte(Bandwidth, (u8 *)("40M"), 3))
2004                bandwidth = 1;
2005        else if (eqNByte(Bandwidth, (u8 *)("80M"), 3))
2006                bandwidth = 2;
2007        else if (eqNByte(Bandwidth, (u8 *)("160M"), 4))
2008                bandwidth = 3;
2009
2010        if (eqNByte(Band, (u8 *)("2.4G"), 4)) {
2011                channelIndex = phy_GetChannelIndexOfTxPowerLimit(BAND_ON_2_4G, channel);
2012
2013                if (channelIndex == -1)
2014                        return;
2015
2016                prevPowerLimit = pHalData->TxPwrLimit_2_4G[regulation][bandwidth][rateSection][channelIndex][ODM_RF_PATH_A];
2017
2018                if (powerLimit < prevPowerLimit)
2019                        pHalData->TxPwrLimit_2_4G[regulation][bandwidth][rateSection][channelIndex][ODM_RF_PATH_A] = powerLimit;
2020
2021                /* DBG_871X("2.4G Band value : [regulation %d][bw %d][rate_section %d][chnl %d][val %d]\n", */
2022                /*        regulation, bandwidth, rateSection, channelIndex, pHalData->TxPwrLimit_2_4G[regulation][bandwidth][rateSection][channelIndex][ODM_RF_PATH_A]); */
2023        } else if (eqNByte(Band, (u8 *)("5G"), 2)) {
2024                channelIndex = phy_GetChannelIndexOfTxPowerLimit(BAND_ON_5G, channel);
2025
2026                if (channelIndex == -1)
2027                        return;
2028
2029                prevPowerLimit = pHalData->TxPwrLimit_5G[regulation][bandwidth][rateSection][channelIndex][ODM_RF_PATH_A];
2030
2031                if (powerLimit < prevPowerLimit)
2032                        pHalData->TxPwrLimit_5G[regulation][bandwidth][rateSection][channelIndex][ODM_RF_PATH_A] = powerLimit;
2033
2034                /* DBG_871X("5G Band value : [regulation %d][bw %d][rate_section %d][chnl %d][val %d]\n", */
2035                /*        regulation, bandwidth, rateSection, channel, pHalData->TxPwrLimit_5G[regulation][bandwidth][rateSection][channelIndex][ODM_RF_PATH_A]); */
2036        } else {
2037                DBG_871X("Cannot recognize the band info in %s\n", Band);
2038                return;
2039        }
2040}
2041
2042u8 PHY_GetTxPowerIndex(
2043        struct adapter *padapter,
2044        u8 RFPath,
2045        u8 Rate,
2046        enum CHANNEL_WIDTH BandWidth,
2047        u8 Channel
2048)
2049{
2050        return PHY_GetTxPowerIndex_8723B(padapter, RFPath, Rate, BandWidth, Channel);
2051}
2052
2053void PHY_SetTxPowerIndex(
2054        struct adapter *padapter, u32 PowerIndex, u8 RFPath, u8 Rate
2055)
2056{
2057        PHY_SetTxPowerIndex_8723B(padapter, PowerIndex, RFPath, Rate);
2058}
2059
2060void Hal_ChannelPlanToRegulation(struct adapter *Adapter, u16 ChannelPlan)
2061{
2062        struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
2063        pHalData->Regulation2_4G = TXPWR_LMT_WW;
2064        pHalData->Regulation5G = TXPWR_LMT_WW;
2065
2066        switch (ChannelPlan) {
2067        case RT_CHANNEL_DOMAIN_WORLD_NULL:
2068                pHalData->Regulation2_4G = TXPWR_LMT_WW;
2069                break;
2070        case RT_CHANNEL_DOMAIN_ETSI1_NULL:
2071                pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
2072                break;
2073        case RT_CHANNEL_DOMAIN_FCC1_NULL:
2074                pHalData->Regulation2_4G = TXPWR_LMT_FCC;
2075                break;
2076        case RT_CHANNEL_DOMAIN_MKK1_NULL:
2077                pHalData->Regulation2_4G = TXPWR_LMT_MKK;
2078                break;
2079        case RT_CHANNEL_DOMAIN_ETSI2_NULL:
2080                pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
2081                break;
2082        case RT_CHANNEL_DOMAIN_FCC1_FCC1:
2083                pHalData->Regulation2_4G = TXPWR_LMT_FCC;
2084                pHalData->Regulation5G = TXPWR_LMT_FCC;
2085                break;
2086        case RT_CHANNEL_DOMAIN_WORLD_ETSI1:
2087                pHalData->Regulation2_4G = TXPWR_LMT_FCC;
2088                pHalData->Regulation5G = TXPWR_LMT_ETSI;
2089                break;
2090        case RT_CHANNEL_DOMAIN_MKK1_MKK1:
2091                pHalData->Regulation2_4G = TXPWR_LMT_MKK;
2092                pHalData->Regulation5G = TXPWR_LMT_MKK;
2093                break;
2094        case RT_CHANNEL_DOMAIN_WORLD_KCC1:
2095                pHalData->Regulation2_4G = TXPWR_LMT_FCC;
2096                pHalData->Regulation5G = TXPWR_LMT_MKK;
2097                break;
2098        case RT_CHANNEL_DOMAIN_WORLD_FCC2:
2099                pHalData->Regulation2_4G = TXPWR_LMT_FCC;
2100                pHalData->Regulation5G = TXPWR_LMT_FCC;
2101                break;
2102        case RT_CHANNEL_DOMAIN_WORLD_FCC3:
2103                pHalData->Regulation2_4G = TXPWR_LMT_FCC;
2104                pHalData->Regulation5G = TXPWR_LMT_FCC;
2105                break;
2106        case RT_CHANNEL_DOMAIN_WORLD_FCC4:
2107                pHalData->Regulation2_4G = TXPWR_LMT_FCC;
2108                pHalData->Regulation5G = TXPWR_LMT_FCC;
2109                break;
2110        case RT_CHANNEL_DOMAIN_WORLD_FCC5:
2111                pHalData->Regulation2_4G = TXPWR_LMT_FCC;
2112                pHalData->Regulation5G = TXPWR_LMT_FCC;
2113                break;
2114        case RT_CHANNEL_DOMAIN_WORLD_FCC6:
2115                pHalData->Regulation2_4G = TXPWR_LMT_FCC;
2116                pHalData->Regulation5G = TXPWR_LMT_FCC;
2117                break;
2118        case RT_CHANNEL_DOMAIN_FCC1_FCC7:
2119                pHalData->Regulation2_4G = TXPWR_LMT_FCC;
2120                pHalData->Regulation5G = TXPWR_LMT_FCC;
2121                break;
2122        case RT_CHANNEL_DOMAIN_WORLD_ETSI2:
2123                pHalData->Regulation2_4G = TXPWR_LMT_FCC;
2124                pHalData->Regulation5G = TXPWR_LMT_FCC;
2125                break;
2126        case RT_CHANNEL_DOMAIN_WORLD_ETSI3:
2127                pHalData->Regulation2_4G = TXPWR_LMT_FCC;
2128                pHalData->Regulation5G = TXPWR_LMT_FCC;
2129                break;
2130        case RT_CHANNEL_DOMAIN_MKK1_MKK2:
2131                pHalData->Regulation2_4G = TXPWR_LMT_MKK;
2132                pHalData->Regulation5G = TXPWR_LMT_FCC;
2133                break;
2134        case RT_CHANNEL_DOMAIN_MKK1_MKK3:
2135                pHalData->Regulation2_4G = TXPWR_LMT_MKK;
2136                pHalData->Regulation5G = TXPWR_LMT_FCC;
2137                break;
2138        case RT_CHANNEL_DOMAIN_FCC1_NCC1:
2139                pHalData->Regulation2_4G = TXPWR_LMT_FCC;
2140                pHalData->Regulation5G = TXPWR_LMT_FCC;
2141                break;
2142        case RT_CHANNEL_DOMAIN_FCC1_NCC2:
2143                pHalData->Regulation2_4G = TXPWR_LMT_FCC;
2144                pHalData->Regulation5G = TXPWR_LMT_FCC;
2145                break;
2146        case RT_CHANNEL_DOMAIN_GLOBAL_NULL:
2147                pHalData->Regulation2_4G = TXPWR_LMT_WW;
2148                pHalData->Regulation5G = TXPWR_LMT_WW;
2149                break;
2150        case RT_CHANNEL_DOMAIN_ETSI1_ETSI4:
2151                pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
2152                pHalData->Regulation5G = TXPWR_LMT_ETSI;
2153                break;
2154        case RT_CHANNEL_DOMAIN_FCC1_FCC2:
2155                pHalData->Regulation2_4G = TXPWR_LMT_FCC;
2156                pHalData->Regulation5G = TXPWR_LMT_FCC;
2157                break;
2158        case RT_CHANNEL_DOMAIN_FCC1_NCC3:
2159                pHalData->Regulation2_4G = TXPWR_LMT_FCC;
2160                pHalData->Regulation5G = TXPWR_LMT_FCC;
2161                break;
2162        case RT_CHANNEL_DOMAIN_WORLD_ETSI5:
2163                pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
2164                pHalData->Regulation5G = TXPWR_LMT_ETSI;
2165                break;
2166        case RT_CHANNEL_DOMAIN_FCC1_FCC8:
2167                pHalData->Regulation2_4G = TXPWR_LMT_FCC;
2168                pHalData->Regulation5G = TXPWR_LMT_FCC;
2169                break;
2170        case RT_CHANNEL_DOMAIN_WORLD_ETSI6:
2171                pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
2172                pHalData->Regulation5G = TXPWR_LMT_ETSI;
2173                break;
2174        case RT_CHANNEL_DOMAIN_WORLD_ETSI7:
2175                pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
2176                pHalData->Regulation5G = TXPWR_LMT_ETSI;
2177                break;
2178        case RT_CHANNEL_DOMAIN_WORLD_ETSI8:
2179                pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
2180                pHalData->Regulation5G = TXPWR_LMT_ETSI;
2181                break;
2182        case RT_CHANNEL_DOMAIN_WORLD_ETSI9:
2183                pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
2184                pHalData->Regulation5G = TXPWR_LMT_ETSI;
2185                break;
2186        case RT_CHANNEL_DOMAIN_WORLD_ETSI10:
2187                pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
2188                pHalData->Regulation5G = TXPWR_LMT_ETSI;
2189                break;
2190        case RT_CHANNEL_DOMAIN_WORLD_ETSI11:
2191                pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
2192                pHalData->Regulation5G = TXPWR_LMT_ETSI;
2193                break;
2194        case RT_CHANNEL_DOMAIN_FCC1_NCC4:
2195                pHalData->Regulation2_4G = TXPWR_LMT_FCC;
2196                pHalData->Regulation5G = TXPWR_LMT_FCC;
2197                break;
2198        case RT_CHANNEL_DOMAIN_WORLD_ETSI12:
2199                pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
2200                pHalData->Regulation5G = TXPWR_LMT_ETSI;
2201                break;
2202        case RT_CHANNEL_DOMAIN_FCC1_FCC9:
2203                pHalData->Regulation2_4G = TXPWR_LMT_FCC;
2204                pHalData->Regulation5G = TXPWR_LMT_FCC;
2205                break;
2206        case RT_CHANNEL_DOMAIN_WORLD_ETSI13:
2207                pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
2208                pHalData->Regulation5G = TXPWR_LMT_ETSI;
2209                break;
2210        case RT_CHANNEL_DOMAIN_FCC1_FCC10:
2211                pHalData->Regulation2_4G = TXPWR_LMT_FCC;
2212                pHalData->Regulation5G = TXPWR_LMT_FCC;
2213                break;
2214        case RT_CHANNEL_DOMAIN_REALTEK_DEFINE: /* Realtek Reserve */
2215                pHalData->Regulation2_4G = TXPWR_LMT_WW;
2216                pHalData->Regulation5G = TXPWR_LMT_WW;
2217                break;
2218        default:
2219                break;
2220        }
2221}
2222
2223
2224static char file_path_bs[PATH_MAX];
2225
2226#define GetLineFromBuffer(buffer)        strsep(&buffer, "\n")
2227
2228int phy_ConfigMACWithParaFile(struct adapter *Adapter, char *pFileName)
2229{
2230        struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
2231        int     rlen = 0, rtStatus = _FAIL;
2232        char *szLine, *ptmp;
2233        u32 u4bRegOffset, u4bRegValue, u4bMove;
2234
2235        if (!(Adapter->registrypriv.load_phy_file & LOAD_MAC_PARA_FILE))
2236                return rtStatus;
2237
2238        memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
2239
2240        if ((pHalData->mac_reg_len == 0) && (pHalData->mac_reg == NULL)) {
2241                rtw_merge_string(file_path_bs, PATH_MAX, rtw_phy_file_path, pFileName);
2242
2243                if (rtw_is_file_readable(file_path_bs) == true) {
2244                        rlen = rtw_retrive_from_file(file_path_bs, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
2245                        if (rlen > 0) {
2246                                rtStatus = _SUCCESS;
2247                                pHalData->mac_reg = vzalloc(rlen);
2248                                if (pHalData->mac_reg) {
2249                                        memcpy(pHalData->mac_reg, pHalData->para_file_buf, rlen);
2250                                        pHalData->mac_reg_len = rlen;
2251                                } else
2252                                        DBG_871X("%s mac_reg alloc fail !\n", __func__);
2253                        }
2254                }
2255        } else {
2256                if ((pHalData->mac_reg_len != 0) && (pHalData->mac_reg != NULL)) {
2257                        memcpy(pHalData->para_file_buf, pHalData->mac_reg, pHalData->mac_reg_len);
2258                        rtStatus = _SUCCESS;
2259                } else
2260                        DBG_871X("%s(): Critical Error !!!\n", __func__);
2261        }
2262
2263        if (rtStatus == _SUCCESS) {
2264                ptmp = pHalData->para_file_buf;
2265                for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
2266                        if (!IsCommentString(szLine)) {
2267                                /*  Get 1st hex value as register offset */
2268                                if (GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove)) {
2269                                        if (u4bRegOffset == 0xffff) /*  Ending. */
2270                                                break;
2271
2272                                        /*  Get 2nd hex value as register value. */
2273                                        szLine += u4bMove;
2274                                        if (GetHexValueFromString(szLine, &u4bRegValue, &u4bMove))
2275                                                rtw_write8(Adapter, u4bRegOffset, (u8)u4bRegValue);
2276                                }
2277                        }
2278                }
2279        } else
2280                DBG_871X("%s(): No File %s, Load from HWImg Array!\n", __func__, pFileName);
2281
2282        return rtStatus;
2283}
2284
2285int phy_ConfigBBWithParaFile(
2286        struct adapter *Adapter, char *pFileName, u32 ConfigType
2287)
2288{
2289        struct hal_com_data     *pHalData = GET_HAL_DATA(Adapter);
2290        int     rlen = 0, rtStatus = _FAIL;
2291        char *szLine, *ptmp;
2292        u32 u4bRegOffset, u4bRegValue, u4bMove;
2293        char *pBuf = NULL;
2294        u32 *pBufLen = NULL;
2295
2296        if (!(Adapter->registrypriv.load_phy_file & LOAD_BB_PARA_FILE))
2297                return rtStatus;
2298
2299        switch (ConfigType) {
2300        case CONFIG_BB_PHY_REG:
2301                pBuf = pHalData->bb_phy_reg;
2302                pBufLen = &pHalData->bb_phy_reg_len;
2303                break;
2304        case CONFIG_BB_AGC_TAB:
2305                pBuf = pHalData->bb_agc_tab;
2306                pBufLen = &pHalData->bb_agc_tab_len;
2307                break;
2308        default:
2309                DBG_871X("Unknown ConfigType!! %d\r\n", ConfigType);
2310                break;
2311        }
2312
2313        memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
2314
2315        if ((pBufLen != NULL) && (*pBufLen == 0) && (pBuf == NULL)) {
2316                rtw_merge_string(file_path_bs, PATH_MAX, rtw_phy_file_path, pFileName);
2317
2318                if (rtw_is_file_readable(file_path_bs) == true) {
2319                        rlen = rtw_retrive_from_file(file_path_bs, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
2320                        if (rlen > 0) {
2321                                rtStatus = _SUCCESS;
2322                                pBuf = vzalloc(rlen);
2323                                if (pBuf) {
2324                                        memcpy(pBuf, pHalData->para_file_buf, rlen);
2325                                        *pBufLen = rlen;
2326
2327                                        switch (ConfigType) {
2328                                        case CONFIG_BB_PHY_REG:
2329                                                pHalData->bb_phy_reg = pBuf;
2330                                                break;
2331                                        case CONFIG_BB_AGC_TAB:
2332                                                pHalData->bb_agc_tab = pBuf;
2333                                                break;
2334                                        }
2335                                } else
2336                                        DBG_871X("%s(): ConfigType %d  alloc fail !\n", __func__, ConfigType);
2337                        }
2338                }
2339        } else {
2340                if ((pBufLen != NULL) && (*pBufLen == 0) && (pBuf == NULL)) {
2341                        memcpy(pHalData->para_file_buf, pBuf, *pBufLen);
2342                        rtStatus = _SUCCESS;
2343                } else
2344                        DBG_871X("%s(): Critical Error !!!\n", __func__);
2345        }
2346
2347        if (rtStatus == _SUCCESS) {
2348                ptmp = pHalData->para_file_buf;
2349                for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
2350                        if (!IsCommentString(szLine)) {
2351                                /*  Get 1st hex value as register offset. */
2352                                if (GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove)) {
2353                                        if (u4bRegOffset == 0xffff) /*  Ending. */
2354                                                break;
2355                                        else if (u4bRegOffset == 0xfe || u4bRegOffset == 0xffe)
2356                                                msleep(50);
2357                                        else if (u4bRegOffset == 0xfd)
2358                                                mdelay(5);
2359                                        else if (u4bRegOffset == 0xfc)
2360                                                mdelay(1);
2361                                        else if (u4bRegOffset == 0xfb)
2362                                                udelay(50);
2363                                        else if (u4bRegOffset == 0xfa)
2364                                                udelay(5);
2365                                        else if (u4bRegOffset == 0xf9)
2366                                                udelay(1);
2367
2368                                        /*  Get 2nd hex value as register value. */
2369                                        szLine += u4bMove;
2370                                        if (GetHexValueFromString(szLine, &u4bRegValue, &u4bMove)) {
2371                                                /* DBG_871X("[BB-ADDR]%03lX =%08lX\n", u4bRegOffset, u4bRegValue); */
2372                                                PHY_SetBBReg(Adapter, u4bRegOffset, bMaskDWord, u4bRegValue);
2373
2374                                                if (u4bRegOffset == 0xa24)
2375                                                        pHalData->odmpriv.RFCalibrateInfo.RegA24 = u4bRegValue;
2376
2377                                                /*  Add 1us delay between BB/RF register setting. */
2378                                                udelay(1);
2379                                        }
2380                                }
2381                        }
2382                }
2383        } else
2384                DBG_871X("%s(): No File %s, Load from HWImg Array!\n", __func__, pFileName);
2385
2386        return rtStatus;
2387}
2388
2389static void phy_DecryptBBPgParaFile(struct adapter *Adapter, char *buffer)
2390{
2391        u32 i = 0, j = 0;
2392        u8 map[95] = {0};
2393        u8 currentChar;
2394        char *BufOfLines, *ptmp;
2395
2396        /* DBG_871X("=====>phy_DecryptBBPgParaFile()\n"); */
2397        /*  32 the ascii code of the first visable char, 126 the last one */
2398        for (i = 0; i < 95; ++i)
2399                map[i] = (u8) (94 - i);
2400
2401        ptmp = buffer;
2402        i = 0;
2403        for (BufOfLines = GetLineFromBuffer(ptmp); BufOfLines != NULL; BufOfLines = GetLineFromBuffer(ptmp)) {
2404                /* DBG_871X("Encrypted Line: %s\n", BufOfLines); */
2405
2406                for (j = 0; j < strlen(BufOfLines); ++j) {
2407                        currentChar = BufOfLines[j];
2408
2409                        if (currentChar == '\0')
2410                                break;
2411
2412                        currentChar -=  (u8) ((((i + j) * 3) % 128));
2413
2414                        BufOfLines[j] = map[currentChar - 32] + 32;
2415                }
2416                /* DBG_871X("Decrypted Line: %s\n", BufOfLines); */
2417                if (strlen(BufOfLines) != 0)
2418                        i++;
2419                BufOfLines[strlen(BufOfLines)] = '\n';
2420        }
2421}
2422
2423static int phy_ParseBBPgParaFile(struct adapter *Adapter, char *buffer)
2424{
2425        int     rtStatus = _SUCCESS;
2426        struct hal_com_data     *pHalData = GET_HAL_DATA(Adapter);
2427        char *szLine, *ptmp;
2428        u32 u4bRegOffset, u4bRegMask, u4bRegValue;
2429        u32 u4bMove;
2430        bool firstLine = true;
2431        u8 tx_num = 0;
2432        u8 band = 0, rf_path = 0;
2433
2434        /* DBG_871X("=====>phy_ParseBBPgParaFile()\n"); */
2435
2436        if (Adapter->registrypriv.RegDecryptCustomFile == 1)
2437                phy_DecryptBBPgParaFile(Adapter, buffer);
2438
2439        ptmp = buffer;
2440        for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
2441                if (!IsCommentString(szLine)) {
2442                        if (isAllSpaceOrTab(szLine, sizeof(*szLine)))
2443                                continue;
2444
2445                        /*  Get header info (relative value or exact value) */
2446                        if (firstLine) {
2447                                if (eqNByte(szLine, (u8 *)("#[v1]"), 5)) {
2448
2449                                        pHalData->odmpriv.PhyRegPgVersion = szLine[3] - '0';
2450                                        /* DBG_871X("This is a new format PHY_REG_PG.txt\n"); */
2451                                } else if (eqNByte(szLine, (u8 *)("#[v0]"), 5)) {
2452                                        pHalData->odmpriv.PhyRegPgVersion = szLine[3] - '0';
2453                                        /* DBG_871X("This is a old format PHY_REG_PG.txt ok\n"); */
2454                                } else {
2455                                        DBG_871X("The format in PHY_REG_PG are invalid %s\n", szLine);
2456                                        return _FAIL;
2457                                }
2458
2459                                if (eqNByte(szLine + 5, (u8 *)("[Exact]#"), 8)) {
2460                                        pHalData->odmpriv.PhyRegPgValueType = PHY_REG_PG_EXACT_VALUE;
2461                                        /* DBG_871X("The values in PHY_REG_PG are exact values ok\n"); */
2462                                        firstLine = false;
2463                                        continue;
2464                                } else if (eqNByte(szLine + 5, (u8 *)("[Relative]#"), 11)) {
2465                                        pHalData->odmpriv.PhyRegPgValueType = PHY_REG_PG_RELATIVE_VALUE;
2466                                        /* DBG_871X("The values in PHY_REG_PG are relative values ok\n"); */
2467                                        firstLine = false;
2468                                        continue;
2469                                } else {
2470                                        DBG_871X("The values in PHY_REG_PG are invalid %s\n", szLine);
2471                                        return _FAIL;
2472                                }
2473                        }
2474
2475                        if (pHalData->odmpriv.PhyRegPgVersion == 0) {
2476                                /*  Get 1st hex value as register offset. */
2477                                if (GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove)) {
2478                                        szLine += u4bMove;
2479                                        if (u4bRegOffset == 0xffff) /*  Ending. */
2480                                                break;
2481
2482                                        /*  Get 2nd hex value as register mask. */
2483                                        if (GetHexValueFromString(szLine, &u4bRegMask, &u4bMove))
2484                                                szLine += u4bMove;
2485                                        else
2486                                                return _FAIL;
2487
2488                                        if (pHalData->odmpriv.PhyRegPgValueType == PHY_REG_PG_RELATIVE_VALUE) {
2489                                                /*  Get 3rd hex value as register value. */
2490                                                if (GetHexValueFromString(szLine, &u4bRegValue, &u4bMove)) {
2491                                                        PHY_StoreTxPowerByRate(Adapter, 0, 0, 1, u4bRegOffset, u4bRegMask, u4bRegValue);
2492                                                        /* DBG_871X("[ADDR] %03X =%08X Mask =%08x\n", u4bRegOffset, u4bRegValue, u4bRegMask); */
2493                                                } else
2494                                                        return _FAIL;
2495                                        } else if (pHalData->odmpriv.PhyRegPgValueType == PHY_REG_PG_EXACT_VALUE) {
2496                                                u32 combineValue = 0;
2497                                                u8 integer = 0, fraction = 0;
2498
2499                                                if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
2500                                                        szLine += u4bMove;
2501                                                else
2502                                                        return _FAIL;
2503
2504                                                integer *= 2;
2505                                                if (fraction == 5)
2506                                                        integer += 1;
2507                                                combineValue |= (((integer / 10) << 4) + (integer % 10));
2508                                                /* DBG_871X(" %d", integer); */
2509
2510                                                if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
2511                                                        szLine += u4bMove;
2512                                                else
2513                                                        return _FAIL;
2514
2515                                                integer *= 2;
2516                                                if (fraction == 5)
2517                                                        integer += 1;
2518                                                combineValue <<= 8;
2519                                                combineValue |= (((integer / 10) << 4) + (integer % 10));
2520                                                /* DBG_871X(" %d", integer); */
2521
2522                                                if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
2523                                                        szLine += u4bMove;
2524                                                else
2525                                                        return _FAIL;
2526
2527                                                integer *= 2;
2528                                                if (fraction == 5)
2529                                                        integer += 1;
2530                                                combineValue <<= 8;
2531                                                combineValue |= (((integer / 10) << 4) + (integer % 10));
2532                                                /* DBG_871X(" %d", integer); */
2533
2534                                                if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
2535                                                        szLine += u4bMove;
2536                                                else
2537                                                        return _FAIL;
2538
2539                                                integer *= 2;
2540                                                if (fraction == 5)
2541                                                        integer += 1;
2542                                                combineValue <<= 8;
2543                                                combineValue |= (((integer / 10) << 4) + (integer % 10));
2544                                                /* DBG_871X(" %d", integer); */
2545                                                PHY_StoreTxPowerByRate(Adapter, 0, 0, 1, u4bRegOffset, u4bRegMask, combineValue);
2546
2547                                                /* DBG_871X("[ADDR] 0x%3x = 0x%4x\n", u4bRegOffset, combineValue); */
2548                                        }
2549                                }
2550                        } else if (pHalData->odmpriv.PhyRegPgVersion > 0) {
2551                                u32 index = 0;
2552
2553                                if (eqNByte(szLine, "0xffff", 6))
2554                                        break;
2555
2556                                if (!eqNByte("#[END]#", szLine, 7)) {
2557                                        /*  load the table label info */
2558                                        if (szLine[0] == '#') {
2559                                                index = 0;
2560                                                if (eqNByte(szLine, "#[2.4G]", 7)) {
2561                                                        band = BAND_ON_2_4G;
2562                                                        index += 8;
2563                                                } else if (eqNByte(szLine, "#[5G]", 5)) {
2564                                                        band = BAND_ON_5G;
2565                                                        index += 6;
2566                                                } else {
2567                                                        DBG_871X("Invalid band %s in PHY_REG_PG.txt\n", szLine);
2568                                                        return _FAIL;
2569                                                }
2570
2571                                                rf_path = szLine[index] - 'A';
2572                                                /* DBG_871X(" Table label Band %d, RfPath %d\n", band, rf_path); */
2573                                        } else { /*  load rows of tables */
2574                                                if (szLine[1] == '1')
2575                                                        tx_num = RF_1TX;
2576                                                else if (szLine[1] == '2')
2577                                                        tx_num = RF_2TX;
2578                                                else if (szLine[1] == '3')
2579                                                        tx_num = RF_3TX;
2580                                                else if (szLine[1] == '4')
2581                                                        tx_num = RF_4TX;
2582                                                else {
2583                                                        DBG_871X("Invalid row in PHY_REG_PG.txt %c\n", szLine[1]);
2584                                                        return _FAIL;
2585                                                }
2586
2587                                                while (szLine[index] != ']')
2588                                                        ++index;
2589                                                ++index;/*  skip ] */
2590
2591                                                /*  Get 2nd hex value as register offset. */
2592                                                szLine += index;
2593                                                if (GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove))
2594                                                        szLine += u4bMove;
2595                                                else
2596                                                        return _FAIL;
2597
2598                                                /*  Get 2nd hex value as register mask. */
2599                                                if (GetHexValueFromString(szLine, &u4bRegMask, &u4bMove))
2600                                                        szLine += u4bMove;
2601                                                else
2602                                                        return _FAIL;
2603
2604                                                if (pHalData->odmpriv.PhyRegPgValueType == PHY_REG_PG_RELATIVE_VALUE) {
2605                                                        /*  Get 3rd hex value as register value. */
2606                                                        if (GetHexValueFromString(szLine, &u4bRegValue, &u4bMove)) {
2607                                                                PHY_StoreTxPowerByRate(Adapter, band, rf_path, tx_num, u4bRegOffset, u4bRegMask, u4bRegValue);
2608                                                                /* DBG_871X("[ADDR] %03X (tx_num %d) =%08X Mask =%08x\n", u4bRegOffset, tx_num, u4bRegValue, u4bRegMask); */
2609                                                        } else
2610                                                                return _FAIL;
2611                                                } else if (pHalData->odmpriv.PhyRegPgValueType == PHY_REG_PG_EXACT_VALUE) {
2612                                                        u32 combineValue = 0;
2613                                                        u8 integer = 0, fraction = 0;
2614
2615                                                        if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
2616                                                                szLine += u4bMove;
2617                                                        else
2618                                                                return _FAIL;
2619
2620                                                        integer *= 2;
2621                                                        if (fraction == 5)
2622                                                                integer += 1;
2623                                                        combineValue |= (((integer / 10) << 4) + (integer % 10));
2624                                                        /* DBG_871X(" %d", integer); */
2625
2626                                                        if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
2627                                                                szLine += u4bMove;
2628                                                        else
2629                                                                return _FAIL;
2630
2631                                                        integer *= 2;
2632                                                        if (fraction == 5)
2633                                                                integer += 1;
2634                                                        combineValue <<= 8;
2635                                                        combineValue |= (((integer / 10) << 4) + (integer % 10));
2636                                                        /* DBG_871X(" %d", integer); */
2637
2638                                                        if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
2639                                                                szLine += u4bMove;
2640                                                        else
2641                                                                return _FAIL;
2642
2643                                                        integer *= 2;
2644                                                        if (fraction == 5)
2645                                                                integer += 1;
2646                                                        combineValue <<= 8;
2647                                                        combineValue |= (((integer / 10) << 4) + (integer % 10));
2648                                                        /* DBG_871X(" %d", integer); */
2649
2650                                                        if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
2651                                                                szLine += u4bMove;
2652                                                        else
2653                                                                return _FAIL;
2654
2655                                                        integer *= 2;
2656                                                        if (fraction == 5)
2657                                                                integer += 1;
2658                                                        combineValue <<= 8;
2659                                                        combineValue |= (((integer / 10) << 4) + (integer % 10));
2660                                                        /* DBG_871X(" %d", integer); */
2661                                                        PHY_StoreTxPowerByRate(Adapter, band, rf_path, tx_num, u4bRegOffset, u4bRegMask, combineValue);
2662
2663                                                        /* DBG_871X("[ADDR] 0x%3x (tx_num %d) = 0x%4x\n", u4bRegOffset, tx_num, combineValue); */
2664                                                }
2665                                        }
2666                                }
2667                        }
2668                }
2669        }
2670        /* DBG_871X("<=====phy_ParseBBPgParaFile()\n"); */
2671        return rtStatus;
2672}
2673
2674int phy_ConfigBBWithPgParaFile(struct adapter *Adapter, char *pFileName)
2675{
2676        struct hal_com_data     *pHalData = GET_HAL_DATA(Adapter);
2677        int     rlen = 0, rtStatus = _FAIL;
2678
2679        if (!(Adapter->registrypriv.load_phy_file & LOAD_BB_PG_PARA_FILE))
2680                return rtStatus;
2681
2682        memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
2683
2684        if ((pHalData->bb_phy_reg_pg_len == 0) && (pHalData->bb_phy_reg_pg == NULL)) {
2685                rtw_merge_string(file_path_bs, PATH_MAX, rtw_phy_file_path, pFileName);
2686
2687                if (rtw_is_file_readable(file_path_bs) == true) {
2688                        rlen = rtw_retrive_from_file(file_path_bs, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
2689                        if (rlen > 0) {
2690                                rtStatus = _SUCCESS;
2691                                pHalData->bb_phy_reg_pg = vzalloc(rlen);
2692                                if (pHalData->bb_phy_reg_pg) {
2693                                        memcpy(pHalData->bb_phy_reg_pg, pHalData->para_file_buf, rlen);
2694                                        pHalData->bb_phy_reg_pg_len = rlen;
2695                                } else
2696                                        DBG_871X("%s bb_phy_reg_pg alloc fail !\n", __func__);
2697                        }
2698                }
2699        } else {
2700                if ((pHalData->bb_phy_reg_pg_len != 0) && (pHalData->bb_phy_reg_pg != NULL)) {
2701                        memcpy(pHalData->para_file_buf, pHalData->bb_phy_reg_pg, pHalData->bb_phy_reg_pg_len);
2702                        rtStatus = _SUCCESS;
2703                } else
2704                        DBG_871X("%s(): Critical Error !!!\n", __func__);
2705        }
2706
2707        if (rtStatus == _SUCCESS) {
2708                /* DBG_871X("phy_ConfigBBWithPgParaFile(): read %s ok\n", pFileName); */
2709                phy_ParseBBPgParaFile(Adapter, pHalData->para_file_buf);
2710        } else
2711                DBG_871X("%s(): No File %s, Load from HWImg Array!\n", __func__, pFileName);
2712
2713        return rtStatus;
2714}
2715
2716int PHY_ConfigRFWithParaFile(
2717        struct adapter *Adapter, char *pFileName, u8 eRFPath
2718)
2719{
2720        struct hal_com_data     *pHalData = GET_HAL_DATA(Adapter);
2721        int     rlen = 0, rtStatus = _FAIL;
2722        char *szLine, *ptmp;
2723        u32 u4bRegOffset, u4bRegValue, u4bMove;
2724        u16 i;
2725        char *pBuf = NULL;
2726        u32 *pBufLen = NULL;
2727
2728        if (!(Adapter->registrypriv.load_phy_file & LOAD_RF_PARA_FILE))
2729                return rtStatus;
2730
2731        switch (eRFPath) {
2732        case ODM_RF_PATH_A:
2733                pBuf = pHalData->rf_radio_a;
2734                pBufLen = &pHalData->rf_radio_a_len;
2735                break;
2736        case ODM_RF_PATH_B:
2737                pBuf = pHalData->rf_radio_b;
2738                pBufLen = &pHalData->rf_radio_b_len;
2739                break;
2740        default:
2741                DBG_871X("Unknown RF path!! %d\r\n", eRFPath);
2742                break;
2743        }
2744
2745        memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
2746
2747        if ((pBufLen != NULL) && (*pBufLen == 0) && (pBuf == NULL)) {
2748                rtw_merge_string(file_path_bs, PATH_MAX, rtw_phy_file_path, pFileName);
2749
2750                if (rtw_is_file_readable(file_path_bs) == true) {
2751                        rlen = rtw_retrive_from_file(file_path_bs, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
2752                        if (rlen > 0) {
2753                                rtStatus = _SUCCESS;
2754                                pBuf = vzalloc(rlen);
2755                                if (pBuf) {
2756                                        memcpy(pBuf, pHalData->para_file_buf, rlen);
2757                                        *pBufLen = rlen;
2758
2759                                        switch (eRFPath) {
2760                                        case ODM_RF_PATH_A:
2761                                                pHalData->rf_radio_a = pBuf;
2762                                                break;
2763                                        case ODM_RF_PATH_B:
2764                                                pHalData->rf_radio_b = pBuf;
2765                                                break;
2766                                        }
2767                                } else
2768                                        DBG_871X("%s(): eRFPath =%d  alloc fail !\n", __func__, eRFPath);
2769                        }
2770                }
2771        } else {
2772                if ((pBufLen != NULL) && (*pBufLen == 0) && (pBuf == NULL)) {
2773                        memcpy(pHalData->para_file_buf, pBuf, *pBufLen);
2774                        rtStatus = _SUCCESS;
2775                } else
2776                        DBG_871X("%s(): Critical Error !!!\n", __func__);
2777        }
2778
2779        if (rtStatus == _SUCCESS) {
2780                /* DBG_871X("%s(): read %s successfully\n", __func__, pFileName); */
2781
2782                ptmp = pHalData->para_file_buf;
2783                for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
2784                        if (!IsCommentString(szLine)) {
2785                                /*  Get 1st hex value as register offset. */
2786                                if (GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove)) {
2787                                        if (u4bRegOffset == 0xfe || u4bRegOffset == 0xffe) /*  Deay specific ms. Only RF configuration require delay. */
2788                                                msleep(50);
2789                                        else if (u4bRegOffset == 0xfd) {
2790                                                /* mdelay(5); */
2791                                                for (i = 0; i < 100; i++)
2792                                                        udelay(MAX_STALL_TIME);
2793                                        } else if (u4bRegOffset == 0xfc) {
2794                                                /* mdelay(1); */
2795                                                for (i = 0; i < 20; i++)
2796                                                        udelay(MAX_STALL_TIME);
2797                                        } else if (u4bRegOffset == 0xfb)
2798                                                udelay(50);
2799                                        else if (u4bRegOffset == 0xfa)
2800                                                udelay(5);
2801                                        else if (u4bRegOffset == 0xf9)
2802                                                udelay(1);
2803                                        else if (u4bRegOffset == 0xffff)
2804                                                break;
2805
2806                                        /*  Get 2nd hex value as register value. */
2807                                        szLine += u4bMove;
2808                                        if (GetHexValueFromString(szLine, &u4bRegValue, &u4bMove)) {
2809                                                PHY_SetRFReg(Adapter, eRFPath, u4bRegOffset, bRFRegOffsetMask, u4bRegValue);
2810
2811                                                /*  Temp add, for frequency lock, if no delay, that may cause */
2812                                                /*  frequency shift, ex: 2412MHz => 2417MHz */
2813                                                /*  If frequency shift, the following action may works. */
2814                                                /*  Fractional-N table in radio_a.txt */
2815                                                /* 0x2a 0x00001         channel 1 */
2816                                                /* 0x2b 0x00808         frequency divider. */
2817                                                /* 0x2b 0x53333 */
2818                                                /* 0x2c 0x0000c */
2819                                                udelay(1);
2820                                        }
2821                                }
2822                        }
2823                }
2824        } else
2825                DBG_871X("%s(): No File %s, Load from HWImg Array!\n", __func__, pFileName);
2826
2827        return rtStatus;
2828}
2829
2830static void initDeltaSwingIndexTables(
2831        struct adapter *Adapter,
2832        char *Band,
2833        char *Path,
2834        char *Sign,
2835        char *Channel,
2836        char *Rate,
2837        char *Data
2838)
2839{
2840        #define STR_EQUAL_5G(_band, _path, _sign, _rate, _chnl) \
2841                ((strcmp(Band, _band) == 0) && (strcmp(Path, _path) == 0) && (strcmp(Sign, _sign) == 0) &&\
2842                (strcmp(Rate, _rate) == 0) && (strcmp(Channel, _chnl) == 0)\
2843        )
2844        #define STR_EQUAL_2G(_band, _path, _sign, _rate) \
2845                ((strcmp(Band, _band) == 0) && (strcmp(Path, _path) == 0) && (strcmp(Sign, _sign) == 0) &&\
2846                (strcmp(Rate, _rate) == 0)\
2847        )
2848
2849        #define STORE_SWING_TABLE(_array, _iteratedIdx) \
2850                for (token = strsep(&Data, delim); token != NULL; token = strsep(&Data, delim)) {\
2851                        sscanf(token, "%d", &idx);\
2852                        _array[_iteratedIdx++] = (u8)idx;\
2853                } \
2854
2855        struct hal_com_data     *pHalData = GET_HAL_DATA(Adapter);
2856        PDM_ODM_T pDM_Odm = &pHalData->odmpriv;
2857        PODM_RF_CAL_T pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo);
2858        u32 j = 0;
2859        char *token;
2860        char delim[] = ",";
2861        u32 idx = 0;
2862
2863        /* DBG_871X("===>initDeltaSwingIndexTables(): Band: %s;\nPath: %s;\nSign: %s;\nChannel: %s;\nRate: %s;\n, Data: %s;\n", */
2864        /*      Band, Path, Sign, Channel, Rate, Data); */
2865
2866        if (STR_EQUAL_2G("2G", "A", "+", "CCK")) {
2867                STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_P, j);
2868        } else if (STR_EQUAL_2G("2G", "A", "-", "CCK")) {
2869                STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_N, j);
2870        } else if (STR_EQUAL_2G("2G", "B", "+", "CCK")) {
2871                STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_P, j);
2872        } else if (STR_EQUAL_2G("2G", "B", "-", "CCK")) {
2873                STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_N, j);
2874        } else if (STR_EQUAL_2G("2G", "A", "+", "ALL")) {
2875                STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GA_P, j);
2876        } else if (STR_EQUAL_2G("2G", "A", "-", "ALL")) {
2877                STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GA_N, j);
2878        } else if (STR_EQUAL_2G("2G", "B", "+", "ALL")) {
2879                STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GB_P, j);
2880        } else if (STR_EQUAL_2G("2G", "B", "-", "ALL")) {
2881                STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GB_N, j);
2882        } else if (STR_EQUAL_5G("5G", "A", "+", "ALL", "0")) {
2883                STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_P[0], j);
2884        } else if (STR_EQUAL_5G("5G", "A", "-", "ALL", "0")) {
2885                STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_N[0], j);
2886        } else if (STR_EQUAL_5G("5G", "B", "+", "ALL", "0")) {
2887                STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_P[0], j);
2888        } else if (STR_EQUAL_5G("5G", "B", "-", "ALL", "0")) {
2889                STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_N[0], j);
2890        } else if (STR_EQUAL_5G("5G", "A", "+", "ALL", "1")) {
2891                STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_P[1], j);
2892        } else if (STR_EQUAL_5G("5G", "A", "-", "ALL", "1")) {
2893                STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_N[1], j);
2894        } else if (STR_EQUAL_5G("5G", "B", "+", "ALL", "1")) {
2895                STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_P[1], j);
2896        } else if (STR_EQUAL_5G("5G", "B", "-", "ALL", "1")) {
2897                STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_N[1], j);
2898        } else if (STR_EQUAL_5G("5G", "A", "+", "ALL", "2")) {
2899                STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_P[2], j);
2900        } else if (STR_EQUAL_5G("5G", "A", "-", "ALL", "2")) {
2901                STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_N[2], j);
2902        } else if (STR_EQUAL_5G("5G", "B", "+", "ALL", "2")) {
2903                STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_P[2], j);
2904        } else if (STR_EQUAL_5G("5G", "B", "-", "ALL", "2")) {
2905                STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_N[2], j);
2906        } else if (STR_EQUAL_5G("5G", "A", "+", "ALL", "3")) {
2907                STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_P[3], j);
2908        } else if (STR_EQUAL_5G("5G", "A", "-", "ALL", "3")) {
2909                STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_N[3], j);
2910        } else if (STR_EQUAL_5G("5G", "B", "+", "ALL", "3")) {
2911                STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_P[3], j);
2912        } else if (STR_EQUAL_5G("5G", "B", "-", "ALL", "3")) {
2913                STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_N[3], j);
2914        } else
2915                DBG_871X("===>initDeltaSwingIndexTables(): The input is invalid!!\n");
2916}
2917
2918int PHY_ConfigRFWithTxPwrTrackParaFile(struct adapter *Adapter, char *pFileName)
2919{
2920        struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
2921        int     rlen = 0, rtStatus = _FAIL;
2922        char *szLine, *ptmp;
2923        u32 i = 0;
2924
2925        if (!(Adapter->registrypriv.load_phy_file & LOAD_RF_TXPWR_TRACK_PARA_FILE))
2926                return rtStatus;
2927
2928        memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
2929
2930        if ((pHalData->rf_tx_pwr_track_len == 0) && (pHalData->rf_tx_pwr_track == NULL)) {
2931                rtw_merge_string(file_path_bs, PATH_MAX, rtw_phy_file_path, pFileName);
2932
2933                if (rtw_is_file_readable(file_path_bs) == true) {
2934                        rlen = rtw_retrive_from_file(file_path_bs, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
2935                        if (rlen > 0) {
2936                                rtStatus = _SUCCESS;
2937                                pHalData->rf_tx_pwr_track = vzalloc(rlen);
2938                                if (pHalData->rf_tx_pwr_track) {
2939                                        memcpy(pHalData->rf_tx_pwr_track, pHalData->para_file_buf, rlen);
2940                                        pHalData->rf_tx_pwr_track_len = rlen;
2941                                } else
2942                                        DBG_871X("%s rf_tx_pwr_track alloc fail !\n", __func__);
2943                        }
2944                }
2945        } else {
2946                if ((pHalData->rf_tx_pwr_track_len != 0) && (pHalData->rf_tx_pwr_track != NULL)) {
2947                        memcpy(pHalData->para_file_buf, pHalData->rf_tx_pwr_track, pHalData->rf_tx_pwr_track_len);
2948                        rtStatus = _SUCCESS;
2949                } else
2950                        DBG_871X("%s(): Critical Error !!!\n", __func__);
2951        }
2952
2953        if (rtStatus == _SUCCESS) {
2954                /* DBG_871X("%s(): read %s successfully\n", __func__, pFileName); */
2955
2956                ptmp = pHalData->para_file_buf;
2957                for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
2958                        if (!IsCommentString(szLine)) {
2959                                char band[5] = "", path[5] = "", sign[5] = "";
2960                                char chnl[5] = "", rate[10] = "";
2961                                char data[300] = ""; /*  100 is too small */
2962
2963                                if (strlen(szLine) < 10 || szLine[0] != '[')
2964                                        continue;
2965
2966                                strncpy(band, szLine+1, 2);
2967                                strncpy(path, szLine+5, 1);
2968                                strncpy(sign, szLine+8, 1);
2969
2970                                i = 10; /*  szLine+10 */
2971                                if (!ParseQualifiedString(szLine, &i, rate, '[', ']')) {
2972                                        /* DBG_871X("Fail to parse rate!\n"); */
2973                                }
2974                                if (!ParseQualifiedString(szLine, &i, chnl, '[', ']')) {
2975                                        /* DBG_871X("Fail to parse channel group!\n"); */
2976                                }
2977                                while (szLine[i] != '{' && i < strlen(szLine))
2978                                        i++;
2979                                if (!ParseQualifiedString(szLine, &i, data, '{', '}')) {
2980                                        /* DBG_871X("Fail to parse data!\n"); */
2981                                }
2982
2983                                initDeltaSwingIndexTables(Adapter, band, path, sign, chnl, rate, data);
2984                        }
2985                }
2986        } else
2987                DBG_871X("%s(): No File %s, Load from HWImg Array!\n", __func__, pFileName);
2988
2989        return rtStatus;
2990}
2991
2992static int phy_ParsePowerLimitTableFile(struct adapter *Adapter, char *buffer)
2993{
2994        u32 i = 0, forCnt = 0;
2995        u8 loadingStage = 0, limitValue = 0, fraction = 0;
2996        char *szLine, *ptmp;
2997        int     rtStatus = _SUCCESS;
2998        char band[10], bandwidth[10], rateSection[10],
2999                regulation[TXPWR_LMT_MAX_REGULATION_NUM][10], rfPath[10], colNumBuf[10];
3000        u8 colNum = 0;
3001
3002        DBG_871X("===>phy_ParsePowerLimitTableFile()\n");
3003
3004        if (Adapter->registrypriv.RegDecryptCustomFile == 1)
3005                phy_DecryptBBPgParaFile(Adapter, buffer);
3006
3007        ptmp = buffer;
3008        for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
3009                /*  skip comment */
3010                if (IsCommentString(szLine)) {
3011                        continue;
3012                }
3013
3014                if (loadingStage == 0) {
3015                        for (forCnt = 0; forCnt < TXPWR_LMT_MAX_REGULATION_NUM; ++forCnt)
3016                                memset((void *) regulation[forCnt], 0, 10);
3017
3018                        memset((void *) band, 0, 10);
3019                        memset((void *) bandwidth, 0, 10);
3020                        memset((void *) rateSection, 0, 10);
3021                        memset((void *) rfPath, 0, 10);
3022                        memset((void *) colNumBuf, 0, 10);
3023
3024                        if (szLine[0] != '#' || szLine[1] != '#')
3025                                continue;
3026
3027                        /*  skip the space */
3028                        i = 2;
3029                        while (szLine[i] == ' ' || szLine[i] == '\t')
3030                                ++i;
3031
3032                        szLine[--i] = ' '; /*  return the space in front of the regulation info */
3033
3034                        /*  Parse the label of the table */
3035                        if (!ParseQualifiedString(szLine, &i, band, ' ', ',')) {
3036                                DBG_871X("Fail to parse band!\n");
3037                                return _FAIL;
3038                        }
3039                        if (!ParseQualifiedString(szLine, &i, bandwidth, ' ', ',')) {
3040                                DBG_871X("Fail to parse bandwidth!\n");
3041                                return _FAIL;
3042                        }
3043                        if (!ParseQualifiedString(szLine, &i, rfPath, ' ', ',')) {
3044                                DBG_871X("Fail to parse rf path!\n");
3045                                return _FAIL;
3046                        }
3047                        if (!ParseQualifiedString(szLine, &i, rateSection, ' ', ',')) {
3048                                DBG_871X("Fail to parse rate!\n");
3049                                return _FAIL;
3050                        }
3051
3052                        loadingStage = 1;
3053                } else if (loadingStage == 1) {
3054                        if (szLine[0] != '#' || szLine[1] != '#')
3055                                continue;
3056
3057                        /*  skip the space */
3058                        i = 2;
3059                        while (szLine[i] == ' ' || szLine[i] == '\t')
3060                                ++i;
3061
3062                        if (!eqNByte((u8 *)(szLine + i), (u8 *)("START"), 5)) {
3063                                DBG_871X("Lost \"##   START\" label\n");
3064                                return _FAIL;
3065                        }
3066
3067                        loadingStage = 2;
3068                } else if (loadingStage == 2) {
3069                        if (szLine[0] != '#' || szLine[1] != '#')
3070                                continue;
3071
3072                        /*  skip the space */
3073                        i = 2;
3074                        while (szLine[i] == ' ' || szLine[i] == '\t')
3075                                ++i;
3076
3077                        if (!ParseQualifiedString(szLine, &i, colNumBuf, '#', '#')) {
3078                                DBG_871X("Fail to parse column number!\n");
3079                                return _FAIL;
3080                        }
3081
3082                        if (!GetU1ByteIntegerFromStringInDecimal(colNumBuf, &colNum))
3083                                return _FAIL;
3084
3085                        if (colNum > TXPWR_LMT_MAX_REGULATION_NUM) {
3086                                DBG_871X(
3087                                        "unvalid col number %d (greater than max %d)\n",
3088                                        colNum, TXPWR_LMT_MAX_REGULATION_NUM
3089                                );
3090                                return _FAIL;
3091                        }
3092
3093                        for (forCnt = 0; forCnt < colNum; ++forCnt) {
3094                                u8 regulation_name_cnt = 0;
3095
3096                                /*  skip the space */
3097                                while (szLine[i] == ' ' || szLine[i] == '\t')
3098                                        ++i;
3099
3100                                while (szLine[i] != ' ' && szLine[i] != '\t' && szLine[i] != '\0')
3101                                        regulation[forCnt][regulation_name_cnt++] = szLine[i++];
3102                                /* DBG_871X("regulation %s!\n", regulation[forCnt]); */
3103
3104                                if (regulation_name_cnt == 0) {
3105                                        DBG_871X("unvalid number of regulation!\n");
3106                                        return _FAIL;
3107                                }
3108                        }
3109
3110                        loadingStage = 3;
3111                } else if (loadingStage == 3) {
3112                        char channel[10] = {0}, powerLimit[10] = {0};
3113                        u8 cnt = 0;
3114
3115                        /*  the table ends */
3116                        if (szLine[0] == '#' && szLine[1] == '#') {
3117                                i = 2;
3118                                while (szLine[i] == ' ' || szLine[i] == '\t')
3119                                        ++i;
3120
3121                                if (eqNByte((u8 *)(szLine + i), (u8 *)("END"), 3)) {
3122                                        loadingStage = 0;
3123                                        continue;
3124                                } else {
3125                                        DBG_871X("Wrong format\n");
3126                                        DBG_871X("<===== phy_ParsePowerLimitTableFile()\n");
3127                                        return _FAIL;
3128                                }
3129                        }
3130
3131                        if ((szLine[0] != 'c' && szLine[0] != 'C') ||
3132                                 (szLine[1] != 'h' && szLine[1] != 'H')) {
3133                                DBG_871X("Meet wrong channel => power limt pair\n");
3134                                continue;
3135                        }
3136                        i = 2;/*  move to the  location behind 'h' */
3137
3138                        /*  load the channel number */
3139                        cnt = 0;
3140                        while (szLine[i] >= '0' && szLine[i] <= '9') {
3141                                channel[cnt] = szLine[i];
3142                                ++cnt;
3143                                ++i;
3144                        }
3145                        /* DBG_871X("chnl %s!\n", channel); */
3146
3147                        for (forCnt = 0; forCnt < colNum; ++forCnt) {
3148                                /*  skip the space between channel number and the power limit value */
3149                                while (szLine[i] == ' ' || szLine[i] == '\t')
3150                                        ++i;
3151
3152                                /*  load the power limit value */
3153                                cnt = 0;
3154                                fraction = 0;
3155                                memset((void *) powerLimit, 0, 10);
3156                                while ((szLine[i] >= '0' && szLine[i] <= '9') || szLine[i] == '.') {
3157                                        if (szLine[i] == '.') {
3158                                                if ((szLine[i+1] >= '0' && szLine[i+1] <= '9')) {
3159                                                        fraction = szLine[i+1];
3160                                                        i += 2;
3161                                                } else {
3162                                                        DBG_871X("Wrong fraction in TXPWR_LMT.txt\n");
3163                                                        return _FAIL;
3164                                                }
3165
3166                                                break;
3167                                        }
3168
3169                                        powerLimit[cnt] = szLine[i];
3170                                        ++cnt;
3171                                        ++i;
3172                                }
3173
3174                                if (powerLimit[0] == '\0') {
3175                                        powerLimit[0] = '6';
3176                                        powerLimit[1] = '3';
3177                                        i += 2;
3178                                } else {
3179                                        if (!GetU1ByteIntegerFromStringInDecimal(powerLimit, &limitValue))
3180                                                return _FAIL;
3181
3182                                        limitValue *= 2;
3183                                        cnt = 0;
3184                                        if (fraction == '5')
3185                                                ++limitValue;
3186
3187                                        /*  the value is greater or equal to 100 */
3188                                        if (limitValue >= 100) {
3189                                                powerLimit[cnt++] = limitValue/100 + '0';
3190                                                limitValue %= 100;
3191
3192                                                if (limitValue >= 10) {
3193                                                        powerLimit[cnt++] = limitValue/10 + '0';
3194                                                        limitValue %= 10;
3195                                                } else
3196                                                        powerLimit[cnt++] = '0';
3197
3198                                                powerLimit[cnt++] = limitValue + '0';
3199                                        } else if (limitValue >= 10) { /*  the value is greater or equal to 10 */
3200                                                powerLimit[cnt++] = limitValue/10 + '0';
3201                                                limitValue %= 10;
3202                                                powerLimit[cnt++] = limitValue + '0';
3203                                        }
3204                                        /*  the value is less than 10 */
3205                                        else
3206                                                powerLimit[cnt++] = limitValue + '0';
3207
3208                                        powerLimit[cnt] = '\0';
3209                                }
3210
3211                                /* DBG_871X("ch%s => %s\n", channel, powerLimit); */
3212
3213                                /*  store the power limit value */
3214                                PHY_SetTxPowerLimit(Adapter, (u8 *)regulation[forCnt], (u8 *)band,
3215                                        (u8 *)bandwidth, (u8 *)rateSection, (u8 *)rfPath, (u8 *)channel, (u8 *)powerLimit);
3216
3217                        }
3218                } else {
3219                        DBG_871X("Abnormal loading stage in phy_ParsePowerLimitTableFile()!\n");
3220                        rtStatus = _FAIL;
3221                        break;
3222                }
3223        }
3224
3225        DBG_871X("<===phy_ParsePowerLimitTableFile()\n");
3226        return rtStatus;
3227}
3228
3229int PHY_ConfigRFWithPowerLimitTableParaFile(
3230        struct adapter *Adapter, char *pFileName
3231)
3232{
3233        struct hal_com_data     *pHalData = GET_HAL_DATA(Adapter);
3234        int     rlen = 0, rtStatus = _FAIL;
3235
3236        if (!(Adapter->registrypriv.load_phy_file & LOAD_RF_TXPWR_LMT_PARA_FILE))
3237                return rtStatus;
3238
3239        memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
3240
3241        if ((pHalData->rf_tx_pwr_lmt_len == 0) && (pHalData->rf_tx_pwr_lmt == NULL)) {
3242                rtw_merge_string(file_path_bs, PATH_MAX, rtw_phy_file_path, pFileName);
3243
3244                if (rtw_is_file_readable(file_path_bs) == true) {
3245                        rlen = rtw_retrive_from_file(file_path_bs, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
3246                        if (rlen > 0) {
3247                                rtStatus = _SUCCESS;
3248                                pHalData->rf_tx_pwr_lmt = vzalloc(rlen);
3249                                if (pHalData->rf_tx_pwr_lmt) {
3250                                        memcpy(pHalData->rf_tx_pwr_lmt, pHalData->para_file_buf, rlen);
3251                                        pHalData->rf_tx_pwr_lmt_len = rlen;
3252                                } else
3253                                        DBG_871X("%s rf_tx_pwr_lmt alloc fail !\n", __func__);
3254                        }
3255                }
3256        } else {
3257                if ((pHalData->rf_tx_pwr_lmt_len != 0) && (pHalData->rf_tx_pwr_lmt != NULL)) {
3258                        memcpy(pHalData->para_file_buf, pHalData->rf_tx_pwr_lmt, pHalData->rf_tx_pwr_lmt_len);
3259                        rtStatus = _SUCCESS;
3260                } else
3261                        DBG_871X("%s(): Critical Error !!!\n", __func__);
3262        }
3263
3264        if (rtStatus == _SUCCESS) {
3265                /* DBG_871X("%s(): read %s ok\n", __func__, pFileName); */
3266                rtStatus = phy_ParsePowerLimitTableFile(Adapter, pHalData->para_file_buf);
3267        } else
3268                DBG_871X("%s(): No File %s, Load from HWImg Array!\n", __func__, pFileName);
3269
3270        return rtStatus;
3271}
3272
3273void phy_free_filebuf(struct adapter *padapter)
3274{
3275        struct hal_com_data             *pHalData = GET_HAL_DATA(padapter);
3276
3277        if (pHalData->mac_reg)
3278                vfree(pHalData->mac_reg);
3279        if (pHalData->bb_phy_reg)
3280                vfree(pHalData->bb_phy_reg);
3281        if (pHalData->bb_agc_tab)
3282                vfree(pHalData->bb_agc_tab);
3283        if (pHalData->bb_phy_reg_pg)
3284                vfree(pHalData->bb_phy_reg_pg);
3285        if (pHalData->bb_phy_reg_mp)
3286                vfree(pHalData->bb_phy_reg_mp);
3287        if (pHalData->rf_radio_a)
3288                vfree(pHalData->rf_radio_a);
3289        if (pHalData->rf_radio_b)
3290                vfree(pHalData->rf_radio_b);
3291        if (pHalData->rf_tx_pwr_track)
3292                vfree(pHalData->rf_tx_pwr_track);
3293        if (pHalData->rf_tx_pwr_lmt)
3294                vfree(pHalData->rf_tx_pwr_lmt);
3295
3296}
3297
3298