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