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