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