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