OSDN Git Service

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