net: wireless: rockchip_wlan: add rtl8188eu support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8188eu / hal / hal_com_phycfg.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
4  *                                        
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20 #define _HAL_COM_PHYCFG_C_
21
22 #include <drv_types.h>
23 #include <hal_data.h>
24
25 /*
26 * rtw_regsty_get_target_tx_power -
27 *
28 * Return dBm or -1 for undefined
29 */
30 s8 rtw_regsty_get_target_tx_power(
31         IN      PADAPTER                Adapter,
32         IN      u8                              Band,
33         IN      u8                              RfPath,
34         IN      RATE_SECTION    RateSection
35         )
36 {
37         struct registry_priv *regsty = adapter_to_regsty(Adapter);
38         s8 value = 0;
39
40         if (RfPath > RF_PATH_D) {
41                 DBG_871X_LEVEL(_drv_always_, "%s invalid RfPath:%d\n", __func__, RfPath);
42                 return -1;
43         }
44
45         if (Band != BAND_ON_2_4G
46                 #ifdef CONFIG_IEEE80211_BAND_5GHZ
47                 && Band != BAND_ON_5G
48                 #endif
49         ) {
50                 DBG_871X_LEVEL(_drv_always_, "%s invalid Band:%d\n", __func__, Band);
51                 return -1;
52         }
53
54         if (RateSection >= RATE_SECTION_NUM
55                 #ifdef CONFIG_IEEE80211_BAND_5GHZ
56                 || (Band == BAND_ON_5G && RateSection == CCK)
57                 #endif
58         ) {
59                 DBG_871X_LEVEL(_drv_always_, "%s invalid RateSection:%d in %sG, RfPath:%d\n", __func__
60                         , RateSection, (Band == BAND_ON_2_4G) ? "2.4" : "5", RfPath);
61                 return -1;
62         }
63
64         if (Band == BAND_ON_2_4G)
65                 value = regsty->target_tx_pwr_2g[RfPath][RateSection];
66 #ifdef CONFIG_IEEE80211_BAND_5GHZ
67         else /* BAND_ON_5G */
68                 value = regsty->target_tx_pwr_5g[RfPath][RateSection - 1];
69 #endif
70
71         return value;
72 }
73
74 bool rtw_regsty_chk_target_tx_power_valid(_adapter *adapter)
75 {
76         struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
77         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
78         int path, tx_num, band, rs;
79         s8 target;
80
81         for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
82                 if (!hal_is_band_support(adapter, band))
83                         continue;
84
85                 for (path = 0; path < RF_PATH_MAX; path++) {
86                         if (path >= hal_data->NumTotalRFPath)
87                                 break;
88
89                         for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
90                                 tx_num = rate_section_to_tx_num(rs);
91                                 if (tx_num >= hal_spec->nss_num)
92                                         continue;
93
94                                 if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
95                                         continue;
96
97                                 if (IS_VHT_RATE_SECTION(rs) && !IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(adapter))
98                                         continue;
99
100                                 target = rtw_regsty_get_target_tx_power(adapter, band, path, rs);
101                                 if (target == -1)
102                                         return _FALSE;
103                         }
104                 }
105         }
106
107         return _TRUE;
108 }
109
110 /*
111 * PHY_GetTxPowerByRateBase -
112 *
113 * Return 2 times of dBm
114 */
115 u8
116 PHY_GetTxPowerByRateBase(
117         IN      PADAPTER                Adapter,
118         IN      u8                              Band,
119         IN      u8                              RfPath,
120         IN      u8                              TxNum,
121         IN      RATE_SECTION    RateSection
122         )
123 {
124         HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
125         u8 value = 0;
126
127         if (RfPath > RF_PATH_D) {
128                 DBG_871X_LEVEL(_drv_always_, "%s invalid RfPath:%d\n", __func__, RfPath);
129                 return 0;
130         }
131
132         if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) {
133                 DBG_871X_LEVEL(_drv_always_, "%s invalid Band:%d\n", __func__, Band);
134                 return 0;
135         }
136
137         if (RateSection >= RATE_SECTION_NUM
138                 || (Band == BAND_ON_5G && RateSection == CCK)
139         ) {
140                 DBG_871X_LEVEL(_drv_always_, "%s invalid RateSection:%d in %sG, RfPath:%d, TxNum:%d\n", __func__
141                         , RateSection, (Band == BAND_ON_2_4G) ? "2.4" : "5", RfPath, TxNum);
142                 return 0;
143         }
144
145         if (Band == BAND_ON_2_4G)
146                 value = pHalData->TxPwrByRateBase2_4G[RfPath][TxNum][RateSection];
147         else /* BAND_ON_5G */
148                 value = pHalData->TxPwrByRateBase5G[RfPath][TxNum][RateSection - 1];
149
150         return value;
151 }
152
153 VOID
154 phy_SetTxPowerByRateBase(
155         IN      PADAPTER                Adapter,
156         IN      u8                              Band,
157         IN      u8                              RfPath,
158         IN      RATE_SECTION    RateSection,
159         IN      u8                              TxNum,
160         IN      u8                              Value
161         )
162 {
163         HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
164         
165         if (RfPath > RF_PATH_D) {
166                 DBG_871X_LEVEL(_drv_always_, "%s invalid RfPath:%d\n", __func__, RfPath);
167                 return;
168         }
169
170         if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) {
171                 DBG_871X_LEVEL(_drv_always_, "%s invalid Band:%d\n", __func__, Band);
172                 return;
173         }
174
175         if (RateSection >= RATE_SECTION_NUM
176                 || (Band == BAND_ON_5G && RateSection == CCK)
177         ) {
178                 DBG_871X_LEVEL(_drv_always_, "%s invalid RateSection:%d in %sG, RfPath:%d, TxNum:%d\n", __func__
179                         , RateSection, (Band == BAND_ON_2_4G) ? "2.4" : "5", RfPath, TxNum);
180                 return;
181         }
182
183         if (Band == BAND_ON_2_4G)
184                 pHalData->TxPwrByRateBase2_4G[RfPath][TxNum][RateSection] = Value;
185         else /* BAND_ON_5G */
186                 pHalData->TxPwrByRateBase5G[RfPath][TxNum][RateSection - 1] = Value;
187 }
188
189 /*
190 * phy_get_target_tx_power -
191 *
192 * Return 2 times of dBm
193 */
194 u8 phy_get_target_tx_power(
195         IN      PADAPTER                Adapter,
196         IN      u8                              Band,
197         IN      u8                              RfPath,
198         IN      RATE_SECTION    RateSection
199         )
200 {
201         struct registry_priv *regsty = adapter_to_regsty(Adapter);
202         s16 target_power;
203
204         if (phy_is_tx_power_by_rate_needed(Adapter) == _FALSE && regsty->target_tx_pwr_valid == _TRUE)
205                 target_power = 2 * rtw_regsty_get_target_tx_power(Adapter, Band, RfPath, RateSection);
206         else
207                 target_power = PHY_GetTxPowerByRateBase(Adapter, Band, RfPath, rate_section_to_tx_num(RateSection), RateSection);
208
209         return target_power;
210 }
211
212 #ifdef TX_POWER_BY_RATE_OLD
213 VOID
214 phy_StoreTxPowerByRateBaseOld(  
215         IN      PADAPTER        pAdapter
216         )
217 {
218         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA( pAdapter );
219         u16                     rawValue = 0;
220         u8                      base = 0;
221         u8                      path = 0;
222
223         rawValue = ( u16 ) ( pHalData->MCSTxPowerLevelOriginalOffset[0][7] >> 8 ) & 0xFF; 
224         base = ( rawValue >> 4 ) * 10 + ( rawValue & 0xF );
225         phy_SetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_A, CCK, RF_1TX, base );
226
227         rawValue = ( u16 ) ( pHalData->MCSTxPowerLevelOriginalOffset[0][1] >> 24 ) & 0xFF; 
228         base = ( rawValue >> 4 ) * 10 + ( rawValue & 0xF );
229         phy_SetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_A, OFDM, RF_1TX, base );
230
231         rawValue = ( u16 ) ( pHalData->MCSTxPowerLevelOriginalOffset[0][3] >> 24 ) & 0xFF; 
232         base = ( rawValue >> 4 ) * 10 + ( rawValue & 0xF );
233         phy_SetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_A, HT_MCS0_MCS7, RF_1TX, base );
234
235         rawValue = ( u16 ) ( pHalData->MCSTxPowerLevelOriginalOffset[0][5] >> 24 ) & 0xFF; 
236         base = ( rawValue >> 4) * 10 + ( rawValue & 0xF );
237         phy_SetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_A, HT_MCS8_MCS15, RF_2TX, base );
238
239         rawValue = ( u16 ) ( pHalData->MCSTxPowerLevelOriginalOffset[0][7] & 0xFF ); 
240         base = ( rawValue >> 4 ) * 10 + ( rawValue & 0xF );
241         phy_SetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_B, CCK, RF_1TX, base );
242
243         rawValue = ( u16 ) ( pHalData->MCSTxPowerLevelOriginalOffset[0][9] >> 24 ) & 0xFF; 
244         base = ( rawValue >> 4 ) * 10 + ( rawValue & 0xF );
245         phy_SetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_B, OFDM, RF_1TX, base );
246
247         rawValue = ( u16 ) ( pHalData->MCSTxPowerLevelOriginalOffset[0][11] >> 24 ) & 0xFF; 
248         base = ( rawValue >> 4 ) * 10 + ( rawValue & 0xF );
249         phy_SetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_B, HT_MCS0_MCS7, RF_1TX, base );
250
251         rawValue = ( u16 ) ( pHalData->MCSTxPowerLevelOriginalOffset[0][13] >> 24 ) & 0xFF; 
252         base = ( rawValue >> 4 ) * 10 + ( rawValue & 0xF );
253         phy_SetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_B, HT_MCS8_MCS15, RF_2TX, base );
254 }
255 #endif /* TX_POWER_BY_RATE_OLD */
256
257 VOID
258 phy_StoreTxPowerByRateBase(     
259         IN      PADAPTER        pAdapter
260         )
261 {
262         struct hal_spec_t *hal_spec = GET_HAL_SPEC(pAdapter);
263
264         u8 rate_sec_base[RATE_SECTION_NUM] = {
265                 MGN_11M,
266                 MGN_54M,
267                 MGN_MCS7,
268                 MGN_MCS15,
269                 MGN_MCS23,
270                 MGN_MCS31,
271                 MGN_VHT1SS_MCS7,
272                 MGN_VHT2SS_MCS7,
273                 MGN_VHT3SS_MCS7,
274                 MGN_VHT4SS_MCS7,
275         };
276
277         u8 band, path, rs, tx_num, base, index;
278
279         for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
280
281                 for (path = RF_PATH_A; path < RF_PATH_MAX; path++) {
282                         /* TODO: 8814A's NumTotalRFPath differs at probe(3) and up(4), need fixed
283                         if (path >= hal_data->NumTotalRFPath)
284                                 break;
285                         */
286
287                         for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
288                                 tx_num = rate_section_to_tx_num(rs);
289                                 if (tx_num >= hal_spec->nss_num)
290                                         continue;
291
292                                 if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
293                                         continue;
294
295                                 base = _PHY_GetTxPowerByRate(pAdapter, band, path, tx_num, rate_sec_base[rs]);
296                                 phy_SetTxPowerByRateBase(pAdapter, band, path, rs, tx_num, base);
297                         }
298                 }
299         }
300 }
301
302 #ifdef TX_POWER_BY_RATE_OLD
303 u8
304 PHY_GetRateSectionIndexOfTxPowerByRate(
305         IN      PADAPTER        pAdapter,
306         IN      u32                     RegAddr,
307         IN      u32                     BitMask
308         )
309 {
310         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA( pAdapter );
311         PDM_ODM_T               pDM_Odm = &pHalData->odmpriv;
312         u8                      index = 0;
313         
314         if ( pDM_Odm->PhyRegPgVersion == 0 )
315         {
316                 switch ( RegAddr )
317                 {
318                         case rTxAGC_A_Rate18_06:         index = 0;             break;
319                         case rTxAGC_A_Rate54_24:         index = 1;             break;
320                         case rTxAGC_A_CCK1_Mcs32:        index = 6;             break;
321                         case rTxAGC_B_CCK11_A_CCK2_11:
322                                 if ( BitMask == bMaskH3Bytes )
323                                         index = 7;
324                                 else if ( BitMask == 0x000000ff )
325                                         index = 15;
326                                 break;
327                                 
328                         case rTxAGC_A_Mcs03_Mcs00:       index = 2;             break;
329                         case rTxAGC_A_Mcs07_Mcs04:       index = 3;             break;
330                         case rTxAGC_A_Mcs11_Mcs08:       index = 4;             break;
331                         case rTxAGC_A_Mcs15_Mcs12:       index = 5;             break;
332                         case rTxAGC_B_Rate18_06:         index = 8;             break;
333                         case rTxAGC_B_Rate54_24:         index = 9;             break;
334                         case rTxAGC_B_CCK1_55_Mcs32: index = 14;        break;
335                         case rTxAGC_B_Mcs03_Mcs00:       index = 10;    break;
336                         case rTxAGC_B_Mcs07_Mcs04:       index = 11;    break;
337                         case rTxAGC_B_Mcs11_Mcs08:       index = 12;    break;
338                         case rTxAGC_B_Mcs15_Mcs12:       index = 13;    break;
339                         default:
340                                 DBG_871X("Invalid RegAddr 0x3%x in PHY_GetRateSectionIndexOfTxPowerByRate()", RegAddr );
341                                 break;
342                 };
343         }
344         
345         return index;
346 }
347 #endif /* TX_POWER_BY_RATE_OLD */
348
349 VOID
350 PHY_GetRateValuesOfTxPowerByRate(
351         IN      PADAPTER pAdapter,
352         IN      u32 RegAddr,
353         IN      u32 BitMask,
354         IN      u32 Value,
355         OUT     u8 *Rate,
356         OUT     s8 *PwrByRateVal,
357         OUT     u8 *RateNum
358         )
359 {
360         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA( pAdapter );
361         PDM_ODM_T               pDM_Odm = &pHalData->odmpriv;
362         u8                              index = 0, i = 0;
363         
364         switch ( RegAddr )
365         {
366                 case rTxAGC_A_Rate18_06:
367                 case rTxAGC_B_Rate18_06:
368                         Rate[0] = MGN_6M;
369                         Rate[1] = MGN_9M;
370                         Rate[2] = MGN_12M;
371                         Rate[3] = MGN_18M;
372                         for ( i = 0; i < 4; ++ i )
373                         {
374                                 PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
375                                                                                                 ( ( Value >> (i * 8) ) & 0xF ) );
376                         }
377                         *RateNum = 4;
378                         break;
379                         
380                 case rTxAGC_A_Rate54_24:
381                 case rTxAGC_B_Rate54_24:
382                         Rate[0] = MGN_24M;
383                         Rate[1] = MGN_36M;
384                         Rate[2] = MGN_48M;
385                         Rate[3] = MGN_54M;
386                         for ( i = 0; i < 4; ++ i )
387                         {
388                                 PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
389                                                                                                 ( ( Value >> (i * 8) ) & 0xF ) );
390                         }
391                         *RateNum = 4;
392                         break;
393                         
394                 case rTxAGC_A_CCK1_Mcs32:
395                         Rate[0] = MGN_1M;
396                         PwrByRateVal[0] = ( s8 ) ( ( ( ( Value >> (8 + 4) ) & 0xF ) ) * 10 + 
397                                                                                         ( ( Value >> 8 ) & 0xF ) );
398                         *RateNum = 1;
399                         break;
400                         
401                 case rTxAGC_B_CCK11_A_CCK2_11:
402                         if ( BitMask == 0xffffff00 )
403                         {
404                                 Rate[0] = MGN_2M;
405                                 Rate[1] = MGN_5_5M;
406                                 Rate[2] = MGN_11M;
407                                 for ( i = 1; i < 4; ++ i )
408                                 {
409                                         PwrByRateVal[i - 1] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
410                                                                                                         ( ( Value >> (i * 8) ) & 0xF ) );
411                                 }
412                                 *RateNum = 3;
413                         }
414                         else if ( BitMask == 0x000000ff )
415                         {
416                                 Rate[0] = MGN_11M;
417                                 PwrByRateVal[0] = ( s8 ) ( ( ( ( Value >> 4 ) & 0xF ) ) * 10 + 
418                                                                                                 ( Value & 0xF ) );
419                                 *RateNum = 1;
420                         }
421                         break;
422                         
423                 case rTxAGC_A_Mcs03_Mcs00:
424                 case rTxAGC_B_Mcs03_Mcs00:
425                         Rate[0] = MGN_MCS0;
426                         Rate[1] = MGN_MCS1;
427                         Rate[2] = MGN_MCS2;
428                         Rate[3] = MGN_MCS3;
429                         for ( i = 0; i < 4; ++ i )
430                         {
431                                 PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
432                                                                                                 ( ( Value >> (i * 8) ) & 0xF ) );
433                         }
434                         *RateNum = 4;
435                         break;
436                         
437                 case rTxAGC_A_Mcs07_Mcs04:
438                 case rTxAGC_B_Mcs07_Mcs04:
439                         Rate[0] = MGN_MCS4;
440                         Rate[1] = MGN_MCS5;
441                         Rate[2] = MGN_MCS6;
442                         Rate[3] = MGN_MCS7;
443                         for ( i = 0; i < 4; ++ i )
444                         {
445                                 PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
446                                                                                                 ( ( Value >> (i * 8) ) & 0xF ) );
447                         }
448                         *RateNum = 4;
449                         break;
450                         
451                 case rTxAGC_A_Mcs11_Mcs08:
452                 case rTxAGC_B_Mcs11_Mcs08:
453                         Rate[0] = MGN_MCS8;
454                         Rate[1] = MGN_MCS9;
455                         Rate[2] = MGN_MCS10;
456                         Rate[3] = MGN_MCS11;
457                         for ( i = 0; i < 4; ++ i )
458                         {
459                                 PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
460                                                                                                 ( ( Value >> (i * 8) ) & 0xF ) );
461                         }
462                         *RateNum = 4;
463                         break;
464                         
465                 case rTxAGC_A_Mcs15_Mcs12:
466                 case rTxAGC_B_Mcs15_Mcs12:
467                         Rate[0] = MGN_MCS12;
468                         Rate[1] = MGN_MCS13;
469                         Rate[2] = MGN_MCS14;
470                         Rate[3] = MGN_MCS15;
471                         for ( i = 0; i < 4; ++ i )
472                         {
473                                 PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
474                                                                                                 ( ( Value >> (i * 8) ) & 0xF ) );
475                         }
476                         *RateNum = 4;
477                         
478                         break;
479                         
480                 case rTxAGC_B_CCK1_55_Mcs32:
481                         Rate[0] = MGN_1M;
482                         Rate[1] = MGN_2M;
483                         Rate[2] = MGN_5_5M;
484                         for ( i = 1; i < 4; ++ i )
485                         {
486                                 PwrByRateVal[i - 1] = ( s8 ) ( ( ( ( Value >> ( i * 8 + 4) ) & 0xF ) ) * 10 + 
487                                                                                                 ( ( Value >> ( i * 8) ) & 0xF ) );
488                         }
489                         *RateNum = 3;
490                         break;
491                         
492                 case 0xC20:
493                 case 0xE20:
494                 case 0x1820:
495                 case 0x1a20:
496                         Rate[0] = MGN_1M;
497                         Rate[1] = MGN_2M;
498                         Rate[2] = MGN_5_5M;
499                         Rate[3] = MGN_11M;
500                         for ( i = 0; i < 4; ++ i )
501                         {
502                                 PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
503                                                                                                 ( ( Value >> (i * 8) ) & 0xF ) );
504                         }
505                         *RateNum = 4;
506                         break;
507                         
508                 case 0xC24:
509                 case 0xE24:
510                 case 0x1824:
511                 case 0x1a24:
512                         Rate[0] = MGN_6M;
513                         Rate[1] = MGN_9M;
514                         Rate[2] = MGN_12M;
515                         Rate[3] = MGN_18M;
516                         for ( i = 0; i < 4; ++ i )
517                         {
518                                 PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
519                                                                                                 ( ( Value >> (i * 8) ) & 0xF ) );
520                         }
521                         *RateNum = 4;
522                         break;
523
524                 case 0xC28:
525                 case 0xE28:
526                 case 0x1828:
527                 case 0x1a28:
528                         Rate[0] = MGN_24M;
529                         Rate[1] = MGN_36M;
530                         Rate[2] = MGN_48M;
531                         Rate[3] = MGN_54M;
532                         for ( i = 0; i < 4; ++ i )
533                         {
534                                 PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
535                                                                                                 ( ( Value >> (i * 8) ) & 0xF ) );
536                         }
537                         *RateNum = 4;
538                         break;
539
540                 case 0xC2C:
541                 case 0xE2C:
542                 case 0x182C:
543                 case 0x1a2C:
544                         Rate[0] = MGN_MCS0;
545                         Rate[1] = MGN_MCS1;
546                         Rate[2] = MGN_MCS2;
547                         Rate[3] = MGN_MCS3;
548                         for ( i = 0; i < 4; ++ i )
549                         {
550                                 PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
551                                                                                                 ( ( Value >> (i * 8) ) & 0xF ) );
552                         }
553                         *RateNum = 4;
554                         break;
555
556                 case 0xC30:
557                 case 0xE30:
558                 case 0x1830:
559                 case 0x1a30:
560                         Rate[0] = MGN_MCS4;
561                         Rate[1] = MGN_MCS5;
562                         Rate[2] = MGN_MCS6;
563                         Rate[3] = MGN_MCS7;
564                         for ( i = 0; i < 4; ++ i )
565                         {
566                                 PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
567                                                                                                 ( ( Value >> (i * 8) ) & 0xF ) );
568                         }
569                         *RateNum = 4;
570                         break;
571
572                 case 0xC34:
573                 case 0xE34:
574                 case 0x1834:
575                 case 0x1a34:
576                         Rate[0] = MGN_MCS8;
577                         Rate[1] = MGN_MCS9;
578                         Rate[2] = MGN_MCS10;
579                         Rate[3] = MGN_MCS11;
580                         for ( i = 0; i < 4; ++ i )
581                         {
582                                 PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
583                                                                                                 ( ( Value >> (i * 8) ) & 0xF ) );
584                         }
585                         *RateNum = 4;
586                         break;
587
588                 case 0xC38:
589                 case 0xE38:
590                 case 0x1838:
591                 case 0x1a38:
592                         Rate[0] = MGN_MCS12;
593                         Rate[1] = MGN_MCS13;
594                         Rate[2] = MGN_MCS14;
595                         Rate[3] = MGN_MCS15;
596                         for ( i = 0; i < 4; ++ i )
597                         {
598                                 PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
599                                                                                                 ( ( Value >> (i * 8) ) & 0xF ) );
600                         }
601                         *RateNum = 4;
602                         break;
603
604                 case 0xC3C:
605                 case 0xE3C:
606                 case 0x183C:
607                 case 0x1a3C:
608                         Rate[0] = MGN_VHT1SS_MCS0;
609                         Rate[1] = MGN_VHT1SS_MCS1;
610                         Rate[2] = MGN_VHT1SS_MCS2;
611                         Rate[3] = MGN_VHT1SS_MCS3;
612                         for ( i = 0; i < 4; ++ i )
613                         {
614                                 PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
615                                                                                                 ( ( Value >> (i * 8) ) & 0xF ) );
616                         }
617                         *RateNum = 4;
618                         break;
619
620                 case 0xC40:
621                 case 0xE40:
622                 case 0x1840:
623                 case 0x1a40:
624                         Rate[0] = MGN_VHT1SS_MCS4;
625                         Rate[1] = MGN_VHT1SS_MCS5;
626                         Rate[2] = MGN_VHT1SS_MCS6;
627                         Rate[3] = MGN_VHT1SS_MCS7;
628                         for ( i = 0; i < 4; ++ i )
629                         {
630                                 PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
631                                                                                                 ( ( Value >> (i * 8) ) & 0xF ) );
632                         }
633                         *RateNum = 4;
634                         break;
635
636                 case 0xC44:
637                 case 0xE44:
638                 case 0x1844:
639                 case 0x1a44:
640                         Rate[0] = MGN_VHT1SS_MCS8;
641                         Rate[1] = MGN_VHT1SS_MCS9;
642                         Rate[2] = MGN_VHT2SS_MCS0;
643                         Rate[3] = MGN_VHT2SS_MCS1;
644                         for ( i = 0; i < 4; ++ i )
645                         {
646                                 PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
647                                                                                                 ( ( Value >> (i * 8) ) & 0xF ) );
648                         }
649                         *RateNum = 4;
650                         break;
651
652                 case 0xC48:
653                 case 0xE48:
654                 case 0x1848:
655                 case 0x1a48:
656                         Rate[0] = MGN_VHT2SS_MCS2;
657                         Rate[1] = MGN_VHT2SS_MCS3;
658                         Rate[2] = MGN_VHT2SS_MCS4;
659                         Rate[3] = MGN_VHT2SS_MCS5;
660                         for ( i = 0; i < 4; ++ i )
661                         {
662                                 PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
663                                                                                                 ( ( Value >> (i * 8) ) & 0xF ) );
664                         }
665                         *RateNum = 4;
666                         break;
667
668                 case 0xC4C:
669                 case 0xE4C:
670                 case 0x184C:
671                 case 0x1a4C:
672                         Rate[0] = MGN_VHT2SS_MCS6;
673                         Rate[1] = MGN_VHT2SS_MCS7;
674                         Rate[2] = MGN_VHT2SS_MCS8;
675                         Rate[3] = MGN_VHT2SS_MCS9;
676                         for ( i = 0; i < 4; ++ i )
677                         {
678                                 PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
679                                                                                                 ( ( Value >> (i * 8) ) & 0xF ) );
680                         }
681                         *RateNum = 4;
682                         break;
683
684                 case 0xCD8:
685                 case 0xED8:
686                 case 0x18D8:
687                 case 0x1aD8:
688                         Rate[0] = MGN_MCS16;
689                         Rate[1] = MGN_MCS17;
690                         Rate[2] = MGN_MCS18;
691                         Rate[3] = MGN_MCS19;
692                         for ( i = 0; i < 4; ++ i )
693                         {
694                                 PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
695                                                                                                 ( ( Value >> (i * 8) ) & 0xF ) );
696                         }
697                         *RateNum = 4;
698                         break;
699
700                 case 0xCDC:
701                 case 0xEDC:
702                 case 0x18DC:
703                 case 0x1aDC:
704                         Rate[0] = MGN_MCS20;
705                         Rate[1] = MGN_MCS21;
706                         Rate[2] = MGN_MCS22;
707                         Rate[3] = MGN_MCS23;
708                         for ( i = 0; i < 4; ++ i )
709                         {
710                                 PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
711                                                                                                 ( ( Value >> (i * 8) ) & 0xF ) );
712                         }
713                         *RateNum = 4;
714                         break;
715
716                 case 0xCE0:
717                 case 0xEE0:
718                 case 0x18E0:
719                 case 0x1aE0:
720                         Rate[0] = MGN_VHT3SS_MCS0;
721                         Rate[1] = MGN_VHT3SS_MCS1;
722                         Rate[2] = MGN_VHT3SS_MCS2;
723                         Rate[3] = MGN_VHT3SS_MCS3;
724                         for ( i = 0; i < 4; ++ i )
725                         {
726                                 PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
727                                                                                                 ( ( Value >> (i * 8) ) & 0xF ) );
728                         }
729                         *RateNum = 4;
730                         break;
731
732                 case 0xCE4:
733                 case 0xEE4:
734                 case 0x18E4:
735                 case 0x1aE4:
736                         Rate[0] = MGN_VHT3SS_MCS4;
737                         Rate[1] = MGN_VHT3SS_MCS5;
738                         Rate[2] = MGN_VHT3SS_MCS6;
739                         Rate[3] = MGN_VHT3SS_MCS7;
740                         for ( i = 0; i < 4; ++ i )
741                         {
742                                 PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
743                                                                                                 ( ( Value >> (i * 8) ) & 0xF ) );
744                         }
745                         *RateNum = 4;
746                         break;
747
748                 case 0xCE8:
749                 case 0xEE8:
750                 case 0x18E8:
751                 case 0x1aE8:
752                         Rate[0] = MGN_VHT3SS_MCS8;
753                         Rate[1] = MGN_VHT3SS_MCS9;
754                         for ( i = 0; i < 2; ++ i )
755                         {
756                                 PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
757                                                                                                 ( ( Value >> (i * 8) ) & 0xF ) );
758                         }
759                         *RateNum = 2;
760                         break;
761                         
762                 default:
763                         DBG_871X_LEVEL(_drv_always_, "Invalid RegAddr 0x%x in %s()\n", RegAddr, __func__);
764                         break;
765         };
766 }
767
768 void
769 PHY_StoreTxPowerByRateNew(
770         IN      PADAPTER        pAdapter,
771         IN      u32                     Band,
772         IN      u32                     RfPath,
773         IN      u32                     TxNum,
774         IN      u32                     RegAddr,
775         IN      u32                     BitMask,
776         IN      u32                     Data
777         )
778 {
779         HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
780         u8      i = 0, rates[4] = {0}, rateNum = 0;
781         s8      PwrByRateVal[4] = {0};
782
783         PHY_GetRateValuesOfTxPowerByRate(pAdapter, RegAddr, BitMask, Data, rates, PwrByRateVal, &rateNum);
784
785         if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) {
786                 DBG_871X_LEVEL(_drv_always_, "Invalid Band %d\n", Band);
787                 return;
788         }
789
790         if (RfPath > ODM_RF_PATH_D) {
791                 DBG_871X_LEVEL(_drv_always_, "Invalid RfPath %d\n", RfPath);
792                 return;
793         }
794
795         if (TxNum > ODM_RF_PATH_D) {
796                 DBG_871X_LEVEL(_drv_always_, "Invalid TxNum %d\n", TxNum);
797                 return;
798         }
799
800         for (i = 0; i < rateNum; ++i) {
801                 u8 rate_idx = PHY_GetRateIndexOfTxPowerByRate(rates[i]);
802
803                 if (IS_1T_RATE(rates[i]))
804                         pHalData->TxPwrByRateOffset[Band][RfPath][RF_1TX][rate_idx] = PwrByRateVal[i];
805                 else if (IS_2T_RATE(rates[i]))
806                         pHalData->TxPwrByRateOffset[Band][RfPath][RF_2TX][rate_idx] = PwrByRateVal[i];
807                 else if (IS_3T_RATE(rates[i]))
808                         pHalData->TxPwrByRateOffset[Band][RfPath][RF_3TX][rate_idx] = PwrByRateVal[i];
809                 else if (IS_4T_RATE(rates[i]))
810                         pHalData->TxPwrByRateOffset[Band][RfPath][RF_4TX][rate_idx] = PwrByRateVal[i];
811                 else
812                         rtw_warn_on(1);
813         }
814 }
815
816 #ifdef TX_POWER_BY_RATE_OLD
817 void 
818 PHY_StoreTxPowerByRateOld(
819         IN      PADAPTER                pAdapter,
820         IN      u32                             RegAddr,
821         IN      u32                             BitMask,
822         IN      u32                             Data
823         )
824 {
825         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(pAdapter);
826         u8                      index = PHY_GetRateSectionIndexOfTxPowerByRate( pAdapter, RegAddr, BitMask );
827
828         pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][index] = Data;
829         //DBG_871X("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n", pHalData->pwrGroupCnt,
830         //      pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][0]);
831 }
832 #endif /* TX_POWER_BY_RATE_OLD */
833
834 VOID
835 PHY_InitTxPowerByRate(
836         IN      PADAPTER        pAdapter
837         )
838 {
839         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(pAdapter);
840         u8      band = 0, rfPath = 0, TxNum = 0, rate = 0, i = 0, j = 0;
841
842         if ( IS_HARDWARE_TYPE_8188E( pAdapter ) )
843         {
844                 for ( i = 0; i < MAX_PG_GROUP; ++i )
845                         for ( j = 0; j < 16; ++j )
846                                 pHalData->MCSTxPowerLevelOriginalOffset[i][j] = 0;
847         }
848         else
849         {
850                 for ( band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band )
851                                 for ( rfPath = 0; rfPath < TX_PWR_BY_RATE_NUM_RF; ++rfPath )
852                                         for ( TxNum = 0; TxNum < TX_PWR_BY_RATE_NUM_RF; ++TxNum )
853                                                 for ( rate = 0; rate < TX_PWR_BY_RATE_NUM_RATE; ++rate )
854                                                         pHalData->TxPwrByRateOffset[band][rfPath][TxNum][rate] = 0;
855         }
856 }
857
858 VOID
859 PHY_StoreTxPowerByRate(
860         IN      PADAPTER        pAdapter,
861         IN      u32                     Band,
862         IN      u32                     RfPath,
863         IN      u32                     TxNum,
864         IN      u32                     RegAddr,
865         IN      u32                     BitMask,
866         IN      u32                     Data
867         )
868 {
869         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(pAdapter);
870         PDM_ODM_T               pDM_Odm = &pHalData->odmpriv;
871         
872         if ( pDM_Odm->PhyRegPgVersion > 0 )
873         {
874                 PHY_StoreTxPowerByRateNew( pAdapter, Band, RfPath, TxNum, RegAddr, BitMask, Data );
875         }
876 #ifdef TX_POWER_BY_RATE_OLD
877         else if ( pDM_Odm->PhyRegPgVersion == 0 )
878         {
879                 PHY_StoreTxPowerByRateOld( pAdapter, RegAddr, BitMask, Data );
880         
881                 if ( RegAddr == rTxAGC_A_Mcs15_Mcs12 && pHalData->rf_type == RF_1T1R )
882                         pHalData->pwrGroupCnt++;
883                 else if ( RegAddr == rTxAGC_B_Mcs15_Mcs12 && pHalData->rf_type != RF_1T1R )
884                         pHalData->pwrGroupCnt++;
885         }
886 #endif
887         else
888                 DBG_871X("Invalid PHY_REG_PG.txt version %d\n",  pDM_Odm->PhyRegPgVersion );
889         
890 }
891
892 #ifdef TX_POWER_BY_RATE_OLD
893 VOID 
894 phy_ConvertTxPowerByRateByBase(
895         IN      u32*            pData,
896         IN      u8                      Start,
897         IN      u8                      End,
898         IN      u8                      BaseValue
899         )
900 {
901         s8      i = 0;
902         u8      TempValue = 0;
903         u32     TempData = 0;
904         
905         for ( i = 3; i >= 0; --i )
906         {
907                 if ( i >= Start && i <= End )
908                 {
909                         // Get the exact value
910                         TempValue = ( u8 ) ( *pData >> ( i * 8 ) ) & 0xF; 
911                         TempValue += ( ( u8 ) ( ( *pData >> ( i * 8 + 4 ) ) & 0xF ) ) * 10; 
912                         
913                         // Change the value to a relative value
914                         TempValue = ( TempValue > BaseValue ) ? TempValue - BaseValue : BaseValue - TempValue;
915                 }
916                 else
917                 {
918                         TempValue = ( u8 ) ( *pData >> ( i * 8 ) ) & 0xFF;
919                 }
920                 
921                 TempData <<= 8;
922                 TempData |= TempValue;
923         }
924
925         *pData = TempData;
926 }
927
928
929 VOID
930 PHY_ConvertTxPowerByRateInDbmToRelativeValuesOld(
931         IN      PADAPTER        pAdapter
932         )
933 {
934         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA( pAdapter );
935         u8                      base = 0;
936         
937         //DBG_871X("===>PHY_ConvertTxPowerByRateInDbmToRelativeValuesOld()\n" );
938         
939         // CCK
940         base = PHY_GetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_A, RF_1TX, CCK );
941         phy_ConvertTxPowerByRateByBase( 
942                         &( pHalData->MCSTxPowerLevelOriginalOffset[0][6] ), 1, 1, base );
943         phy_ConvertTxPowerByRateByBase( 
944                         &( pHalData->MCSTxPowerLevelOriginalOffset[0][7] ), 1, 3, base );
945
946         // OFDM
947         base = PHY_GetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_A, RF_1TX, OFDM );
948         phy_ConvertTxPowerByRateByBase( 
949                         &( pHalData->MCSTxPowerLevelOriginalOffset[0][0] ), 0, 3, base );
950         phy_ConvertTxPowerByRateByBase( 
951                         &( pHalData->MCSTxPowerLevelOriginalOffset[0][1] ),     0, 3, base );
952
953         // HT MCS0~7
954         base = PHY_GetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_A, RF_1TX, HT_MCS0_MCS7 );
955         phy_ConvertTxPowerByRateByBase( 
956                         &( pHalData->MCSTxPowerLevelOriginalOffset[0][2] ),     0, 3, base );
957         phy_ConvertTxPowerByRateByBase( 
958                         &( pHalData->MCSTxPowerLevelOriginalOffset[0][3] ),     0, 3, base );
959
960         // HT MCS8~15
961         base = PHY_GetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_A, RF_2TX, HT_MCS8_MCS15 );
962         phy_ConvertTxPowerByRateByBase( 
963                         &( pHalData->MCSTxPowerLevelOriginalOffset[0][4] ), 0, 3, base );
964         phy_ConvertTxPowerByRateByBase( 
965                         &( pHalData->MCSTxPowerLevelOriginalOffset[0][5] ), 0, 3, base );
966
967         // CCK
968         base = PHY_GetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_B, RF_1TX, CCK );
969         phy_ConvertTxPowerByRateByBase( 
970                         &( pHalData->MCSTxPowerLevelOriginalOffset[0][14] ), 1, 3, base );
971         phy_ConvertTxPowerByRateByBase( 
972                         &( pHalData->MCSTxPowerLevelOriginalOffset[0][15] ), 0, 0, base );
973
974         // OFDM
975         base = PHY_GetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_B, RF_1TX, OFDM );
976         phy_ConvertTxPowerByRateByBase( 
977                         &( pHalData->MCSTxPowerLevelOriginalOffset[0][8] ), 0, 3, base );
978         phy_ConvertTxPowerByRateByBase( 
979                         &( pHalData->MCSTxPowerLevelOriginalOffset[0][9] ),     0, 3, base );
980
981         // HT MCS0~7
982         base = PHY_GetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_B, RF_1TX, HT_MCS0_MCS7 );
983         phy_ConvertTxPowerByRateByBase( 
984                         &( pHalData->MCSTxPowerLevelOriginalOffset[0][10] ), 0, 3, base );
985         phy_ConvertTxPowerByRateByBase( 
986                         &( pHalData->MCSTxPowerLevelOriginalOffset[0][11] ), 0, 3, base );
987
988         // HT MCS8~15
989         base = PHY_GetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_B, RF_2TX, HT_MCS8_MCS15 );
990         phy_ConvertTxPowerByRateByBase( 
991                         &( pHalData->MCSTxPowerLevelOriginalOffset[0][12] ), 0, 3, base );
992         phy_ConvertTxPowerByRateByBase( 
993                         &( pHalData->MCSTxPowerLevelOriginalOffset[0][13] ), 0, 3, base );
994
995         //DBG_871X("<===PHY_ConvertTxPowerByRateInDbmToRelativeValuesOld()\n" );
996 }
997 #endif /* TX_POWER_BY_RATE_OLD */
998
999 VOID
1000 phy_ConvertTxPowerByRateInDbmToRelativeValues(
1001         IN      PADAPTER        pAdapter
1002         )
1003 {
1004         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA( pAdapter );
1005         u8                      base = 0, i = 0, value = 0,
1006                                 band = 0, path = 0, txNum = 0, index = 0, 
1007                                 startIndex = 0, endIndex = 0;
1008         u8                      cckRates[4] = {MGN_1M, MGN_2M, MGN_5_5M, MGN_11M},
1009                                 ofdmRates[8] = {MGN_6M, MGN_9M, MGN_12M, MGN_18M, MGN_24M, MGN_36M, MGN_48M, MGN_54M},
1010                                 mcs0_7Rates[8] = {MGN_MCS0, MGN_MCS1, MGN_MCS2, MGN_MCS3, MGN_MCS4, MGN_MCS5, MGN_MCS6, MGN_MCS7},
1011                                 mcs8_15Rates[8] = {MGN_MCS8, MGN_MCS9, MGN_MCS10, MGN_MCS11, MGN_MCS12, MGN_MCS13, MGN_MCS14, MGN_MCS15},
1012                                 mcs16_23Rates[8] = {MGN_MCS16, MGN_MCS17, MGN_MCS18, MGN_MCS19, MGN_MCS20, MGN_MCS21, MGN_MCS22, MGN_MCS23},
1013                                 vht1ssRates[10] = {MGN_VHT1SS_MCS0, MGN_VHT1SS_MCS1, MGN_VHT1SS_MCS2, MGN_VHT1SS_MCS3, MGN_VHT1SS_MCS4, 
1014                                                            MGN_VHT1SS_MCS5, MGN_VHT1SS_MCS6, MGN_VHT1SS_MCS7, MGN_VHT1SS_MCS8, MGN_VHT1SS_MCS9},
1015                                 vht2ssRates[10] = {MGN_VHT2SS_MCS0, MGN_VHT2SS_MCS1, MGN_VHT2SS_MCS2, MGN_VHT2SS_MCS3, MGN_VHT2SS_MCS4, 
1016                                                            MGN_VHT2SS_MCS5, MGN_VHT2SS_MCS6, MGN_VHT2SS_MCS7, MGN_VHT2SS_MCS8, MGN_VHT2SS_MCS9},
1017                                 vht3ssRates[10] = {MGN_VHT3SS_MCS0, MGN_VHT3SS_MCS1, MGN_VHT3SS_MCS2, MGN_VHT3SS_MCS3, MGN_VHT3SS_MCS4, 
1018                                                                    MGN_VHT3SS_MCS5, MGN_VHT3SS_MCS6, MGN_VHT3SS_MCS7, MGN_VHT3SS_MCS8, MGN_VHT3SS_MCS9};
1019
1020         //DBG_871X("===>PHY_ConvertTxPowerByRateInDbmToRelativeValues()\n" );
1021
1022         for ( band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band )
1023         {
1024                 for ( path = ODM_RF_PATH_A; path <= ODM_RF_PATH_D; ++path )
1025                 {
1026                         for ( txNum = RF_1TX; txNum < RF_MAX_TX_NUM; ++txNum )
1027                         {
1028                                 // CCK
1029                                 base = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, MGN_11M );
1030                                 for ( i = 0; i < sizeof( cckRates ); ++i )
1031                                 {
1032                                         value = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, cckRates[i] );
1033                                         PHY_SetTxPowerByRate( pAdapter, band, path, txNum, cckRates[i], value - base );
1034                                 }
1035
1036                                 // OFDM
1037                                 base = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, MGN_54M );
1038                                 for ( i = 0; i < sizeof( ofdmRates ); ++i )
1039                                 {
1040                                         value = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, ofdmRates[i] );
1041                                         PHY_SetTxPowerByRate( pAdapter, band, path, txNum, ofdmRates[i], value - base );
1042                                 }
1043                                 
1044                                 // HT MCS0~7
1045                                 base = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, MGN_MCS7 );
1046                                 for ( i = 0; i < sizeof( mcs0_7Rates ); ++i )
1047                                 {
1048                                         value = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, mcs0_7Rates[i] );
1049                                         PHY_SetTxPowerByRate( pAdapter, band, path, txNum, mcs0_7Rates[i], value - base );
1050                                 }
1051
1052                                 // HT MCS8~15
1053                                 base = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, MGN_MCS15 );
1054                                 for ( i = 0; i < sizeof( mcs8_15Rates ); ++i )
1055                                 {
1056                                         value = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, mcs8_15Rates[i] );
1057                                         PHY_SetTxPowerByRate( pAdapter, band, path, txNum, mcs8_15Rates[i], value - base );
1058                                 }
1059
1060                                 // HT MCS16~23
1061                                 base = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, MGN_MCS23 );
1062                                 for ( i = 0; i < sizeof( mcs16_23Rates ); ++i )
1063                                 {
1064                                         value = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, mcs16_23Rates[i] );
1065                                         PHY_SetTxPowerByRate( pAdapter, band, path, txNum, mcs16_23Rates[i], value - base );
1066                                 }
1067
1068                                 // VHT 1SS
1069                                 base = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, MGN_VHT1SS_MCS7 );
1070                                 for ( i = 0; i < sizeof( vht1ssRates ); ++i )
1071                                 {
1072                                         value = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, vht1ssRates[i] );
1073                                         PHY_SetTxPowerByRate( pAdapter, band, path, txNum, vht1ssRates[i], value - base );
1074                                 }
1075
1076                                 // VHT 2SS
1077                                 base = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, MGN_VHT2SS_MCS7 );
1078                                 for ( i = 0; i < sizeof( vht2ssRates ); ++i )
1079                                 {
1080                                         value = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, vht2ssRates[i] );
1081                                         PHY_SetTxPowerByRate( pAdapter, band, path, txNum, vht2ssRates[i], value - base );
1082                                 }
1083
1084                                 // VHT 3SS
1085                                 base = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, MGN_VHT3SS_MCS7 );
1086                                 for ( i = 0; i < sizeof( vht3ssRates ); ++i )
1087                                 {
1088                                         value = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, vht3ssRates[i] );
1089                                         PHY_SetTxPowerByRate( pAdapter, band, path, txNum, vht3ssRates[i], value - base );
1090                                 }
1091                         }
1092                 }
1093         }
1094
1095         //DBG_871X("<===PHY_ConvertTxPowerByRateInDbmToRelativeValues()\n" );
1096 }
1097
1098 /*
1099   * This function must be called if the value in the PHY_REG_PG.txt(or header)
1100   * is exact dBm values
1101   */
1102 VOID
1103 PHY_TxPowerByRateConfiguration(
1104         IN  PADAPTER                    pAdapter
1105         )
1106 {
1107         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA( pAdapter);
1108
1109         phy_StoreTxPowerByRateBase( pAdapter );
1110         phy_ConvertTxPowerByRateInDbmToRelativeValues( pAdapter );
1111 }
1112
1113 VOID 
1114 PHY_SetTxPowerIndexByRateSection(
1115         IN      PADAPTER                pAdapter,
1116         IN      u8                              RFPath, 
1117         IN      u8                              Channel,
1118         IN      u8                              RateSection
1119         )
1120 {
1121         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(pAdapter);
1122
1123         if ( RateSection == CCK )
1124         {
1125                 u8      cckRates[]   = {MGN_1M, MGN_2M, MGN_5_5M, MGN_11M};
1126                 if ( pHalData->CurrentBandType == BAND_ON_2_4G )
1127                         PHY_SetTxPowerIndexByRateArray( pAdapter, RFPath, pHalData->CurrentChannelBW, Channel,
1128                                                                           cckRates, sizeof(cckRates)/sizeof(u8) );
1129                         
1130         }
1131         else if ( RateSection == OFDM )
1132         {
1133                 u8      ofdmRates[]  = {MGN_6M, MGN_9M, MGN_12M, MGN_18M, MGN_24M, MGN_36M, MGN_48M, MGN_54M};
1134                 PHY_SetTxPowerIndexByRateArray( pAdapter, RFPath, pHalData->CurrentChannelBW, Channel,
1135                                                                          ofdmRates, sizeof(ofdmRates)/sizeof(u8));
1136                 
1137         }
1138         else if ( RateSection == HT_MCS0_MCS7 )
1139         {
1140                 u8      htRates1T[]  = {MGN_MCS0, MGN_MCS1, MGN_MCS2, MGN_MCS3, MGN_MCS4, MGN_MCS5, MGN_MCS6, MGN_MCS7};
1141                 PHY_SetTxPowerIndexByRateArray( pAdapter, RFPath, pHalData->CurrentChannelBW, Channel,
1142                                                                          htRates1T, sizeof(htRates1T)/sizeof(u8));
1143
1144         }
1145         else if ( RateSection == HT_MCS8_MCS15 )
1146         {
1147                 u8      htRates2T[]  = {MGN_MCS8, MGN_MCS9, MGN_MCS10, MGN_MCS11, MGN_MCS12, MGN_MCS13, MGN_MCS14, MGN_MCS15};
1148                 PHY_SetTxPowerIndexByRateArray( pAdapter, RFPath, pHalData->CurrentChannelBW, Channel,
1149                                                                          htRates2T, sizeof(htRates2T)/sizeof(u8));
1150                 
1151         }
1152         else if ( RateSection == HT_MCS16_MCS23 )
1153         {
1154                 u1Byte  htRates3T[]  = {MGN_MCS16, MGN_MCS17, MGN_MCS18, MGN_MCS19, MGN_MCS20, MGN_MCS21, MGN_MCS22, MGN_MCS23};
1155                 PHY_SetTxPowerIndexByRateArray( pAdapter, RFPath, pHalData->CurrentChannelBW, Channel,
1156                                                                          htRates3T, sizeof(htRates3T)/sizeof(u1Byte));
1157                 
1158         }
1159         else if ( RateSection == HT_MCS24_MCS31 )
1160         {
1161                 u1Byte  htRates4T[]  = {MGN_MCS24, MGN_MCS25, MGN_MCS26, MGN_MCS27, MGN_MCS28, MGN_MCS29, MGN_MCS30, MGN_MCS31};
1162                 PHY_SetTxPowerIndexByRateArray( pAdapter, RFPath, pHalData->CurrentChannelBW, Channel,
1163                                                                          htRates4T, sizeof(htRates4T)/sizeof(u1Byte));
1164                 
1165         }
1166         else if ( RateSection == VHT_1SSMCS0_1SSMCS9 )
1167         {       
1168                 u8      vhtRates1T[] = {MGN_VHT1SS_MCS0, MGN_VHT1SS_MCS1, MGN_VHT1SS_MCS2, MGN_VHT1SS_MCS3, MGN_VHT1SS_MCS4, 
1169                                 MGN_VHT1SS_MCS5, MGN_VHT1SS_MCS6, MGN_VHT1SS_MCS7, MGN_VHT1SS_MCS8, MGN_VHT1SS_MCS9};
1170                 PHY_SetTxPowerIndexByRateArray( pAdapter, RFPath, pHalData->CurrentChannelBW, Channel,
1171                                                                         vhtRates1T, sizeof(vhtRates1T)/sizeof(u8));
1172
1173         }
1174         else if ( RateSection == VHT_2SSMCS0_2SSMCS9 )
1175         {
1176                 u8      vhtRates2T[] = {MGN_VHT2SS_MCS0, MGN_VHT2SS_MCS1, MGN_VHT2SS_MCS2, MGN_VHT2SS_MCS3, MGN_VHT2SS_MCS4, 
1177                                 MGN_VHT2SS_MCS5, MGN_VHT2SS_MCS6, MGN_VHT2SS_MCS7, MGN_VHT2SS_MCS8, MGN_VHT2SS_MCS9};
1178
1179                 PHY_SetTxPowerIndexByRateArray( pAdapter, RFPath, pHalData->CurrentChannelBW, Channel,
1180                                                                   vhtRates2T, sizeof(vhtRates2T)/sizeof(u8));
1181         }
1182         else if ( RateSection == VHT_3SSMCS0_3SSMCS9 )
1183         {
1184                 u1Byte  vhtRates3T[] = {MGN_VHT3SS_MCS0, MGN_VHT3SS_MCS1, MGN_VHT3SS_MCS2, MGN_VHT3SS_MCS3, MGN_VHT3SS_MCS4, 
1185                                 MGN_VHT3SS_MCS5, MGN_VHT3SS_MCS6, MGN_VHT3SS_MCS7, MGN_VHT3SS_MCS8, MGN_VHT3SS_MCS9};
1186
1187                 PHY_SetTxPowerIndexByRateArray( pAdapter, RFPath, pHalData->CurrentChannelBW, Channel,
1188                                                                   vhtRates3T, sizeof(vhtRates3T)/sizeof(u1Byte));
1189         }
1190         else if ( RateSection == VHT_4SSMCS0_4SSMCS9 )
1191         {
1192                 u1Byte  vhtRates4T[] = {MGN_VHT4SS_MCS0, MGN_VHT4SS_MCS1, MGN_VHT4SS_MCS2, MGN_VHT4SS_MCS3, MGN_VHT4SS_MCS4, 
1193                                 MGN_VHT4SS_MCS5, MGN_VHT4SS_MCS6, MGN_VHT4SS_MCS7, MGN_VHT4SS_MCS8, MGN_VHT4SS_MCS9};
1194
1195                 PHY_SetTxPowerIndexByRateArray( pAdapter, RFPath, pHalData->CurrentChannelBW, Channel,
1196                                                                   vhtRates4T, sizeof(vhtRates4T)/sizeof(u1Byte));
1197         }
1198         else
1199         {
1200                 DBG_871X("Invalid RateSection %d in %s", RateSection, __FUNCTION__ );
1201         }
1202 }
1203
1204 BOOLEAN 
1205 phy_GetChnlIndex(
1206         IN      u8      Channel,
1207         OUT u8* ChannelIdx
1208         )
1209 {
1210         u8  i = 0;
1211         BOOLEAN bIn24G=_TRUE;
1212
1213         if (Channel <= 14) {
1214                 bIn24G = _TRUE;
1215                 *ChannelIdx = Channel - 1;
1216         } else {
1217                 bIn24G = _FALSE;        
1218
1219                 for (i = 0; i < CENTER_CH_5G_ALL_NUM; ++i) {
1220                         if (center_ch_5g_all[i] == Channel) {
1221                                 *ChannelIdx = i;
1222                                 return bIn24G;
1223                         }
1224                 }
1225         }
1226
1227         return bIn24G;
1228 }
1229
1230 u8
1231 PHY_GetTxPowerIndexBase(
1232         IN      PADAPTER                pAdapter,
1233         IN      u8                              RFPath,
1234         IN      u8                              Rate,   
1235         IN      CHANNEL_WIDTH   BandWidth,      
1236         IN      u8                              Channel,
1237         OUT PBOOLEAN            bIn24G
1238         )
1239 {
1240         PHAL_DATA_TYPE          pHalData = GET_HAL_DATA(pAdapter);
1241         PDM_ODM_T                       pDM_Odm = &pHalData->odmpriv;
1242         u8                                      i = 0;  //default set to 1S
1243         u8                                      txPower = 0;
1244         u8                                      chnlIdx = (Channel-1);
1245         
1246         if (HAL_IsLegalChannel(pAdapter, Channel) == _FALSE)
1247         {
1248                 chnlIdx = 0;
1249                 DBG_871X("Illegal channel!!\n");
1250         }
1251
1252         *bIn24G = phy_GetChnlIndex(Channel, &chnlIdx);
1253
1254         //DBG_871X("[%s] Channel Index: %d\n", (*bIn24G?"2.4G":"5G"), chnlIdx);
1255
1256         if (*bIn24G) //3 ============================== 2.4 G ==============================
1257         {
1258                 if ( IS_CCK_RATE(Rate) )
1259                 {
1260                         txPower = pHalData->Index24G_CCK_Base[RFPath][chnlIdx]; 
1261                 }
1262                 else if ( MGN_6M <= Rate )
1263                 {                               
1264                         txPower = pHalData->Index24G_BW40_Base[RFPath][chnlIdx];
1265                 }
1266                 else
1267                 {
1268                         DBG_871X("PHY_GetTxPowerIndexBase: INVALID Rate.\n");
1269                 }
1270
1271                 //DBG_871X("Base Tx power(RF-%c, Rate #%d, Channel Index %d) = 0x%X\n", 
1272                 //              ((RFPath==0)?'A':'B'), Rate, chnlIdx, txPower);
1273                 
1274                 // OFDM-1T
1275                 if ( (MGN_6M <= Rate && Rate <= MGN_54M) && ! IS_CCK_RATE(Rate) )
1276                 {
1277                         txPower += pHalData->OFDM_24G_Diff[RFPath][TX_1S];
1278                         //DBG_871X("+PowerDiff 2.4G (RF-%c): (OFDM-1T) = (%d)\n", ((RFPath==0)?'A':'B'), pHalData->OFDM_24G_Diff[RFPath][TX_1S]);
1279                 }
1280                 // BW20-1S, BW20-2S
1281                 if (BandWidth == CHANNEL_WIDTH_20)
1282                 {
1283                         if ( (MGN_MCS0 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1284                                 txPower += pHalData->BW20_24G_Diff[RFPath][TX_1S];
1285                         if ( (MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1286                                 txPower += pHalData->BW20_24G_Diff[RFPath][TX_2S];
1287                         if ( (MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1288                                 txPower += pHalData->BW20_24G_Diff[RFPath][TX_3S];
1289                         if ( (MGN_MCS24 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1290                                 txPower += pHalData->BW20_24G_Diff[RFPath][TX_4S];
1291
1292                         //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'), 
1293                         //      pHalData->BW20_24G_Diff[RFPath][TX_1S], pHalData->BW20_24G_Diff[RFPath][TX_2S], 
1294                         //      pHalData->BW20_24G_Diff[RFPath][TX_3S], pHalData->BW20_24G_Diff[RFPath][TX_4S]);
1295                 }
1296                 // BW40-1S, BW40-2S
1297                 else if (BandWidth == CHANNEL_WIDTH_40)
1298                 {
1299                         if ( (MGN_MCS0 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1300                                 txPower += pHalData->BW40_24G_Diff[RFPath][TX_1S];
1301                         if ( (MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1302                                 txPower += pHalData->BW40_24G_Diff[RFPath][TX_2S];
1303                         if ( (MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1304                                 txPower += pHalData->BW40_24G_Diff[RFPath][TX_3S];
1305                         if ( (MGN_MCS24 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1306                                 txPower += pHalData->BW40_24G_Diff[RFPath][TX_4S];                       
1307
1308                         //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'), 
1309                         //      pHalData->BW40_24G_Diff[RFPath][TX_1S], pHalData->BW40_24G_Diff[RFPath][TX_2S],
1310                         //      pHalData->BW40_24G_Diff[RFPath][TX_3S], pHalData->BW40_24G_Diff[RFPath][TX_4S]);
1311                 }
1312                 // Willis suggest adopt BW 40M power index while in BW 80 mode
1313                 else if ( BandWidth == CHANNEL_WIDTH_80 )
1314                 {
1315                         if ( (MGN_MCS0 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1316                                 txPower += pHalData->BW40_24G_Diff[RFPath][TX_1S];
1317                         if ( (MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1318                                 txPower += pHalData->BW40_24G_Diff[RFPath][TX_2S];
1319                         if ( (MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1320                                 txPower += pHalData->BW40_24G_Diff[RFPath][TX_3S];
1321                         if ( (MGN_MCS24 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1322                                 txPower += pHalData->BW40_24G_Diff[RFPath][TX_4S];
1323
1324                         //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'), 
1325                         //      pHalData->BW40_24G_Diff[RFPath][TX_1S], pHalData->BW40_24G_Diff[RFPath][TX_2S],
1326                         //      pHalData->BW40_24G_Diff[RFPath][TX_3S], pHalData->BW40_24G_Diff[RFPath][TX_4S]);
1327                 }
1328         }
1329         else //3 ============================== 5 G ==============================
1330         {
1331                 if ( MGN_6M <= Rate )
1332                 {                               
1333                         txPower = pHalData->Index5G_BW40_Base[RFPath][chnlIdx];
1334                 }
1335                 else
1336                 {
1337                         DBG_871X("===> mpt_ProQueryCalTxPower_Jaguar: INVALID Rate.\n");
1338                 }
1339
1340                 //DBG_871X("Base Tx power(RF-%c, Rate #%d, Channel Index %d) = 0x%X\n", 
1341                 //      ((RFPath==0)?'A':'B'), Rate, chnlIdx, txPower);
1342
1343                 // OFDM-1T
1344                 if ( (MGN_6M <= Rate && Rate <= MGN_54M) && ! IS_CCK_RATE(Rate))
1345                 {
1346                         txPower += pHalData->OFDM_5G_Diff[RFPath][TX_1S];
1347                         //DBG_871X("+PowerDiff 5G (RF-%c): (OFDM-1T) = (%d)\n", ((RFPath==0)?'A':'B'), pHalData->OFDM_5G_Diff[RFPath][TX_1S]);
1348                 }
1349                 
1350                 // BW20-1S, BW20-2S
1351                 if (BandWidth == CHANNEL_WIDTH_20)
1352                 {
1353                         if ( (MGN_MCS0 <= Rate && Rate <= MGN_MCS31)  || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1354                                 txPower += pHalData->BW20_5G_Diff[RFPath][TX_1S];
1355                         if ( (MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1356                                 txPower += pHalData->BW20_5G_Diff[RFPath][TX_2S];
1357                         if ( (MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1358                                 txPower += pHalData->BW20_5G_Diff[RFPath][TX_3S];
1359                         if ( (MGN_MCS24 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1360                                 txPower += pHalData->BW20_5G_Diff[RFPath][TX_4S];
1361
1362                         //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'), 
1363                         //      pHalData->BW20_5G_Diff[RFPath][TX_1S], pHalData->BW20_5G_Diff[RFPath][TX_2S],
1364                         //      pHalData->BW20_5G_Diff[RFPath][TX_3S], pHalData->BW20_5G_Diff[RFPath][TX_4S]);
1365                 }
1366                 // BW40-1S, BW40-2S
1367                 else if (BandWidth == CHANNEL_WIDTH_40)
1368                 {
1369                         if ( (MGN_MCS0 <= Rate && Rate <= MGN_MCS31)  || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1370                                 txPower += pHalData->BW40_5G_Diff[RFPath][TX_1S];
1371                         if ( (MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1372                                 txPower += pHalData->BW40_5G_Diff[RFPath][TX_2S];
1373                         if ( (MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1374                                 txPower += pHalData->BW40_5G_Diff[RFPath][TX_3S];
1375                         if ( (MGN_MCS24 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1376                                 txPower += pHalData->BW40_5G_Diff[RFPath][TX_4S];
1377
1378                         //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'), 
1379                         //      pHalData->BW40_5G_Diff[RFPath][TX_1S], pHalData->BW40_5G_Diff[RFPath][TX_2S],
1380                         //      pHalData->BW40_5G_Diff[RFPath][TX_3S], pHalData->BW40_5G_Diff[RFPath][TX_4S]);
1381                 }
1382                 // BW80-1S, BW80-2S
1383                 else if (BandWidth== CHANNEL_WIDTH_80)
1384                 {
1385                         // <20121220, Kordan> Get the index of array "Index5G_BW80_Base".
1386                         for (i = 0; i < CENTER_CH_5G_80M_NUM; ++i)
1387                                 if (center_ch_5g_80m[i] == Channel)
1388                                         chnlIdx = i;
1389
1390                         txPower = pHalData->Index5G_BW80_Base[RFPath][chnlIdx];
1391
1392                         if ( (MGN_MCS0 <= Rate && Rate <= MGN_MCS31)  || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1393                                 txPower += + pHalData->BW80_5G_Diff[RFPath][TX_1S];
1394                         if ( (MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1395                                 txPower += pHalData->BW80_5G_Diff[RFPath][TX_2S];
1396                         if ( (MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1397                                 txPower += pHalData->BW80_5G_Diff[RFPath][TX_3S];
1398                         if ( (MGN_MCS23 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
1399                                 txPower += pHalData->BW80_5G_Diff[RFPath][TX_4S];
1400
1401                         //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'), 
1402                         //      pHalData->BW80_5G_Diff[RFPath][TX_1S], pHalData->BW80_5G_Diff[RFPath][TX_2S],
1403                         //      pHalData->BW80_5G_Diff[RFPath][TX_3S], pHalData->BW80_5G_Diff[RFPath][TX_4S]);
1404                 }
1405         }
1406
1407         return txPower; 
1408 }
1409
1410 s8
1411 PHY_GetTxPowerTrackingOffset( 
1412         PADAPTER        pAdapter,
1413         u8                      RFPath,
1414         u8                      Rate
1415         )
1416 {
1417         PHAL_DATA_TYPE          pHalData = GET_HAL_DATA(pAdapter);
1418         PDM_ODM_T                       pDM_Odm = &pHalData->odmpriv;   
1419         s8      offset = 0;
1420         
1421         if( pDM_Odm->RFCalibrateInfo.TxPowerTrackControl  == _FALSE)
1422                 return offset;
1423         
1424         if ((Rate == MGN_1M) ||(Rate == MGN_2M)||(Rate == MGN_5_5M)||(Rate == MGN_11M))
1425         { 
1426                 offset = pDM_Odm->RFCalibrateInfo.Remnant_CCKSwingIdx;
1427                 /*DBG_871X("+Remnant_CCKSwingIdx = 0x%x\n", RFPath, Rate, pRFCalibrateInfo->Remnant_CCKSwingIdx);*/
1428         }
1429         else
1430         {
1431                 offset = pDM_Odm->RFCalibrateInfo.Remnant_OFDMSwingIdx[RFPath]; 
1432                 /*DBG_871X("+Remanant_OFDMSwingIdx[RFPath %u][Rate 0x%x] = 0x%x\n", RFPath, Rate, pRFCalibrateInfo->Remnant_OFDMSwingIdx[RFPath]);      */      
1433                 
1434         }
1435
1436         return offset;
1437 }
1438
1439 u8
1440 PHY_GetRateIndexOfTxPowerByRate(
1441         IN      u8              Rate
1442         )
1443 {
1444         u8      index = 0;
1445         switch ( Rate )
1446         {
1447                 case MGN_1M: index = 0; break;
1448                 case MGN_2M: index = 1; break;
1449                 case MGN_5_5M: index = 2; break;
1450                 case MGN_11M: index = 3; break;
1451                 case MGN_6M: index = 4; break;
1452                 case MGN_9M: index = 5; break;
1453                 case MGN_12M: index = 6; break;
1454                 case MGN_18M: index = 7; break;
1455                 case MGN_24M: index = 8; break;
1456                 case MGN_36M: index = 9; break;
1457                 case MGN_48M: index = 10; break;
1458                 case MGN_54M: index = 11; break;
1459                 case MGN_MCS0: index = 12; break;
1460                 case MGN_MCS1: index = 13; break;
1461                 case MGN_MCS2: index = 14; break;
1462                 case MGN_MCS3: index = 15; break;
1463                 case MGN_MCS4: index = 16; break;
1464                 case MGN_MCS5: index = 17; break;
1465                 case MGN_MCS6: index = 18; break;
1466                 case MGN_MCS7: index = 19; break;
1467                 case MGN_MCS8: index = 20; break;
1468                 case MGN_MCS9: index = 21; break;
1469                 case MGN_MCS10: index = 22; break;
1470                 case MGN_MCS11: index = 23; break;
1471                 case MGN_MCS12: index = 24; break;
1472                 case MGN_MCS13: index = 25; break;
1473                 case MGN_MCS14: index = 26; break;
1474                 case MGN_MCS15: index = 27; break;
1475                 case MGN_MCS16: index = 28; break;
1476                 case MGN_MCS17: index = 29; break;
1477                 case MGN_MCS18: index = 30; break;
1478                 case MGN_MCS19: index = 31; break;
1479                 case MGN_MCS20: index = 32; break;
1480                 case MGN_MCS21: index = 33; break;
1481                 case MGN_MCS22: index = 34; break;
1482                 case MGN_MCS23: index = 35; break;
1483                 case MGN_MCS24: index = 36; break;
1484                 case MGN_MCS25: index = 37; break;
1485                 case MGN_MCS26: index = 38; break;
1486                 case MGN_MCS27: index = 39; break;
1487                 case MGN_MCS28: index = 40; break;
1488                 case MGN_MCS29: index = 41; break;
1489                 case MGN_MCS30: index = 42; break;
1490                 case MGN_MCS31: index = 43; break;
1491                 case MGN_VHT1SS_MCS0: index = 44; break;
1492                 case MGN_VHT1SS_MCS1: index = 45; break;
1493                 case MGN_VHT1SS_MCS2: index = 46; break;
1494                 case MGN_VHT1SS_MCS3: index = 47; break;
1495                 case MGN_VHT1SS_MCS4: index = 48; break;
1496                 case MGN_VHT1SS_MCS5: index = 49; break;
1497                 case MGN_VHT1SS_MCS6: index = 50; break;
1498                 case MGN_VHT1SS_MCS7: index = 51; break;
1499                 case MGN_VHT1SS_MCS8: index = 52; break;
1500                 case MGN_VHT1SS_MCS9: index = 53; break;
1501                 case MGN_VHT2SS_MCS0: index = 54; break;
1502                 case MGN_VHT2SS_MCS1: index = 55; break;
1503                 case MGN_VHT2SS_MCS2: index = 56; break;
1504                 case MGN_VHT2SS_MCS3: index = 57; break;
1505                 case MGN_VHT2SS_MCS4: index = 58; break;
1506                 case MGN_VHT2SS_MCS5: index = 59; break;
1507                 case MGN_VHT2SS_MCS6: index = 60; break;
1508                 case MGN_VHT2SS_MCS7: index = 61; break;
1509                 case MGN_VHT2SS_MCS8: index = 62; break;
1510                 case MGN_VHT2SS_MCS9: index = 63; break;
1511                 case MGN_VHT3SS_MCS0: index = 64; break;
1512                 case MGN_VHT3SS_MCS1: index = 65; break;
1513                 case MGN_VHT3SS_MCS2: index = 66; break;
1514                 case MGN_VHT3SS_MCS3: index = 67; break;
1515                 case MGN_VHT3SS_MCS4: index = 68; break;
1516                 case MGN_VHT3SS_MCS5: index = 69; break;
1517                 case MGN_VHT3SS_MCS6: index = 70; break;
1518                 case MGN_VHT3SS_MCS7: index = 71; break;
1519                 case MGN_VHT3SS_MCS8: index = 72; break;
1520                 case MGN_VHT3SS_MCS9: index = 73; break;
1521                 case MGN_VHT4SS_MCS0: index = 74; break;
1522                 case MGN_VHT4SS_MCS1: index = 75; break;
1523                 case MGN_VHT4SS_MCS2: index = 76; break;
1524                 case MGN_VHT4SS_MCS3: index = 77; break;
1525                 case MGN_VHT4SS_MCS4: index = 78; break;
1526                 case MGN_VHT4SS_MCS5: index = 79; break;
1527                 case MGN_VHT4SS_MCS6: index = 80; break;
1528                 case MGN_VHT4SS_MCS7: index = 81; break;
1529                 case MGN_VHT4SS_MCS8: index = 82; break;
1530                 case MGN_VHT4SS_MCS9: index = 83; break;
1531                 default:
1532                         DBG_871X("Invalid rate 0x%x in %s\n", Rate, __FUNCTION__ );
1533                         break;
1534         };
1535
1536         return index;
1537 }
1538
1539 s8
1540 _PHY_GetTxPowerByRate(
1541         IN      PADAPTER        pAdapter, 
1542         IN      u8                      Band, 
1543         IN      u8                      RFPath, 
1544         IN      u8                      TxNum, 
1545         IN      u8                      Rate
1546         )
1547 {
1548         HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
1549         s8 value = 0;
1550         u8 rateIndex = PHY_GetRateIndexOfTxPowerByRate(Rate);
1551
1552         if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) {
1553                 DBG_871X("Invalid band %d in %s\n", Band, __func__);
1554                 goto exit;
1555         }
1556         if (RFPath > ODM_RF_PATH_D) {
1557                 DBG_871X("Invalid RfPath %d in %s\n", RFPath, __func__);
1558                 goto exit;
1559         }
1560         if (TxNum >= RF_MAX_TX_NUM) {
1561                 DBG_871X("Invalid TxNum %d in %s\n", TxNum, __func__);
1562                 goto exit;
1563         }
1564         if (rateIndex >= TX_PWR_BY_RATE_NUM_RATE) {
1565                 DBG_871X("Invalid RateIndex %d in %s\n", rateIndex, __func__);
1566                 goto exit;
1567         }
1568
1569         value = pHalData->TxPwrByRateOffset[Band][RFPath][TxNum][rateIndex];
1570
1571 exit:
1572         return value;
1573 }
1574
1575
1576 s8
1577 PHY_GetTxPowerByRate(
1578         IN      PADAPTER        pAdapter,
1579         IN      u8                      Band,
1580         IN      u8                      RFPath,
1581         IN      u8                      TxNum,
1582         IN      u8                      Rate
1583         )
1584 {
1585         if (!phy_is_tx_power_by_rate_needed(pAdapter))
1586                 return 0;
1587
1588         return _PHY_GetTxPowerByRate(pAdapter, Band, RFPath, TxNum, Rate);
1589 }
1590
1591 VOID
1592 PHY_SetTxPowerByRate( 
1593         IN      PADAPTER        pAdapter, 
1594         IN      u8                      Band, 
1595         IN      u8                      RFPath, 
1596         IN      u8                      TxNum, 
1597         IN      u8                      Rate,
1598         IN      s8                      Value
1599         )
1600 {
1601         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA( pAdapter );
1602         u8      rateIndex = PHY_GetRateIndexOfTxPowerByRate( Rate );
1603         
1604         if ( Band != BAND_ON_2_4G && Band != BAND_ON_5G )
1605         {
1606                 DBG_871X("Invalid band %d in %s\n", Band, __FUNCTION__ );
1607                 return;
1608         }
1609         if ( RFPath > ODM_RF_PATH_D )
1610         {
1611                 DBG_871X("Invalid RfPath %d in %s\n", RFPath, __FUNCTION__ );
1612                 return;
1613         }
1614         if ( TxNum >= RF_MAX_TX_NUM )
1615         {
1616                 DBG_871X( "Invalid TxNum %d in %s\n", TxNum, __FUNCTION__ );
1617                 return;
1618         }
1619         if ( rateIndex >= TX_PWR_BY_RATE_NUM_RATE )
1620         {
1621                 DBG_871X("Invalid RateIndex %d in %s\n", rateIndex, __FUNCTION__ );
1622                 return;
1623         }
1624
1625         pHalData->TxPwrByRateOffset[Band][RFPath][TxNum][rateIndex] = Value;
1626 }
1627
1628 VOID
1629 PHY_SetTxPowerLevelByPath(
1630         IN      PADAPTER        Adapter,
1631         IN      u8                      channel,
1632         IN      u8                      path
1633         )
1634 {
1635         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(Adapter);
1636         BOOLEAN bIsIn24G = (pHalData->CurrentBandType == BAND_ON_2_4G );
1637
1638         //if ( pMgntInfo->RegNByteAccess == 0 )
1639         {
1640                 if ( bIsIn24G )
1641                         PHY_SetTxPowerIndexByRateSection( Adapter, path, channel, CCK );
1642                 
1643                 PHY_SetTxPowerIndexByRateSection( Adapter, path, channel, OFDM );
1644                 PHY_SetTxPowerIndexByRateSection( Adapter, path, channel, HT_MCS0_MCS7 );
1645
1646                 if (IS_HARDWARE_TYPE_JAGUAR(Adapter) || IS_HARDWARE_TYPE_8814A(Adapter))
1647                         PHY_SetTxPowerIndexByRateSection(Adapter, path, channel, VHT_1SSMCS0_1SSMCS9);
1648
1649                 if (pHalData->NumTotalRFPath >= 2)
1650                 {
1651                         PHY_SetTxPowerIndexByRateSection( Adapter, path, channel, HT_MCS8_MCS15 );
1652
1653                         if (IS_HARDWARE_TYPE_JAGUAR(Adapter) || IS_HARDWARE_TYPE_8814A(Adapter))
1654                                 PHY_SetTxPowerIndexByRateSection(Adapter, path, channel, VHT_2SSMCS0_2SSMCS9);
1655
1656                         if (IS_HARDWARE_TYPE_8814A(Adapter))
1657                         {
1658                                 PHY_SetTxPowerIndexByRateSection( Adapter, path, channel, HT_MCS16_MCS23 );
1659                                 PHY_SetTxPowerIndexByRateSection( Adapter, path, channel, VHT_3SSMCS0_3SSMCS9 );
1660                         }
1661                 }
1662         }
1663 }
1664
1665 VOID
1666 PHY_SetTxPowerIndexByRateArray(
1667         IN      PADAPTER                        pAdapter,
1668         IN      u8                                      RFPath,
1669         IN      CHANNEL_WIDTH           BandWidth,      
1670         IN      u8                                      Channel,
1671         IN      u8*                                     Rates,
1672         IN      u8                                      RateArraySize
1673         )
1674 {
1675         u32     powerIndex = 0;
1676         int     i = 0;
1677
1678         for (i = 0; i < RateArraySize; ++i) 
1679         {
1680                 powerIndex = PHY_GetTxPowerIndex(pAdapter, RFPath, Rates[i], BandWidth, Channel);
1681                 PHY_SetTxPowerIndex(pAdapter, powerIndex, RFPath, Rates[i]);
1682         }
1683 }
1684
1685 s8
1686 phy_GetWorldWideLimit(
1687         s8* LimitTable
1688 )
1689 {
1690         s8      min = LimitTable[0];
1691         u8      i = 0;
1692         
1693         for (i = 0; i < MAX_REGULATION_NUM; ++i) {
1694                 if (LimitTable[i] < min)
1695                         min = LimitTable[i];
1696         }
1697
1698         return min;
1699 }
1700
1701 s8
1702 phy_GetChannelIndexOfTxPowerLimit(
1703         IN      u8                      Band,
1704         IN      u8                      Channel
1705         )
1706 {
1707         s8      channelIndex = -1;
1708         u8      i = 0;
1709
1710         if (Band == BAND_ON_2_4G) {
1711                 channelIndex = Channel - 1;
1712         } else if (Band == BAND_ON_5G) {
1713                 for (i = 0; i < CENTER_CH_5G_ALL_NUM; ++i) {
1714                         if (center_ch_5g_all[i] == Channel)
1715                                 channelIndex = i;
1716                 }
1717         } else {
1718                 DBG_871X_LEVEL(_drv_always_, "Invalid Band %d in %s\n", Band, __func__);
1719         }
1720
1721         if (channelIndex == -1)
1722                 DBG_871X_LEVEL(_drv_always_, "Invalid Channel %d of Band %d in %s\n", Channel, Band, __func__);
1723
1724         return channelIndex;
1725 }
1726
1727 s8
1728 PHY_GetTxPowerLimit(
1729         IN      PADAPTER                        Adapter,
1730         IN      u32                                     RegPwrTblSel,
1731         IN      BAND_TYPE                       Band,
1732         IN      CHANNEL_WIDTH           Bandwidth,
1733         IN      u8                                      RfPath,
1734         IN      u8                                      DataRate,
1735         IN      u8                                      Channel
1736         )
1737 {
1738         HAL_DATA_TYPE           *pHalData = GET_HAL_DATA(Adapter);
1739         s16                             band = -1, regulation = -1, bandwidth = -1,
1740                                         rateSection = -1, channel = -1;
1741         s8                              powerLimit = MAX_POWER_INDEX;
1742
1743         if ( ( Adapter->registrypriv.RegEnableTxPowerLimit == 2 && pHalData->EEPROMRegulatory != 1 ) || 
1744                    Adapter->registrypriv.RegEnableTxPowerLimit == 0 )
1745                 return MAX_POWER_INDEX;
1746
1747         switch (RegPwrTblSel) {
1748         case 1:
1749                 regulation = TXPWR_LMT_ETSI;
1750                 break;
1751         case 2:
1752                 regulation = TXPWR_LMT_MKK;
1753                 break;
1754         case 3:
1755                 regulation = TXPWR_LMT_FCC;
1756                 break;
1757         case 4:
1758                 regulation = TXPWR_LMT_WW;
1759                 break;
1760         default:
1761                 regulation = (Band == BAND_ON_2_4G) ? pHalData->Regulation2_4G : pHalData->Regulation5G;
1762                 break;
1763         }
1764
1765         //DBG_871X("pMgntInfo->RegPwrTblSel %d, final regulation %d\n", Adapter->registrypriv.RegPwrTblSel, regulation );
1766
1767         
1768         if ( Band == BAND_ON_2_4G ) band = 0; 
1769         else if ( Band == BAND_ON_5G ) band = 1; 
1770
1771         if ( Bandwidth == CHANNEL_WIDTH_20 ) bandwidth = 0;
1772         else if ( Bandwidth == CHANNEL_WIDTH_40 ) bandwidth = 1;
1773         else if ( Bandwidth == CHANNEL_WIDTH_80 ) bandwidth = 2;
1774         else if ( Bandwidth == CHANNEL_WIDTH_160 ) bandwidth = 3;
1775
1776         switch ( DataRate )
1777         {
1778                 case MGN_1M: case MGN_2M: case MGN_5_5M: case MGN_11M:
1779                         rateSection = 0;
1780                         break;
1781
1782                 case MGN_6M: case MGN_9M: case MGN_12M: case MGN_18M:
1783                 case MGN_24M: case MGN_36M: case MGN_48M: case MGN_54M:
1784                         rateSection = 1;
1785                         break;
1786
1787                 case MGN_MCS0: case MGN_MCS1: case MGN_MCS2: case MGN_MCS3: 
1788                 case MGN_MCS4: case MGN_MCS5: case MGN_MCS6: case MGN_MCS7:
1789                         rateSection = 2;
1790                         break;
1791                         
1792                 case MGN_MCS8: case MGN_MCS9: case MGN_MCS10: case MGN_MCS11: 
1793                 case MGN_MCS12: case MGN_MCS13: case MGN_MCS14: case MGN_MCS15:
1794                         rateSection = 3;
1795                         break;
1796
1797                 case MGN_MCS16: case MGN_MCS17: case MGN_MCS18: case MGN_MCS19: 
1798                 case MGN_MCS20: case MGN_MCS21: case MGN_MCS22: case MGN_MCS23:
1799                         rateSection = 4;
1800                         break;
1801
1802                 case MGN_MCS24: case MGN_MCS25: case MGN_MCS26: case MGN_MCS27: 
1803                 case MGN_MCS28: case MGN_MCS29: case MGN_MCS30: case MGN_MCS31:
1804                         rateSection = 5;
1805                         break;
1806
1807                 case MGN_VHT1SS_MCS0: case MGN_VHT1SS_MCS1: case MGN_VHT1SS_MCS2:
1808                 case MGN_VHT1SS_MCS3: case MGN_VHT1SS_MCS4: case MGN_VHT1SS_MCS5:
1809                 case MGN_VHT1SS_MCS6: case MGN_VHT1SS_MCS7: case MGN_VHT1SS_MCS8:
1810                 case MGN_VHT1SS_MCS9:
1811                         rateSection = 6;
1812                         break;
1813                         
1814                 case MGN_VHT2SS_MCS0: case MGN_VHT2SS_MCS1: case MGN_VHT2SS_MCS2:
1815                 case MGN_VHT2SS_MCS3: case MGN_VHT2SS_MCS4: case MGN_VHT2SS_MCS5:
1816                 case MGN_VHT2SS_MCS6: case MGN_VHT2SS_MCS7: case MGN_VHT2SS_MCS8:
1817                 case MGN_VHT2SS_MCS9:
1818                         rateSection = 7;
1819                         break;
1820
1821                 case MGN_VHT3SS_MCS0: case MGN_VHT3SS_MCS1: case MGN_VHT3SS_MCS2:
1822                 case MGN_VHT3SS_MCS3: case MGN_VHT3SS_MCS4: case MGN_VHT3SS_MCS5:
1823                 case MGN_VHT3SS_MCS6: case MGN_VHT3SS_MCS7: case MGN_VHT3SS_MCS8:
1824                 case MGN_VHT3SS_MCS9:
1825                         rateSection = 8;
1826                         break;
1827
1828                 case MGN_VHT4SS_MCS0: case MGN_VHT4SS_MCS1: case MGN_VHT4SS_MCS2:
1829                 case MGN_VHT4SS_MCS3: case MGN_VHT4SS_MCS4: case MGN_VHT4SS_MCS5:
1830                 case MGN_VHT4SS_MCS6: case MGN_VHT4SS_MCS7: case MGN_VHT4SS_MCS8:
1831                 case MGN_VHT4SS_MCS9:
1832                         rateSection = 9;
1833                         break;
1834
1835                 default:
1836                         DBG_871X("Wrong rate 0x%x\n", DataRate );
1837                         break;
1838         }
1839
1840         if ( Band == BAND_ON_5G  && rateSection == 0 )
1841                         DBG_871X("Wrong rate 0x%x: No CCK in 5G Band\n", DataRate );
1842
1843         // workaround for wrong index combination to obtain tx power limit, 
1844         // OFDM only exists in BW 20M
1845         if ( rateSection == 1 )
1846                 bandwidth = 0;
1847
1848         // workaround for wrong index combination to obtain tx power limit, 
1849         // CCK table will only be given in BW 20M
1850         if ( rateSection == 0 )
1851                 bandwidth = 0;
1852
1853         // workaround for wrong indxe combination to obtain tx power limit, 
1854         // HT on 80M will reference to HT on 40M
1855         if ( ( rateSection == 2 || rateSection == 3 ) && Band == BAND_ON_5G && bandwidth == 2 ) {
1856                 bandwidth = 1;
1857         }
1858         
1859         if ( Band == BAND_ON_2_4G )
1860                 channel = phy_GetChannelIndexOfTxPowerLimit( BAND_ON_2_4G, Channel );
1861         else if ( Band == BAND_ON_5G )
1862                 channel = phy_GetChannelIndexOfTxPowerLimit( BAND_ON_5G, Channel );
1863         else if ( Band == BAND_ON_BOTH )
1864         {
1865                 // BAND_ON_BOTH don't care temporarily 
1866         }
1867         
1868         if ( band == -1 || regulation == -1 || bandwidth == -1 || 
1869              rateSection == -1 || channel == -1 )
1870         {
1871                 //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",
1872                 //        band, regulation, bandwidth, RfPath, rateSection, channelGroup );
1873
1874                 return MAX_POWER_INDEX;
1875         }
1876
1877         if ( Band == BAND_ON_2_4G ) {
1878                 s8 limits[10] = {0}; u8 i = 0;
1879                 if (bandwidth >= MAX_2_4G_BANDWIDTH_NUM)
1880                         bandwidth = MAX_2_4G_BANDWIDTH_NUM - 1;
1881                 for (i = 0; i < MAX_REGULATION_NUM; ++i)
1882                         limits[i] = pHalData->TxPwrLimit_2_4G[i][bandwidth][rateSection][channel][RfPath]; 
1883
1884                 powerLimit = (regulation == TXPWR_LMT_WW) ? phy_GetWorldWideLimit(limits) :
1885                                   pHalData->TxPwrLimit_2_4G[regulation][bandwidth][rateSection][channel][RfPath];
1886
1887         } else if ( Band == BAND_ON_5G ) {
1888                 s8 limits[10] = {0}; u8 i = 0;
1889                 for (i = 0; i < MAX_REGULATION_NUM; ++i)
1890                         limits[i] = pHalData->TxPwrLimit_5G[i][bandwidth][rateSection][channel][RfPath];
1891                 
1892                 powerLimit = (regulation == TXPWR_LMT_WW) ? phy_GetWorldWideLimit(limits) : 
1893                                           pHalData->TxPwrLimit_5G[regulation][bandwidth][rateSection][channel][RfPath];
1894         } else 
1895                 DBG_871X("No power limit table of the specified band\n" );
1896
1897         // combine 5G VHT & HT rate
1898         // 5G 20M and 40M HT and VHT can cross reference
1899         /*
1900         if ( Band == BAND_ON_5G && powerLimit == MAX_POWER_INDEX ) {
1901                 if ( bandwidth == 0 || bandwidth == 1 ) { 
1902                         RT_TRACE( COMP_INIT, DBG_LOUD, ( "No power limit table of the specified band %d, bandwidth %d, ratesection %d, rf path %d\n", 
1903                                           band, bandwidth, rateSection, RfPath ) );
1904                         if ( rateSection == 2 )
1905                                 powerLimit = pHalData->TxPwrLimit_5G[regulation]
1906                                                                                 [bandwidth][4][channelGroup][RfPath];
1907                         else if ( rateSection == 4 )
1908                                 powerLimit = pHalData->TxPwrLimit_5G[regulation]
1909                                                                                 [bandwidth][2][channelGroup][RfPath];
1910                         else if ( rateSection == 3 )
1911                                 powerLimit = pHalData->TxPwrLimit_5G[regulation]
1912                                                                                 [bandwidth][5][channelGroup][RfPath];
1913                         else if ( rateSection == 5 )
1914                                 powerLimit = pHalData->TxPwrLimit_5G[regulation]
1915                                                                                 [bandwidth][3][channelGroup][RfPath];
1916                 }
1917         }
1918         */
1919         //DBG_871X("TxPwrLmt[Regulation %d][Band %d][BW %d][RFPath %d][Rate 0x%x][Chnl %d] = %d\n", 
1920         //              regulation, pHalData->CurrentBandType, Bandwidth, RfPath, DataRate, Channel, powerLimit);
1921         return powerLimit;
1922 }
1923
1924 VOID
1925 phy_CrossReferenceHTAndVHTTxPowerLimit(
1926         IN      PADAPTER                        pAdapter
1927         )
1928 {
1929         HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
1930         u8 regulation, bw, channel, rs, ref_rs;
1931         int ht_ref_vht_5g_20_40 = 0;
1932         int vht_ref_ht_5g_20_40 = 0;
1933         int ht_has_ref_5g_20_40 = 0;
1934         int vht_has_ref_5g_20_40 = 0;
1935
1936         pHalData->tx_pwr_lmt_5g_20_40_ref = 0;
1937
1938         for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
1939
1940                 for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; ++bw) {
1941
1942                         for (channel = 0; channel < CENTER_CH_5G_ALL_NUM; ++channel) {
1943
1944                                 for (rs = 0; rs < MAX_RATE_SECTION_NUM; ++rs) {
1945
1946                                         /* 5G 20M 40M VHT and HT can cross reference */
1947                                         if (bw == CHANNEL_WIDTH_20 || bw == CHANNEL_WIDTH_40) {
1948                                                 if (rs == HT_1SS)
1949                                                         ref_rs = VHT_1SS;
1950                                                 else if (rs == HT_2SS)
1951                                                         ref_rs = VHT_2SS;
1952                                                 else if (rs == HT_3SS)
1953                                                         ref_rs = VHT_3SS;
1954                                                 else if (rs == HT_4SS)
1955                                                         ref_rs = VHT_4SS;
1956                                                 else if (rs == VHT_1SS)
1957                                                         ref_rs = HT_1SS;
1958                                                 else if (rs == VHT_2SS)
1959                                                         ref_rs = HT_2SS;
1960                                                 else if (rs == VHT_3SS)
1961                                                         ref_rs = HT_3SS;
1962                                                 else if (rs == VHT_4SS)
1963                                                         ref_rs = HT_4SS;
1964                                                 else
1965                                                         continue;
1966
1967                                                 if (pHalData->TxPwrLimit_5G[regulation][bw][ref_rs][channel][RF_PATH_A] == MAX_POWER_INDEX)
1968                                                         continue;
1969
1970                                                 if (IS_HT_RATE_SECTION(rs))
1971                                                         ht_has_ref_5g_20_40++;
1972                                                 else if (IS_VHT_RATE_SECTION(rs))
1973                                                         vht_has_ref_5g_20_40++;
1974                                                 else
1975                                                         continue;
1976
1977                                                 if (pHalData->TxPwrLimit_5G[regulation][bw][rs][channel][RF_PATH_A] != MAX_POWER_INDEX)
1978                                                         continue;
1979
1980                                                 if (IS_HT_RATE_SECTION(rs) && IS_VHT_RATE_SECTION(ref_rs))
1981                                                         ht_ref_vht_5g_20_40++;
1982                                                 else if (IS_VHT_RATE_SECTION(rs) && IS_HT_RATE_SECTION(ref_rs))
1983                                                         vht_ref_ht_5g_20_40++;
1984
1985                                                 if (0)
1986                                                         DBG_871X("reg:%u, bw:%u, ch:%u, %s ref %s\n"
1987                                                                 , regulation, bw, channel
1988                                                                 , rate_section_str(rs), rate_section_str(ref_rs));
1989
1990                                                 pHalData->TxPwrLimit_5G[regulation][bw][rs][channel][RF_PATH_A] =
1991                                                         pHalData->TxPwrLimit_5G[regulation][bw][ref_rs][channel][RF_PATH_A];
1992                                         }
1993
1994                                 }
1995                         }
1996                 }
1997         }
1998
1999         if (0) {
2000                 DBG_871X("ht_ref_vht_5g_20_40:%d, ht_has_ref_5g_20_40:%d\n", ht_ref_vht_5g_20_40, ht_has_ref_5g_20_40);
2001                 DBG_871X("vht_ref_hht_5g_20_40:%d, vht_has_ref_5g_20_40:%d\n", vht_ref_ht_5g_20_40, vht_has_ref_5g_20_40);
2002         }
2003
2004         /* 5G 20M&40M HT all come from VHT*/
2005         if (ht_ref_vht_5g_20_40 && ht_has_ref_5g_20_40 == ht_ref_vht_5g_20_40)
2006                 pHalData->tx_pwr_lmt_5g_20_40_ref |= TX_PWR_LMT_REF_HT_FROM_VHT;
2007
2008         /* 5G 20M&40M VHT all come from HT*/
2009         if (vht_ref_ht_5g_20_40 && vht_has_ref_5g_20_40 == vht_ref_ht_5g_20_40)
2010                 pHalData->tx_pwr_lmt_5g_20_40_ref |= TX_PWR_LMT_REF_VHT_FROM_HT;
2011 }
2012
2013 VOID 
2014 PHY_ConvertTxPowerLimitToPowerIndex(
2015         IN      PADAPTER                        Adapter
2016         )
2017 {
2018         HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
2019         u8 base;
2020         u8 regulation, bw, channel, rateSection;
2021         s8 tempValue = 0, tempPwrLmt = 0;
2022         u8 rfPath = 0;
2023
2024         if (pHalData->odmpriv.PhyRegPgValueType != PHY_REG_PG_EXACT_VALUE) {
2025                 rtw_warn_on(1);
2026                 return;
2027         }
2028
2029         phy_CrossReferenceHTAndVHTTxPowerLimit(Adapter);
2030
2031         for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
2032
2033                 for (bw = 0; bw < MAX_2_4G_BANDWIDTH_NUM; ++bw) {
2034
2035                         for (channel = 0; channel < CENTER_CH_2G_NUM; ++channel) {
2036
2037                                 for (rateSection = CCK; rateSection <= HT_4SS; ++rateSection) {
2038                                         tempPwrLmt = pHalData->TxPwrLimit_2_4G[regulation][bw][rateSection][channel][RF_PATH_A];
2039
2040                                         if (tempPwrLmt != MAX_POWER_INDEX) {
2041
2042                                                 for (rfPath = RF_PATH_A; rfPath < MAX_RF_PATH; ++rfPath) {
2043                                                         base = phy_get_target_tx_power(Adapter, BAND_ON_2_4G, rfPath, rateSection);
2044                                                         tempValue = tempPwrLmt - base;
2045                                                         pHalData->TxPwrLimit_2_4G[regulation][bw][rateSection][channel][rfPath] = tempValue;
2046                                                 }
2047                                         }
2048                                 }
2049                         }
2050                 }
2051         }
2052         
2053         if (IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(Adapter)) {
2054
2055                 for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
2056
2057                         for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; ++bw) {
2058
2059                                 for (channel = 0; channel < CENTER_CH_5G_ALL_NUM; ++channel) {
2060
2061                                         for (rateSection = OFDM; rateSection <= VHT_4SS; ++rateSection) {
2062                                                 tempPwrLmt = pHalData->TxPwrLimit_5G[regulation][bw][rateSection][channel][RF_PATH_A];
2063
2064                                                 if (tempPwrLmt != MAX_POWER_INDEX) {
2065
2066                                                         for (rfPath = RF_PATH_A; rfPath < MAX_RF_PATH; ++rfPath) {
2067                                                                 base = phy_get_target_tx_power(Adapter, BAND_ON_5G, rfPath, rateSection);
2068                                                                 tempValue = tempPwrLmt - base;
2069                                                                 pHalData->TxPwrLimit_5G[regulation][bw][rateSection][channel][rfPath] = tempValue;
2070                                                         }
2071                                                 }
2072                                         }
2073                                 }
2074                         }
2075                 }
2076         }
2077 }
2078
2079 /*
2080 * PHY_InitTxPowerLimit - Set all hal_data.TxPwrLimit_2_4G, TxPwrLimit_5G array to MAX_POWER_INDEX
2081 */
2082 VOID
2083 PHY_InitTxPowerLimit(
2084         IN      PADAPTER                Adapter
2085         )
2086 {
2087         HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
2088         u8 i, j, k, l, m;
2089
2090         for (i = 0; i < MAX_REGULATION_NUM; ++i)
2091                 for (j = 0; j < MAX_2_4G_BANDWIDTH_NUM; ++j)
2092                         for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
2093                                 for (m = 0; m < CENTER_CH_2G_NUM; ++m)
2094                                         for (l = 0; l < MAX_RF_PATH; ++l)
2095                                                 pHalData->TxPwrLimit_2_4G[i][j][k][m][l] = MAX_POWER_INDEX;
2096
2097         for (i = 0; i < MAX_REGULATION_NUM; ++i)
2098                 for (j = 0; j < MAX_5G_BANDWIDTH_NUM; ++j)
2099                         for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
2100                                 for (m = 0; m < CENTER_CH_5G_ALL_NUM; ++m)
2101                                         for (l = 0; l < MAX_RF_PATH; ++l)
2102                                                 pHalData->TxPwrLimit_5G[i][j][k][m][l] = MAX_POWER_INDEX;
2103 }
2104
2105 /*
2106 * PHY_SetTxPowerLimit - Parsing TX power limit from phydm array, called by odm_ConfigBB_TXPWR_LMT_XXX in phydm
2107 */
2108 VOID
2109 PHY_SetTxPowerLimit(
2110         IN      PDM_ODM_T               pDM_Odm,
2111         IN      u8                              *Regulation,
2112         IN      u8                              *Band,
2113         IN      u8                              *Bandwidth,
2114         IN      u8                              *RateSection,
2115         IN      u8                              *RfPath,
2116         IN      u8                              *Channel,
2117         IN      u8                              *PowerLimit
2118         )
2119 {
2120         PADAPTER Adapter = pDM_Odm->Adapter;
2121         HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
2122         u8 regulation = 0, bandwidth = 0, rateSection = 0, channel;
2123         s8 powerLimit = 0, prevPowerLimit, channelIndex;
2124
2125         if (0)
2126                 DBG_871X("Index of power limit table [band %s][regulation %s][bw %s][rate section %s][rf path %s][chnl %s][val %s]\n"
2127                         , Band, Regulation, Bandwidth, RateSection, RfPath, Channel, PowerLimit);
2128
2129         if (GetU1ByteIntegerFromStringInDecimal((s8 *)Channel, &channel) == _FALSE
2130                 || GetU1ByteIntegerFromStringInDecimal((s8 *)PowerLimit, &powerLimit) == _FALSE
2131         ){
2132                 DBG_871X_LEVEL(_drv_always_, "Illegal index of power limit table [ch %s][val %s]\n", Channel, PowerLimit);
2133                 return;
2134         }
2135
2136         powerLimit = powerLimit > MAX_POWER_INDEX ? MAX_POWER_INDEX : powerLimit;
2137
2138         if (eqNByte(Regulation, (u8 *)("FCC"), 3))
2139                 regulation = TXPWR_LMT_FCC;
2140         else if (eqNByte(Regulation, (u8 *)("MKK"), 3))
2141                 regulation = TXPWR_LMT_MKK;
2142         else if (eqNByte(Regulation, (u8 *)("ETSI"), 4))
2143                 regulation = TXPWR_LMT_ETSI;
2144         else if (eqNByte(Regulation, (u8 *)("WW13"), 4))
2145                 regulation = TXPWR_LMT_WW;
2146         else {
2147                 DBG_871X_LEVEL(_drv_always_, "unknown regulation:%s", Regulation);
2148                 return;
2149         }
2150
2151         if (eqNByte(RateSection, (u8 *)("CCK"), 3) && eqNByte(RfPath, (u8 *)("1T"), 2))
2152                 rateSection = CCK;
2153         else if (eqNByte(RateSection, (u8 *)("OFDM"), 4) && eqNByte(RfPath, (u8 *)("1T"), 2))
2154                 rateSection = OFDM;
2155         else if (eqNByte(RateSection, (u8 *)("HT"), 2) && eqNByte(RfPath, (u8 *)("1T"), 2))
2156                 rateSection = HT_1SS;
2157         else if (eqNByte(RateSection, (u8 *)("HT"), 2) && eqNByte(RfPath, (u8 *)("2T"), 2))
2158                 rateSection = HT_2SS;
2159         else if (eqNByte(RateSection, (u8 *)("HT"), 2) && eqNByte(RfPath, (u8 *)("3T"), 2))
2160                 rateSection = HT_3SS;
2161         else if (eqNByte(RateSection, (u8 *)("HT"), 2) && eqNByte(RfPath, (u8 *)("4T"), 2))
2162                 rateSection = HT_4SS;
2163         else if (eqNByte(RateSection, (u8 *)("VHT"), 3) && eqNByte(RfPath, (u8 *)("1T"), 2))
2164                 rateSection = VHT_1SS;
2165         else if (eqNByte(RateSection, (u8 *)("VHT"), 3) && eqNByte(RfPath, (u8 *)("2T"), 2))
2166                 rateSection = VHT_2SS;
2167         else if (eqNByte(RateSection, (u8 *)("VHT"), 3) && eqNByte(RfPath, (u8 *)("3T"), 2))
2168                 rateSection = VHT_3SS;
2169         else if (eqNByte(RateSection, (u8 *)("VHT"), 3) && eqNByte(RfPath, (u8 *)("4T"), 2))
2170                 rateSection = VHT_4SS;
2171         else {
2172                 DBG_871X_LEVEL(_drv_always_, "Wrong rate section: (%s,%s)\n", RateSection, RfPath);
2173                 return;
2174         }
2175
2176         if (eqNByte(Bandwidth, (u8 *)("20M"), 3))
2177                 bandwidth = CHANNEL_WIDTH_20;
2178         else if (eqNByte(Bandwidth, (u8 *)("40M"), 3))
2179                 bandwidth = CHANNEL_WIDTH_40;
2180         else if (eqNByte(Bandwidth, (u8 *)("80M"), 3))
2181                 bandwidth = CHANNEL_WIDTH_80;
2182         else {
2183                 DBG_871X_LEVEL(_drv_always_, "unknown bandwidth: %s\n", Bandwidth);
2184                 return;
2185         }
2186
2187         if (eqNByte(Band, (u8 *)("2.4G"), 4)) {
2188                 channelIndex = phy_GetChannelIndexOfTxPowerLimit(BAND_ON_2_4G, channel);
2189
2190                 if (channelIndex == -1) {
2191                         DBG_871X_LEVEL(_drv_always_, "unsupported channel: %d at 2.4G\n", channel);
2192                         return;
2193                 }
2194
2195                 if (bandwidth >= MAX_2_4G_BANDWIDTH_NUM) {
2196                         DBG_871X_LEVEL(_drv_always_, "unsupported bandwidth: %s at 2.4G\n", Bandwidth);
2197                         return;
2198                 }
2199
2200                 prevPowerLimit = pHalData->TxPwrLimit_2_4G[regulation][bandwidth][rateSection][channelIndex][RF_PATH_A];
2201
2202                 if (prevPowerLimit != MAX_POWER_INDEX)
2203                         DBG_871X_LEVEL(_drv_always_, "duplicate tx power limit combination [band %s][regulation %s][bw %s][rate section %s][rf path %s][chnl %s]\n"
2204                                 , Band, Regulation, Bandwidth, RateSection, RfPath, Channel);
2205
2206                 if (powerLimit < prevPowerLimit)
2207                         pHalData->TxPwrLimit_2_4G[regulation][bandwidth][rateSection][channelIndex][RF_PATH_A] = powerLimit;
2208
2209                 if (0)
2210                         DBG_871X("2.4G Band value : [regulation %d][bw %d][rate_section %d][chnl %d][val %d]\n"
2211                                 , regulation, bandwidth, rateSection, channelIndex, pHalData->TxPwrLimit_2_4G[regulation][bandwidth][rateSection][channelIndex][ODM_RF_PATH_A]);
2212         } else if (eqNByte(Band, (u8 *)("5G"), 2)) {
2213
2214                 channelIndex = phy_GetChannelIndexOfTxPowerLimit(BAND_ON_5G, channel);
2215
2216                 if (channelIndex == -1) {
2217                         DBG_871X_LEVEL(_drv_always_, "unsupported channel: %d at 5G\n", channel);
2218                         return;
2219                 }
2220
2221                 prevPowerLimit = pHalData->TxPwrLimit_5G[regulation][bandwidth][rateSection][channelIndex][RF_PATH_A];
2222
2223                 if (prevPowerLimit != MAX_POWER_INDEX)
2224                         DBG_871X_LEVEL(_drv_always_, "duplicate tx power limit combination [band %s][regulation %s][bw %s][rate section %s][rf path %s][chnl %s]\n"
2225                                 , Band, Regulation, Bandwidth, RateSection, RfPath, Channel);
2226
2227                 if (powerLimit < prevPowerLimit)
2228                         pHalData->TxPwrLimit_5G[regulation][bandwidth][rateSection][channelIndex][RF_PATH_A] = powerLimit;
2229
2230                 if (0)
2231                         DBG_871X("5G Band value : [regulation %d][bw %d][rate_section %d][chnl %d][val %d]\n"
2232                                 , regulation, bandwidth, rateSection, channel, pHalData->TxPwrLimit_5G[regulation][bandwidth][rateSection][channelIndex][RF_PATH_A]);
2233         } else {
2234                 DBG_871X_LEVEL(_drv_always_, "Cannot recognize the band info in %s\n", Band);
2235                 return;
2236         }
2237 }
2238
2239 u8
2240 PHY_GetTxPowerIndex(
2241         IN      PADAPTER                        pAdapter,
2242         IN      u8                                      RFPath,
2243         IN      u8                                      Rate,   
2244         IN      CHANNEL_WIDTH           BandWidth,      
2245         IN      u8                                      Channel
2246         )
2247 {
2248         u8      txPower = 0x3E;
2249
2250         if (IS_HARDWARE_TYPE_8814A(pAdapter)) {
2251 #if (RTL8814A_SUPPORT == 1)
2252                 txPower = PHY_GetTxPowerIndex_8814A(pAdapter, RFPath, Rate, BandWidth, Channel);
2253 #endif
2254         } else if (IS_HARDWARE_TYPE_JAGUAR(pAdapter)) {
2255 #if ((RTL8812A_SUPPORT == 1) || (RTL8821A_SUPPORT == 1))
2256                 txPower = PHY_GetTxPowerIndex_8812A(pAdapter, RFPath, Rate, BandWidth, Channel);
2257 #endif
2258         }
2259         else if (IS_HARDWARE_TYPE_8723B(pAdapter)) {
2260 #if (RTL8723B_SUPPORT == 1)
2261                 txPower = PHY_GetTxPowerIndex_8723B(pAdapter, RFPath, Rate, BandWidth, Channel);
2262 #endif
2263         }
2264         else if (IS_HARDWARE_TYPE_8703B(pAdapter)) {
2265 #if (RTL8703B_SUPPORT == 1)
2266                 txPower = PHY_GetTxPowerIndex_8703B(pAdapter, RFPath, Rate, BandWidth, Channel);
2267 #endif
2268         }
2269         else if (IS_HARDWARE_TYPE_8192E(pAdapter)) {
2270 #if (RTL8192E_SUPPORT==1)
2271                 txPower = PHY_GetTxPowerIndex_8192E(pAdapter, RFPath, Rate, BandWidth, Channel);
2272 #endif
2273         }
2274         else if (IS_HARDWARE_TYPE_8188E(pAdapter)) {
2275 #if (RTL8188E_SUPPORT==1)
2276                 txPower = PHY_GetTxPowerIndex_8188E(pAdapter, RFPath, Rate, BandWidth, Channel);
2277 #endif
2278         } else if (IS_HARDWARE_TYPE_8188F(pAdapter)) {
2279 #if (RTL8188F_SUPPORT == 1)
2280                 txPower = PHY_GetTxPowerIndex_8188F(pAdapter, RFPath, Rate, BandWidth, Channel);
2281 #endif
2282         }
2283
2284         return txPower;
2285 }
2286
2287 VOID
2288 PHY_SetTxPowerIndex(
2289         IN      PADAPTER                pAdapter,
2290         IN      u32                             PowerIndex,
2291         IN      u8                              RFPath, 
2292         IN      u8                              Rate
2293         )
2294 {
2295         if (IS_HARDWARE_TYPE_8814A(pAdapter)) {
2296 #if (RTL8814A_SUPPORT == 1)
2297                 PHY_SetTxPowerIndex_8814A(pAdapter, PowerIndex, RFPath, Rate);
2298 #endif
2299         }
2300         else if (IS_HARDWARE_TYPE_JAGUAR(pAdapter)) {
2301 #if ((RTL8812A_SUPPORT==1) || (RTL8821A_SUPPORT == 1))
2302                 PHY_SetTxPowerIndex_8812A( pAdapter, PowerIndex, RFPath, Rate );
2303 #endif
2304         }
2305         else if (IS_HARDWARE_TYPE_8723B(pAdapter)) {
2306 #if (RTL8723B_SUPPORT==1)
2307                 PHY_SetTxPowerIndex_8723B( pAdapter, PowerIndex, RFPath, Rate );
2308 #endif
2309         }
2310         else if (IS_HARDWARE_TYPE_8703B(pAdapter)) {
2311 #if (RTL8703B_SUPPORT==1)
2312                 PHY_SetTxPowerIndex_8703B( pAdapter, PowerIndex, RFPath, Rate );
2313 #endif
2314         }
2315         else if (IS_HARDWARE_TYPE_8192E(pAdapter)) {
2316 #if (RTL8192E_SUPPORT==1)
2317                 PHY_SetTxPowerIndex_8192E( pAdapter, PowerIndex, RFPath, Rate );
2318 #endif
2319         }
2320         else if (IS_HARDWARE_TYPE_8188E(pAdapter)) {
2321 #if (RTL8188E_SUPPORT==1)
2322                 PHY_SetTxPowerIndex_8188E( pAdapter, PowerIndex, RFPath, Rate );
2323 #endif
2324         } else if (IS_HARDWARE_TYPE_8188F(pAdapter)) {
2325 #if (RTL8188F_SUPPORT == 1)
2326                 PHY_SetTxPowerIndex_8188F(pAdapter, PowerIndex, RFPath, Rate);
2327 #endif
2328         }
2329 }
2330
2331 bool phy_is_tx_power_limit_needed(_adapter *adapter)
2332 {
2333         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
2334         struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
2335
2336         if (regsty->RegEnableTxPowerLimit == 1
2337                 || (regsty->RegEnableTxPowerLimit == 2 && hal_data->EEPROMRegulatory == 1))
2338                 return _TRUE;
2339         return _FALSE;
2340 }
2341
2342 bool phy_is_tx_power_by_rate_needed(_adapter *adapter)
2343 {
2344         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
2345         struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
2346
2347         if (regsty->RegEnableTxPowerByRate == 1
2348                 || (regsty->RegEnableTxPowerByRate == 2 && hal_data->EEPROMRegulatory != 2))
2349                 return _TRUE;
2350         return _FALSE;
2351 }
2352
2353 int phy_load_tx_power_by_rate(_adapter *adapter, const char *hal_file_name, u8 force)
2354 {
2355         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
2356         struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
2357         int ret = _FAIL;
2358
2359         if (!force
2360                 && !rtw_is_phy_file_readable(hal_file_name)
2361                 && hal_data->txpwr_by_rate_loaded == 1
2362                 && hal_data->txpwr_by_rate_from_file == 0
2363         ) {
2364                 /* No file and already load default(compile-time) table */
2365                 ret = _SUCCESS;
2366                 goto exit;
2367         }
2368
2369         hal_data->txpwr_by_rate_loaded = 0;
2370         PHY_InitTxPowerByRate(adapter);
2371
2372         /* tx power limit is based on tx power by rate */
2373         hal_data->txpwr_limit_loaded = 0;
2374
2375 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
2376         if (rtw_is_phy_file_readable(hal_file_name)
2377                 && phy_ConfigBBWithPgParaFile(adapter, hal_file_name) == _SUCCESS
2378         ) {
2379                 hal_data->txpwr_by_rate_from_file = 1;
2380                 goto post_hdl;
2381         }
2382 #endif
2383
2384 #ifdef CONFIG_EMBEDDED_FWIMG
2385         if (HAL_STATUS_SUCCESS == ODM_ConfigBBWithHeaderFile(&hal_data->odmpriv, CONFIG_BB_PHY_REG_PG)) {
2386                 DBG_871X("default power by rate loaded\n");
2387                 hal_data->txpwr_by_rate_from_file = 0;
2388                 goto post_hdl;
2389         }
2390 #endif
2391
2392         DBG_871X_LEVEL(_drv_err_, "%s():Read Tx power by rate fail\n", __func__);
2393         goto exit;
2394
2395 post_hdl:
2396         if (hal_data->odmpriv.PhyRegPgValueType != PHY_REG_PG_EXACT_VALUE) {
2397                 rtw_warn_on(1);
2398                 goto exit;
2399         }
2400
2401         PHY_TxPowerByRateConfiguration(adapter);
2402         hal_data->txpwr_by_rate_loaded = 1;
2403
2404         ret = _SUCCESS;
2405
2406 exit:
2407         return ret;
2408 }
2409
2410 int phy_load_tx_power_limit(_adapter *adapter, const char *hal_file_name, u8 force)
2411 {
2412         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
2413         struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
2414         int ret = _FAIL;
2415
2416         if (!force
2417                 && !rtw_is_phy_file_readable(hal_file_name)
2418                 && hal_data->txpwr_by_rate_loaded == 1
2419                 && hal_data->txpwr_by_rate_from_file == 0
2420         ) {
2421                 /* No file and already load default(compile-time) table */
2422                 ret = _SUCCESS;
2423                 goto exit;
2424         }
2425
2426         hal_data->txpwr_limit_loaded = 0;
2427         PHY_InitTxPowerLimit(adapter);
2428
2429         if (!hal_data->txpwr_by_rate_loaded && regsty->target_tx_pwr_valid != _TRUE) {
2430                 DBG_871X_LEVEL(_drv_err_, "%s():Read Tx power limit before target tx power is specify\n", __func__);
2431                 goto exit;
2432         }
2433
2434 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
2435         if (rtw_is_phy_file_readable(hal_file_name)
2436                 && PHY_ConfigRFWithPowerLimitTableParaFile(adapter, hal_file_name) == _SUCCESS
2437         ) {
2438                 hal_data->txpwr_limit_from_file = 1;
2439                 goto post_hdl;
2440         }
2441 #endif
2442
2443 #ifdef CONFIG_EMBEDDED_FWIMG
2444         if (HAL_STATUS_SUCCESS == ODM_ConfigRFWithHeaderFile(&hal_data->odmpriv, CONFIG_RF_TXPWR_LMT, (ODM_RF_RADIO_PATH_E)0)) {
2445                 DBG_871X("default power limit loaded\n");
2446                 hal_data->txpwr_limit_from_file = 0;
2447                 goto post_hdl;
2448         }
2449 #endif
2450
2451         DBG_871X_LEVEL(_drv_err_, "%s():Read Tx power limit fail\n", __func__);
2452         goto exit;
2453
2454 post_hdl:
2455         PHY_ConvertTxPowerLimitToPowerIndex(adapter);
2456         hal_data->txpwr_limit_loaded = 1;
2457         ret = _SUCCESS;
2458
2459 exit:
2460         return ret;
2461 }
2462
2463 const char *hal_phy_reg_pg_str(_adapter *adapter)
2464 {
2465         u8 interface_type = 0;
2466         const char *str = NULL;
2467
2468         interface_type = rtw_get_intf_type(adapter);
2469
2470         switch (rtw_get_chip_type(adapter)) {
2471 #ifdef CONFIG_RTL8723B
2472         case RTL8723B:
2473                 str = RTL8723B_PHY_REG_PG;
2474                 break;
2475 #endif
2476 #ifdef CONFIG_RTL8703B
2477         case RTL8703B:
2478                 str = RTL8703B_PHY_REG_PG;
2479                 break;
2480 #endif
2481 #ifdef CONFIG_RTL8188E
2482         case RTL8188E:
2483                 str = RTL8188E_PHY_REG_PG;
2484                 break;
2485 #endif
2486 #ifdef CONFIG_RTL8188F
2487         case RTL8188F:
2488                 str = RTL8188F_PHY_REG_PG;
2489                 break;
2490 #endif
2491 #ifdef CONFIG_RTL8812A
2492         case RTL8812:
2493                 str = RTL8812_PHY_REG_PG;
2494                 break;
2495 #endif
2496 #ifdef CONFIG_RTL8821A
2497         case RTL8821:
2498                 str = RTL8821_PHY_REG_PG;
2499                 break;
2500 #endif
2501 #ifdef CONFIG_RTL8192E
2502         case RTL8192E:
2503                 str = RTL8192E_PHY_REG_PG;
2504                 break;
2505 #endif
2506 #ifdef CONFIG_RTL8814A
2507         case RTL8814A:
2508                 str = RTL8814A_PHY_REG_PG;
2509                 break;
2510 #endif
2511         }
2512
2513         if (str == NULL) {
2514                 DBG_871X_LEVEL(_drv_err_, "%s: unknown chip_type:%u\n"
2515                         , __func__, rtw_get_chip_type(adapter));
2516         }
2517
2518         return str;
2519 }
2520
2521 const char *hal_txpwr_lmt_str(_adapter *adapter)
2522 {
2523         u8 interface_type = 0;
2524         const char *str = NULL;
2525
2526         interface_type = rtw_get_intf_type(adapter);
2527
2528         switch (rtw_get_chip_type(adapter)) {
2529 #ifdef CONFIG_RTL8723B
2530         case RTL8723B:
2531                 str = RTL8723B_TXPWR_LMT;
2532                 break;
2533 #endif
2534 #ifdef CONFIG_RTL8703B
2535         case RTL8703B:
2536                 str = RTL8703B_TXPWR_LMT;
2537                 break;
2538 #endif
2539 #ifdef CONFIG_RTL8188E
2540         case RTL8188E:
2541                 str = RTL8188E_TXPWR_LMT;
2542                 break;
2543 #endif
2544 #ifdef CONFIG_RTL8188F
2545         case RTL8188F:
2546                 str = RTL8188F_TXPWR_LMT;
2547                 break;
2548 #endif
2549 #ifdef CONFIG_RTL8812A
2550         case RTL8812:
2551                 str = RTL8812_TXPWR_LMT;
2552                 break;
2553 #endif
2554 #ifdef CONFIG_RTL8821A
2555         case RTL8821:
2556                 str = RTL8821_TXPWR_LMT;
2557                 break;
2558 #endif
2559 #ifdef CONFIG_RTL8192E
2560         case RTL8192E:
2561                 str = RTL8192E_TXPWR_LMT;
2562                 break;
2563 #endif
2564 #ifdef CONFIG_RTL8814A
2565         case RTL8814A:
2566                 str = RTL8814A_TXPWR_LMT;
2567                 break;
2568 #endif
2569         }
2570
2571         if (str == NULL) {
2572                 DBG_871X_LEVEL(_drv_err_, "%s: unknown chip_type:%u\n"
2573                         , __func__, rtw_get_chip_type(adapter));
2574         }
2575
2576         return str;
2577 }
2578
2579 void phy_load_tx_power_ext_info(_adapter *adapter, u8 chk_file, u8 force)
2580 {
2581         struct registry_priv *regsty = adapter_to_regsty(adapter);
2582         const char *str = NULL;
2583
2584         /* check registy target tx power */
2585         regsty->target_tx_pwr_valid = rtw_regsty_chk_target_tx_power_valid(adapter);
2586
2587         /* power by rate and limit */
2588         if (phy_is_tx_power_by_rate_needed(adapter)
2589                 || (phy_is_tx_power_limit_needed(adapter) && regsty->target_tx_pwr_valid != _TRUE)
2590         ) {
2591                 str = chk_file ? hal_phy_reg_pg_str(adapter) : NULL;
2592                 phy_load_tx_power_by_rate(adapter, str, force);
2593         }
2594
2595         if (phy_is_tx_power_limit_needed(adapter)) {
2596                 str = chk_file ? hal_txpwr_lmt_str(adapter) : NULL;
2597                 phy_load_tx_power_limit(adapter, str, force);
2598         }
2599 }
2600
2601 inline void phy_reload_tx_power_ext_info(_adapter *adapter)
2602 {
2603         phy_load_tx_power_ext_info(adapter, 1, 1);
2604 }
2605
2606 inline void phy_reload_default_tx_power_ext_info(_adapter *adapter)
2607 {
2608         phy_load_tx_power_ext_info(adapter, 0, 1);
2609 }
2610
2611 void dump_tx_power_ext_info(void *sel, _adapter *adapter)
2612 {
2613         struct registry_priv *regsty = adapter_to_regsty(adapter);
2614         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
2615
2616         if (phy_is_tx_power_by_rate_needed(adapter)
2617                 || (phy_is_tx_power_limit_needed(adapter) && regsty->target_tx_pwr_valid != _TRUE))
2618                 DBG_871X_SEL_NL(sel, "target_tx_power: from powr by rate\n");
2619         else if (regsty->target_tx_pwr_valid == _TRUE)
2620                 DBG_871X_SEL_NL(sel, "target_tx_power: from registry\n");
2621         else
2622                 DBG_871X_SEL_NL(sel, "target_tx_power: unavailable\n");
2623
2624
2625         DBG_871X_SEL_NL(sel, "tx_power_by_rate: %s, %s, %s\n"
2626                 , phy_is_tx_power_by_rate_needed(adapter) ? "enabled" : "disabled"
2627                 , hal_data->txpwr_by_rate_loaded ? "loaded" : "unloaded"
2628                 , hal_data->txpwr_by_rate_from_file ? "file" : "default"
2629         );
2630
2631         DBG_871X_SEL_NL(sel, "tx_power_limit: %s, %s, %s\n"
2632                 , phy_is_tx_power_limit_needed(adapter) ? "enabled" : "disabled"
2633                 , hal_data->txpwr_limit_loaded ? "loaded" : "unloaded"
2634                 , hal_data->txpwr_limit_from_file ? "file" : "default"
2635         );
2636 }
2637
2638 void dump_target_tx_power(void *sel, _adapter *adapter)
2639 {
2640         struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
2641         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
2642         struct registry_priv *regsty = adapter_to_regsty(adapter);
2643         int path, tx_num, band, rs;
2644         u8 target;
2645
2646         for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
2647                 if (!hal_is_band_support(adapter, band))
2648                         continue;
2649
2650                 for (path = 0; path < RF_PATH_MAX; path++) {
2651                         if (path >= hal_data->NumTotalRFPath)
2652                                 break;
2653
2654                         DBG_871X_SEL_NL(sel, "[%s][%c]\n", band_str(band), rf_path_char(path));
2655
2656                         for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
2657                                 tx_num = rate_section_to_tx_num(rs);
2658                                 if (tx_num >= hal_spec->nss_num)
2659                                         continue;
2660
2661                                 if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
2662                                         continue;
2663
2664                                 if (IS_VHT_RATE_SECTION(rs) && !IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(adapter))
2665                                         continue;
2666
2667                                 target = phy_get_target_tx_power(adapter, band, path, rs);
2668
2669                                 if (target % 2)
2670                                         DBG_871X_SEL(sel, "%7s: %2d.5\n", rate_section_str(rs), target / 2);
2671                                 else
2672                                         DBG_871X_SEL(sel, "%7s: %4d\n", rate_section_str(rs), target / 2);
2673                         }
2674                 }
2675         }
2676
2677 exit:
2678         return;
2679 }
2680
2681 void dump_tx_power_by_rate(void *sel, _adapter *adapter)
2682 {
2683         struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
2684         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
2685         int path, tx_num, band, n, rs;
2686         u8 rate_num, max_rate_num, base;
2687         s8 by_rate_offset;
2688
2689         for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
2690                 if (!hal_is_band_support(adapter, band))
2691                         continue;
2692
2693                 for (path = 0; path < RF_PATH_MAX; path++) {
2694                         if (path >= hal_data->NumTotalRFPath)
2695                                 break;
2696
2697                         DBG_871X_SEL_NL(sel, "[%s][%c]\n", band_str(band), rf_path_char(path));
2698
2699                         for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
2700                                 tx_num = rate_section_to_tx_num(rs);
2701                                 if (tx_num >= hal_spec->nss_num)
2702                                         continue;
2703
2704                                 if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
2705                                         continue;
2706
2707                                 if (IS_VHT_RATE_SECTION(rs) && !IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(adapter))
2708                                         continue;
2709
2710                                 if (IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(adapter))
2711                                         max_rate_num = 10;
2712                                 else
2713                                         max_rate_num = 8;
2714                                 rate_num = rate_section_rate_num(rs);
2715                                 base = PHY_GetTxPowerByRateBase(adapter, band, path, tx_num, rs);
2716
2717                                 DBG_871X_SEL_NL(sel, "%7s: ", rate_section_str(rs));
2718
2719                                 /* dump power by rate in db */
2720                                 for (n = rate_num - 1; n >= 0; n--) {
2721                                         by_rate_offset = PHY_GetTxPowerByRate(adapter, band, path, tx_num, rates_by_sections[rs].rates[n]);
2722
2723                                         if ((base + by_rate_offset) % 2)
2724                                                 DBG_871X_SEL(sel, "%2d.5 ", (base + by_rate_offset) / 2);
2725                                         else
2726                                                 DBG_871X_SEL(sel, "%4d ", (base + by_rate_offset) / 2);
2727                                 }
2728                                 for (n = 0; n < max_rate_num - rate_num; n++)
2729                                         DBG_871X_SEL(sel, "%4s ", "");
2730
2731                                 DBG_871X_SEL(sel, "|");
2732
2733                                 /* dump power by rate in offset */
2734                                 for (n = rate_num - 1; n >= 0; n--) {
2735                                         by_rate_offset = PHY_GetTxPowerByRate(adapter, band, path, tx_num, rates_by_sections[rs].rates[n]);
2736                                         DBG_871X_SEL(sel, "%3d ", by_rate_offset);
2737                                 }
2738                                 DBG_871X_SEL_NL(sel, "\n");
2739
2740                         }
2741                 }
2742         }
2743 }
2744
2745 void dump_tx_power_limit(void *sel, _adapter *adapter)
2746 {
2747         struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
2748         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
2749         struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
2750
2751         int bw, band, ch_num, rs, i, path;
2752         u8 ch, n, rd;
2753
2754         if (IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(adapter))
2755                 DBG_871X_SEL_NL(sel, "tx_pwr_lmt_5g_20_40_ref:0x%02x\n", hal_data->tx_pwr_lmt_5g_20_40_ref);
2756
2757         for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
2758                 if (!hal_is_band_support(adapter, band))
2759                         continue;
2760
2761                 rd = (band == BAND_ON_2_4G ? hal_data->Regulation2_4G : hal_data->Regulation5G);
2762
2763                 for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; bw++) {
2764
2765                         if (bw >= CHANNEL_WIDTH_160)
2766                                 break;
2767                         if (band == BAND_ON_2_4G && bw >= CHANNEL_WIDTH_80)
2768                                 break;
2769
2770                         if (band == BAND_ON_2_4G)
2771                                 ch_num = CENTER_CH_2G_NUM;
2772                         else
2773                                 ch_num = center_chs_5g_num(bw);
2774
2775                         if (ch_num == 0) {
2776                                 rtw_warn_on(1);
2777                                 break;
2778                         }
2779
2780                         for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
2781                                 if (band == BAND_ON_2_4G && IS_VHT_RATE_SECTION(rs))
2782                                         continue;
2783                                 if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
2784                                         continue;
2785                                 if (bw > CHANNEL_WIDTH_20 && (IS_CCK_RATE_SECTION(rs) || IS_OFDM_RATE_SECTION(rs)))
2786                                         continue;
2787                                 if (bw > CHANNEL_WIDTH_40 && IS_HT_RATE_SECTION(rs))
2788                                         continue;
2789
2790                                 if (rate_section_to_tx_num(rs) >= hal_spec->nss_num)
2791                                         continue;
2792
2793                                 if (IS_VHT_RATE_SECTION(rs) && !IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(adapter))
2794                                         continue;
2795
2796                                 /* by pass 5G 20M, 40M pure reference */
2797                                 if (band == BAND_ON_5G && (bw == CHANNEL_WIDTH_20 || bw == CHANNEL_WIDTH_40)) {
2798                                         if (hal_data->tx_pwr_lmt_5g_20_40_ref == TX_PWR_LMT_REF_HT_FROM_VHT) {
2799                                                 if (IS_HT_RATE_SECTION(rs))
2800                                                         continue;
2801                                         } else if (hal_data->tx_pwr_lmt_5g_20_40_ref == TX_PWR_LMT_REF_VHT_FROM_HT) {
2802                                                 if (IS_VHT_RATE_SECTION(rs) && bw <= CHANNEL_WIDTH_40)
2803                                                         continue;
2804                                         }
2805                                 }
2806
2807                                 DBG_871X_SEL_NL(sel, "[%s][%s][%s]\n"
2808                                         , band_str(band)
2809                                         , ch_width_str(bw)
2810                                         , rate_section_str(rs)
2811                                 );
2812
2813                                 /* header for limit in db */
2814                                 DBG_871X_SEL_NL(sel, "%3s %5s %5s %5s %5s "
2815                                         , "ch"
2816                                         , (rd == TXPWR_LMT_FCC ? "*FCC" : "FCC")
2817                                         , (rd == TXPWR_LMT_ETSI ? "*ETSI" : "ETSI")
2818                                         , (rd == TXPWR_LMT_MKK ? "*MKK" : "MKK")
2819                                         , (rd == TXPWR_LMT_WW ? "*WW" : "WW")
2820                                 );
2821
2822                                 /* header for limit offset */
2823                                 for (path = 0; path < RF_PATH_MAX; path++) {
2824                                         if (path >= hal_data->NumTotalRFPath)
2825                                                 break;
2826                                         DBG_871X_SEL(sel, "|%3c %3c %3c %3c "
2827                                                 , (rd == TXPWR_LMT_FCC ? rf_path_char(path) : ' ')
2828                                                 , (rd == TXPWR_LMT_ETSI ? rf_path_char(path) : ' ')
2829                                                 , (rd == TXPWR_LMT_MKK ? rf_path_char(path) : ' ')
2830                                                 , (rd == TXPWR_LMT_WW ? rf_path_char(path) : ' ')
2831                                         );
2832                                 }
2833                                 DBG_871X_SEL(sel, "\n");
2834
2835                                 for (n = 0; n < ch_num; n++) {
2836                                         s8 limit_idx[RF_PATH_MAX][MAX_REGULATION_NUM];
2837                                         s8 limit_offset[MAX_REGULATION_NUM];
2838                                         u8 base;
2839
2840                                         if (band == BAND_ON_2_4G)
2841                                                 ch = n + 1;
2842                                         else
2843                                                 ch = center_chs_5g(bw, n);
2844
2845                                         if (ch == 0) {
2846                                                 rtw_warn_on(1);
2847                                                 break;
2848                                         }
2849
2850                                         /* dump limit in db (calculate from path A) */
2851                                         limit_offset[0] = PHY_GetTxPowerLimit(adapter, 3, band, bw, RF_PATH_A, rates_by_sections[rs].rates[0], ch); /* FCC */
2852                                         limit_offset[1] = PHY_GetTxPowerLimit(adapter, 1, band, bw, RF_PATH_A, rates_by_sections[rs].rates[0], ch); /* ETSI */
2853                                         limit_offset[2] = PHY_GetTxPowerLimit(adapter, 2, band, bw, RF_PATH_A, rates_by_sections[rs].rates[0], ch); /* MKK */
2854                                         limit_offset[3] = PHY_GetTxPowerLimit(adapter, 4, band, bw, RF_PATH_A, rates_by_sections[rs].rates[0], ch); /* WW */
2855
2856                                         base = phy_get_target_tx_power(adapter, band, RF_PATH_A, rs);
2857
2858                                         DBG_871X_SEL_NL(sel, "%3u ", ch);
2859                                         for (i = 0; i < MAX_REGULATION_NUM; i++) {
2860                                                 if (limit_offset[i] == MAX_POWER_INDEX) {
2861                                                         limit_idx[0][i] = MAX_POWER_INDEX;
2862                                                         DBG_871X_SEL(sel, "%5s ", "NA");
2863                                                 } else {
2864                                                         limit_idx[0][i] = limit_offset[i] + base;
2865                                                         if ((limit_offset[i] + base) % 2)
2866                                                                 DBG_871X_SEL(sel, "%3d.5 ", (limit_offset[i] + base) / 2);
2867                                                         else
2868                                                                 DBG_871X_SEL(sel, "%5d ", (limit_offset[i] + base) / 2);
2869                                                 }
2870                                         }
2871
2872                                         /* dump limit offset of each path */
2873                                         for (path = 0; path < RF_PATH_MAX; path++) {
2874                                                 if (path >= hal_data->NumTotalRFPath)
2875                                                         break;
2876                                                 limit_offset[0] = PHY_GetTxPowerLimit(adapter, 3, band, bw, path, rates_by_sections[rs].rates[0], ch); /* FCC */
2877                                                 limit_offset[1] = PHY_GetTxPowerLimit(adapter, 1, band, bw, path, rates_by_sections[rs].rates[0], ch); /* ETSI */
2878                                                 limit_offset[2] = PHY_GetTxPowerLimit(adapter, 2, band, bw, path, rates_by_sections[rs].rates[0], ch); /* MKK */
2879                                                 limit_offset[3] = PHY_GetTxPowerLimit(adapter, 4, band, bw, path, rates_by_sections[rs].rates[0], ch); /* WW */
2880
2881                                                 base = phy_get_target_tx_power(adapter, band, path, rs);
2882
2883                                                 DBG_871X_SEL(sel, "|");
2884                                                 for (i = 0; i < MAX_REGULATION_NUM; i++) {
2885                                                         if (limit_offset[i] == MAX_POWER_INDEX) {
2886                                                                 limit_idx[path][i] = MAX_POWER_INDEX;
2887                                                                 DBG_871X_SEL(sel, "%3s ", "NA");
2888                                                         } else {
2889                                                                 limit_idx[path][i] = limit_offset[i] + base;
2890                                                                 DBG_871X_SEL(sel, "%3d ", limit_offset[i]);
2891                                                         }
2892                                                 }
2893                                         }
2894
2895                                         /* compare limit_idx of each path, print 'x' when mismatch */
2896                                         if (hal_data->NumTotalRFPath > 1) {
2897                                                 for (i = 0; i < MAX_REGULATION_NUM; i++) {
2898                                                         for (path = 0; path < RF_PATH_MAX; path++) {
2899                                                                 if (path >= hal_data->NumTotalRFPath)
2900                                                                         break;
2901                                                                 if (limit_idx[path][i] != limit_idx[(path + 1) % hal_data->NumTotalRFPath][i])
2902                                                                         break;
2903                                                         }
2904                                                         if (path >= hal_data->NumTotalRFPath)
2905                                                                 DBG_871X_SEL(sel, " ");
2906                                                         else
2907                                                                 DBG_871X_SEL(sel, "x");
2908                                                 }
2909                                         }
2910                                         DBG_871X_SEL(sel, "\n");
2911
2912                                 }
2913                                 DBG_871X_SEL_NL(sel, "\n");
2914                         }
2915                 }
2916         }
2917 }
2918
2919 int rtw_is_phy_file_readable(const char *hal_file_name)
2920 {
2921 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
2922         if (hal_file_name) {
2923                 rtw_merge_string(rtw_phy_para_file_path, PATH_LENGTH_MAX, rtw_phy_file_path, hal_file_name);
2924                 return rtw_is_file_readable(rtw_phy_para_file_path);
2925         }
2926 #endif
2927         return _FALSE;
2928 }
2929
2930 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
2931 int
2932 phy_ConfigMACWithParaFile(
2933         IN      PADAPTER        Adapter,
2934         IN      char*           pFileName
2935 )
2936 {
2937         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(Adapter);
2938         int     rlen = 0, rtStatus = _FAIL;
2939         char    *szLine, *ptmp;
2940         u32     u4bRegOffset, u4bRegValue, u4bMove;
2941
2942         if(!(Adapter->registrypriv.load_phy_file & LOAD_MAC_PARA_FILE))
2943                 return rtStatus;
2944
2945         _rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
2946
2947         if ((pHalData->mac_reg_len == 0) && (pHalData->mac_reg == NULL))
2948         {
2949                 rtw_merge_string(rtw_phy_para_file_path, PATH_LENGTH_MAX, rtw_phy_file_path, pFileName);
2950         
2951                 if (rtw_is_file_readable(rtw_phy_para_file_path) == _TRUE)
2952                 {
2953                         rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
2954                         if (rlen > 0)
2955                         {
2956                                 rtStatus = _SUCCESS;
2957                                 pHalData->mac_reg = rtw_zvmalloc(rlen);
2958                                 if(pHalData->mac_reg) {
2959                                         _rtw_memcpy(pHalData->mac_reg, pHalData->para_file_buf, rlen);
2960                                         pHalData->mac_reg_len = rlen;
2961                                 }
2962                                 else {
2963                                         DBG_871X("%s mac_reg alloc fail !\n",__FUNCTION__);
2964                                 }
2965                         }
2966                 }
2967         }
2968         else
2969         {
2970                 if ((pHalData->mac_reg_len != 0) && (pHalData->mac_reg != NULL)) {
2971                         _rtw_memcpy(pHalData->para_file_buf, pHalData->mac_reg, pHalData->mac_reg_len);
2972                         rtStatus = _SUCCESS;
2973                 }
2974                 else {
2975                         DBG_871X("%s(): Critical Error !!!\n",__FUNCTION__);
2976                 }
2977         }
2978
2979         if (rtStatus == _SUCCESS)
2980         {
2981                 ptmp = pHalData->para_file_buf;
2982                 for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp))
2983                 {
2984                         if(!IsCommentString(szLine))
2985                         {
2986                                 // Get 1st hex value as register offset
2987                                 if(GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove))
2988                                 {
2989                                         if(u4bRegOffset == 0xffff)
2990                                         { // Ending.
2991                                                 break;
2992                                         }
2993
2994                                         // Get 2nd hex value as register value.
2995                                         szLine += u4bMove;
2996                                         if(GetHexValueFromString(szLine, &u4bRegValue, &u4bMove))
2997                                         {
2998                                                 rtw_write8(Adapter, u4bRegOffset, (u8)u4bRegValue);
2999                                         }
3000                                 }
3001                         }
3002                 }
3003         }
3004         else
3005         {
3006                 DBG_871X("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
3007         }
3008
3009         return rtStatus;
3010 }
3011
3012 int
3013 phy_ConfigBBWithParaFile(
3014         IN      PADAPTER        Adapter,
3015         IN      char*           pFileName,
3016         IN      u32                     ConfigType
3017 )
3018 {
3019         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(Adapter);
3020         int     rlen = 0, rtStatus = _FAIL;
3021         char    *szLine, *ptmp;
3022         u32     u4bRegOffset, u4bRegValue, u4bMove;
3023         char    *pBuf = NULL;
3024         u32     *pBufLen = NULL;
3025
3026         if(!(Adapter->registrypriv.load_phy_file & LOAD_BB_PARA_FILE))
3027                 return rtStatus;
3028
3029         switch(ConfigType)
3030         {
3031                 case CONFIG_BB_PHY_REG:
3032                         pBuf = pHalData->bb_phy_reg;
3033                         pBufLen = &pHalData->bb_phy_reg_len;
3034                         break;
3035                 case CONFIG_BB_AGC_TAB:
3036                         pBuf = pHalData->bb_agc_tab;
3037                         pBufLen = &pHalData->bb_agc_tab_len;
3038                         break;
3039                 default:
3040                         DBG_871X("Unknown ConfigType!! %d\r\n", ConfigType);
3041                         break;
3042         }
3043
3044         _rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
3045
3046         if ((pBufLen != NULL) && (*pBufLen == 0) && (pBuf == NULL))
3047         {
3048                 rtw_merge_string(rtw_phy_para_file_path, PATH_LENGTH_MAX, rtw_phy_file_path, pFileName);
3049         
3050                 if (rtw_is_file_readable(rtw_phy_para_file_path) == _TRUE)
3051                 {
3052                         rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
3053                         if (rlen > 0)
3054                         {
3055                                 rtStatus = _SUCCESS;
3056                                 pBuf = rtw_zvmalloc(rlen);
3057                                 if(pBuf) {
3058                                         _rtw_memcpy(pBuf, pHalData->para_file_buf, rlen);
3059                                         *pBufLen = rlen;
3060
3061                                         switch(ConfigType)
3062                                         {
3063                                                 case CONFIG_BB_PHY_REG:
3064                                                         pHalData->bb_phy_reg = pBuf;
3065                                                         break;
3066                                                 case CONFIG_BB_AGC_TAB:
3067                                                         pHalData->bb_agc_tab = pBuf;
3068                                                         break;
3069                                         }
3070                                 }
3071                                 else {
3072                                         DBG_871X("%s(): ConfigType %d  alloc fail !\n",__FUNCTION__,ConfigType);
3073                                 }
3074                         }
3075                 }
3076         }
3077         else
3078         {
3079                 if ((pBufLen != NULL) && (*pBufLen != 0) && (pBuf != NULL)) {
3080                         _rtw_memcpy(pHalData->para_file_buf, pBuf, *pBufLen);
3081                         rtStatus = _SUCCESS;
3082                 }
3083                 else {
3084                         DBG_871X("%s(): Critical Error !!!\n",__FUNCTION__);
3085                 }
3086         }
3087
3088         if (rtStatus == _SUCCESS)
3089         {
3090                 ptmp = pHalData->para_file_buf;
3091                 for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp))
3092                 {
3093                         if(!IsCommentString(szLine))
3094                         {
3095                                 // Get 1st hex value as register offset.
3096                                 if(GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove))
3097                                 {
3098                                         if(u4bRegOffset == 0xffff)
3099                                         { // Ending.
3100                                                 break;
3101                                         }
3102                                         else if (u4bRegOffset == 0xfe || u4bRegOffset == 0xffe)
3103                                         {
3104                                                 #ifdef CONFIG_LONG_DELAY_ISSUE
3105                                                 rtw_msleep_os(50);
3106                                                 #else
3107                                                 rtw_mdelay_os(50);
3108                                                 #endif
3109                                         }
3110                                         else if (u4bRegOffset == 0xfd)
3111                                         {
3112                                                 rtw_mdelay_os(5);
3113                                         }
3114                                         else if (u4bRegOffset == 0xfc)
3115                                         {
3116                                                 rtw_mdelay_os(1);
3117                                         }
3118                                         else if (u4bRegOffset == 0xfb)
3119                                         {
3120                                                 rtw_udelay_os(50);
3121                                         }
3122                                         else if (u4bRegOffset == 0xfa)
3123                                         {
3124                                                 rtw_udelay_os(5);
3125                                         }
3126                                         else if (u4bRegOffset == 0xf9)
3127                                         {
3128                                                 rtw_udelay_os(1);
3129                                         }
3130                                         
3131                                         // Get 2nd hex value as register value.
3132                                         szLine += u4bMove;
3133                                         if(GetHexValueFromString(szLine, &u4bRegValue, &u4bMove))
3134                                         {
3135                                                 //DBG_871X("[BB-ADDR]%03lX=%08lX\n", u4bRegOffset, u4bRegValue);
3136                                                 PHY_SetBBReg(Adapter, u4bRegOffset, bMaskDWord, u4bRegValue);
3137
3138                                                 if (u4bRegOffset == 0xa24)
3139                                                         pHalData->odmpriv.RFCalibrateInfo.RegA24 = u4bRegValue;
3140
3141                                                 // Add 1us delay between BB/RF register setting.
3142                                                 rtw_udelay_os(1);
3143                                         }
3144                                 }
3145                         }
3146                 }
3147         }
3148         else
3149         {
3150                 DBG_871X("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
3151         }
3152
3153         return rtStatus;
3154 }
3155
3156 VOID
3157 phy_DecryptBBPgParaFile(
3158         PADAPTER                Adapter,
3159         char*                   buffer
3160         )
3161 {
3162         u32     i = 0, j = 0;
3163         u8      map[95] = {0};
3164         u8      currentChar;
3165         char    *BufOfLines, *ptmp;
3166
3167         //DBG_871X("=====>phy_DecryptBBPgParaFile()\n");
3168         // 32 the ascii code of the first visable char, 126 the last one
3169         for ( i = 0; i < 95; ++i )
3170                 map[i] = ( u8 ) ( 94 - i );
3171
3172         ptmp = buffer;
3173         i = 0;
3174         for (BufOfLines = GetLineFromBuffer(ptmp); BufOfLines != NULL; BufOfLines = GetLineFromBuffer(ptmp))
3175         {
3176                 //DBG_871X("Encrypted Line: %s\n", BufOfLines);
3177
3178                 for ( j = 0; j < strlen(BufOfLines); ++j )
3179                 {
3180                         currentChar = BufOfLines[j];
3181
3182                         if ( currentChar == '\0' )
3183                                 break;
3184
3185                         currentChar -=  (u8) ( ( ( ( i + j ) * 3 ) % 128 ) );
3186                         
3187                         BufOfLines[j] = map[currentChar - 32] + 32;
3188                 }
3189                 //DBG_871X("Decrypted Line: %s\n", BufOfLines );
3190                 if (strlen(BufOfLines) != 0)
3191                         i++;
3192                 BufOfLines[strlen(BufOfLines)] = '\n';
3193         }
3194 }
3195
3196 int
3197 phy_ParseBBPgParaFile(
3198         PADAPTER                Adapter,
3199         char*                   buffer
3200         )
3201 {
3202         int     rtStatus = _SUCCESS;
3203         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(Adapter);
3204         char    *szLine, *ptmp;
3205         u32     u4bRegOffset, u4bRegMask, u4bRegValue;
3206         u32     u4bMove;
3207         BOOLEAN firstLine = _TRUE;
3208         u8      tx_num = 0;
3209         u8      band = 0, rf_path = 0;
3210
3211         //DBG_871X("=====>phy_ParseBBPgParaFile()\n");
3212         
3213         if ( Adapter->registrypriv.RegDecryptCustomFile == 1 )
3214                 phy_DecryptBBPgParaFile( Adapter, buffer);
3215
3216         ptmp = buffer;
3217         for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp))
3218         {
3219                 if (isAllSpaceOrTab(szLine, sizeof(*szLine)))
3220                         continue;
3221
3222                 if(!IsCommentString(szLine))
3223                 {
3224                         // Get header info (relative value or exact value)
3225                         if ( firstLine )
3226                         {
3227                                 if ( eqNByte( szLine, (u8 *)("#[v1]"), 5 ) )
3228                                 {
3229                                         
3230                                         pHalData->odmpriv.PhyRegPgVersion = szLine[3] - '0';
3231                                         //DBG_871X("This is a new format PHY_REG_PG.txt \n");
3232                                 }
3233                                 else if ( eqNByte( szLine, (u8 *)("#[v0]"), 5 ))
3234                                 {
3235                                         pHalData->odmpriv.PhyRegPgVersion = szLine[3] - '0';
3236                                         //DBG_871X("This is a old format PHY_REG_PG.txt ok\n");
3237                                 }
3238                                 else
3239                                 {
3240                                         DBG_871X("The format in PHY_REG_PG are invalid %s\n", szLine);
3241                                         return _FAIL;
3242                                 }
3243                                         
3244                                 if ( eqNByte( szLine + 5, (u8 *)("[Exact]#"), 8 ) )
3245                                 {
3246                                         pHalData->odmpriv.PhyRegPgValueType = PHY_REG_PG_EXACT_VALUE;
3247                                         //DBG_871X("The values in PHY_REG_PG are exact values ok\n");
3248                                         firstLine = _FALSE;
3249                                         continue;
3250                                 }
3251                                 else if ( eqNByte( szLine + 5, (pu1Byte)("[Relative]#"), 11 ) )
3252                                 {
3253                                         pHalData->odmpriv.PhyRegPgValueType = PHY_REG_PG_RELATIVE_VALUE;
3254                                         //DBG_871X("The values in PHY_REG_PG are relative values ok\n");
3255                                         firstLine = _FALSE;
3256                                         continue;
3257                                 }
3258                                 else
3259                                 {
3260                                         DBG_871X("The values in PHY_REG_PG are invalid %s\n", szLine);
3261                                         return _FAIL;
3262                                 }
3263                         }
3264
3265                         if ( pHalData->odmpriv.PhyRegPgVersion == 0 )
3266                         {
3267                                 // Get 1st hex value as register offset.
3268                                 if(GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove))
3269                                 {
3270                                         szLine += u4bMove;
3271                                         if(u4bRegOffset == 0xffff)
3272                                         { // Ending.
3273                                                 break;
3274                                         }
3275
3276                                         // Get 2nd hex value as register mask.
3277                                         if ( GetHexValueFromString(szLine, &u4bRegMask, &u4bMove) )
3278                                                 szLine += u4bMove;
3279                                         else
3280                                                 return _FAIL;
3281
3282                                         if ( pHalData->odmpriv.PhyRegPgValueType == PHY_REG_PG_RELATIVE_VALUE ) 
3283                                         {
3284                                                 // Get 3rd hex value as register value.
3285                                                 if(GetHexValueFromString(szLine, &u4bRegValue, &u4bMove))
3286                                                 {
3287                                                         PHY_StoreTxPowerByRate(Adapter, 0, 0, 1, u4bRegOffset, u4bRegMask, u4bRegValue);
3288                                                         //DBG_871X("[ADDR] %03X=%08X Mask=%08x\n", u4bRegOffset, u4bRegValue, u4bRegMask);
3289                                                 }
3290                                                 else
3291                                                 {
3292                                                         return _FAIL;
3293                                                 }
3294                                         }
3295                                         else if ( pHalData->odmpriv.PhyRegPgValueType == PHY_REG_PG_EXACT_VALUE ) 
3296                                         {
3297                                                 u32     combineValue = 0;
3298                                                 u8      integer = 0, fraction = 0;
3299                                                 
3300                                                 if ( GetFractionValueFromString( szLine, &integer, &fraction, &u4bMove ) )
3301                                                         szLine += u4bMove;
3302                                                 else 
3303                                                         return _FAIL;
3304                                                 
3305                                                 integer *= 2;
3306                                                 if ( fraction == 5 ) integer += 1;
3307                                                 combineValue |= ( ( ( integer / 10 ) << 4 ) + ( integer % 10 ) );
3308                                                 //DBG_871X(" %d", integer );
3309
3310                                                 if ( GetFractionValueFromString( szLine, &integer, &fraction, &u4bMove ) )
3311                                                         szLine += u4bMove;
3312                                                 else 
3313                                                         return _FAIL;
3314
3315                                                 integer *= 2;
3316                                                 if ( fraction == 5 ) integer += 1;
3317                                                 combineValue <<= 8;
3318                                                 combineValue |= ( ( ( integer / 10 ) << 4 ) + ( integer % 10 ) );
3319                                                 //DBG_871X(" %d", integer );
3320
3321                                                 if ( GetFractionValueFromString( szLine, &integer, &fraction, &u4bMove ) )
3322                                                         szLine += u4bMove;
3323                                                 else
3324                                                         return _FAIL;
3325                                                 
3326                                                 integer *= 2;
3327                                                 if ( fraction == 5 ) integer += 1;
3328                                                 combineValue <<= 8;
3329                                                 combineValue |= ( ( ( integer / 10 ) << 4 ) + ( integer % 10 ) );
3330                                                 //DBG_871X(" %d", integer );
3331
3332                                                 if ( GetFractionValueFromString( szLine, &integer, &fraction, &u4bMove ) )
3333                                                         szLine += u4bMove;
3334                                                 else 
3335                                                         return _FAIL;
3336
3337                                                 integer *= 2;
3338                                                 if ( fraction == 5 ) integer += 1;
3339                                                 combineValue <<= 8;
3340                                                 combineValue |= ( ( ( integer / 10 ) << 4 ) + ( integer % 10 ) );
3341                                                 //DBG_871X(" %d", integer );
3342                                                 PHY_StoreTxPowerByRate(Adapter, 0, 0, 1, u4bRegOffset, u4bRegMask, combineValue);
3343
3344                                                 //DBG_871X("[ADDR] 0x%3x = 0x%4x\n", u4bRegOffset, combineValue );
3345                                         }
3346                                 }
3347                         }
3348                         else if ( pHalData->odmpriv.PhyRegPgVersion > 0 )
3349                         {
3350                                 u32     index = 0, cnt = 0;
3351
3352                                 if ( eqNByte( szLine, "0xffff", 6 ) )
3353                                         break;
3354
3355                                 if( !eqNByte( "#[END]#", szLine, 7 ) )
3356                                 {
3357                                         // load the table label info
3358                                         if ( szLine[0] == '#' )
3359                                         {
3360                                                 index = 0;
3361                                                 if ( eqNByte( szLine, "#[2.4G]" , 7 ) )
3362                                                 {
3363                                                         band = BAND_ON_2_4G;
3364                                                         index += 8;
3365                                                 }
3366                                                 else if ( eqNByte( szLine, "#[5G]", 5) )
3367                                                 {
3368                                                         band = BAND_ON_5G;
3369                                                         index += 6;
3370                                                 }
3371                                                 else
3372                                                 {
3373                                                         DBG_871X("Invalid band %s in PHY_REG_PG.txt \n", szLine );
3374                                                         return _FAIL;
3375                                                 }
3376
3377                                                 rf_path= szLine[index] - 'A';
3378                                                 //DBG_871X(" Table label Band %d, RfPath %d\n", band, rf_path );
3379                                         }
3380                                         else // load rows of tables
3381                                         {
3382                                                 if ( szLine[1] == '1' )
3383                                                         tx_num = RF_1TX;
3384                                                 else if ( szLine[1] == '2' )
3385                                                         tx_num = RF_2TX;
3386                                                 else if ( szLine[1] == '3' )
3387                                                         tx_num = RF_3TX;
3388                                                 else if ( szLine[1] == '4' )
3389                                                         tx_num = RF_4TX;
3390                                                 else
3391                                                 {
3392                                                         DBG_871X("Invalid row in PHY_REG_PG.txt '%c'(%d)\n", szLine[1], szLine[1]);
3393                                                         return _FAIL;
3394                                                 }
3395
3396                                                 while ( szLine[index] != ']' )
3397                                                         ++index;
3398                                                 ++index;// skip ]
3399
3400                                                 // Get 2nd hex value as register offset.
3401                                                 szLine += index;
3402                                                 if ( GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove) )
3403                                                         szLine += u4bMove;
3404                                                 else
3405                                                         return _FAIL;
3406
3407                                                 // Get 2nd hex value as register mask.
3408                                                 if ( GetHexValueFromString(szLine, &u4bRegMask, &u4bMove) )
3409                                                         szLine += u4bMove;
3410                                                 else
3411                                                         return _FAIL;
3412
3413                                                 if ( pHalData->odmpriv.PhyRegPgValueType == PHY_REG_PG_RELATIVE_VALUE ) 
3414                                                 {
3415                                                         // Get 3rd hex value as register value.
3416                                                         if(GetHexValueFromString(szLine, &u4bRegValue, &u4bMove))
3417                                                         {
3418                                                                 PHY_StoreTxPowerByRate(Adapter, band, rf_path, tx_num, u4bRegOffset, u4bRegMask, u4bRegValue);
3419                                                                 //DBG_871X("[ADDR] %03X (tx_num %d) =%08X Mask=%08x\n", u4bRegOffset, tx_num, u4bRegValue, u4bRegMask);
3420                                                         }
3421                                                         else
3422                                                         {
3423                                                                 return _FAIL;
3424                                                         }
3425                                                 }
3426                                                 else if ( pHalData->odmpriv.PhyRegPgValueType == PHY_REG_PG_EXACT_VALUE ) 
3427                                                 {
3428                                                         u32     combineValue = 0;
3429                                                         u8      integer = 0, fraction = 0;
3430
3431                                                         if ( GetFractionValueFromString( szLine, &integer, &fraction, &u4bMove ) )
3432                                                                 szLine += u4bMove;
3433                                                         else
3434                                                                 return _FAIL;
3435
3436                                                         integer *= 2;
3437                                                         if ( fraction == 5 ) integer += 1;
3438                                                         combineValue |= ( ( ( integer / 10 ) << 4 ) + ( integer % 10 ) );
3439                                                         //DBG_871X(" %d", integer );
3440
3441                                                         if ( GetFractionValueFromString( szLine, &integer, &fraction, &u4bMove ) )
3442                                                                 szLine += u4bMove;
3443                                                         else
3444                                                                 return _FAIL;
3445
3446                                                         integer *= 2;
3447                                                         if ( fraction == 5 ) integer += 1;
3448                                                         combineValue <<= 8;
3449                                                         combineValue |= ( ( ( integer / 10 ) << 4 ) + ( integer % 10 ) );
3450                                                         //DBG_871X(" %d", integer );
3451
3452                                                         if ( GetFractionValueFromString( szLine, &integer, &fraction, &u4bMove ) )
3453                                                                 szLine += u4bMove;
3454                                                         else
3455                                                                 return _FAIL;
3456
3457                                                         integer *= 2;
3458                                                         if ( fraction == 5 ) integer += 1;
3459                                                         combineValue <<= 8;
3460                                                         combineValue |= ( ( ( integer / 10 ) << 4 ) + ( integer % 10 ) );
3461                                                         //DBG_871X(" %d", integer );
3462
3463                                                         if ( GetFractionValueFromString( szLine, &integer, &fraction, &u4bMove ) )
3464                                                                 szLine += u4bMove;
3465                                                         else
3466                                                                 return _FAIL;
3467
3468                                                         integer *= 2;
3469                                                         if ( fraction == 5 ) integer += 1;
3470                                                         combineValue <<= 8;
3471                                                         combineValue |= ( ( ( integer / 10 ) << 4 ) + ( integer % 10 ) );
3472                                                         //DBG_871X(" %d", integer );
3473                                                         PHY_StoreTxPowerByRate(Adapter, band, rf_path, tx_num, u4bRegOffset, u4bRegMask, combineValue);
3474
3475                                                         //DBG_871X("[ADDR] 0x%3x (tx_num %d) = 0x%4x\n", u4bRegOffset, tx_num, combineValue );
3476                                                 }
3477                                         }
3478                                 }
3479                         }
3480                 }
3481         }
3482         //DBG_871X("<=====phy_ParseBBPgParaFile()\n");
3483         return rtStatus;
3484 }
3485
3486 int
3487 phy_ConfigBBWithPgParaFile(
3488         IN      PADAPTER        Adapter,
3489         IN      const char      *pFileName)
3490 {
3491         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(Adapter);
3492         int     rlen = 0, rtStatus = _FAIL;
3493
3494         if(!(Adapter->registrypriv.load_phy_file & LOAD_BB_PG_PARA_FILE))
3495                 return rtStatus;
3496
3497         _rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
3498
3499         if (pHalData->bb_phy_reg_pg == NULL) {
3500                 rtw_merge_string(rtw_phy_para_file_path, PATH_LENGTH_MAX, rtw_phy_file_path, pFileName);
3501         
3502                 if (rtw_is_file_readable(rtw_phy_para_file_path) == _TRUE)
3503                 {
3504                         rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
3505                         if (rlen > 0)
3506                         {
3507                                 rtStatus = _SUCCESS;
3508                                 pHalData->bb_phy_reg_pg = rtw_zvmalloc(rlen);
3509                                 if(pHalData->bb_phy_reg_pg) {
3510                                         _rtw_memcpy(pHalData->bb_phy_reg_pg, pHalData->para_file_buf, rlen);
3511                                         pHalData->bb_phy_reg_pg_len = rlen;
3512                                 }
3513                                 else {
3514                                         DBG_871X("%s bb_phy_reg_pg alloc fail !\n",__FUNCTION__);
3515                                 }
3516                         }
3517                 }
3518         } else {
3519                 if ((pHalData->bb_phy_reg_pg_len != 0) && (pHalData->bb_phy_reg_pg != NULL)) {
3520                         _rtw_memcpy(pHalData->para_file_buf, pHalData->bb_phy_reg_pg, pHalData->bb_phy_reg_pg_len);
3521                         rtStatus = _SUCCESS;
3522                 }
3523                 else {
3524                         DBG_871X("%s(): Critical Error !!!\n",__FUNCTION__);
3525                 }
3526         }
3527
3528         if(rtStatus == _SUCCESS)
3529         {
3530                 //DBG_871X("phy_ConfigBBWithPgParaFile(): read %s ok\n", pFileName);
3531                 phy_ParseBBPgParaFile(Adapter, pHalData->para_file_buf);
3532         }
3533         else
3534         {
3535                 DBG_871X("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
3536         }
3537
3538         return rtStatus;
3539 }
3540
3541 #if (MP_DRIVER == 1 )
3542
3543 int
3544 phy_ConfigBBWithMpParaFile(
3545         IN      PADAPTER        Adapter,
3546         IN      char*           pFileName
3547 )
3548 {
3549         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(Adapter);
3550         int     rlen = 0, rtStatus = _FAIL;
3551         char    *szLine, *ptmp;
3552         u32     u4bRegOffset, u4bRegValue, u4bMove;
3553
3554         if(!(Adapter->registrypriv.load_phy_file & LOAD_BB_MP_PARA_FILE))
3555                 return rtStatus;
3556
3557         _rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
3558
3559         if ((pHalData->bb_phy_reg_mp_len == 0) && (pHalData->bb_phy_reg_mp == NULL))
3560         {
3561                 rtw_merge_string(rtw_phy_para_file_path, PATH_LENGTH_MAX, rtw_phy_file_path, pFileName);
3562         
3563                 if (rtw_is_file_readable(rtw_phy_para_file_path) == _TRUE)
3564                 {
3565                         rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
3566                         if (rlen > 0)
3567                         {
3568                                 rtStatus = _SUCCESS;
3569                                 pHalData->bb_phy_reg_mp = rtw_zvmalloc(rlen);
3570                                 if(pHalData->bb_phy_reg_mp) {
3571                                         _rtw_memcpy(pHalData->bb_phy_reg_mp, pHalData->para_file_buf, rlen);
3572                                         pHalData->bb_phy_reg_mp_len = rlen;
3573                                 }
3574                                 else {
3575                                         DBG_871X("%s bb_phy_reg_mp alloc fail !\n",__FUNCTION__);
3576                                 }
3577                         }
3578                 }
3579         }
3580         else
3581         {
3582                 if ((pHalData->bb_phy_reg_mp_len != 0) && (pHalData->bb_phy_reg_mp != NULL)) {
3583                         _rtw_memcpy(pHalData->para_file_buf, pHalData->bb_phy_reg_mp, pHalData->bb_phy_reg_mp_len);
3584                         rtStatus = _SUCCESS;
3585                 }
3586                 else {
3587                         DBG_871X("%s(): Critical Error !!!\n",__FUNCTION__);
3588                 }
3589         }
3590
3591         if(rtStatus == _SUCCESS)
3592         {
3593                 //DBG_871X("phy_ConfigBBWithMpParaFile(): read %s ok\n", pFileName);
3594
3595                 ptmp = pHalData->para_file_buf;
3596                 for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp))
3597                 {
3598                         if(!IsCommentString(szLine))
3599                         {
3600                                 // Get 1st hex value as register offset.
3601                                 if(GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove))
3602                                 {
3603                                         if(u4bRegOffset == 0xffff)
3604                                         { // Ending.
3605                                                 break;
3606                                         }
3607                                         else if (u4bRegOffset == 0xfe || u4bRegOffset == 0xffe)
3608                                         {
3609                                                 #ifdef CONFIG_LONG_DELAY_ISSUE
3610                                                 rtw_msleep_os(50);
3611                                                 #else
3612                                                 rtw_mdelay_os(50);
3613                                                 #endif
3614                                         }
3615                                         else if (u4bRegOffset == 0xfd)
3616                                         {
3617                                                 rtw_mdelay_os(5);
3618                                         }
3619                                         else if (u4bRegOffset == 0xfc)
3620                                         {
3621                                                 rtw_mdelay_os(1);
3622                                         }
3623                                         else if (u4bRegOffset == 0xfb)
3624                                         {
3625                                                 rtw_udelay_os(50);
3626                                         }
3627                                         else if (u4bRegOffset == 0xfa)
3628                                         {
3629                                                 rtw_udelay_os(5);
3630                                         }
3631                                         else if (u4bRegOffset == 0xf9)
3632                                         {
3633                                                 rtw_udelay_os(1);
3634                                         }
3635
3636                                         // Get 2nd hex value as register value.
3637                                         szLine += u4bMove;
3638                                         if(GetHexValueFromString(szLine, &u4bRegValue, &u4bMove))
3639                                         {
3640                                                 //DBG_871X("[ADDR]%03lX=%08lX\n", u4bRegOffset, u4bRegValue);
3641                                                 PHY_SetBBReg(Adapter, u4bRegOffset, bMaskDWord, u4bRegValue);
3642
3643                                                 // Add 1us delay between BB/RF register setting.
3644                                                 rtw_udelay_os(1);
3645                                         }
3646                                 }
3647                         }
3648                 }
3649         }
3650         else
3651         {
3652                 DBG_871X("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
3653         }
3654
3655         return rtStatus;
3656 }
3657
3658 #endif
3659
3660 int
3661 PHY_ConfigRFWithParaFile(
3662         IN      PADAPTER        Adapter,
3663         IN      char*           pFileName,
3664         IN      u8                      eRFPath
3665 )
3666 {
3667         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(Adapter);
3668         int     rlen = 0, rtStatus = _FAIL;
3669         char    *szLine, *ptmp;
3670         u32     u4bRegOffset, u4bRegValue, u4bMove;
3671         u16     i;
3672         char    *pBuf = NULL;
3673         u32     *pBufLen = NULL;
3674
3675         if(!(Adapter->registrypriv.load_phy_file & LOAD_RF_PARA_FILE))
3676                 return rtStatus;
3677
3678         switch(eRFPath)
3679         {
3680                 case ODM_RF_PATH_A:
3681                         pBuf = pHalData->rf_radio_a;
3682                         pBufLen = &pHalData->rf_radio_a_len;
3683                         break;
3684                 case ODM_RF_PATH_B:
3685                         pBuf = pHalData->rf_radio_b;
3686                         pBufLen = &pHalData->rf_radio_b_len;
3687                         break;
3688                 default:
3689                         DBG_871X("Unknown RF path!! %d\r\n", eRFPath);
3690                         break;                  
3691         }
3692
3693         _rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
3694
3695         if ((pBufLen != NULL) && (*pBufLen == 0) && (pBuf == NULL))
3696         {
3697                 rtw_merge_string(rtw_phy_para_file_path, PATH_LENGTH_MAX, rtw_phy_file_path, pFileName);
3698
3699                 if (rtw_is_file_readable(rtw_phy_para_file_path) == _TRUE)
3700                 {
3701                         rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
3702                         if (rlen > 0)
3703                         {
3704                                 rtStatus = _SUCCESS;
3705                                 pBuf = rtw_zvmalloc(rlen);
3706                                 if(pBuf) {
3707                                         _rtw_memcpy(pBuf, pHalData->para_file_buf, rlen);
3708                                         *pBufLen = rlen;
3709
3710                                         switch(eRFPath)
3711                                         {
3712                                                 case ODM_RF_PATH_A:
3713                                                         pHalData->rf_radio_a = pBuf;
3714                                                         break;
3715                                                 case ODM_RF_PATH_B:
3716                                                         pHalData->rf_radio_b = pBuf;
3717                                                         break;
3718                                         }
3719                                 }
3720                                 else {
3721                                         DBG_871X("%s(): eRFPath=%d  alloc fail !\n",__FUNCTION__,eRFPath);
3722                                 }
3723                         }
3724                 }
3725         }
3726         else
3727         {
3728                 if ((pBufLen != NULL) && (*pBufLen != 0) && (pBuf != NULL)) {
3729                         _rtw_memcpy(pHalData->para_file_buf, pBuf, *pBufLen);
3730                         rtStatus = _SUCCESS;
3731                 }
3732                 else {
3733                         DBG_871X("%s(): Critical Error !!!\n",__FUNCTION__);
3734                 }
3735         }
3736
3737         if(rtStatus == _SUCCESS)
3738         {
3739                 //DBG_871X("%s(): read %s successfully\n", __FUNCTION__, pFileName);
3740         
3741                 ptmp = pHalData->para_file_buf;
3742                 for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp))
3743                 {
3744                         if(!IsCommentString(szLine))
3745                         {
3746                                 // Get 1st hex value as register offset.
3747                                 if(GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove))
3748                                 {
3749                                         if(u4bRegOffset == 0xfe || u4bRegOffset == 0xffe)
3750                                         { // Deay specific ms. Only RF configuration require delay.                                                                                             
3751                                                 #ifdef CONFIG_LONG_DELAY_ISSUE
3752                                                 rtw_msleep_os(50);
3753                                                 #else
3754                                                 rtw_mdelay_os(50);
3755                                                 #endif
3756                                         }
3757                                         else if (u4bRegOffset == 0xfd)
3758                                         {
3759                                                 //delay_ms(5);
3760                                                 for(i=0;i<100;i++)
3761                                                         rtw_udelay_os(MAX_STALL_TIME);
3762                                         }
3763                                         else if (u4bRegOffset == 0xfc)
3764                                         {
3765                                                 //delay_ms(1);
3766                                                 for(i=0;i<20;i++)
3767                                                         rtw_udelay_os(MAX_STALL_TIME);
3768                                         }
3769                                         else if (u4bRegOffset == 0xfb)
3770                                         {
3771                                                 rtw_udelay_os(50);
3772                                         }
3773                                         else if (u4bRegOffset == 0xfa)
3774                                         {
3775                                                 rtw_udelay_os(5);
3776                                         }
3777                                         else if (u4bRegOffset == 0xf9)
3778                                         {
3779                                                 rtw_udelay_os(1);
3780                                         }
3781                                         else if(u4bRegOffset == 0xffff)
3782                                         {
3783                                                 break;                                  
3784                                         }
3785                                         
3786                                         // Get 2nd hex value as register value.
3787                                         szLine += u4bMove;
3788                                         if(GetHexValueFromString(szLine, &u4bRegValue, &u4bMove))
3789                                         {
3790                                                 PHY_SetRFReg(Adapter, eRFPath, u4bRegOffset, bRFRegOffsetMask, u4bRegValue);
3791                                                 
3792                                                 // Temp add, for frequency lock, if no delay, that may cause
3793                                                 // frequency shift, ex: 2412MHz => 2417MHz
3794                                                 // If frequency shift, the following action may works.
3795                                                 // Fractional-N table in radio_a.txt 
3796                                                 //0x2a 0x00001          // channel 1
3797                                                 //0x2b 0x00808          frequency divider.
3798                                                 //0x2b 0x53333
3799                                                 //0x2c 0x0000c
3800                                                 rtw_udelay_os(1);
3801                                         }
3802                                 }
3803                         }
3804                 }
3805         }
3806         else
3807         {
3808                 DBG_871X("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
3809         }
3810
3811         return rtStatus;
3812 }
3813
3814 VOID
3815 initDeltaSwingIndexTables(
3816         PADAPTER        Adapter, 
3817         char*           Band, 
3818         char*           Path,
3819         char*           Sign,
3820         char*           Channel, 
3821         char*           Rate,
3822         char*           Data
3823 )
3824 {
3825         #define STR_EQUAL_5G(_band, _path, _sign, _rate, _chnl) \
3826                 ((strcmp(Band, _band) == 0) && (strcmp(Path, _path) == 0) && (strcmp(Sign, _sign) == 0) &&\
3827                 (strcmp(Rate, _rate) == 0) && (strcmp(Channel, _chnl) == 0)\
3828         )
3829         #define STR_EQUAL_2G(_band, _path, _sign, _rate) \
3830                 ((strcmp(Band, _band) == 0) && (strcmp(Path, _path) == 0) && (strcmp(Sign, _sign) == 0) &&\
3831                 (strcmp(Rate, _rate) == 0)\
3832         )
3833         
3834         #define STORE_SWING_TABLE(_array, _iteratedIdx) \
3835                 for(token = strsep(&Data, delim); token != NULL; token = strsep(&Data, delim))\
3836                 {\
3837                         sscanf(token, "%d", &idx);\
3838                         _array[_iteratedIdx++] = (u8)idx;\
3839                 }\
3840
3841         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(Adapter);
3842         PDM_ODM_T               pDM_Odm = &pHalData->odmpriv;
3843         PODM_RF_CAL_T   pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo);
3844         u32     j = 0;
3845         char    *token;
3846         char    delim[] = ",";
3847         u32     idx = 0;
3848         
3849         //DBG_871X("===>initDeltaSwingIndexTables(): Band: %s;\nPath: %s;\nSign: %s;\nChannel: %s;\nRate: %s;\n, Data: %s;\n", 
3850         //      Band, Path, Sign, Channel, Rate, Data);
3851         
3852         if ( STR_EQUAL_2G("2G", "A", "+", "CCK") )
3853         {
3854                 STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_P, j);
3855         }
3856         else if ( STR_EQUAL_2G("2G", "A", "-", "CCK") )
3857         {
3858                 STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_N, j);
3859         }
3860         else if ( STR_EQUAL_2G("2G", "B", "+", "CCK") )
3861         {
3862                 STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_P, j);
3863         }
3864         else if ( STR_EQUAL_2G("2G", "B", "-", "CCK") )
3865         {
3866                 STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_N, j);
3867         }
3868         else if ( STR_EQUAL_2G("2G", "A", "+", "ALL") )
3869         {
3870                 STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GA_P, j);
3871         }
3872         else if ( STR_EQUAL_2G("2G", "A", "-", "ALL") )
3873         {
3874                 STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GA_N, j);
3875         }
3876         else if ( STR_EQUAL_2G("2G", "B", "+", "ALL") )
3877         {
3878                 STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GB_P, j);
3879         }
3880         else if ( STR_EQUAL_2G("2G", "B", "-", "ALL") )
3881         {
3882                 STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GB_N, j);
3883         }
3884         else if ( STR_EQUAL_5G("5G", "A", "+", "ALL", "0") )
3885         {
3886                 STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_P[0], j);
3887         }
3888         else if ( STR_EQUAL_5G("5G", "A", "-", "ALL", "0") )
3889         {
3890                 STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_N[0], j);
3891         }
3892         else if ( STR_EQUAL_5G("5G", "B", "+", "ALL", "0") )
3893         {
3894                 STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_P[0], j);
3895         }
3896         else if ( STR_EQUAL_5G("5G", "B", "-", "ALL", "0") )
3897         {
3898                 STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_N[0], j);
3899         }
3900         else if ( STR_EQUAL_5G("5G", "A", "+", "ALL", "1") )
3901         {
3902                 STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_P[1], j);
3903         }
3904         else if ( STR_EQUAL_5G("5G", "A", "-", "ALL", "1") )
3905         {
3906                 STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_N[1], j);
3907         }
3908         else if ( STR_EQUAL_5G("5G", "B", "+", "ALL", "1") )
3909         {
3910                 STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_P[1], j);
3911         }
3912         else if ( STR_EQUAL_5G("5G", "B", "-", "ALL", "1") )
3913         {
3914                 STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_N[1], j);
3915         }
3916         else if ( STR_EQUAL_5G("5G", "A", "+", "ALL", "2") )
3917         {
3918                 STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_P[2], j);
3919         }
3920         else if ( STR_EQUAL_5G("5G", "A", "-", "ALL", "2") )
3921         {
3922                 STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_N[2], j);
3923         }
3924         else if ( STR_EQUAL_5G("5G", "B", "+", "ALL", "2") )
3925         {
3926                 STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_P[2], j);
3927         }
3928         else if ( STR_EQUAL_5G("5G", "B", "-", "ALL", "2") )
3929         {
3930                 STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_N[2], j);
3931         }
3932         else if ( STR_EQUAL_5G("5G", "A", "+", "ALL", "3") )
3933         {
3934                 STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_P[3], j);
3935         }
3936         else if ( STR_EQUAL_5G("5G", "A", "-", "ALL", "3") )
3937         {
3938                 STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_N[3], j);
3939         }
3940         else if ( STR_EQUAL_5G("5G", "B", "+", "ALL", "3") )
3941         {
3942                 STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_P[3], j);
3943         }
3944         else if ( STR_EQUAL_5G("5G", "B", "-", "ALL", "3") )
3945         {
3946                 STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_N[3], j);
3947         }
3948         else
3949         {
3950                 DBG_871X("===>initDeltaSwingIndexTables(): The input is invalid!!\n");
3951         }
3952 }
3953
3954 int
3955 PHY_ConfigRFWithTxPwrTrackParaFile(
3956         IN      PADAPTER                Adapter,
3957         IN      char*                   pFileName
3958 )
3959 {
3960         HAL_DATA_TYPE           *pHalData = GET_HAL_DATA(Adapter);
3961         PDM_ODM_T                       pDM_Odm = &pHalData->odmpriv;
3962         PODM_RF_CAL_T           pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo);
3963         int     rlen = 0, rtStatus = _FAIL;
3964         char    *szLine, *ptmp;
3965         u32     i = 0, j = 0;
3966         char    c = 0;
3967
3968         if(!(Adapter->registrypriv.load_phy_file & LOAD_RF_TXPWR_TRACK_PARA_FILE))
3969                 return rtStatus;
3970
3971         _rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
3972
3973         if ((pHalData->rf_tx_pwr_track_len == 0) && (pHalData->rf_tx_pwr_track == NULL))
3974         {
3975                 rtw_merge_string(rtw_phy_para_file_path, PATH_LENGTH_MAX, rtw_phy_file_path, pFileName);
3976         
3977                 if (rtw_is_file_readable(rtw_phy_para_file_path) == _TRUE)
3978                 {
3979                         rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
3980                         if (rlen > 0)
3981                         {
3982                                 rtStatus = _SUCCESS;
3983                                 pHalData->rf_tx_pwr_track = rtw_zvmalloc(rlen);
3984                                 if(pHalData->rf_tx_pwr_track) {
3985                                         _rtw_memcpy(pHalData->rf_tx_pwr_track, pHalData->para_file_buf, rlen);
3986                                         pHalData->rf_tx_pwr_track_len = rlen;
3987                                 }
3988                                 else {
3989                                         DBG_871X("%s rf_tx_pwr_track alloc fail !\n",__FUNCTION__);
3990                                 }
3991                         }
3992                 }
3993         }
3994         else
3995         {
3996                 if ((pHalData->rf_tx_pwr_track_len != 0) && (pHalData->rf_tx_pwr_track != NULL)) {
3997                         _rtw_memcpy(pHalData->para_file_buf, pHalData->rf_tx_pwr_track, pHalData->rf_tx_pwr_track_len);
3998                         rtStatus = _SUCCESS;
3999                 }
4000                 else {
4001                         DBG_871X("%s(): Critical Error !!!\n",__FUNCTION__);
4002                 }
4003         }
4004
4005         if(rtStatus == _SUCCESS)
4006         {
4007                 //DBG_871X("%s(): read %s successfully\n", __FUNCTION__, pFileName);
4008
4009                 ptmp = pHalData->para_file_buf;
4010                 for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp))
4011                 {
4012                         if ( ! IsCommentString(szLine) )
4013                         {
4014                                 char    band[5]="", path[5]="", sign[5]  = "";
4015                                 char    chnl[5]="", rate[10]="";
4016                                 char    data[300]=""; // 100 is too small
4017
4018                                 if (strlen(szLine) < 10 || szLine[0] != '[')
4019                                         continue;
4020
4021                                 strncpy(band, szLine+1, 2); 
4022                                 strncpy(path, szLine+5, 1); 
4023                                 strncpy(sign, szLine+8, 1);
4024
4025                                 i = 10; // szLine+10
4026                                 if ( ! ParseQualifiedString(szLine, &i, rate, '[', ']') ) {
4027                                         //DBG_871X("Fail to parse rate!\n");
4028                                 }
4029                                 if ( ! ParseQualifiedString(szLine, &i, chnl, '[', ']') ) {
4030                                         //DBG_871X("Fail to parse channel group!\n");
4031                                 }
4032                                 while ( szLine[i] != '{' && i < strlen(szLine))
4033                                         i++;
4034                                 if ( ! ParseQualifiedString(szLine, &i, data, '{', '}') ) {
4035                                         //DBG_871X("Fail to parse data!\n");
4036                                 }
4037
4038                                 initDeltaSwingIndexTables(Adapter, band, path, sign, chnl, rate, data);
4039                         }
4040                 }
4041         }
4042         else
4043         {
4044                 DBG_871X("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
4045         }
4046 #if 0
4047         for (i = 0; i < DELTA_SWINGIDX_SIZE; ++i)
4048         {
4049                 DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_2GA_P[%d] = %d\n", i, pRFCalibrateInfo->DeltaSwingTableIdx_2GA_P[i]);
4050                 DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_2GA_N[%d] = %d\n", i, pRFCalibrateInfo->DeltaSwingTableIdx_2GA_N[i]);
4051                 DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_2GB_P[%d] = %d\n", i, pRFCalibrateInfo->DeltaSwingTableIdx_2GB_P[i]);
4052                 DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_2GB_N[%d] = %d\n", i, pRFCalibrateInfo->DeltaSwingTableIdx_2GB_N[i]);
4053                 DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_P[%d] = %d\n", i, pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_P[i]);
4054                 DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_N[%d] = %d\n", i, pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_N[i]);
4055                 DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_P[%d] = %d\n", i, pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_P[i]);
4056                 DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_N[%d] = %d\n", i, pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_N[i]);
4057
4058                 for (j = 0; j < 3; ++j)
4059                 {
4060                     DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_5GA_P[%d][%d] = %d\n", j, i, pRFCalibrateInfo->DeltaSwingTableIdx_5GA_P[j][i]);
4061                     DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_5GA_N[%d][%d] = %d\n", j, i, pRFCalibrateInfo->DeltaSwingTableIdx_5GA_N[j][i]);
4062                     DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_5GB_P[%d][%d] = %d\n", j, i, pRFCalibrateInfo->DeltaSwingTableIdx_5GB_P[j][i]);
4063                     DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_5GB_N[%d][%d] = %d\n", j, i, pRFCalibrateInfo->DeltaSwingTableIdx_5GB_N[j][i]);
4064                 }
4065         }
4066 #endif
4067         return rtStatus;
4068 }
4069
4070 int
4071 phy_ParsePowerLimitTableFile(
4072   PADAPTER              Adapter,
4073   char*                 buffer
4074 )
4075 {
4076         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(Adapter);
4077         PDM_ODM_T       pDM_Odm = &(pHalData->odmpriv);
4078         u32     i = 0, forCnt = 0;
4079         u8      loadingStage = 0, limitValue = 0, fraction = 0;
4080         char    *szLine, *ptmp;
4081         int     rtStatus = _SUCCESS;
4082         char band[10], bandwidth[10], rateSection[10],
4083                 regulation[TXPWR_LMT_MAX_REGULATION_NUM][10], rfPath[10],colNumBuf[10];
4084         u8      colNum = 0;
4085
4086         DBG_871X("===>phy_ParsePowerLimitTableFile()\n" );
4087
4088         if ( Adapter->registrypriv.RegDecryptCustomFile == 1 )
4089                 phy_DecryptBBPgParaFile( Adapter, buffer);
4090
4091         ptmp = buffer;
4092         for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp))
4093         {
4094                 if (isAllSpaceOrTab(szLine, sizeof(*szLine)))
4095                         continue;
4096
4097                 // skip comment 
4098                 if ( IsCommentString( szLine ) ) {
4099                         continue;
4100                 }
4101
4102                 if( loadingStage == 0 ) {
4103                         for ( forCnt = 0; forCnt < TXPWR_LMT_MAX_REGULATION_NUM; ++forCnt )
4104                                 _rtw_memset( ( PVOID ) regulation[forCnt], 0, 10 );
4105                         _rtw_memset( ( PVOID ) band, 0, 10 );
4106                         _rtw_memset( ( PVOID ) bandwidth, 0, 10 );
4107                         _rtw_memset( ( PVOID ) rateSection, 0, 10 );
4108                         _rtw_memset( ( PVOID ) rfPath, 0, 10 );
4109                         _rtw_memset( ( PVOID ) colNumBuf, 0, 10 );
4110
4111                         if ( szLine[0] != '#' || szLine[1] != '#' )
4112                                 continue;
4113
4114                         // skip the space
4115                         i = 2;
4116                         while ( szLine[i] == ' ' || szLine[i] == '\t' )
4117                                 ++i;
4118
4119                         szLine[--i] = ' '; // return the space in front of the regulation info
4120
4121                         // Parse the label of the table
4122                         if ( ! ParseQualifiedString( szLine, &i, band, ' ', ',' ) ) {
4123                                 DBG_871X( "Fail to parse band!\n");
4124                                 return _FAIL;
4125                         }
4126                         if ( ! ParseQualifiedString( szLine, &i, bandwidth, ' ', ',' ) ) {
4127                                 DBG_871X("Fail to parse bandwidth!\n");
4128                                 return _FAIL;
4129                         }
4130                         if ( ! ParseQualifiedString( szLine, &i, rfPath, ' ', ',' ) ) {
4131                                 DBG_871X("Fail to parse rf path!\n");
4132                                 return _FAIL;
4133                         }
4134                         if ( ! ParseQualifiedString( szLine, &i, rateSection, ' ', ',' ) ) {
4135                                 DBG_871X("Fail to parse rate!\n");
4136                                 return _FAIL;
4137                         }
4138
4139                         loadingStage = 1;
4140                 }
4141                 else if ( loadingStage == 1 )
4142                 {
4143                         if ( szLine[0] != '#' || szLine[1] != '#' )
4144                                 continue;
4145
4146                         // skip the space
4147                         i = 2;
4148                         while ( szLine[i] == ' ' || szLine[i] == '\t' )
4149                                 ++i;
4150
4151                         if ( !eqNByte( (u8 *)(szLine + i), (u8 *)("START"), 5 ) ) {
4152                                 DBG_871X("Lost \"##   START\" label\n");
4153                                 return _FAIL;
4154                         }
4155
4156                         loadingStage = 2;
4157                 }
4158                 else if ( loadingStage == 2 )
4159                 {
4160                         if ( szLine[0] != '#' || szLine[1] != '#' )
4161                                 continue;
4162
4163                         // skip the space
4164                         i = 2;
4165                         while ( szLine[i] == ' ' || szLine[i] == '\t' )
4166                                 ++i;
4167
4168                         if ( ! ParseQualifiedString( szLine, &i, colNumBuf, '#', '#' ) ) {
4169                                 DBG_871X("Fail to parse column number!\n");
4170                                 return _FAIL;
4171                         }
4172
4173                         if ( !GetU1ByteIntegerFromStringInDecimal( colNumBuf, &colNum ) )
4174                                 return _FAIL;
4175
4176                         if ( colNum > TXPWR_LMT_MAX_REGULATION_NUM ) {
4177                                 DBG_871X("unvalid col number %d (greater than max %d)\n", 
4178                                           colNum, TXPWR_LMT_MAX_REGULATION_NUM );
4179                                 return _FAIL;
4180                         }
4181
4182                         for ( forCnt = 0; forCnt < colNum; ++forCnt )
4183                         {
4184                                 u8      regulation_name_cnt = 0;
4185
4186                                 // skip the space
4187                                 while ( szLine[i] == ' ' || szLine[i] == '\t' )
4188                                         ++i;
4189
4190                                 while ( szLine[i] != ' ' && szLine[i] != '\t' && szLine[i] != '\0' )
4191                                         regulation[forCnt][regulation_name_cnt++] = szLine[i++];
4192                                 //DBG_871X("regulation %s!\n", regulation[forCnt]);
4193
4194                                 if ( regulation_name_cnt == 0 ) {
4195                                         DBG_871X("unvalid number of regulation!\n");
4196                                         return _FAIL;
4197                                 }
4198                         }
4199
4200                         loadingStage = 3;
4201                 }
4202                 else if ( loadingStage == 3 )
4203                 {
4204                         char    channel[10] = {0}, powerLimit[10] = {0};
4205                         u8      cnt = 0;
4206                         
4207                         // the table ends
4208                         if ( szLine[0] == '#' && szLine[1] == '#' ) {
4209                                 i = 2;
4210                                 while ( szLine[i] == ' ' || szLine[i] == '\t' )
4211                                         ++i;
4212
4213                                 if ( eqNByte( (u8 *)(szLine + i), (u8 *)("END"), 3 ) ) {
4214                                         loadingStage = 0;
4215                                         continue;
4216                                 }
4217                                 else {
4218                                         DBG_871X("Wrong format\n");
4219                                         DBG_871X("<===== phy_ParsePowerLimitTableFile()\n");
4220                                         return _FAIL;
4221                                 }
4222                         }
4223
4224                         if ( ( szLine[0] != 'c' && szLine[0] != 'C' ) || 
4225                                  ( szLine[1] != 'h' && szLine[1] != 'H' ) ) {
4226                                 DBG_871X("Meet wrong channel => power limt pair '%c','%c'(%d,%d)\n", szLine[0], szLine[1], szLine[0], szLine[1]);
4227                                 continue;
4228                         }
4229                         i = 2;// move to the  location behind 'h'
4230
4231                         // load the channel number
4232                         cnt = 0;
4233                         while ( szLine[i] >= '0' && szLine[i] <= '9' ) {
4234                                 channel[cnt] = szLine[i];
4235                                 ++cnt;
4236                                 ++i;
4237                         }
4238                         //DBG_871X("chnl %s!\n", channel);
4239                         
4240                         for ( forCnt = 0; forCnt < colNum; ++forCnt )
4241                         {
4242                                 // skip the space between channel number and the power limit value
4243                                 while ( szLine[i] == ' ' || szLine[i] == '\t' )
4244                                         ++i;
4245
4246                                 // load the power limit value
4247                                 cnt = 0;
4248                                 fraction = 0;
4249                                 _rtw_memset( ( PVOID ) powerLimit, 0, 10 );
4250                                 while ( ( szLine[i] >= '0' && szLine[i] <= '9' ) || szLine[i] == '.' )
4251                                 {
4252                                         if ( szLine[i] == '.' ){
4253                                                 if ( ( szLine[i+1] >= '0' && szLine[i+1] <= '9' ) ) {
4254                                                         fraction = szLine[i+1];
4255                                                         i += 2;
4256                                                 }
4257                                                 else {
4258                                                         DBG_871X("Wrong fraction in TXPWR_LMT.txt\n");
4259                                                         return _FAIL;
4260                                                 }
4261
4262                                                 break;
4263                                         }
4264
4265                                         powerLimit[cnt] = szLine[i];
4266                                         ++cnt;
4267                                         ++i;
4268                                 }
4269
4270                                 if ( powerLimit[0] == '\0' ) {
4271                                         powerLimit[0] = '6';
4272                                         powerLimit[1] = '3';
4273                                         i += 2;
4274                                 }
4275                                 else {
4276                                         if ( !GetU1ByteIntegerFromStringInDecimal( powerLimit, &limitValue ) )
4277                                                 return _FAIL;
4278
4279                                         limitValue *= 2;
4280                                         cnt = 0;
4281                                         if ( fraction == '5' )
4282                                                 ++limitValue;
4283
4284                                         // the value is greater or equal to 100
4285                                         if ( limitValue >= 100 ) {
4286                                                 powerLimit[cnt++] = limitValue/100 + '0';
4287                                                 limitValue %= 100;
4288
4289                                                 if ( limitValue >= 10 ) {
4290                                                         powerLimit[cnt++] = limitValue/10 + '0';
4291                                                         limitValue %= 10;
4292                                                 }
4293                                                 else {
4294                                                         powerLimit[cnt++] = '0';
4295                                                 }
4296
4297                                                 powerLimit[cnt++] = limitValue + '0';
4298                                         }
4299                                         // the value is greater or equal to 10
4300                                         else if ( limitValue >= 10 ) {
4301                                                 powerLimit[cnt++] = limitValue/10 + '0';
4302                                                 limitValue %= 10;
4303                                                 powerLimit[cnt++] = limitValue + '0';
4304                                         }
4305                                         // the value is less than 10 
4306                                         else
4307                                                 powerLimit[cnt++] = limitValue + '0';
4308
4309                                         powerLimit[cnt] = '\0';
4310                                 }
4311
4312                                 //DBG_871X("ch%s => %s\n", channel, powerLimit);
4313
4314                                 // store the power limit value
4315                                 PHY_SetTxPowerLimit(pDM_Odm, (u8 *)regulation[forCnt], (u8 *)band,
4316                                         (u8 *)bandwidth, (u8 *)rateSection, (u8 *)rfPath, (u8 *)channel, (u8 *)powerLimit );
4317
4318                         }
4319                 }
4320                 else 
4321                 {
4322                         DBG_871X("Abnormal loading stage in phy_ParsePowerLimitTableFile()!\n");
4323                         rtStatus = _FAIL;
4324                         break;
4325                 }
4326         }
4327
4328         DBG_871X("<===phy_ParsePowerLimitTableFile()\n");
4329         return rtStatus;
4330 }
4331
4332 int
4333 PHY_ConfigRFWithPowerLimitTableParaFile(
4334         IN      PADAPTER        Adapter,
4335         IN      const char      *pFileName
4336 )
4337 {
4338         HAL_DATA_TYPE           *pHalData = GET_HAL_DATA(Adapter);
4339         int     rlen = 0, rtStatus = _FAIL;
4340
4341         if(!(Adapter->registrypriv.load_phy_file & LOAD_RF_TXPWR_LMT_PARA_FILE))
4342                 return rtStatus;
4343
4344         _rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
4345
4346         if (pHalData->rf_tx_pwr_lmt == NULL) {
4347                 rtw_merge_string(rtw_phy_para_file_path, PATH_LENGTH_MAX, rtw_phy_file_path, pFileName);
4348         
4349                 if (rtw_is_file_readable(rtw_phy_para_file_path) == _TRUE)
4350                 {
4351                         rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
4352                         if (rlen > 0)
4353                         {
4354                                 rtStatus = _SUCCESS;
4355                                 pHalData->rf_tx_pwr_lmt = rtw_zvmalloc(rlen);
4356                                 if(pHalData->rf_tx_pwr_lmt) {
4357                                         _rtw_memcpy(pHalData->rf_tx_pwr_lmt, pHalData->para_file_buf, rlen);
4358                                         pHalData->rf_tx_pwr_lmt_len = rlen;
4359                                 }
4360                                 else {
4361                                         DBG_871X("%s rf_tx_pwr_lmt alloc fail !\n",__FUNCTION__);
4362                                 }
4363                         }
4364                 }
4365         } else {
4366                 if ((pHalData->rf_tx_pwr_lmt_len != 0) && (pHalData->rf_tx_pwr_lmt != NULL)) {
4367                         _rtw_memcpy(pHalData->para_file_buf, pHalData->rf_tx_pwr_lmt, pHalData->rf_tx_pwr_lmt_len);
4368                         rtStatus = _SUCCESS;
4369                 }
4370                 else {
4371                         DBG_871X("%s(): Critical Error !!!\n",__FUNCTION__);
4372                 }
4373         }
4374
4375         if(rtStatus == _SUCCESS)
4376         {
4377                 //DBG_871X("%s(): read %s ok\n", __FUNCTION__, pFileName);
4378                 rtStatus = phy_ParsePowerLimitTableFile( Adapter, pHalData->para_file_buf );
4379         }
4380         else
4381         {
4382                 DBG_871X("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
4383         }
4384
4385         return rtStatus;
4386 }
4387
4388 void phy_free_filebuf_mask(_adapter *padapter, u8 mask)
4389 {
4390         HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
4391
4392         if (pHalData->mac_reg && (mask & LOAD_MAC_PARA_FILE)) {
4393                 rtw_vmfree(pHalData->mac_reg, pHalData->mac_reg_len);
4394                 pHalData->mac_reg = NULL;
4395         }
4396         if (mask & LOAD_BB_PARA_FILE) {
4397                 if (pHalData->bb_phy_reg) {
4398                         rtw_vmfree(pHalData->bb_phy_reg, pHalData->bb_phy_reg_len);
4399                         pHalData->bb_phy_reg = NULL;
4400                 }
4401                 if (pHalData->bb_agc_tab) {
4402                         rtw_vmfree(pHalData->bb_agc_tab, pHalData->bb_agc_tab_len);
4403                         pHalData->bb_agc_tab = NULL;
4404                 }
4405         }
4406         if (pHalData->bb_phy_reg_pg && (mask & LOAD_BB_PG_PARA_FILE)) {
4407                 rtw_vmfree(pHalData->bb_phy_reg_pg, pHalData->bb_phy_reg_pg_len);
4408                 pHalData->bb_phy_reg_pg = NULL;
4409         }
4410         if (pHalData->bb_phy_reg_mp && (mask & LOAD_BB_MP_PARA_FILE)) {
4411                 rtw_vmfree(pHalData->bb_phy_reg_mp, pHalData->bb_phy_reg_mp_len);
4412                 pHalData->bb_phy_reg_mp = NULL;
4413         }
4414         if (mask & LOAD_RF_PARA_FILE) {
4415                 if (pHalData->rf_radio_a) {
4416                         rtw_vmfree(pHalData->rf_radio_a, pHalData->rf_radio_a_len);
4417                         pHalData->rf_radio_a = NULL;
4418                 }
4419                 if (pHalData->rf_radio_b) {
4420                         rtw_vmfree(pHalData->rf_radio_b, pHalData->rf_radio_b_len);
4421                         pHalData->rf_radio_b = NULL;
4422                 }
4423         }
4424         if (pHalData->rf_tx_pwr_track && (mask & LOAD_RF_TXPWR_TRACK_PARA_FILE)) {
4425                 rtw_vmfree(pHalData->rf_tx_pwr_track, pHalData->rf_tx_pwr_track_len);
4426                 pHalData->rf_tx_pwr_track = NULL;
4427         }
4428         if (pHalData->rf_tx_pwr_lmt && (mask & LOAD_RF_TXPWR_LMT_PARA_FILE)) {
4429                 rtw_vmfree(pHalData->rf_tx_pwr_lmt, pHalData->rf_tx_pwr_lmt_len);
4430                 pHalData->rf_tx_pwr_lmt = NULL;
4431         }
4432 }
4433
4434 inline void phy_free_filebuf(_adapter *padapter)
4435 {
4436         phy_free_filebuf_mask(padapter, 0xFF);
4437 }
4438
4439 #endif
4440