GNU Linux-libre 6.7.9-gnu
[releases.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
8 #include <drv_types.h>
9 #include <rtw_debug.h>
10 #include <hal_data.h>
11 #include <linux/kernel.h>
12
13 u8 PHY_GetTxPowerByRateBase(struct adapter *Adapter, u8 RfPath,
14                             enum rate_section RateSection)
15 {
16         struct hal_com_data     *pHalData = GET_HAL_DATA(Adapter);
17         u8      value = 0;
18
19         if (RfPath >= RF_PATH_MAX)
20                 return 0;
21
22         switch (RateSection) {
23         case CCK:
24                 value = pHalData->TxPwrByRateBase2_4G[RfPath][0];
25                 break;
26         case OFDM:
27                 value = pHalData->TxPwrByRateBase2_4G[RfPath][1];
28                 break;
29         case HT_MCS0_MCS7:
30                 value = pHalData->TxPwrByRateBase2_4G[RfPath][2];
31                 break;
32         default:
33                 break;
34         }
35
36         return value;
37 }
38
39 static void
40 phy_SetTxPowerByRateBase(struct adapter *Adapter, u8 RfPath,
41                          enum rate_section RateSection, u8 Value)
42 {
43         struct hal_com_data     *pHalData = GET_HAL_DATA(Adapter);
44
45         if (RfPath >= RF_PATH_MAX)
46                 return;
47
48         switch (RateSection) {
49         case CCK:
50                 pHalData->TxPwrByRateBase2_4G[RfPath][0] = Value;
51                 break;
52         case OFDM:
53                 pHalData->TxPwrByRateBase2_4G[RfPath][1] = Value;
54                 break;
55         case HT_MCS0_MCS7:
56                 pHalData->TxPwrByRateBase2_4G[RfPath][2] = Value;
57                 break;
58         default:
59                 break;
60         }
61 }
62
63 static void
64 phy_StoreTxPowerByRateBase(
65 struct adapter *padapter
66         )
67 {
68         u8 path, base;
69
70         for (path = RF_PATH_A; path <= RF_PATH_B; ++path) {
71                 base = PHY_GetTxPowerByRate(padapter, path, MGN_11M);
72                 phy_SetTxPowerByRateBase(padapter, path, CCK, base);
73
74                 base = PHY_GetTxPowerByRate(padapter, path, MGN_54M);
75                 phy_SetTxPowerByRateBase(padapter, path, OFDM, base);
76
77                 base = PHY_GetTxPowerByRate(padapter, path, MGN_MCS7);
78                 phy_SetTxPowerByRateBase(padapter, path, HT_MCS0_MCS7, base);
79         }
80 }
81
82 u8 PHY_GetRateSectionIndexOfTxPowerByRate(
83         struct adapter *padapter, u32 RegAddr, u32 BitMask
84 )
85 {
86         struct hal_com_data     *pHalData = GET_HAL_DATA(padapter);
87         struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
88         u8      index = 0;
89
90         if (pDM_Odm->PhyRegPgVersion == 0) {
91                 switch (RegAddr) {
92                 case rTxAGC_A_Rate18_06:
93                         index = 0;
94                         break;
95                 case rTxAGC_A_Rate54_24:
96                         index = 1;
97                         break;
98                 case rTxAGC_A_CCK1_Mcs32:
99                         index = 6;
100                         break;
101                 case rTxAGC_B_CCK11_A_CCK2_11:
102                         if (BitMask == bMaskH3Bytes)
103                                 index = 7;
104                         else if (BitMask == 0x000000ff)
105                                 index = 15;
106                         break;
107
108                 case rTxAGC_A_Mcs03_Mcs00:
109                         index = 2;
110                         break;
111                 case rTxAGC_A_Mcs07_Mcs04:
112                         index = 3;
113                         break;
114                 case rTxAGC_B_Rate18_06:
115                         index = 8;
116                         break;
117                 case rTxAGC_B_Rate54_24:
118                         index = 9;
119                         break;
120                 case rTxAGC_B_CCK1_55_Mcs32:
121                         index = 14;
122                         break;
123                 case rTxAGC_B_Mcs03_Mcs00:
124                         index = 10;
125                         break;
126                 case rTxAGC_B_Mcs07_Mcs04:
127                         index = 11;
128                         break;
129                 default:
130                         break;
131                 }
132         }
133
134         return index;
135 }
136
137 void
138 PHY_GetRateValuesOfTxPowerByRate(
139         struct adapter *padapter,
140         u32     RegAddr,
141         u32     BitMask,
142         u32     Value,
143         u8 *RateIndex,
144         s8 *PwrByRateVal,
145         u8 *RateNum
146 )
147 {
148         u8 i = 0;
149
150         switch (RegAddr) {
151         case rTxAGC_A_Rate18_06:
152         case rTxAGC_B_Rate18_06:
153                 RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_6M);
154                 RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_9M);
155                 RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_12M);
156                 RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_18M);
157                 for (i = 0; i < 4; ++i) {
158                         PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
159                                                                                         ((Value >> (i * 8)) & 0xF));
160                 }
161                 *RateNum = 4;
162                 break;
163
164         case rTxAGC_A_Rate54_24:
165         case rTxAGC_B_Rate54_24:
166                 RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_24M);
167                 RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_36M);
168                 RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_48M);
169                 RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_54M);
170                 for (i = 0; i < 4; ++i) {
171                         PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
172                                                                                         ((Value >> (i * 8)) & 0xF));
173                 }
174                 *RateNum = 4;
175                 break;
176
177         case rTxAGC_A_CCK1_Mcs32:
178                 RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_1M);
179                 PwrByRateVal[0] = (s8) ((((Value >> (8 + 4)) & 0xF)) * 10 +
180                                                                                 ((Value >> 8) & 0xF));
181                 *RateNum = 1;
182                 break;
183
184         case rTxAGC_B_CCK11_A_CCK2_11:
185                 if (BitMask == 0xffffff00) {
186                         RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_2M);
187                         RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_5_5M);
188                         RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_11M);
189                         for (i = 1; i < 4; ++i) {
190                                 PwrByRateVal[i - 1] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
191                                                                                                 ((Value >> (i * 8)) & 0xF));
192                         }
193                         *RateNum = 3;
194                 } else if (BitMask == 0x000000ff) {
195                         RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_11M);
196                         PwrByRateVal[0] = (s8) ((((Value >> 4) & 0xF)) * 10 + (Value & 0xF));
197                         *RateNum = 1;
198                 }
199                 break;
200
201         case rTxAGC_A_Mcs03_Mcs00:
202         case rTxAGC_B_Mcs03_Mcs00:
203                 RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS0);
204                 RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS1);
205                 RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS2);
206                 RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS3);
207                 for (i = 0; i < 4; ++i) {
208                         PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
209                                                                                         ((Value >> (i * 8)) & 0xF));
210                 }
211                 *RateNum = 4;
212                 break;
213
214         case rTxAGC_A_Mcs07_Mcs04:
215         case rTxAGC_B_Mcs07_Mcs04:
216                 RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS4);
217                 RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS5);
218                 RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS6);
219                 RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS7);
220                 for (i = 0; i < 4; ++i) {
221                         PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
222                                                                                         ((Value >> (i * 8)) & 0xF));
223                 }
224                 *RateNum = 4;
225                 break;
226
227         case rTxAGC_B_CCK1_55_Mcs32:
228                 RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_1M);
229                 RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_2M);
230                 RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_5_5M);
231                 for (i = 1; i < 4; ++i) {
232                         PwrByRateVal[i - 1] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
233                                                                                         ((Value >> (i * 8)) & 0xF));
234                 }
235                 *RateNum = 3;
236                 break;
237
238         case 0xC20:
239         case 0xE20:
240         case 0x1820:
241         case 0x1a20:
242                 RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_1M);
243                 RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_2M);
244                 RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_5_5M);
245                 RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_11M);
246                 for (i = 0; i < 4; ++i) {
247                         PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
248                                                                                         ((Value >> (i * 8)) & 0xF));
249                 }
250                 *RateNum = 4;
251                 break;
252
253         case 0xC24:
254         case 0xE24:
255         case 0x1824:
256         case 0x1a24:
257                 RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_6M);
258                 RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_9M);
259                 RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_12M);
260                 RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_18M);
261                 for (i = 0; i < 4; ++i) {
262                         PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
263                                                                                         ((Value >> (i * 8)) & 0xF));
264                 }
265                 *RateNum = 4;
266                 break;
267
268         case 0xC28:
269         case 0xE28:
270         case 0x1828:
271         case 0x1a28:
272                 RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_24M);
273                 RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_36M);
274                 RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_48M);
275                 RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_54M);
276                 for (i = 0; i < 4; ++i) {
277                         PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
278                                                                                         ((Value >> (i * 8)) & 0xF));
279                 }
280                 *RateNum = 4;
281                 break;
282
283         case 0xC2C:
284         case 0xE2C:
285         case 0x182C:
286         case 0x1a2C:
287                 RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS0);
288                 RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS1);
289                 RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS2);
290                 RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS3);
291                 for (i = 0; i < 4; ++i) {
292                         PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
293                                                                                         ((Value >> (i * 8)) & 0xF));
294                 }
295                 *RateNum = 4;
296                 break;
297
298         case 0xC30:
299         case 0xE30:
300         case 0x1830:
301         case 0x1a30:
302                 RateIndex[0] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS4);
303                 RateIndex[1] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS5);
304                 RateIndex[2] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS6);
305                 RateIndex[3] = PHY_GetRateIndexOfTxPowerByRate(MGN_MCS7);
306                 for (i = 0; i < 4; ++i) {
307                         PwrByRateVal[i] = (s8) ((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
308                                                                                         ((Value >> (i * 8)) & 0xF));
309                 }
310                 *RateNum = 4;
311                 break;
312
313         default:
314                 break;
315         }
316 }
317
318 static void PHY_StoreTxPowerByRateNew(struct adapter *padapter, u32 RfPath,
319                                       u32 RegAddr, u32 BitMask, u32 Data)
320 {
321         struct hal_com_data     *pHalData = GET_HAL_DATA(padapter);
322         u8 i = 0, rateIndex[4] = {0}, rateNum = 0;
323         s8      PwrByRateVal[4] = {0};
324
325         PHY_GetRateValuesOfTxPowerByRate(padapter, RegAddr, BitMask, Data, rateIndex, PwrByRateVal, &rateNum);
326
327         if (RfPath >= RF_PATH_MAX)
328                 return;
329
330         for (i = 0; i < rateNum; ++i) {
331                 pHalData->TxPwrByRateOffset[RfPath][rateIndex[i]] = PwrByRateVal[i];
332         }
333 }
334
335 static void PHY_StoreTxPowerByRateOld(
336         struct adapter *padapter, u32   RegAddr, u32 BitMask, u32 Data
337 )
338 {
339         struct hal_com_data     *pHalData = GET_HAL_DATA(padapter);
340         u8      index = PHY_GetRateSectionIndexOfTxPowerByRate(padapter, RegAddr, BitMask);
341
342         pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][index] = Data;
343 }
344
345 void PHY_InitTxPowerByRate(struct adapter *padapter)
346 {
347         struct hal_com_data     *pHalData = GET_HAL_DATA(padapter);
348         u8 rfPath, rate;
349
350         for (rfPath = RF_PATH_A; rfPath < MAX_RF_PATH_NUM; ++rfPath)
351                 for (rate = 0; rate < TX_PWR_BY_RATE_NUM_RATE; ++rate)
352                         pHalData->TxPwrByRateOffset[rfPath][rate] = 0;
353 }
354
355 void PHY_StoreTxPowerByRate(
356         struct adapter *padapter,
357         u32     RfPath,
358         u32     RegAddr,
359         u32     BitMask,
360         u32     Data
361 )
362 {
363         struct hal_com_data     *pHalData = GET_HAL_DATA(padapter);
364         struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
365
366         if (pDM_Odm->PhyRegPgVersion > 0)
367                 PHY_StoreTxPowerByRateNew(padapter, RfPath, RegAddr, BitMask, Data);
368         else if (pDM_Odm->PhyRegPgVersion == 0) {
369                 PHY_StoreTxPowerByRateOld(padapter, RegAddr, BitMask, Data);
370         }
371 }
372
373 static void
374 phy_ConvertTxPowerByRateInDbmToRelativeValues(
375 struct adapter *padapter
376         )
377 {
378         u8      base = 0, i = 0, value = 0, path = 0;
379         u8      cckRates[4] = {
380                 MGN_1M, MGN_2M, MGN_5_5M, MGN_11M
381         };
382         u8      ofdmRates[8] = {
383                 MGN_6M, MGN_9M, MGN_12M, MGN_18M, MGN_24M, MGN_36M, MGN_48M, MGN_54M
384         };
385         u8 mcs0_7Rates[8] = {
386                 MGN_MCS0, MGN_MCS1, MGN_MCS2, MGN_MCS3, MGN_MCS4, MGN_MCS5, MGN_MCS6, MGN_MCS7
387         };
388         for (path = RF_PATH_A; path < RF_PATH_MAX; ++path) {
389                 /*  CCK */
390                 base = PHY_GetTxPowerByRate(padapter, path, MGN_11M);
391                 for (i = 0; i < ARRAY_SIZE(cckRates); ++i) {
392                         value = PHY_GetTxPowerByRate(padapter, path, cckRates[i]);
393                         PHY_SetTxPowerByRate(padapter, path, cckRates[i], value - base);
394                 }
395
396                 /*  OFDM */
397                 base = PHY_GetTxPowerByRate(padapter, path, MGN_54M);
398                 for (i = 0; i < sizeof(ofdmRates); ++i) {
399                         value = PHY_GetTxPowerByRate(padapter, path, ofdmRates[i]);
400                         PHY_SetTxPowerByRate(padapter, path, ofdmRates[i], value - base);
401                 }
402
403                 /*  HT MCS0~7 */
404                 base = PHY_GetTxPowerByRate(padapter, path, MGN_MCS7);
405                 for (i = 0; i < sizeof(mcs0_7Rates); ++i) {
406                         value = PHY_GetTxPowerByRate(padapter, path, mcs0_7Rates[i]);
407                         PHY_SetTxPowerByRate(padapter, path, mcs0_7Rates[i], value - base);
408                 }
409         }
410 }
411
412 /*
413   * This function must be called if the value in the PHY_REG_PG.txt(or header)
414   * is exact dBm values
415   */
416 void PHY_TxPowerByRateConfiguration(struct adapter *padapter)
417 {
418         phy_StoreTxPowerByRateBase(padapter);
419         phy_ConvertTxPowerByRateInDbmToRelativeValues(padapter);
420 }
421
422 void PHY_SetTxPowerIndexByRateSection(
423         struct adapter *padapter, u8 RFPath, u8 Channel, u8 RateSection
424 )
425 {
426         struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
427
428         if (RateSection == CCK) {
429                 u8 cckRates[]   = {MGN_1M, MGN_2M, MGN_5_5M, MGN_11M};
430                 PHY_SetTxPowerIndexByRateArray(padapter, RFPath,
431                                              pHalData->CurrentChannelBW,
432                                              Channel, cckRates,
433                                              ARRAY_SIZE(cckRates));
434
435         } else if (RateSection == OFDM) {
436                 u8 ofdmRates[]  = {MGN_6M, MGN_9M, MGN_12M, MGN_18M, MGN_24M, MGN_36M, MGN_48M, MGN_54M};
437                 PHY_SetTxPowerIndexByRateArray(padapter, RFPath,
438                                                pHalData->CurrentChannelBW,
439                                                Channel, ofdmRates,
440                                                ARRAY_SIZE(ofdmRates));
441
442         } else if (RateSection == HT_MCS0_MCS7) {
443                 u8 htRates1T[]  = {MGN_MCS0, MGN_MCS1, MGN_MCS2, MGN_MCS3, MGN_MCS4, MGN_MCS5, MGN_MCS6, MGN_MCS7};
444                 PHY_SetTxPowerIndexByRateArray(padapter, RFPath,
445                                                pHalData->CurrentChannelBW,
446                                                Channel, htRates1T,
447                                                ARRAY_SIZE(htRates1T));
448
449         }
450 }
451
452 u8 PHY_GetTxPowerIndexBase(
453         struct adapter *padapter,
454         u8 RFPath,
455         u8 Rate,
456         enum channel_width      BandWidth,
457         u8 Channel
458 )
459 {
460         struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
461         u8 txPower = 0;
462         u8 chnlIdx = (Channel-1);
463
464         if (HAL_IsLegalChannel(padapter, Channel) == false)
465                 chnlIdx = 0;
466
467         if (IS_CCK_RATE(Rate))
468                 txPower = pHalData->Index24G_CCK_Base[RFPath][chnlIdx];
469         else if (MGN_6M <= Rate)
470                 txPower = pHalData->Index24G_BW40_Base[RFPath][chnlIdx];
471
472         /*  OFDM-1T */
473         if ((MGN_6M <= Rate && Rate <= MGN_54M) && !IS_CCK_RATE(Rate))
474                 txPower += pHalData->OFDM_24G_Diff[RFPath][TX_1S];
475
476         if (BandWidth == CHANNEL_WIDTH_20) { /*  BW20-1S, BW20-2S */
477                 if (MGN_MCS0 <= Rate && Rate <= MGN_MCS7)
478                         txPower += pHalData->BW20_24G_Diff[RFPath][TX_1S];
479         } else if (BandWidth == CHANNEL_WIDTH_40) { /*  BW40-1S, BW40-2S */
480                 if (MGN_MCS0 <= Rate && Rate <= MGN_MCS7)
481                         txPower += pHalData->BW40_24G_Diff[RFPath][TX_1S];
482         }
483
484         return txPower;
485 }
486
487 s8 PHY_GetTxPowerTrackingOffset(struct adapter *padapter, u8 RFPath, u8 Rate)
488 {
489         struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
490         struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
491         s8 offset = 0;
492
493         if (pDM_Odm->RFCalibrateInfo.TxPowerTrackControl  == false)
494                 return offset;
495
496         if ((Rate == MGN_1M) || (Rate == MGN_2M) || (Rate == MGN_5_5M) || (Rate == MGN_11M))
497                 offset = pDM_Odm->Remnant_CCKSwingIdx;
498         else
499                 offset = pDM_Odm->Remnant_OFDMSwingIdx[RFPath];
500
501         return offset;
502 }
503
504 u8 PHY_GetRateIndexOfTxPowerByRate(u8 Rate)
505 {
506         u8 index = 0;
507         switch (Rate) {
508         case MGN_1M:
509                 index = 0;
510                 break;
511         case MGN_2M:
512                 index = 1;
513                 break;
514         case MGN_5_5M:
515                 index = 2;
516                 break;
517         case MGN_11M:
518                 index = 3;
519                 break;
520         case MGN_6M:
521                 index = 4;
522                 break;
523         case MGN_9M:
524                 index = 5;
525                 break;
526         case MGN_12M:
527                 index = 6;
528                 break;
529         case MGN_18M:
530                 index = 7;
531                 break;
532         case MGN_24M:
533                 index = 8;
534                 break;
535         case MGN_36M:
536                 index = 9;
537                 break;
538         case MGN_48M:
539                 index = 10;
540                 break;
541         case MGN_54M:
542                 index = 11;
543                 break;
544         case MGN_MCS0:
545                 index = 12;
546                 break;
547         case MGN_MCS1:
548                 index = 13;
549                 break;
550         case MGN_MCS2:
551                 index = 14;
552                 break;
553         case MGN_MCS3:
554                 index = 15;
555                 break;
556         case MGN_MCS4:
557                 index = 16;
558                 break;
559         case MGN_MCS5:
560                 index = 17;
561                 break;
562         case MGN_MCS6:
563                 index = 18;
564                 break;
565         case MGN_MCS7:
566                 index = 19;
567                 break;
568         default:
569                 break;
570         }
571         return index;
572 }
573
574 s8 PHY_GetTxPowerByRate(struct adapter *padapter, u8 RFPath, u8 Rate)
575 {
576         struct hal_com_data     *pHalData = GET_HAL_DATA(padapter);
577         s8 value = 0;
578         u8 rateIndex = PHY_GetRateIndexOfTxPowerByRate(Rate);
579
580         if ((padapter->registrypriv.RegEnableTxPowerByRate == 2 && pHalData->EEPROMRegulatory == 2) ||
581                    padapter->registrypriv.RegEnableTxPowerByRate == 0)
582                 return 0;
583
584         if (RFPath >= RF_PATH_MAX)
585                 return value;
586
587         if (rateIndex >= TX_PWR_BY_RATE_NUM_RATE)
588                 return value;
589
590         return pHalData->TxPwrByRateOffset[RFPath][rateIndex];
591
592 }
593
594 void PHY_SetTxPowerByRate(
595         struct adapter *padapter,
596         u8 RFPath,
597         u8 Rate,
598         s8 Value
599 )
600 {
601         struct hal_com_data     *pHalData = GET_HAL_DATA(padapter);
602         u8 rateIndex = PHY_GetRateIndexOfTxPowerByRate(Rate);
603
604         if (RFPath >= RF_PATH_MAX)
605                 return;
606
607         if (rateIndex >= TX_PWR_BY_RATE_NUM_RATE)
608                 return;
609
610         pHalData->TxPwrByRateOffset[RFPath][rateIndex] = Value;
611 }
612
613 void PHY_SetTxPowerLevelByPath(struct adapter *Adapter, u8 channel, u8 path)
614 {
615         PHY_SetTxPowerIndexByRateSection(Adapter, path, channel, CCK);
616
617         PHY_SetTxPowerIndexByRateSection(Adapter, path, channel, OFDM);
618         PHY_SetTxPowerIndexByRateSection(Adapter, path, channel, HT_MCS0_MCS7);
619 }
620
621 void PHY_SetTxPowerIndexByRateArray(
622         struct adapter *padapter,
623         u8 RFPath,
624         enum channel_width BandWidth,
625         u8 Channel,
626         u8 *Rates,
627         u8 RateArraySize
628 )
629 {
630         u32 powerIndex = 0;
631         int     i = 0;
632
633         for (i = 0; i < RateArraySize; ++i) {
634                 powerIndex = PHY_GetTxPowerIndex(padapter, RFPath, Rates[i], BandWidth, Channel);
635                 PHY_SetTxPowerIndex(padapter, powerIndex, RFPath, Rates[i]);
636         }
637 }
638
639 static s8 phy_GetWorldWideLimit(s8 *LimitTable)
640 {
641         s8      min = LimitTable[0];
642         u8 i = 0;
643
644         for (i = 0; i < MAX_REGULATION_NUM; ++i) {
645                 if (LimitTable[i] < min)
646                         min = LimitTable[i];
647         }
648
649         return min;
650 }
651
652 static s8 phy_GetChannelIndexOfTxPowerLimit(u8 Channel)
653 {
654         return Channel - 1;
655 }
656
657 static s16 get_bandwidth_idx(const enum channel_width bandwidth)
658 {
659         switch (bandwidth) {
660         case CHANNEL_WIDTH_20:
661                 return 0;
662         case CHANNEL_WIDTH_40:
663                 return 1;
664         default:
665                 return -1;
666         }
667 }
668
669 static s16 get_rate_sctn_idx(const u8 rate)
670 {
671         switch (rate) {
672         case MGN_1M: case MGN_2M: case MGN_5_5M: case MGN_11M:
673                 return 0;
674         case MGN_6M: case MGN_9M: case MGN_12M: case MGN_18M:
675         case MGN_24M: case MGN_36M: case MGN_48M: case MGN_54M:
676                 return 1;
677         case MGN_MCS0: case MGN_MCS1: case MGN_MCS2: case MGN_MCS3:
678         case MGN_MCS4: case MGN_MCS5: case MGN_MCS6: case MGN_MCS7:
679                 return 2;
680         default:
681                 return -1;
682         }
683 }
684
685 s8 phy_get_tx_pwr_lmt(struct adapter *adapter, u32 reg_pwr_tbl_sel,
686                       enum channel_width bandwidth,
687                       u8 rf_path, u8 data_rate, u8 channel)
688 {
689         s16 idx_regulation = -1;
690         s16 idx_bandwidth  = -1;
691         s16 idx_rate_sctn  = -1;
692         s16 idx_channel    = -1;
693         s8 pwr_lmt = MAX_POWER_INDEX;
694         struct hal_com_data *hal_data = GET_HAL_DATA(adapter);
695         s8 limits[10] = {0}; u8 i = 0;
696
697         if (((adapter->registrypriv.RegEnableTxPowerLimit == 2) &&
698              (hal_data->EEPROMRegulatory != 1)) ||
699             (adapter->registrypriv.RegEnableTxPowerLimit == 0))
700                 return MAX_POWER_INDEX;
701
702         switch (adapter->registrypriv.RegPwrTblSel) {
703         case 1:
704                 idx_regulation = TXPWR_LMT_ETSI;
705                 break;
706         case 2:
707                 idx_regulation = TXPWR_LMT_MKK;
708                 break;
709         case 3:
710                 idx_regulation = TXPWR_LMT_FCC;
711                 break;
712         case 4:
713                 idx_regulation = TXPWR_LMT_WW;
714                 break;
715         default:
716                 idx_regulation = hal_data->Regulation2_4G;
717                 break;
718         }
719
720         idx_bandwidth = get_bandwidth_idx(bandwidth);
721         idx_rate_sctn = get_rate_sctn_idx(data_rate);
722
723         /*  workaround for wrong index combination to obtain tx power limit, */
724         /*  OFDM only exists in BW 20M */
725         /*  CCK table will only be given in BW 20M */
726         /*  HT on 80M will reference to HT on 40M */
727         if (idx_rate_sctn == 0 || idx_rate_sctn == 1)
728                 idx_bandwidth = 0;
729
730         channel = phy_GetChannelIndexOfTxPowerLimit(channel);
731
732         if (idx_regulation == -1 || idx_bandwidth == -1 ||
733             idx_rate_sctn == -1 || idx_channel == -1)
734                 return MAX_POWER_INDEX;
735
736
737         for (i = 0; i < MAX_REGULATION_NUM; i++)
738                 limits[i] = hal_data->TxPwrLimit_2_4G[i]
739                                                      [idx_bandwidth]
740                                                      [idx_rate_sctn]
741                                                      [idx_channel]
742                                                      [rf_path];
743
744         pwr_lmt = (idx_regulation == TXPWR_LMT_WW) ?
745                 phy_GetWorldWideLimit(limits) :
746                 hal_data->TxPwrLimit_2_4G[idx_regulation]
747                                          [idx_bandwidth]
748                                          [idx_rate_sctn]
749                                          [idx_channel]
750                                          [rf_path];
751
752         return pwr_lmt;
753 }
754
755 void PHY_ConvertTxPowerLimitToPowerIndex(struct adapter *Adapter)
756 {
757         struct hal_com_data     *pHalData = GET_HAL_DATA(Adapter);
758         u8 BW40PwrBasedBm2_4G = 0x2E;
759         u8 regulation, bw, channel, rateSection;
760         s8 tempValue = 0, tempPwrLmt = 0;
761         u8 rfPath = 0;
762
763         for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
764                 for (bw = 0; bw < MAX_2_4G_BANDWIDTH_NUM; ++bw) {
765                         for (channel = 0; channel < CHANNEL_MAX_NUMBER_2G; ++channel) {
766                                 for (rateSection = 0; rateSection < MAX_RATE_SECTION_NUM; ++rateSection) {
767                                         tempPwrLmt = pHalData->TxPwrLimit_2_4G[regulation][bw][rateSection][channel][RF_PATH_A];
768
769                                         for (rfPath = RF_PATH_A; rfPath < MAX_RF_PATH_NUM; ++rfPath) {
770                                                 if (pHalData->odmpriv.PhyRegPgValueType == PHY_REG_PG_EXACT_VALUE) {
771                                                         if (rateSection == 2) /*  HT 1T */
772                                                                 BW40PwrBasedBm2_4G = PHY_GetTxPowerByRateBase(Adapter, rfPath, HT_MCS0_MCS7);
773                                                         else if (rateSection == 1) /*  OFDM */
774                                                                 BW40PwrBasedBm2_4G = PHY_GetTxPowerByRateBase(Adapter, rfPath, OFDM);
775                                                         else if (rateSection == 0) /*  CCK */
776                                                                 BW40PwrBasedBm2_4G = PHY_GetTxPowerByRateBase(Adapter, rfPath, CCK);
777                                                 } else
778                                                         BW40PwrBasedBm2_4G = Adapter->registrypriv.RegPowerBase * 2;
779
780                                                 if (tempPwrLmt != MAX_POWER_INDEX) {
781                                                         tempValue = tempPwrLmt - BW40PwrBasedBm2_4G;
782                                                         pHalData->TxPwrLimit_2_4G[regulation][bw][rateSection][channel][rfPath] = tempValue;
783                                                 }
784                                         }
785                                 }
786                         }
787                 }
788         }
789 }
790
791 void PHY_InitTxPowerLimit(struct adapter *Adapter)
792 {
793         struct hal_com_data     *pHalData = GET_HAL_DATA(Adapter);
794         u8 i, j, k, l, m;
795
796         for (i = 0; i < MAX_REGULATION_NUM; ++i) {
797                 for (j = 0; j < MAX_2_4G_BANDWIDTH_NUM; ++j)
798                         for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
799                                 for (m = 0; m < CHANNEL_MAX_NUMBER_2G; ++m)
800                                         for (l = 0; l < MAX_RF_PATH_NUM; ++l)
801                                                 pHalData->TxPwrLimit_2_4G[i][j][k][m][l] = MAX_POWER_INDEX;
802         }
803 }
804
805 void PHY_SetTxPowerLimit(
806         struct adapter *Adapter,
807         u8 *Regulation,
808         u8 *Bandwidth,
809         u8 *RateSection,
810         u8 *RfPath,
811         u8 *Channel,
812         u8 *PowerLimit
813 )
814 {
815         struct hal_com_data     *pHalData = GET_HAL_DATA(Adapter);
816         u8 regulation = 0, bandwidth = 0, rateSection = 0, channel;
817         s8 powerLimit = 0, prevPowerLimit, channelIndex;
818
819         GetU1ByteIntegerFromStringInDecimal((s8 *)Channel, &channel);
820         GetU1ByteIntegerFromStringInDecimal((s8 *)PowerLimit, &powerLimit);
821
822         powerLimit = powerLimit > MAX_POWER_INDEX ? MAX_POWER_INDEX : powerLimit;
823
824         if (eqNByte(Regulation, (u8 *)("FCC"), 3))
825                 regulation = 0;
826         else if (eqNByte(Regulation, (u8 *)("MKK"), 3))
827                 regulation = 1;
828         else if (eqNByte(Regulation, (u8 *)("ETSI"), 4))
829                 regulation = 2;
830         else if (eqNByte(Regulation, (u8 *)("WW13"), 4))
831                 regulation = 3;
832
833         if (eqNByte(RateSection, (u8 *)("CCK"), 3) && eqNByte(RfPath, (u8 *)("1T"), 2))
834                 rateSection = 0;
835         else if (eqNByte(RateSection, (u8 *)("OFDM"), 4) && eqNByte(RfPath, (u8 *)("1T"), 2))
836                 rateSection = 1;
837         else if (eqNByte(RateSection, (u8 *)("HT"), 2) && eqNByte(RfPath, (u8 *)("1T"), 2))
838                 rateSection = 2;
839         else
840                 return;
841
842         if (eqNByte(Bandwidth, (u8 *)("20M"), 3))
843                 bandwidth = 0;
844         else if (eqNByte(Bandwidth, (u8 *)("40M"), 3))
845                 bandwidth = 1;
846
847         channelIndex = phy_GetChannelIndexOfTxPowerLimit(channel);
848
849         if (channelIndex == -1)
850                 return;
851
852         prevPowerLimit = pHalData->TxPwrLimit_2_4G[regulation][bandwidth][rateSection][channelIndex][RF_PATH_A];
853
854         if (powerLimit < prevPowerLimit)
855                 pHalData->TxPwrLimit_2_4G[regulation][bandwidth][rateSection][channelIndex][RF_PATH_A] = powerLimit;
856 }
857
858 void Hal_ChannelPlanToRegulation(struct adapter *Adapter, u16 ChannelPlan)
859 {
860         struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
861         pHalData->Regulation2_4G = TXPWR_LMT_WW;
862
863         switch (ChannelPlan) {
864         case RT_CHANNEL_DOMAIN_WORLD_NULL:
865                 pHalData->Regulation2_4G = TXPWR_LMT_WW;
866                 break;
867         case RT_CHANNEL_DOMAIN_ETSI1_NULL:
868                 pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
869                 break;
870         case RT_CHANNEL_DOMAIN_FCC1_NULL:
871                 pHalData->Regulation2_4G = TXPWR_LMT_FCC;
872                 break;
873         case RT_CHANNEL_DOMAIN_MKK1_NULL:
874                 pHalData->Regulation2_4G = TXPWR_LMT_MKK;
875                 break;
876         case RT_CHANNEL_DOMAIN_ETSI2_NULL:
877                 pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
878                 break;
879         case RT_CHANNEL_DOMAIN_FCC1_FCC1:
880                 pHalData->Regulation2_4G = TXPWR_LMT_FCC;
881                 break;
882         case RT_CHANNEL_DOMAIN_WORLD_ETSI1:
883                 pHalData->Regulation2_4G = TXPWR_LMT_FCC;
884                 break;
885         case RT_CHANNEL_DOMAIN_MKK1_MKK1:
886                 pHalData->Regulation2_4G = TXPWR_LMT_MKK;
887                 break;
888         case RT_CHANNEL_DOMAIN_WORLD_KCC1:
889                 pHalData->Regulation2_4G = TXPWR_LMT_FCC;
890                 break;
891         case RT_CHANNEL_DOMAIN_WORLD_FCC2:
892                 pHalData->Regulation2_4G = TXPWR_LMT_FCC;
893                 break;
894         case RT_CHANNEL_DOMAIN_WORLD_FCC3:
895                 pHalData->Regulation2_4G = TXPWR_LMT_FCC;
896                 break;
897         case RT_CHANNEL_DOMAIN_WORLD_FCC4:
898                 pHalData->Regulation2_4G = TXPWR_LMT_FCC;
899                 break;
900         case RT_CHANNEL_DOMAIN_WORLD_FCC5:
901                 pHalData->Regulation2_4G = TXPWR_LMT_FCC;
902                 break;
903         case RT_CHANNEL_DOMAIN_WORLD_FCC6:
904                 pHalData->Regulation2_4G = TXPWR_LMT_FCC;
905                 break;
906         case RT_CHANNEL_DOMAIN_FCC1_FCC7:
907                 pHalData->Regulation2_4G = TXPWR_LMT_FCC;
908                 break;
909         case RT_CHANNEL_DOMAIN_WORLD_ETSI2:
910                 pHalData->Regulation2_4G = TXPWR_LMT_FCC;
911                 break;
912         case RT_CHANNEL_DOMAIN_WORLD_ETSI3:
913                 pHalData->Regulation2_4G = TXPWR_LMT_FCC;
914                 break;
915         case RT_CHANNEL_DOMAIN_MKK1_MKK2:
916                 pHalData->Regulation2_4G = TXPWR_LMT_MKK;
917                 break;
918         case RT_CHANNEL_DOMAIN_MKK1_MKK3:
919                 pHalData->Regulation2_4G = TXPWR_LMT_MKK;
920                 break;
921         case RT_CHANNEL_DOMAIN_FCC1_NCC1:
922                 pHalData->Regulation2_4G = TXPWR_LMT_FCC;
923                 break;
924         case RT_CHANNEL_DOMAIN_FCC1_NCC2:
925                 pHalData->Regulation2_4G = TXPWR_LMT_FCC;
926                 break;
927         case RT_CHANNEL_DOMAIN_GLOBAL_NULL:
928                 pHalData->Regulation2_4G = TXPWR_LMT_WW;
929                 break;
930         case RT_CHANNEL_DOMAIN_ETSI1_ETSI4:
931                 pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
932                 break;
933         case RT_CHANNEL_DOMAIN_FCC1_FCC2:
934                 pHalData->Regulation2_4G = TXPWR_LMT_FCC;
935                 break;
936         case RT_CHANNEL_DOMAIN_FCC1_NCC3:
937                 pHalData->Regulation2_4G = TXPWR_LMT_FCC;
938                 break;
939         case RT_CHANNEL_DOMAIN_WORLD_ETSI5:
940                 pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
941                 break;
942         case RT_CHANNEL_DOMAIN_FCC1_FCC8:
943                 pHalData->Regulation2_4G = TXPWR_LMT_FCC;
944                 break;
945         case RT_CHANNEL_DOMAIN_WORLD_ETSI6:
946                 pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
947                 break;
948         case RT_CHANNEL_DOMAIN_WORLD_ETSI7:
949                 pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
950                 break;
951         case RT_CHANNEL_DOMAIN_WORLD_ETSI8:
952                 pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
953                 break;
954         case RT_CHANNEL_DOMAIN_WORLD_ETSI9:
955                 pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
956                 break;
957         case RT_CHANNEL_DOMAIN_WORLD_ETSI10:
958                 pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
959                 break;
960         case RT_CHANNEL_DOMAIN_WORLD_ETSI11:
961                 pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
962                 break;
963         case RT_CHANNEL_DOMAIN_FCC1_NCC4:
964                 pHalData->Regulation2_4G = TXPWR_LMT_FCC;
965                 break;
966         case RT_CHANNEL_DOMAIN_WORLD_ETSI12:
967                 pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
968                 break;
969         case RT_CHANNEL_DOMAIN_FCC1_FCC9:
970                 pHalData->Regulation2_4G = TXPWR_LMT_FCC;
971                 break;
972         case RT_CHANNEL_DOMAIN_WORLD_ETSI13:
973                 pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
974                 break;
975         case RT_CHANNEL_DOMAIN_FCC1_FCC10:
976                 pHalData->Regulation2_4G = TXPWR_LMT_FCC;
977                 break;
978         case RT_CHANNEL_DOMAIN_REALTEK_DEFINE: /* Realtek Reserve */
979                 pHalData->Regulation2_4G = TXPWR_LMT_WW;
980                 break;
981         default:
982                 break;
983         }
984 }