xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8189fs/hal/hal_com_phycfg.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /******************************************************************************
2*4882a593Smuzhiyun  *
3*4882a593Smuzhiyun  * Copyright(c) 2007 - 2017 Realtek Corporation.
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * This program is free software; you can redistribute it and/or modify it
6*4882a593Smuzhiyun  * under the terms of version 2 of the GNU General Public License as
7*4882a593Smuzhiyun  * published by the Free Software Foundation.
8*4882a593Smuzhiyun  *
9*4882a593Smuzhiyun  * This program is distributed in the hope that it will be useful, but WITHOUT
10*4882a593Smuzhiyun  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11*4882a593Smuzhiyun  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12*4882a593Smuzhiyun  * more details.
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  *****************************************************************************/
15*4882a593Smuzhiyun #define _HAL_COM_PHYCFG_C_
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #include <drv_types.h>
18*4882a593Smuzhiyun #include <hal_data.h>
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun #define PG_TXPWR_1PATH_BYTE_NUM_2G 18
21*4882a593Smuzhiyun #define PG_TXPWR_BASE_BYTE_NUM_2G 11
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun #define PG_TXPWR_1PATH_BYTE_NUM_5G 24
24*4882a593Smuzhiyun #define PG_TXPWR_BASE_BYTE_NUM_5G 14
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun #define PG_TXPWR_MSB_DIFF_S4BIT(_pg_v) (((_pg_v) & 0xf0) >> 4)
27*4882a593Smuzhiyun #define PG_TXPWR_LSB_DIFF_S4BIT(_pg_v) ((_pg_v) & 0x0f)
28*4882a593Smuzhiyun #define PG_TXPWR_MSB_DIFF_TO_S8BIT(_pg_v) ((PG_TXPWR_MSB_DIFF_S4BIT(_pg_v) & BIT3) ? (PG_TXPWR_MSB_DIFF_S4BIT(_pg_v) | 0xF0) : PG_TXPWR_MSB_DIFF_S4BIT(_pg_v))
29*4882a593Smuzhiyun #define PG_TXPWR_LSB_DIFF_TO_S8BIT(_pg_v) ((PG_TXPWR_LSB_DIFF_S4BIT(_pg_v) & BIT3) ? (PG_TXPWR_LSB_DIFF_S4BIT(_pg_v) | 0xF0) : PG_TXPWR_LSB_DIFF_S4BIT(_pg_v))
30*4882a593Smuzhiyun #define IS_PG_TXPWR_BASE_INVALID(hal_spec, _base) ((_base) > hal_spec->txgi_max)
31*4882a593Smuzhiyun #define IS_PG_TXPWR_DIFF_INVALID(_diff) ((_diff) > 7 || (_diff) < -8)
32*4882a593Smuzhiyun #define PG_TXPWR_INVALID_BASE 255
33*4882a593Smuzhiyun #define PG_TXPWR_INVALID_DIFF 8
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun #if !IS_PG_TXPWR_DIFF_INVALID(PG_TXPWR_INVALID_DIFF)
36*4882a593Smuzhiyun #error "PG_TXPWR_DIFF definition has problem"
37*4882a593Smuzhiyun #endif
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun #define PG_TXPWR_SRC_PG_DATA	0
40*4882a593Smuzhiyun #define PG_TXPWR_SRC_IC_DEF		1
41*4882a593Smuzhiyun #define PG_TXPWR_SRC_DEF		2
42*4882a593Smuzhiyun #define PG_TXPWR_SRC_NUM		3
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun const char *const _pg_txpwr_src_str[] = {
45*4882a593Smuzhiyun 	"PG_DATA",
46*4882a593Smuzhiyun 	"IC_DEF",
47*4882a593Smuzhiyun 	"DEF",
48*4882a593Smuzhiyun 	"UNKNOWN"
49*4882a593Smuzhiyun };
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun #define pg_txpwr_src_str(src) (((src) >= PG_TXPWR_SRC_NUM) ? _pg_txpwr_src_str[PG_TXPWR_SRC_NUM] : _pg_txpwr_src_str[(src)])
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun const char *const _txpwr_pg_mode_str[] = {
54*4882a593Smuzhiyun 	"PWR_IDX",
55*4882a593Smuzhiyun 	"TSSI_OFFSET",
56*4882a593Smuzhiyun 	"UNKNOWN",
57*4882a593Smuzhiyun };
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun static const u8 rate_sec_base[RATE_SECTION_NUM] = {
60*4882a593Smuzhiyun 	MGN_11M,
61*4882a593Smuzhiyun 	MGN_54M,
62*4882a593Smuzhiyun 	MGN_MCS7,
63*4882a593Smuzhiyun 	MGN_MCS15,
64*4882a593Smuzhiyun 	MGN_MCS23,
65*4882a593Smuzhiyun 	MGN_MCS31,
66*4882a593Smuzhiyun 	MGN_VHT1SS_MCS7,
67*4882a593Smuzhiyun 	MGN_VHT2SS_MCS7,
68*4882a593Smuzhiyun 	MGN_VHT3SS_MCS7,
69*4882a593Smuzhiyun 	MGN_VHT4SS_MCS7,
70*4882a593Smuzhiyun };
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun #ifdef CONFIG_TXPWR_PG_WITH_PWR_IDX
73*4882a593Smuzhiyun typedef struct _TxPowerInfo24G {
74*4882a593Smuzhiyun 	u8 IndexCCK_Base[MAX_RF_PATH][MAX_CHNL_GROUP_24G];
75*4882a593Smuzhiyun 	u8 IndexBW40_Base[MAX_RF_PATH][MAX_CHNL_GROUP_24G];
76*4882a593Smuzhiyun 	/* If only one tx, only BW20 and OFDM are used. */
77*4882a593Smuzhiyun 	s8 CCK_Diff[MAX_RF_PATH][MAX_TX_COUNT];
78*4882a593Smuzhiyun 	s8 OFDM_Diff[MAX_RF_PATH][MAX_TX_COUNT];
79*4882a593Smuzhiyun 	s8 BW20_Diff[MAX_RF_PATH][MAX_TX_COUNT];
80*4882a593Smuzhiyun 	s8 BW40_Diff[MAX_RF_PATH][MAX_TX_COUNT];
81*4882a593Smuzhiyun } TxPowerInfo24G;
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun typedef struct _TxPowerInfo5G {
84*4882a593Smuzhiyun 	u8 IndexBW40_Base[MAX_RF_PATH][MAX_CHNL_GROUP_5G];
85*4882a593Smuzhiyun 	/* If only one tx, only BW20, OFDM, BW80 and BW160 are used. */
86*4882a593Smuzhiyun 	s8 OFDM_Diff[MAX_RF_PATH][MAX_TX_COUNT];
87*4882a593Smuzhiyun 	s8 BW20_Diff[MAX_RF_PATH][MAX_TX_COUNT];
88*4882a593Smuzhiyun 	s8 BW40_Diff[MAX_RF_PATH][MAX_TX_COUNT];
89*4882a593Smuzhiyun 	s8 BW80_Diff[MAX_RF_PATH][MAX_TX_COUNT];
90*4882a593Smuzhiyun 	s8 BW160_Diff[MAX_RF_PATH][MAX_TX_COUNT];
91*4882a593Smuzhiyun } TxPowerInfo5G;
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun #ifndef DBG_PG_TXPWR_READ
94*4882a593Smuzhiyun #define DBG_PG_TXPWR_READ 0
95*4882a593Smuzhiyun #endif
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun #if DBG_PG_TXPWR_READ
dump_pg_txpwr_info_2g(void * sel,TxPowerInfo24G * txpwr_info,u8 rfpath_num,u8 max_tx_cnt)98*4882a593Smuzhiyun static void dump_pg_txpwr_info_2g(void *sel, TxPowerInfo24G *txpwr_info, u8 rfpath_num, u8 max_tx_cnt)
99*4882a593Smuzhiyun {
100*4882a593Smuzhiyun 	int path, group, tx_idx;
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "2.4G\n");
103*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "CCK-1T base:\n");
104*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "%4s ", "");
105*4882a593Smuzhiyun 	for (group = 0; group < MAX_CHNL_GROUP_24G; group++)
106*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "G%02d ", group);
107*4882a593Smuzhiyun 	_RTW_PRINT_SEL(sel, "\n");
108*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
109*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
110*4882a593Smuzhiyun 		for (group = 0; group < MAX_CHNL_GROUP_24G; group++)
111*4882a593Smuzhiyun 			_RTW_PRINT_SEL(sel, "%3u ", txpwr_info->IndexCCK_Base[path][group]);
112*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "\n");
113*4882a593Smuzhiyun 	}
114*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "\n");
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "CCK diff:\n");
117*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "%4s ", "");
118*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++)
119*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "%dT ", path + 1);
120*4882a593Smuzhiyun 	_RTW_PRINT_SEL(sel, "\n");
121*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
122*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
123*4882a593Smuzhiyun 		for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
124*4882a593Smuzhiyun 			_RTW_PRINT_SEL(sel, "%2d ", txpwr_info->CCK_Diff[path][tx_idx]);
125*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "\n");
126*4882a593Smuzhiyun 	}
127*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "\n");
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "BW40-1S base:\n");
130*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "%4s ", "");
131*4882a593Smuzhiyun 	for (group = 0; group < MAX_CHNL_GROUP_24G - 1; group++)
132*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "G%02d ", group);
133*4882a593Smuzhiyun 	_RTW_PRINT_SEL(sel, "\n");
134*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
135*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
136*4882a593Smuzhiyun 		for (group = 0; group < MAX_CHNL_GROUP_24G - 1; group++)
137*4882a593Smuzhiyun 			_RTW_PRINT_SEL(sel, "%3u ", txpwr_info->IndexBW40_Base[path][group]);
138*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "\n");
139*4882a593Smuzhiyun 	}
140*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "\n");
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "OFDM diff:\n");
143*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "%4s ", "");
144*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++)
145*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "%dT ", path + 1);
146*4882a593Smuzhiyun 	_RTW_PRINT_SEL(sel, "\n");
147*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
148*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
149*4882a593Smuzhiyun 		for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
150*4882a593Smuzhiyun 			_RTW_PRINT_SEL(sel, "%2d ", txpwr_info->OFDM_Diff[path][tx_idx]);
151*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "\n");
152*4882a593Smuzhiyun 	}
153*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "\n");
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "BW20 diff:\n");
156*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "%4s ", "");
157*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++)
158*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "%dS ", path + 1);
159*4882a593Smuzhiyun 	_RTW_PRINT_SEL(sel, "\n");
160*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
161*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
162*4882a593Smuzhiyun 		for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
163*4882a593Smuzhiyun 			_RTW_PRINT_SEL(sel, "%2d ", txpwr_info->BW20_Diff[path][tx_idx]);
164*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "\n");
165*4882a593Smuzhiyun 	}
166*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "\n");
167*4882a593Smuzhiyun 
168*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "BW40 diff:\n");
169*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "%4s ", "");
170*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++)
171*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "%dS ", path + 1);
172*4882a593Smuzhiyun 	_RTW_PRINT_SEL(sel, "\n");
173*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
174*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
175*4882a593Smuzhiyun 		for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
176*4882a593Smuzhiyun 			_RTW_PRINT_SEL(sel, "%2d ", txpwr_info->BW40_Diff[path][tx_idx]);
177*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "\n");
178*4882a593Smuzhiyun 	}
179*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "\n");
180*4882a593Smuzhiyun }
181*4882a593Smuzhiyun 
dump_pg_txpwr_info_5g(void * sel,TxPowerInfo5G * txpwr_info,u8 rfpath_num,u8 max_tx_cnt)182*4882a593Smuzhiyun static void dump_pg_txpwr_info_5g(void *sel, TxPowerInfo5G *txpwr_info, u8 rfpath_num, u8 max_tx_cnt)
183*4882a593Smuzhiyun {
184*4882a593Smuzhiyun 	int path, group, tx_idx;
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "5G\n");
187*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "BW40-1S base:\n");
188*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "%4s ", "");
189*4882a593Smuzhiyun 	for (group = 0; group < MAX_CHNL_GROUP_5G; group++)
190*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "G%02d ", group);
191*4882a593Smuzhiyun 	_RTW_PRINT_SEL(sel, "\n");
192*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
193*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
194*4882a593Smuzhiyun 		for (group = 0; group < MAX_CHNL_GROUP_5G; group++)
195*4882a593Smuzhiyun 			_RTW_PRINT_SEL(sel, "%3u ", txpwr_info->IndexBW40_Base[path][group]);
196*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "\n");
197*4882a593Smuzhiyun 	}
198*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "\n");
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "OFDM diff:\n");
201*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "%4s ", "");
202*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++)
203*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "%dT ", path + 1);
204*4882a593Smuzhiyun 	_RTW_PRINT_SEL(sel, "\n");
205*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
206*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
207*4882a593Smuzhiyun 		for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
208*4882a593Smuzhiyun 			_RTW_PRINT_SEL(sel, "%2d ", txpwr_info->OFDM_Diff[path][tx_idx]);
209*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "\n");
210*4882a593Smuzhiyun 	}
211*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "\n");
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "BW20 diff:\n");
214*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "%4s ", "");
215*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++)
216*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "%dS ", path + 1);
217*4882a593Smuzhiyun 	_RTW_PRINT_SEL(sel, "\n");
218*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
219*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
220*4882a593Smuzhiyun 		for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
221*4882a593Smuzhiyun 			_RTW_PRINT_SEL(sel, "%2d ", txpwr_info->BW20_Diff[path][tx_idx]);
222*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "\n");
223*4882a593Smuzhiyun 	}
224*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "\n");
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "BW40 diff:\n");
227*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "%4s ", "");
228*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++)
229*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "%dS ", path + 1);
230*4882a593Smuzhiyun 	_RTW_PRINT_SEL(sel, "\n");
231*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
232*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
233*4882a593Smuzhiyun 		for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
234*4882a593Smuzhiyun 			_RTW_PRINT_SEL(sel, "%2d ", txpwr_info->BW40_Diff[path][tx_idx]);
235*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "\n");
236*4882a593Smuzhiyun 	}
237*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "\n");
238*4882a593Smuzhiyun 
239*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "BW80 diff:\n");
240*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "%4s ", "");
241*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++)
242*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "%dS ", path + 1);
243*4882a593Smuzhiyun 	_RTW_PRINT_SEL(sel, "\n");
244*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
245*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
246*4882a593Smuzhiyun 		for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
247*4882a593Smuzhiyun 			_RTW_PRINT_SEL(sel, "%2d ", txpwr_info->BW80_Diff[path][tx_idx]);
248*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "\n");
249*4882a593Smuzhiyun 	}
250*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "\n");
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "BW160 diff:\n");
253*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "%4s ", "");
254*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++)
255*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "%dS ", path + 1);
256*4882a593Smuzhiyun 	_RTW_PRINT_SEL(sel, "\n");
257*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
258*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
259*4882a593Smuzhiyun 		for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
260*4882a593Smuzhiyun 			_RTW_PRINT_SEL(sel, "%2d ", txpwr_info->BW160_Diff[path][tx_idx]);
261*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "\n");
262*4882a593Smuzhiyun 	}
263*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "\n");
264*4882a593Smuzhiyun }
265*4882a593Smuzhiyun #endif /* DBG_PG_TXPWR_READ */
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun const struct map_t pg_txpwr_def_info =
268*4882a593Smuzhiyun 	MAP_ENT(0xB8, 1, 0xFF
269*4882a593Smuzhiyun 		, MAPSEG_ARRAY_ENT(0x10, 168,
270*4882a593Smuzhiyun 			0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x24, 0xEE, 0xEE, 0xEE, 0xEE,
271*4882a593Smuzhiyun 			0xEE, 0xEE, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
272*4882a593Smuzhiyun 			0x04, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
273*4882a593Smuzhiyun 			0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x24, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0x2A, 0x2A, 0x2A, 0x2A,
274*4882a593Smuzhiyun 			0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x04, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
275*4882a593Smuzhiyun 			0xEE, 0xEE, 0xEE, 0xEE, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x24,
276*4882a593Smuzhiyun 			0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
277*4882a593Smuzhiyun 			0x2A, 0x2A, 0x2A, 0x2A, 0x04, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0x2D, 0x2D,
278*4882a593Smuzhiyun 			0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x24, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
279*4882a593Smuzhiyun 			0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x04, 0xEE,
280*4882a593Smuzhiyun 			0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE)
281*4882a593Smuzhiyun 	);
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun #ifdef CONFIG_RTL8188E
284*4882a593Smuzhiyun static const struct map_t rtl8188e_pg_txpwr_def_info =
285*4882a593Smuzhiyun 	MAP_ENT(0xB8, 1, 0xFF
286*4882a593Smuzhiyun 		, MAPSEG_ARRAY_ENT(0x10, 12,
287*4882a593Smuzhiyun 			0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x24)
288*4882a593Smuzhiyun 	);
289*4882a593Smuzhiyun #endif
290*4882a593Smuzhiyun 
291*4882a593Smuzhiyun #ifdef CONFIG_RTL8188F
292*4882a593Smuzhiyun static const struct map_t rtl8188f_pg_txpwr_def_info =
293*4882a593Smuzhiyun 	MAP_ENT(0xB8, 1, 0xFF
294*4882a593Smuzhiyun 		, MAPSEG_ARRAY_ENT(0x10, 12,
295*4882a593Smuzhiyun 			0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x27, 0x27, 0x27, 0x27, 0x27, 0x24)
296*4882a593Smuzhiyun 	);
297*4882a593Smuzhiyun #endif
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun #ifdef CONFIG_RTL8188GTV
300*4882a593Smuzhiyun static const struct map_t rtl8188gtv_pg_txpwr_def_info =
301*4882a593Smuzhiyun 	MAP_ENT(0xB8, 1, 0xFF
302*4882a593Smuzhiyun 		, MAPSEG_ARRAY_ENT(0x10, 12,
303*4882a593Smuzhiyun 			0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x27, 0x27, 0x27, 0x27, 0x27, 0x24)
304*4882a593Smuzhiyun 	);
305*4882a593Smuzhiyun #endif
306*4882a593Smuzhiyun 
307*4882a593Smuzhiyun #ifdef CONFIG_RTL8723B
308*4882a593Smuzhiyun static const struct map_t rtl8723b_pg_txpwr_def_info =
309*4882a593Smuzhiyun 	MAP_ENT(0xB8, 2, 0xFF
310*4882a593Smuzhiyun 		, MAPSEG_ARRAY_ENT(0x10, 12,
311*4882a593Smuzhiyun 			0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0xE0)
312*4882a593Smuzhiyun 		, MAPSEG_ARRAY_ENT(0x3A, 12,
313*4882a593Smuzhiyun 			0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0xE0)
314*4882a593Smuzhiyun 	);
315*4882a593Smuzhiyun #endif
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun #ifdef CONFIG_RTL8703B
318*4882a593Smuzhiyun static const struct map_t rtl8703b_pg_txpwr_def_info =
319*4882a593Smuzhiyun 	MAP_ENT(0xB8, 1, 0xFF
320*4882a593Smuzhiyun 		, MAPSEG_ARRAY_ENT(0x10, 12,
321*4882a593Smuzhiyun 			0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02)
322*4882a593Smuzhiyun 	);
323*4882a593Smuzhiyun #endif
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun #ifdef CONFIG_RTL8723D
326*4882a593Smuzhiyun static const struct map_t rtl8723d_pg_txpwr_def_info =
327*4882a593Smuzhiyun 	MAP_ENT(0xB8, 2, 0xFF
328*4882a593Smuzhiyun 		, MAPSEG_ARRAY_ENT(0x10, 12,
329*4882a593Smuzhiyun 			0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02)
330*4882a593Smuzhiyun 		, MAPSEG_ARRAY_ENT(0x3A, 12,
331*4882a593Smuzhiyun 			0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x02)
332*4882a593Smuzhiyun 	);
333*4882a593Smuzhiyun #endif
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun #ifdef CONFIG_RTL8192E
336*4882a593Smuzhiyun static const struct map_t rtl8192e_pg_txpwr_def_info =
337*4882a593Smuzhiyun 	MAP_ENT(0xB8, 2, 0xFF
338*4882a593Smuzhiyun 		, MAPSEG_ARRAY_ENT(0x10, 14,
339*4882a593Smuzhiyun 			0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x24, 0xEE, 0xEE)
340*4882a593Smuzhiyun 		, MAPSEG_ARRAY_ENT(0x3A, 14,
341*4882a593Smuzhiyun 			0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x24, 0xEE, 0xEE)
342*4882a593Smuzhiyun 	);
343*4882a593Smuzhiyun #endif
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun #ifdef CONFIG_RTL8821A
346*4882a593Smuzhiyun static const struct map_t rtl8821a_pg_txpwr_def_info =
347*4882a593Smuzhiyun 	MAP_ENT(0xB8, 1, 0xFF
348*4882a593Smuzhiyun 		, MAPSEG_ARRAY_ENT(0x10, 39,
349*4882a593Smuzhiyun 			0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x24, 0xFF, 0xFF, 0xFF, 0xFF,
350*4882a593Smuzhiyun 			0xFF, 0xFF, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
351*4882a593Smuzhiyun 			0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00)
352*4882a593Smuzhiyun 	);
353*4882a593Smuzhiyun #endif
354*4882a593Smuzhiyun 
355*4882a593Smuzhiyun #ifdef CONFIG_RTL8821C
356*4882a593Smuzhiyun static const struct map_t rtl8821c_pg_txpwr_def_info =
357*4882a593Smuzhiyun 	MAP_ENT(0xB8, 1, 0xFF
358*4882a593Smuzhiyun 		, MAPSEG_ARRAY_ENT(0x10, 54,
359*4882a593Smuzhiyun 			0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02, 0xFF, 0xFF, 0xFF, 0xFF,
360*4882a593Smuzhiyun 			0xFF, 0xFF, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
361*4882a593Smuzhiyun 			0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0xFF, 0xFF, 0xFF, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
362*4882a593Smuzhiyun 			0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02)
363*4882a593Smuzhiyun 	);
364*4882a593Smuzhiyun #endif
365*4882a593Smuzhiyun 
366*4882a593Smuzhiyun #ifdef CONFIG_RTL8710B
367*4882a593Smuzhiyun static const struct map_t rtl8710b_pg_txpwr_def_info =
368*4882a593Smuzhiyun 	MAP_ENT(0xC8, 1, 0xFF
369*4882a593Smuzhiyun 		, MAPSEG_ARRAY_ENT(0x20, 12,
370*4882a593Smuzhiyun 			0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x20)
371*4882a593Smuzhiyun 	);
372*4882a593Smuzhiyun #endif
373*4882a593Smuzhiyun 
374*4882a593Smuzhiyun #ifdef CONFIG_RTL8812A
375*4882a593Smuzhiyun static const struct map_t rtl8812a_pg_txpwr_def_info =
376*4882a593Smuzhiyun 	MAP_ENT(0xB8, 1, 0xFF
377*4882a593Smuzhiyun 		, MAPSEG_ARRAY_ENT(0x10, 82,
378*4882a593Smuzhiyun 			0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02, 0xEE, 0xEE, 0xFF, 0xFF,
379*4882a593Smuzhiyun 			0xFF, 0xFF, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
380*4882a593Smuzhiyun 			0x02, 0xEE, 0xFF, 0xFF, 0xEE, 0xFF, 0x00, 0xEE, 0xFF, 0xFF, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
381*4882a593Smuzhiyun 			0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02, 0xEE, 0xEE, 0xFF, 0xFF, 0xFF, 0xFF, 0x2A, 0x2A, 0x2A, 0x2A,
382*4882a593Smuzhiyun 			0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x02, 0xEE, 0xFF, 0xFF, 0xEE, 0xFF,
383*4882a593Smuzhiyun 			0x00, 0xEE)
384*4882a593Smuzhiyun 	);
385*4882a593Smuzhiyun #endif
386*4882a593Smuzhiyun 
387*4882a593Smuzhiyun #ifdef CONFIG_RTL8822B
388*4882a593Smuzhiyun static const struct map_t rtl8822b_pg_txpwr_def_info =
389*4882a593Smuzhiyun 	MAP_ENT(0xB8, 1, 0xFF
390*4882a593Smuzhiyun 		, MAPSEG_ARRAY_ENT(0x10, 82,
391*4882a593Smuzhiyun 			0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02, 0xEE, 0xEE, 0xFF, 0xFF,
392*4882a593Smuzhiyun 			0xFF, 0xFF, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
393*4882a593Smuzhiyun 			0x02, 0xEE, 0xFF, 0xFF, 0xEE, 0xFF, 0xEC, 0xEC, 0xFF, 0xFF, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
394*4882a593Smuzhiyun 			0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02, 0xEE, 0xEE, 0xFF, 0xFF, 0xFF, 0xFF, 0x2A, 0x2A, 0x2A, 0x2A,
395*4882a593Smuzhiyun 			0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x02, 0xEE, 0xFF, 0xFF, 0xEE, 0xFF,
396*4882a593Smuzhiyun 			0xEC, 0xEC)
397*4882a593Smuzhiyun 	);
398*4882a593Smuzhiyun #endif
399*4882a593Smuzhiyun 
400*4882a593Smuzhiyun #ifdef CONFIG_RTL8822C
401*4882a593Smuzhiyun static const struct map_t rtl8822c_pg_txpwr_def_info =
402*4882a593Smuzhiyun 	MAP_ENT(0xB8, 1, 0xFF
403*4882a593Smuzhiyun 		, MAPSEG_ARRAY_ENT(0x10, 82,
404*4882a593Smuzhiyun 			0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x02, 0x00, 0x00, 0xFF, 0xFF,
405*4882a593Smuzhiyun 			0xFF, 0xFF, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
406*4882a593Smuzhiyun 			0x02, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
407*4882a593Smuzhiyun 			0x33, 0x33, 0x33, 0x33, 0x33, 0x02, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x33, 0x33, 0x33, 0x33,
408*4882a593Smuzhiyun 			0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x02, 0x00, 0xFF, 0xFF, 0x00, 0xFF,
409*4882a593Smuzhiyun 			0x00, 0x00)
410*4882a593Smuzhiyun 	);
411*4882a593Smuzhiyun #endif
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun #ifdef CONFIG_RTL8814A
414*4882a593Smuzhiyun static const struct map_t rtl8814a_pg_txpwr_def_info =
415*4882a593Smuzhiyun 	MAP_ENT(0xB8, 1, 0xFF
416*4882a593Smuzhiyun 		, MAPSEG_ARRAY_ENT(0x10, 168,
417*4882a593Smuzhiyun 			0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02, 0xEE, 0xEE, 0xEE, 0xEE,
418*4882a593Smuzhiyun 			0xEE, 0xEE, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
419*4882a593Smuzhiyun 			0x02, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0x00, 0xEE, 0xEE, 0xEE, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
420*4882a593Smuzhiyun 			0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0x2A, 0x2A, 0x2A, 0x2A,
421*4882a593Smuzhiyun 			0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x02, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
422*4882a593Smuzhiyun 			0x00, 0xEE, 0xEE, 0xEE, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02,
423*4882a593Smuzhiyun 			0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
424*4882a593Smuzhiyun 			0x2A, 0x2A, 0x2A, 0x2A, 0x02, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0x00, 0xEE, 0xEE, 0xEE, 0x2D, 0x2D,
425*4882a593Smuzhiyun 			0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
426*4882a593Smuzhiyun 			0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x02, 0xEE,
427*4882a593Smuzhiyun 			0xEE, 0xEE, 0xEE, 0xEE, 0x00, 0xEE, 0xEE, 0xEE)
428*4882a593Smuzhiyun 	);
429*4882a593Smuzhiyun #endif
430*4882a593Smuzhiyun 
431*4882a593Smuzhiyun #ifdef CONFIG_RTL8192F/*use 8192F default,no document*/
432*4882a593Smuzhiyun static const struct map_t rtl8192f_pg_txpwr_def_info =
433*4882a593Smuzhiyun 	MAP_ENT(0xB8, 2, 0xFF
434*4882a593Smuzhiyun 		, MAPSEG_ARRAY_ENT(0x10, 14,
435*4882a593Smuzhiyun 			0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x24, 0xEE, 0xEE)
436*4882a593Smuzhiyun 		, MAPSEG_ARRAY_ENT(0x3A, 14,
437*4882a593Smuzhiyun 			0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x24, 0xEE, 0xEE)
438*4882a593Smuzhiyun 	);
439*4882a593Smuzhiyun #endif
440*4882a593Smuzhiyun 
441*4882a593Smuzhiyun #ifdef CONFIG_RTL8814B
442*4882a593Smuzhiyun static const struct map_t rtl8814b_pg_txpwr_def_info =
443*4882a593Smuzhiyun 	MAP_ENT(0xB8, 1, 0xFF
444*4882a593Smuzhiyun 		, MAPSEG_ARRAY_ENT(0x10, 168,
445*4882a593Smuzhiyun 			0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x02, 0xFF, 0xFF, 0xFF, 0xFF,
446*4882a593Smuzhiyun 			0xFF, 0xFF, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
447*4882a593Smuzhiyun 			0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0xFF, 0xFF, 0xFF, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
448*4882a593Smuzhiyun 			0x28, 0x28, 0x28, 0x28, 0x28, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
449*4882a593Smuzhiyun 			0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
450*4882a593Smuzhiyun 			0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
451*4882a593Smuzhiyun 			0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
452*4882a593Smuzhiyun 			0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
453*4882a593Smuzhiyun 			0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
454*4882a593Smuzhiyun 			0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
455*4882a593Smuzhiyun 			0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)
456*4882a593Smuzhiyun 	);
457*4882a593Smuzhiyun #endif
458*4882a593Smuzhiyun 
hal_pg_txpwr_def_info(_adapter * adapter)459*4882a593Smuzhiyun const struct map_t *hal_pg_txpwr_def_info(_adapter *adapter)
460*4882a593Smuzhiyun {
461*4882a593Smuzhiyun 	u8 interface_type = 0;
462*4882a593Smuzhiyun 	const struct map_t *map = NULL;
463*4882a593Smuzhiyun 
464*4882a593Smuzhiyun 	interface_type = rtw_get_intf_type(adapter);
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun 	switch (rtw_get_chip_type(adapter)) {
467*4882a593Smuzhiyun #ifdef CONFIG_RTL8723B
468*4882a593Smuzhiyun 	case RTL8723B:
469*4882a593Smuzhiyun 		map = &rtl8723b_pg_txpwr_def_info;
470*4882a593Smuzhiyun 		break;
471*4882a593Smuzhiyun #endif
472*4882a593Smuzhiyun #ifdef CONFIG_RTL8703B
473*4882a593Smuzhiyun 	case RTL8703B:
474*4882a593Smuzhiyun 		map = &rtl8703b_pg_txpwr_def_info;
475*4882a593Smuzhiyun 		break;
476*4882a593Smuzhiyun #endif
477*4882a593Smuzhiyun #ifdef CONFIG_RTL8723D
478*4882a593Smuzhiyun 	case RTL8723D:
479*4882a593Smuzhiyun 		map = &rtl8723d_pg_txpwr_def_info;
480*4882a593Smuzhiyun 		break;
481*4882a593Smuzhiyun #endif
482*4882a593Smuzhiyun #ifdef CONFIG_RTL8188E
483*4882a593Smuzhiyun 	case RTL8188E:
484*4882a593Smuzhiyun 		map = &rtl8188e_pg_txpwr_def_info;
485*4882a593Smuzhiyun 		break;
486*4882a593Smuzhiyun #endif
487*4882a593Smuzhiyun #ifdef CONFIG_RTL8188F
488*4882a593Smuzhiyun 	case RTL8188F:
489*4882a593Smuzhiyun 		map = &rtl8188f_pg_txpwr_def_info;
490*4882a593Smuzhiyun 		break;
491*4882a593Smuzhiyun #endif
492*4882a593Smuzhiyun #ifdef CONFIG_RTL8188GTV
493*4882a593Smuzhiyun 	case RTL8188GTV:
494*4882a593Smuzhiyun 		map = &rtl8188gtv_pg_txpwr_def_info;
495*4882a593Smuzhiyun 		break;
496*4882a593Smuzhiyun #endif
497*4882a593Smuzhiyun #ifdef CONFIG_RTL8812A
498*4882a593Smuzhiyun 	case RTL8812:
499*4882a593Smuzhiyun 		map = &rtl8812a_pg_txpwr_def_info;
500*4882a593Smuzhiyun 		break;
501*4882a593Smuzhiyun #endif
502*4882a593Smuzhiyun #ifdef CONFIG_RTL8821A
503*4882a593Smuzhiyun 	case RTL8821:
504*4882a593Smuzhiyun 		map = &rtl8821a_pg_txpwr_def_info;
505*4882a593Smuzhiyun 		break;
506*4882a593Smuzhiyun #endif
507*4882a593Smuzhiyun #ifdef CONFIG_RTL8192E
508*4882a593Smuzhiyun 	case RTL8192E:
509*4882a593Smuzhiyun 		map = &rtl8192e_pg_txpwr_def_info;
510*4882a593Smuzhiyun 		break;
511*4882a593Smuzhiyun #endif
512*4882a593Smuzhiyun #ifdef CONFIG_RTL8814A
513*4882a593Smuzhiyun 	case RTL8814A:
514*4882a593Smuzhiyun 		map = &rtl8814a_pg_txpwr_def_info;
515*4882a593Smuzhiyun 		break;
516*4882a593Smuzhiyun #endif
517*4882a593Smuzhiyun #ifdef CONFIG_RTL8822B
518*4882a593Smuzhiyun 	case RTL8822B:
519*4882a593Smuzhiyun 		map = &rtl8822b_pg_txpwr_def_info;
520*4882a593Smuzhiyun 		break;
521*4882a593Smuzhiyun #endif
522*4882a593Smuzhiyun #ifdef CONFIG_RTL8821C
523*4882a593Smuzhiyun 	case RTL8821C:
524*4882a593Smuzhiyun 		map = &rtl8821c_pg_txpwr_def_info;
525*4882a593Smuzhiyun 		break;
526*4882a593Smuzhiyun #endif
527*4882a593Smuzhiyun #ifdef CONFIG_RTL8710B
528*4882a593Smuzhiyun 	case RTL8710B:
529*4882a593Smuzhiyun 		map = &rtl8710b_pg_txpwr_def_info;
530*4882a593Smuzhiyun 		break;
531*4882a593Smuzhiyun #endif
532*4882a593Smuzhiyun #ifdef CONFIG_RTL8192F
533*4882a593Smuzhiyun 	case RTL8192F:
534*4882a593Smuzhiyun 		map = &rtl8192f_pg_txpwr_def_info;
535*4882a593Smuzhiyun 		break;
536*4882a593Smuzhiyun #endif
537*4882a593Smuzhiyun #ifdef CONFIG_RTL8822C
538*4882a593Smuzhiyun 	case RTL8822C:
539*4882a593Smuzhiyun 		map = &rtl8822c_pg_txpwr_def_info;
540*4882a593Smuzhiyun 		break;
541*4882a593Smuzhiyun #endif
542*4882a593Smuzhiyun #ifdef CONFIG_RTL8814B
543*4882a593Smuzhiyun 	case RTL8814B:
544*4882a593Smuzhiyun 		map = &rtl8814b_pg_txpwr_def_info;
545*4882a593Smuzhiyun 		break;
546*4882a593Smuzhiyun #endif
547*4882a593Smuzhiyun 	}
548*4882a593Smuzhiyun 
549*4882a593Smuzhiyun 	if (map == NULL) {
550*4882a593Smuzhiyun 		RTW_ERR("%s: unknown chip_type:%u\n"
551*4882a593Smuzhiyun 			, __func__, rtw_get_chip_type(adapter));
552*4882a593Smuzhiyun 		rtw_warn_on(1);
553*4882a593Smuzhiyun 	}
554*4882a593Smuzhiyun 
555*4882a593Smuzhiyun 	return map;
556*4882a593Smuzhiyun }
557*4882a593Smuzhiyun 
hal_chk_pg_txpwr_info_2g(_adapter * adapter,TxPowerInfo24G * pwr_info)558*4882a593Smuzhiyun static u8 hal_chk_pg_txpwr_info_2g(_adapter *adapter, TxPowerInfo24G *pwr_info)
559*4882a593Smuzhiyun {
560*4882a593Smuzhiyun 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
561*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
562*4882a593Smuzhiyun 	u8 path, group, tx_idx;
563*4882a593Smuzhiyun 
564*4882a593Smuzhiyun 	if (pwr_info == NULL || !hal_chk_band_cap(adapter, BAND_CAP_2G))
565*4882a593Smuzhiyun 		return _SUCCESS;
566*4882a593Smuzhiyun 
567*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH; path++) {
568*4882a593Smuzhiyun 		if (!HAL_SPEC_CHK_RF_PATH_2G(hal_spec, path))
569*4882a593Smuzhiyun 			continue;
570*4882a593Smuzhiyun 		for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
571*4882a593Smuzhiyun 			if (IS_PG_TXPWR_BASE_INVALID(hal_spec, pwr_info->IndexCCK_Base[path][group])
572*4882a593Smuzhiyun 				|| IS_PG_TXPWR_BASE_INVALID(hal_spec, pwr_info->IndexBW40_Base[path][group]))
573*4882a593Smuzhiyun 				return _FAIL;
574*4882a593Smuzhiyun 		}
575*4882a593Smuzhiyun 		for (tx_idx = 0; tx_idx < MAX_TX_COUNT; tx_idx++) {
576*4882a593Smuzhiyun 			if (tx_idx + 1 > hal_data->max_tx_cnt)
577*4882a593Smuzhiyun 				continue;
578*4882a593Smuzhiyun 			if (IS_PG_TXPWR_DIFF_INVALID(pwr_info->CCK_Diff[path][tx_idx])
579*4882a593Smuzhiyun 				|| IS_PG_TXPWR_DIFF_INVALID(pwr_info->OFDM_Diff[path][tx_idx])
580*4882a593Smuzhiyun 				|| IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW20_Diff[path][tx_idx])
581*4882a593Smuzhiyun 				|| IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW40_Diff[path][tx_idx]))
582*4882a593Smuzhiyun 				return _FAIL;
583*4882a593Smuzhiyun 		}
584*4882a593Smuzhiyun 	}
585*4882a593Smuzhiyun 
586*4882a593Smuzhiyun 	return _SUCCESS;
587*4882a593Smuzhiyun }
588*4882a593Smuzhiyun 
hal_chk_pg_txpwr_info_5g(_adapter * adapter,TxPowerInfo5G * pwr_info)589*4882a593Smuzhiyun static u8 hal_chk_pg_txpwr_info_5g(_adapter *adapter, TxPowerInfo5G *pwr_info)
590*4882a593Smuzhiyun {
591*4882a593Smuzhiyun #if CONFIG_IEEE80211_BAND_5GHZ
592*4882a593Smuzhiyun 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
593*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
594*4882a593Smuzhiyun 	u8 path, group, tx_idx;
595*4882a593Smuzhiyun 
596*4882a593Smuzhiyun 	if (pwr_info == NULL || !hal_chk_band_cap(adapter, BAND_CAP_5G))
597*4882a593Smuzhiyun 		return _SUCCESS;
598*4882a593Smuzhiyun 
599*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH; path++) {
600*4882a593Smuzhiyun 		if (!HAL_SPEC_CHK_RF_PATH_5G(hal_spec, path))
601*4882a593Smuzhiyun 			continue;
602*4882a593Smuzhiyun 		for (group = 0; group < MAX_CHNL_GROUP_5G; group++)
603*4882a593Smuzhiyun 			if (IS_PG_TXPWR_BASE_INVALID(hal_spec, pwr_info->IndexBW40_Base[path][group]))
604*4882a593Smuzhiyun 				return _FAIL;
605*4882a593Smuzhiyun 		for (tx_idx = 0; tx_idx < MAX_TX_COUNT; tx_idx++) {
606*4882a593Smuzhiyun 			if (tx_idx + 1 > hal_data->max_tx_cnt)
607*4882a593Smuzhiyun 				continue;
608*4882a593Smuzhiyun 			if (IS_PG_TXPWR_DIFF_INVALID(pwr_info->OFDM_Diff[path][tx_idx])
609*4882a593Smuzhiyun 				|| IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW20_Diff[path][tx_idx])
610*4882a593Smuzhiyun 				|| IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW40_Diff[path][tx_idx])
611*4882a593Smuzhiyun 				|| IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW80_Diff[path][tx_idx])
612*4882a593Smuzhiyun 				|| IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW160_Diff[path][tx_idx]))
613*4882a593Smuzhiyun 				return _FAIL;
614*4882a593Smuzhiyun 		}
615*4882a593Smuzhiyun 	}
616*4882a593Smuzhiyun #endif /* CONFIG_IEEE80211_BAND_5GHZ */
617*4882a593Smuzhiyun 	return _SUCCESS;
618*4882a593Smuzhiyun }
619*4882a593Smuzhiyun 
hal_init_pg_txpwr_info_2g(_adapter * adapter,TxPowerInfo24G * pwr_info)620*4882a593Smuzhiyun static inline void hal_init_pg_txpwr_info_2g(_adapter *adapter, TxPowerInfo24G *pwr_info)
621*4882a593Smuzhiyun {
622*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
623*4882a593Smuzhiyun 	u8 path, group, tx_idx;
624*4882a593Smuzhiyun 
625*4882a593Smuzhiyun 	if (pwr_info == NULL)
626*4882a593Smuzhiyun 		return;
627*4882a593Smuzhiyun 
628*4882a593Smuzhiyun 	_rtw_memset(pwr_info, 0, sizeof(TxPowerInfo24G));
629*4882a593Smuzhiyun 
630*4882a593Smuzhiyun 	/* init with invalid value */
631*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH; path++) {
632*4882a593Smuzhiyun 		for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
633*4882a593Smuzhiyun 			pwr_info->IndexCCK_Base[path][group] = PG_TXPWR_INVALID_BASE;
634*4882a593Smuzhiyun 			pwr_info->IndexBW40_Base[path][group] = PG_TXPWR_INVALID_BASE;
635*4882a593Smuzhiyun 		}
636*4882a593Smuzhiyun 		for (tx_idx = 0; tx_idx < MAX_TX_COUNT; tx_idx++) {
637*4882a593Smuzhiyun 			pwr_info->CCK_Diff[path][tx_idx] = PG_TXPWR_INVALID_DIFF;
638*4882a593Smuzhiyun 			pwr_info->OFDM_Diff[path][tx_idx] = PG_TXPWR_INVALID_DIFF;
639*4882a593Smuzhiyun 			pwr_info->BW20_Diff[path][tx_idx] = PG_TXPWR_INVALID_DIFF;
640*4882a593Smuzhiyun 			pwr_info->BW40_Diff[path][tx_idx] = PG_TXPWR_INVALID_DIFF;
641*4882a593Smuzhiyun 		}
642*4882a593Smuzhiyun 	}
643*4882a593Smuzhiyun 
644*4882a593Smuzhiyun 	/* init for dummy base and diff */
645*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH; path++) {
646*4882a593Smuzhiyun 		if (!HAL_SPEC_CHK_RF_PATH_2G(hal_spec, path))
647*4882a593Smuzhiyun 			break;
648*4882a593Smuzhiyun 		/* 2.4G BW40 base has 1 less group than CCK base*/
649*4882a593Smuzhiyun 		pwr_info->IndexBW40_Base[path][MAX_CHNL_GROUP_24G - 1] = 0;
650*4882a593Smuzhiyun 
651*4882a593Smuzhiyun 		/* dummy diff */
652*4882a593Smuzhiyun 		pwr_info->CCK_Diff[path][0] = 0; /* 2.4G CCK-1TX */
653*4882a593Smuzhiyun 		pwr_info->BW40_Diff[path][0] = 0; /* 2.4G BW40-1S */
654*4882a593Smuzhiyun 	}
655*4882a593Smuzhiyun }
656*4882a593Smuzhiyun 
hal_init_pg_txpwr_info_5g(_adapter * adapter,TxPowerInfo5G * pwr_info)657*4882a593Smuzhiyun static inline void hal_init_pg_txpwr_info_5g(_adapter *adapter, TxPowerInfo5G *pwr_info)
658*4882a593Smuzhiyun {
659*4882a593Smuzhiyun #if CONFIG_IEEE80211_BAND_5GHZ
660*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
661*4882a593Smuzhiyun 	u8 path, group, tx_idx;
662*4882a593Smuzhiyun 
663*4882a593Smuzhiyun 	if (pwr_info == NULL)
664*4882a593Smuzhiyun 		return;
665*4882a593Smuzhiyun 
666*4882a593Smuzhiyun 	_rtw_memset(pwr_info, 0, sizeof(TxPowerInfo5G));
667*4882a593Smuzhiyun 
668*4882a593Smuzhiyun 	/* init with invalid value */
669*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH; path++) {
670*4882a593Smuzhiyun 		for (group = 0; group < MAX_CHNL_GROUP_5G; group++)
671*4882a593Smuzhiyun 			pwr_info->IndexBW40_Base[path][group] = PG_TXPWR_INVALID_BASE;
672*4882a593Smuzhiyun 		for (tx_idx = 0; tx_idx < MAX_TX_COUNT; tx_idx++) {
673*4882a593Smuzhiyun 			pwr_info->OFDM_Diff[path][tx_idx] = PG_TXPWR_INVALID_DIFF;
674*4882a593Smuzhiyun 			pwr_info->BW20_Diff[path][tx_idx] = PG_TXPWR_INVALID_DIFF;
675*4882a593Smuzhiyun 			pwr_info->BW40_Diff[path][tx_idx] = PG_TXPWR_INVALID_DIFF;
676*4882a593Smuzhiyun 			pwr_info->BW80_Diff[path][tx_idx] = PG_TXPWR_INVALID_DIFF;
677*4882a593Smuzhiyun 			pwr_info->BW160_Diff[path][tx_idx] = PG_TXPWR_INVALID_DIFF;
678*4882a593Smuzhiyun 		}
679*4882a593Smuzhiyun 	}
680*4882a593Smuzhiyun 
681*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH; path++) {
682*4882a593Smuzhiyun 		if (!HAL_SPEC_CHK_RF_PATH_5G(hal_spec, path))
683*4882a593Smuzhiyun 			break;
684*4882a593Smuzhiyun 		/* dummy diff */
685*4882a593Smuzhiyun 		pwr_info->BW40_Diff[path][0] = 0; /* 5G BW40-1S */
686*4882a593Smuzhiyun 	}
687*4882a593Smuzhiyun #endif /* CONFIG_IEEE80211_BAND_5GHZ */
688*4882a593Smuzhiyun }
689*4882a593Smuzhiyun 
690*4882a593Smuzhiyun #if DBG_PG_TXPWR_READ
691*4882a593Smuzhiyun #define LOAD_PG_TXPWR_WARN_COND(_txpwr_src) 1
692*4882a593Smuzhiyun #else
693*4882a593Smuzhiyun #define LOAD_PG_TXPWR_WARN_COND(_txpwr_src) (_txpwr_src > PG_TXPWR_SRC_PG_DATA)
694*4882a593Smuzhiyun #endif
695*4882a593Smuzhiyun 
hal_load_pg_txpwr_info_path_2g(_adapter * adapter,TxPowerInfo24G * pwr_info,u32 path,u8 txpwr_src,const struct map_t * txpwr_map,u16 pg_offset)696*4882a593Smuzhiyun u16 hal_load_pg_txpwr_info_path_2g(
697*4882a593Smuzhiyun 	_adapter *adapter,
698*4882a593Smuzhiyun 	TxPowerInfo24G	*pwr_info,
699*4882a593Smuzhiyun 	u32 path,
700*4882a593Smuzhiyun 	u8 txpwr_src,
701*4882a593Smuzhiyun 	const struct map_t *txpwr_map,
702*4882a593Smuzhiyun 	u16 pg_offset)
703*4882a593Smuzhiyun {
704*4882a593Smuzhiyun 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
705*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
706*4882a593Smuzhiyun 	u16 offset = pg_offset;
707*4882a593Smuzhiyun 	u8 group, tx_idx;
708*4882a593Smuzhiyun 	u8 val;
709*4882a593Smuzhiyun 	u8 tmp_base;
710*4882a593Smuzhiyun 	s8 tmp_diff;
711*4882a593Smuzhiyun 
712*4882a593Smuzhiyun 	if (pwr_info == NULL || !hal_chk_band_cap(adapter, BAND_CAP_2G)) {
713*4882a593Smuzhiyun 		offset += PG_TXPWR_1PATH_BYTE_NUM_2G;
714*4882a593Smuzhiyun 		goto exit;
715*4882a593Smuzhiyun 	}
716*4882a593Smuzhiyun 
717*4882a593Smuzhiyun 	if (DBG_PG_TXPWR_READ)
718*4882a593Smuzhiyun 		RTW_INFO("%s [%c] offset:0x%03x\n", __func__, rf_path_char(path), offset);
719*4882a593Smuzhiyun 
720*4882a593Smuzhiyun 	for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
721*4882a593Smuzhiyun 		if (HAL_SPEC_CHK_RF_PATH_2G(hal_spec, path)) {
722*4882a593Smuzhiyun 			tmp_base = map_read8(txpwr_map, offset);
723*4882a593Smuzhiyun 			if (!IS_PG_TXPWR_BASE_INVALID(hal_spec, tmp_base)
724*4882a593Smuzhiyun 				&& IS_PG_TXPWR_BASE_INVALID(hal_spec, pwr_info->IndexCCK_Base[path][group])
725*4882a593Smuzhiyun 			) {
726*4882a593Smuzhiyun 				pwr_info->IndexCCK_Base[path][group] = tmp_base;
727*4882a593Smuzhiyun 				if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
728*4882a593Smuzhiyun 					RTW_INFO("[%c] 2G G%02d CCK-1T base:%u from %s\n", rf_path_char(path), group, tmp_base, pg_txpwr_src_str(txpwr_src));
729*4882a593Smuzhiyun 			}
730*4882a593Smuzhiyun 		}
731*4882a593Smuzhiyun 		offset++;
732*4882a593Smuzhiyun 	}
733*4882a593Smuzhiyun 
734*4882a593Smuzhiyun 	for (group = 0; group < MAX_CHNL_GROUP_24G - 1; group++) {
735*4882a593Smuzhiyun 		if (HAL_SPEC_CHK_RF_PATH_2G(hal_spec, path)) {
736*4882a593Smuzhiyun 			tmp_base = map_read8(txpwr_map, offset);
737*4882a593Smuzhiyun 			if (!IS_PG_TXPWR_BASE_INVALID(hal_spec, tmp_base)
738*4882a593Smuzhiyun 				&& IS_PG_TXPWR_BASE_INVALID(hal_spec, pwr_info->IndexBW40_Base[path][group])
739*4882a593Smuzhiyun 			) {
740*4882a593Smuzhiyun 				pwr_info->IndexBW40_Base[path][group] =	tmp_base;
741*4882a593Smuzhiyun 				if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
742*4882a593Smuzhiyun 					RTW_INFO("[%c] 2G G%02d BW40-1S base:%u from %s\n", rf_path_char(path), group, tmp_base, pg_txpwr_src_str(txpwr_src));
743*4882a593Smuzhiyun 			}
744*4882a593Smuzhiyun 		}
745*4882a593Smuzhiyun 		offset++;
746*4882a593Smuzhiyun 	}
747*4882a593Smuzhiyun 
748*4882a593Smuzhiyun 	for (tx_idx = 0; tx_idx < MAX_TX_COUNT; tx_idx++) {
749*4882a593Smuzhiyun 		if (tx_idx == 0) {
750*4882a593Smuzhiyun 			if (HAL_SPEC_CHK_RF_PATH_2G(hal_spec, path)) {
751*4882a593Smuzhiyun 				val = map_read8(txpwr_map, offset);
752*4882a593Smuzhiyun 				tmp_diff = PG_TXPWR_MSB_DIFF_TO_S8BIT(val);
753*4882a593Smuzhiyun 				if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
754*4882a593Smuzhiyun 					&& IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW20_Diff[path][tx_idx])
755*4882a593Smuzhiyun 				) {
756*4882a593Smuzhiyun 					pwr_info->BW20_Diff[path][tx_idx] = tmp_diff;
757*4882a593Smuzhiyun 					if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
758*4882a593Smuzhiyun 						RTW_INFO("[%c] 2G BW20-%dS diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
759*4882a593Smuzhiyun 				}
760*4882a593Smuzhiyun 				tmp_diff = PG_TXPWR_LSB_DIFF_TO_S8BIT(val);
761*4882a593Smuzhiyun 				if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
762*4882a593Smuzhiyun 					&& IS_PG_TXPWR_DIFF_INVALID(pwr_info->OFDM_Diff[path][tx_idx])
763*4882a593Smuzhiyun 				) {
764*4882a593Smuzhiyun 					pwr_info->OFDM_Diff[path][tx_idx] = tmp_diff;
765*4882a593Smuzhiyun 					if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
766*4882a593Smuzhiyun 						RTW_INFO("[%c] 2G OFDM-%dT diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
767*4882a593Smuzhiyun 				}
768*4882a593Smuzhiyun 			}
769*4882a593Smuzhiyun 			offset++;
770*4882a593Smuzhiyun 		} else {
771*4882a593Smuzhiyun 			if (HAL_SPEC_CHK_RF_PATH_2G(hal_spec, path) && tx_idx + 1 <= hal_data->max_tx_cnt) {
772*4882a593Smuzhiyun 				val = map_read8(txpwr_map, offset);
773*4882a593Smuzhiyun 				tmp_diff = PG_TXPWR_MSB_DIFF_TO_S8BIT(val);
774*4882a593Smuzhiyun 				if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
775*4882a593Smuzhiyun 					&& IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW40_Diff[path][tx_idx])
776*4882a593Smuzhiyun 				) {
777*4882a593Smuzhiyun 					pwr_info->BW40_Diff[path][tx_idx] = tmp_diff;
778*4882a593Smuzhiyun 					if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
779*4882a593Smuzhiyun 						RTW_INFO("[%c] 2G BW40-%dS diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
780*4882a593Smuzhiyun 
781*4882a593Smuzhiyun 				}
782*4882a593Smuzhiyun 				tmp_diff = PG_TXPWR_LSB_DIFF_TO_S8BIT(val);
783*4882a593Smuzhiyun 				if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
784*4882a593Smuzhiyun 					&& IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW20_Diff[path][tx_idx])
785*4882a593Smuzhiyun 				) {
786*4882a593Smuzhiyun 					pwr_info->BW20_Diff[path][tx_idx] = tmp_diff;
787*4882a593Smuzhiyun 					if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
788*4882a593Smuzhiyun 						RTW_INFO("[%c] 2G BW20-%dS diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
789*4882a593Smuzhiyun 				}
790*4882a593Smuzhiyun 			}
791*4882a593Smuzhiyun 			offset++;
792*4882a593Smuzhiyun 
793*4882a593Smuzhiyun 			if (HAL_SPEC_CHK_RF_PATH_2G(hal_spec, path) && tx_idx + 1 <= hal_data->max_tx_cnt) {
794*4882a593Smuzhiyun 				val = map_read8(txpwr_map, offset);
795*4882a593Smuzhiyun 				tmp_diff = PG_TXPWR_MSB_DIFF_TO_S8BIT(val);
796*4882a593Smuzhiyun 				if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
797*4882a593Smuzhiyun 					&& IS_PG_TXPWR_DIFF_INVALID(pwr_info->OFDM_Diff[path][tx_idx])
798*4882a593Smuzhiyun 				) {
799*4882a593Smuzhiyun 					pwr_info->OFDM_Diff[path][tx_idx] = tmp_diff;
800*4882a593Smuzhiyun 					if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
801*4882a593Smuzhiyun 						RTW_INFO("[%c] 2G OFDM-%dT diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
802*4882a593Smuzhiyun 				}
803*4882a593Smuzhiyun 				tmp_diff = PG_TXPWR_LSB_DIFF_TO_S8BIT(val);
804*4882a593Smuzhiyun 				if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
805*4882a593Smuzhiyun 					&& IS_PG_TXPWR_DIFF_INVALID(pwr_info->CCK_Diff[path][tx_idx])
806*4882a593Smuzhiyun 				) {
807*4882a593Smuzhiyun 					pwr_info->CCK_Diff[path][tx_idx] =	tmp_diff;
808*4882a593Smuzhiyun 					if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
809*4882a593Smuzhiyun 						RTW_INFO("[%c] 2G CCK-%dT diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
810*4882a593Smuzhiyun 				}
811*4882a593Smuzhiyun 			}
812*4882a593Smuzhiyun 			offset++;
813*4882a593Smuzhiyun 		}
814*4882a593Smuzhiyun 	}
815*4882a593Smuzhiyun 
816*4882a593Smuzhiyun 	if (offset != pg_offset + PG_TXPWR_1PATH_BYTE_NUM_2G) {
817*4882a593Smuzhiyun 		RTW_ERR("%s parse %d bytes != %d\n", __func__, offset - pg_offset, PG_TXPWR_1PATH_BYTE_NUM_2G);
818*4882a593Smuzhiyun 		rtw_warn_on(1);
819*4882a593Smuzhiyun 	}
820*4882a593Smuzhiyun 
821*4882a593Smuzhiyun exit:
822*4882a593Smuzhiyun 	return offset;
823*4882a593Smuzhiyun }
824*4882a593Smuzhiyun 
hal_load_pg_txpwr_info_path_5g(_adapter * adapter,TxPowerInfo5G * pwr_info,u32 path,u8 txpwr_src,const struct map_t * txpwr_map,u16 pg_offset)825*4882a593Smuzhiyun u16 hal_load_pg_txpwr_info_path_5g(
826*4882a593Smuzhiyun 	_adapter *adapter,
827*4882a593Smuzhiyun 	TxPowerInfo5G	*pwr_info,
828*4882a593Smuzhiyun 	u32 path,
829*4882a593Smuzhiyun 	u8 txpwr_src,
830*4882a593Smuzhiyun 	const struct map_t *txpwr_map,
831*4882a593Smuzhiyun 	u16 pg_offset)
832*4882a593Smuzhiyun {
833*4882a593Smuzhiyun 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
834*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
835*4882a593Smuzhiyun 	u16 offset = pg_offset;
836*4882a593Smuzhiyun 	u8 group, tx_idx;
837*4882a593Smuzhiyun 	u8 val;
838*4882a593Smuzhiyun 	u8 tmp_base;
839*4882a593Smuzhiyun 	s8 tmp_diff;
840*4882a593Smuzhiyun 
841*4882a593Smuzhiyun #if CONFIG_IEEE80211_BAND_5GHZ
842*4882a593Smuzhiyun 	if (pwr_info == NULL || !hal_chk_band_cap(adapter, BAND_CAP_5G))
843*4882a593Smuzhiyun #endif
844*4882a593Smuzhiyun 	{
845*4882a593Smuzhiyun 		offset += PG_TXPWR_1PATH_BYTE_NUM_5G;
846*4882a593Smuzhiyun 		goto exit;
847*4882a593Smuzhiyun 	}
848*4882a593Smuzhiyun 
849*4882a593Smuzhiyun #if CONFIG_IEEE80211_BAND_5GHZ
850*4882a593Smuzhiyun 	if (DBG_PG_TXPWR_READ)
851*4882a593Smuzhiyun 		RTW_INFO("%s[%c] eaddr:0x%03x\n", __func__, rf_path_char(path), offset);
852*4882a593Smuzhiyun 
853*4882a593Smuzhiyun 	for (group = 0; group < MAX_CHNL_GROUP_5G; group++) {
854*4882a593Smuzhiyun 		if (HAL_SPEC_CHK_RF_PATH_5G(hal_spec, path)) {
855*4882a593Smuzhiyun 			tmp_base = map_read8(txpwr_map, offset);
856*4882a593Smuzhiyun 			if (!IS_PG_TXPWR_BASE_INVALID(hal_spec, tmp_base)
857*4882a593Smuzhiyun 				&& IS_PG_TXPWR_BASE_INVALID(hal_spec, pwr_info->IndexBW40_Base[path][group])
858*4882a593Smuzhiyun 			) {
859*4882a593Smuzhiyun 				pwr_info->IndexBW40_Base[path][group] = tmp_base;
860*4882a593Smuzhiyun 				if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
861*4882a593Smuzhiyun 					RTW_INFO("[%c] 5G G%02d BW40-1S base:%u from %s\n", rf_path_char(path), group, tmp_base, pg_txpwr_src_str(txpwr_src));
862*4882a593Smuzhiyun 			}
863*4882a593Smuzhiyun 		}
864*4882a593Smuzhiyun 		offset++;
865*4882a593Smuzhiyun 	}
866*4882a593Smuzhiyun 
867*4882a593Smuzhiyun 	for (tx_idx = 0; tx_idx < MAX_TX_COUNT; tx_idx++) {
868*4882a593Smuzhiyun 		if (tx_idx == 0) {
869*4882a593Smuzhiyun 			if (HAL_SPEC_CHK_RF_PATH_5G(hal_spec, path)) {
870*4882a593Smuzhiyun 				val = map_read8(txpwr_map, offset);
871*4882a593Smuzhiyun 				tmp_diff = PG_TXPWR_MSB_DIFF_TO_S8BIT(val);
872*4882a593Smuzhiyun 				if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
873*4882a593Smuzhiyun 					&& IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW20_Diff[path][tx_idx])
874*4882a593Smuzhiyun 				) {
875*4882a593Smuzhiyun 					pwr_info->BW20_Diff[path][tx_idx] = tmp_diff;
876*4882a593Smuzhiyun 					if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
877*4882a593Smuzhiyun 						RTW_INFO("[%c] 5G BW20-%dS diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
878*4882a593Smuzhiyun 				}
879*4882a593Smuzhiyun 				tmp_diff = PG_TXPWR_LSB_DIFF_TO_S8BIT(val);
880*4882a593Smuzhiyun 				if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
881*4882a593Smuzhiyun 					&& IS_PG_TXPWR_DIFF_INVALID(pwr_info->OFDM_Diff[path][tx_idx])
882*4882a593Smuzhiyun 				) {
883*4882a593Smuzhiyun 					pwr_info->OFDM_Diff[path][tx_idx] = tmp_diff;
884*4882a593Smuzhiyun 					if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
885*4882a593Smuzhiyun 						RTW_INFO("[%c] 5G OFDM-%dT diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
886*4882a593Smuzhiyun 				}
887*4882a593Smuzhiyun 			}
888*4882a593Smuzhiyun 			offset++;
889*4882a593Smuzhiyun 		} else {
890*4882a593Smuzhiyun 			if (HAL_SPEC_CHK_RF_PATH_5G(hal_spec, path) && tx_idx + 1 <= hal_data->max_tx_cnt) {
891*4882a593Smuzhiyun 				val = map_read8(txpwr_map, offset);
892*4882a593Smuzhiyun 				tmp_diff = PG_TXPWR_MSB_DIFF_TO_S8BIT(val);
893*4882a593Smuzhiyun 				if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
894*4882a593Smuzhiyun 					&& IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW40_Diff[path][tx_idx])
895*4882a593Smuzhiyun 				) {
896*4882a593Smuzhiyun 					pwr_info->BW40_Diff[path][tx_idx] = tmp_diff;
897*4882a593Smuzhiyun 					if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
898*4882a593Smuzhiyun 						RTW_INFO("[%c] 5G BW40-%dS diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
899*4882a593Smuzhiyun 				}
900*4882a593Smuzhiyun 				tmp_diff = PG_TXPWR_LSB_DIFF_TO_S8BIT(val);
901*4882a593Smuzhiyun 				if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
902*4882a593Smuzhiyun 					&& IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW20_Diff[path][tx_idx])
903*4882a593Smuzhiyun 				) {
904*4882a593Smuzhiyun 					pwr_info->BW20_Diff[path][tx_idx] = tmp_diff;
905*4882a593Smuzhiyun 					if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
906*4882a593Smuzhiyun 						RTW_INFO("[%c] 5G BW20-%dS diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
907*4882a593Smuzhiyun 				}
908*4882a593Smuzhiyun 			}
909*4882a593Smuzhiyun 			offset++;
910*4882a593Smuzhiyun 		}
911*4882a593Smuzhiyun 	}
912*4882a593Smuzhiyun 
913*4882a593Smuzhiyun 	/* OFDM diff 2T ~ 3T */
914*4882a593Smuzhiyun 	if (HAL_SPEC_CHK_RF_PATH_5G(hal_spec, path) && hal_data->max_tx_cnt > 1) {
915*4882a593Smuzhiyun 		val = map_read8(txpwr_map, offset);
916*4882a593Smuzhiyun 		tmp_diff = PG_TXPWR_MSB_DIFF_TO_S8BIT(val);
917*4882a593Smuzhiyun 		if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
918*4882a593Smuzhiyun 			&& IS_PG_TXPWR_DIFF_INVALID(pwr_info->OFDM_Diff[path][1])
919*4882a593Smuzhiyun 		) {
920*4882a593Smuzhiyun 			pwr_info->OFDM_Diff[path][1] = tmp_diff;
921*4882a593Smuzhiyun 			if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
922*4882a593Smuzhiyun 				RTW_INFO("[%c] 5G OFDM-%dT diff:%d from %s\n", rf_path_char(path), 2, tmp_diff, pg_txpwr_src_str(txpwr_src));
923*4882a593Smuzhiyun 		}
924*4882a593Smuzhiyun 		if (hal_data->max_tx_cnt > 2) {
925*4882a593Smuzhiyun 			tmp_diff = PG_TXPWR_LSB_DIFF_TO_S8BIT(val);
926*4882a593Smuzhiyun 			if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
927*4882a593Smuzhiyun 				&& IS_PG_TXPWR_DIFF_INVALID(pwr_info->OFDM_Diff[path][2])
928*4882a593Smuzhiyun 			) {
929*4882a593Smuzhiyun 				pwr_info->OFDM_Diff[path][2] = tmp_diff;
930*4882a593Smuzhiyun 				if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
931*4882a593Smuzhiyun 					RTW_INFO("[%c] 5G OFDM-%dT diff:%d from %s\n", rf_path_char(path), 3, tmp_diff, pg_txpwr_src_str(txpwr_src));
932*4882a593Smuzhiyun 			}
933*4882a593Smuzhiyun 		}
934*4882a593Smuzhiyun 	}
935*4882a593Smuzhiyun 	offset++;
936*4882a593Smuzhiyun 
937*4882a593Smuzhiyun 	/* OFDM diff 4T */
938*4882a593Smuzhiyun 	if (HAL_SPEC_CHK_RF_PATH_5G(hal_spec, path) && hal_data->max_tx_cnt > 3) {
939*4882a593Smuzhiyun 		val = map_read8(txpwr_map, offset);
940*4882a593Smuzhiyun 		tmp_diff = PG_TXPWR_LSB_DIFF_TO_S8BIT(val);
941*4882a593Smuzhiyun 		if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
942*4882a593Smuzhiyun 			&& IS_PG_TXPWR_DIFF_INVALID(pwr_info->OFDM_Diff[path][3])
943*4882a593Smuzhiyun 		) {
944*4882a593Smuzhiyun 			pwr_info->OFDM_Diff[path][3] = tmp_diff;
945*4882a593Smuzhiyun 			if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
946*4882a593Smuzhiyun 				RTW_INFO("[%c] 5G OFDM-%dT diff:%d from %s\n", rf_path_char(path), 4, tmp_diff, pg_txpwr_src_str(txpwr_src));
947*4882a593Smuzhiyun 		}
948*4882a593Smuzhiyun 	}
949*4882a593Smuzhiyun 	offset++;
950*4882a593Smuzhiyun 
951*4882a593Smuzhiyun 	for (tx_idx = 0; tx_idx < MAX_TX_COUNT; tx_idx++) {
952*4882a593Smuzhiyun 		if (HAL_SPEC_CHK_RF_PATH_5G(hal_spec, path) && tx_idx + 1 <= hal_data->max_tx_cnt) {
953*4882a593Smuzhiyun 			val = map_read8(txpwr_map, offset);
954*4882a593Smuzhiyun 			tmp_diff = PG_TXPWR_MSB_DIFF_TO_S8BIT(val);
955*4882a593Smuzhiyun 			if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
956*4882a593Smuzhiyun 				&& IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW80_Diff[path][tx_idx])
957*4882a593Smuzhiyun 			) {
958*4882a593Smuzhiyun 				pwr_info->BW80_Diff[path][tx_idx] = tmp_diff;
959*4882a593Smuzhiyun 				if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
960*4882a593Smuzhiyun 					RTW_INFO("[%c] 5G BW80-%dS diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
961*4882a593Smuzhiyun 			}
962*4882a593Smuzhiyun 			tmp_diff = PG_TXPWR_LSB_DIFF_TO_S8BIT(val);
963*4882a593Smuzhiyun 			if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
964*4882a593Smuzhiyun 				&& IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW160_Diff[path][tx_idx])
965*4882a593Smuzhiyun 			) {
966*4882a593Smuzhiyun 				pwr_info->BW160_Diff[path][tx_idx] = tmp_diff;
967*4882a593Smuzhiyun 				if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
968*4882a593Smuzhiyun 					RTW_INFO("[%c] 5G BW160-%dS diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
969*4882a593Smuzhiyun 			}
970*4882a593Smuzhiyun 		}
971*4882a593Smuzhiyun 		offset++;
972*4882a593Smuzhiyun 	}
973*4882a593Smuzhiyun 
974*4882a593Smuzhiyun 	if (offset != pg_offset + PG_TXPWR_1PATH_BYTE_NUM_5G) {
975*4882a593Smuzhiyun 		RTW_ERR("%s parse %d bytes != %d\n", __func__, offset - pg_offset, PG_TXPWR_1PATH_BYTE_NUM_5G);
976*4882a593Smuzhiyun 		rtw_warn_on(1);
977*4882a593Smuzhiyun 	}
978*4882a593Smuzhiyun 
979*4882a593Smuzhiyun #endif /* CONFIG_IEEE80211_BAND_5GHZ */
980*4882a593Smuzhiyun 
981*4882a593Smuzhiyun exit:
982*4882a593Smuzhiyun 	return offset;
983*4882a593Smuzhiyun }
984*4882a593Smuzhiyun 
hal_load_pg_txpwr_info(_adapter * adapter,TxPowerInfo24G * pwr_info_2g,TxPowerInfo5G * pwr_info_5g,u8 * pg_data,BOOLEAN AutoLoadFail)985*4882a593Smuzhiyun void hal_load_pg_txpwr_info(
986*4882a593Smuzhiyun 	_adapter *adapter,
987*4882a593Smuzhiyun 	TxPowerInfo24G *pwr_info_2g,
988*4882a593Smuzhiyun 	TxPowerInfo5G *pwr_info_5g,
989*4882a593Smuzhiyun 	u8 *pg_data,
990*4882a593Smuzhiyun 	BOOLEAN AutoLoadFail
991*4882a593Smuzhiyun )
992*4882a593Smuzhiyun {
993*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
994*4882a593Smuzhiyun 	u8 path;
995*4882a593Smuzhiyun 	u16 pg_offset;
996*4882a593Smuzhiyun 	u8 txpwr_src = PG_TXPWR_SRC_PG_DATA;
997*4882a593Smuzhiyun 	struct map_t pg_data_map = MAP_ENT(184, 1, 0xFF, MAPSEG_PTR_ENT(0x00, 184, pg_data));
998*4882a593Smuzhiyun 	const struct map_t *txpwr_map = NULL;
999*4882a593Smuzhiyun 
1000*4882a593Smuzhiyun 	/* init with invalid value and some dummy base and diff */
1001*4882a593Smuzhiyun 	hal_init_pg_txpwr_info_2g(adapter, pwr_info_2g);
1002*4882a593Smuzhiyun 	hal_init_pg_txpwr_info_5g(adapter, pwr_info_5g);
1003*4882a593Smuzhiyun 
1004*4882a593Smuzhiyun select_src:
1005*4882a593Smuzhiyun 	pg_offset = hal_spec->pg_txpwr_saddr;
1006*4882a593Smuzhiyun 
1007*4882a593Smuzhiyun 	switch (txpwr_src) {
1008*4882a593Smuzhiyun 	case PG_TXPWR_SRC_PG_DATA:
1009*4882a593Smuzhiyun 		txpwr_map = &pg_data_map;
1010*4882a593Smuzhiyun 		break;
1011*4882a593Smuzhiyun 	case PG_TXPWR_SRC_IC_DEF:
1012*4882a593Smuzhiyun 		txpwr_map = hal_pg_txpwr_def_info(adapter);
1013*4882a593Smuzhiyun 		break;
1014*4882a593Smuzhiyun 	case PG_TXPWR_SRC_DEF:
1015*4882a593Smuzhiyun 	default:
1016*4882a593Smuzhiyun 		txpwr_map = &pg_txpwr_def_info;
1017*4882a593Smuzhiyun 		break;
1018*4882a593Smuzhiyun 	};
1019*4882a593Smuzhiyun 
1020*4882a593Smuzhiyun 	if (txpwr_map == NULL)
1021*4882a593Smuzhiyun 		goto end_parse;
1022*4882a593Smuzhiyun 
1023*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH ; path++) {
1024*4882a593Smuzhiyun 		if (!HAL_SPEC_CHK_RF_PATH_2G(hal_spec, path) && !HAL_SPEC_CHK_RF_PATH_5G(hal_spec, path))
1025*4882a593Smuzhiyun 			break;
1026*4882a593Smuzhiyun 		pg_offset = hal_load_pg_txpwr_info_path_2g(adapter, pwr_info_2g, path, txpwr_src, txpwr_map, pg_offset);
1027*4882a593Smuzhiyun 		pg_offset = hal_load_pg_txpwr_info_path_5g(adapter, pwr_info_5g, path, txpwr_src, txpwr_map, pg_offset);
1028*4882a593Smuzhiyun 	}
1029*4882a593Smuzhiyun 
1030*4882a593Smuzhiyun 	if (hal_chk_pg_txpwr_info_2g(adapter, pwr_info_2g) == _SUCCESS
1031*4882a593Smuzhiyun 		&& hal_chk_pg_txpwr_info_5g(adapter, pwr_info_5g) == _SUCCESS)
1032*4882a593Smuzhiyun 		goto exit;
1033*4882a593Smuzhiyun 
1034*4882a593Smuzhiyun end_parse:
1035*4882a593Smuzhiyun 	txpwr_src++;
1036*4882a593Smuzhiyun 	if (txpwr_src < PG_TXPWR_SRC_NUM)
1037*4882a593Smuzhiyun 		goto select_src;
1038*4882a593Smuzhiyun 
1039*4882a593Smuzhiyun 	if (hal_chk_pg_txpwr_info_2g(adapter, pwr_info_2g) != _SUCCESS
1040*4882a593Smuzhiyun 		|| hal_chk_pg_txpwr_info_5g(adapter, pwr_info_5g) != _SUCCESS)
1041*4882a593Smuzhiyun 		rtw_warn_on(1);
1042*4882a593Smuzhiyun 
1043*4882a593Smuzhiyun exit:
1044*4882a593Smuzhiyun 	#if DBG_PG_TXPWR_READ
1045*4882a593Smuzhiyun 	if (pwr_info_2g)
1046*4882a593Smuzhiyun 		dump_pg_txpwr_info_2g(RTW_DBGDUMP, pwr_info_2g, 4, 4);
1047*4882a593Smuzhiyun 	if (pwr_info_5g)
1048*4882a593Smuzhiyun 		dump_pg_txpwr_info_5g(RTW_DBGDUMP, pwr_info_5g, 4, 4);
1049*4882a593Smuzhiyun 	#endif
1050*4882a593Smuzhiyun 
1051*4882a593Smuzhiyun 	return;
1052*4882a593Smuzhiyun }
1053*4882a593Smuzhiyun #endif /* CONFIG_TXPWR_PG_WITH_PWR_IDX */
1054*4882a593Smuzhiyun 
1055*4882a593Smuzhiyun #ifdef CONFIG_EFUSE_CONFIG_FILE
1056*4882a593Smuzhiyun 
1057*4882a593Smuzhiyun #define EFUSE_POWER_INDEX_INVALID 0xFF
1058*4882a593Smuzhiyun 
_check_phy_efuse_tx_power_info_valid(u8 * pg_data,int chk_len,u16 pg_offset)1059*4882a593Smuzhiyun static u8 _check_phy_efuse_tx_power_info_valid(u8 *pg_data, int chk_len, u16 pg_offset)
1060*4882a593Smuzhiyun {
1061*4882a593Smuzhiyun 	int ff_cnt = 0;
1062*4882a593Smuzhiyun 	int i;
1063*4882a593Smuzhiyun 
1064*4882a593Smuzhiyun 	for (i = 0; i < chk_len; i++) {
1065*4882a593Smuzhiyun 		if (*(pg_data + pg_offset + i) == 0xFF)
1066*4882a593Smuzhiyun 			ff_cnt++;
1067*4882a593Smuzhiyun 	}
1068*4882a593Smuzhiyun 
1069*4882a593Smuzhiyun 	if (ff_cnt == 0)
1070*4882a593Smuzhiyun 		return _TRUE;
1071*4882a593Smuzhiyun 	else if (ff_cnt == chk_len)
1072*4882a593Smuzhiyun 		return _FALSE;
1073*4882a593Smuzhiyun 	else
1074*4882a593Smuzhiyun 		return EFUSE_POWER_INDEX_INVALID;
1075*4882a593Smuzhiyun }
1076*4882a593Smuzhiyun 
check_phy_efuse_tx_power_info_valid(_adapter * adapter)1077*4882a593Smuzhiyun int check_phy_efuse_tx_power_info_valid(_adapter *adapter)
1078*4882a593Smuzhiyun {
1079*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
1080*4882a593Smuzhiyun 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1081*4882a593Smuzhiyun 	u8 *pg_data = hal_data->efuse_eeprom_data;
1082*4882a593Smuzhiyun 	u16 pg_offset = hal_spec->pg_txpwr_saddr;
1083*4882a593Smuzhiyun 	u8 path;
1084*4882a593Smuzhiyun 	u8 valid_2g_path_bmp = 0;
1085*4882a593Smuzhiyun #if CONFIG_IEEE80211_BAND_5GHZ
1086*4882a593Smuzhiyun 	u8 valid_5g_path_bmp = 0;
1087*4882a593Smuzhiyun #endif
1088*4882a593Smuzhiyun 
1089*4882a593Smuzhiyun 	/* NOTE: TSSI offset use the same layout as TXPWR base */
1090*4882a593Smuzhiyun 
1091*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH; path++) {
1092*4882a593Smuzhiyun 		u8 ret = _FALSE;
1093*4882a593Smuzhiyun 
1094*4882a593Smuzhiyun 		if (!HAL_SPEC_CHK_RF_PATH_2G(hal_spec, path) && !HAL_SPEC_CHK_RF_PATH_5G(hal_spec, path))
1095*4882a593Smuzhiyun 			break;
1096*4882a593Smuzhiyun 
1097*4882a593Smuzhiyun 		if (HAL_SPEC_CHK_RF_PATH_2G(hal_spec, path)) {
1098*4882a593Smuzhiyun 			ret = _check_phy_efuse_tx_power_info_valid(pg_data, PG_TXPWR_BASE_BYTE_NUM_2G, pg_offset);
1099*4882a593Smuzhiyun 			if (ret == _TRUE)
1100*4882a593Smuzhiyun 				valid_2g_path_bmp |= BIT(path);
1101*4882a593Smuzhiyun 			else if (ret == EFUSE_POWER_INDEX_INVALID)
1102*4882a593Smuzhiyun 				return _FALSE;
1103*4882a593Smuzhiyun 		}
1104*4882a593Smuzhiyun 		pg_offset += PG_TXPWR_1PATH_BYTE_NUM_2G;
1105*4882a593Smuzhiyun 
1106*4882a593Smuzhiyun 		#if CONFIG_IEEE80211_BAND_5GHZ
1107*4882a593Smuzhiyun 		if (HAL_SPEC_CHK_RF_PATH_5G(hal_spec, path)) {
1108*4882a593Smuzhiyun 			ret = _check_phy_efuse_tx_power_info_valid(pg_data, PG_TXPWR_BASE_BYTE_NUM_5G, pg_offset);
1109*4882a593Smuzhiyun 			if (ret == _TRUE)
1110*4882a593Smuzhiyun 				valid_5g_path_bmp |= BIT(path);
1111*4882a593Smuzhiyun 			else if (ret == EFUSE_POWER_INDEX_INVALID)
1112*4882a593Smuzhiyun 				return _FALSE;
1113*4882a593Smuzhiyun 		}
1114*4882a593Smuzhiyun 		#endif
1115*4882a593Smuzhiyun 		pg_offset += PG_TXPWR_1PATH_BYTE_NUM_5G;
1116*4882a593Smuzhiyun 	}
1117*4882a593Smuzhiyun 
1118*4882a593Smuzhiyun 	if ((hal_chk_band_cap(adapter, BAND_CAP_2G) && valid_2g_path_bmp)
1119*4882a593Smuzhiyun 		#if CONFIG_IEEE80211_BAND_5GHZ
1120*4882a593Smuzhiyun 		|| (hal_chk_band_cap(adapter, BAND_CAP_5G) && valid_5g_path_bmp)
1121*4882a593Smuzhiyun 		#endif
1122*4882a593Smuzhiyun 	)
1123*4882a593Smuzhiyun 		return _TRUE;
1124*4882a593Smuzhiyun 
1125*4882a593Smuzhiyun 	return _FALSE;
1126*4882a593Smuzhiyun }
1127*4882a593Smuzhiyun #endif /* CONFIG_EFUSE_CONFIG_FILE */
1128*4882a593Smuzhiyun 
1129*4882a593Smuzhiyun #ifdef CONFIG_TXPWR_PG_WITH_PWR_IDX
hal_load_txpwr_info(_adapter * adapter)1130*4882a593Smuzhiyun void hal_load_txpwr_info(_adapter *adapter)
1131*4882a593Smuzhiyun {
1132*4882a593Smuzhiyun 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1133*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
1134*4882a593Smuzhiyun 	u8 max_tx_cnt = hal_data->max_tx_cnt;
1135*4882a593Smuzhiyun 	u8 *pg_data = hal_data->efuse_eeprom_data;
1136*4882a593Smuzhiyun 	TxPowerInfo24G *pwr_info_2g = NULL;
1137*4882a593Smuzhiyun 	TxPowerInfo5G *pwr_info_5g = NULL;
1138*4882a593Smuzhiyun 	u8 rfpath, ch_idx, group, tx_idx;
1139*4882a593Smuzhiyun 
1140*4882a593Smuzhiyun 	if (hal_chk_band_cap(adapter, BAND_CAP_2G))
1141*4882a593Smuzhiyun 		pwr_info_2g = rtw_vmalloc(sizeof(TxPowerInfo24G));
1142*4882a593Smuzhiyun #if CONFIG_IEEE80211_BAND_5GHZ
1143*4882a593Smuzhiyun 	if (hal_chk_band_cap(adapter, BAND_CAP_5G))
1144*4882a593Smuzhiyun 		pwr_info_5g = rtw_vmalloc(sizeof(TxPowerInfo5G));
1145*4882a593Smuzhiyun #endif
1146*4882a593Smuzhiyun 
1147*4882a593Smuzhiyun 	/* load from pg data (or default value) */
1148*4882a593Smuzhiyun 	hal_load_pg_txpwr_info(adapter, pwr_info_2g, pwr_info_5g, pg_data, _FALSE);
1149*4882a593Smuzhiyun 
1150*4882a593Smuzhiyun 	/* transform to hal_data */
1151*4882a593Smuzhiyun 	for (rfpath = 0; rfpath < MAX_RF_PATH; rfpath++) {
1152*4882a593Smuzhiyun 
1153*4882a593Smuzhiyun 		if (!pwr_info_2g || !HAL_SPEC_CHK_RF_PATH_2G(hal_spec, rfpath))
1154*4882a593Smuzhiyun 			goto bypass_2g;
1155*4882a593Smuzhiyun 
1156*4882a593Smuzhiyun 		/* 2.4G base */
1157*4882a593Smuzhiyun 		for (ch_idx = 0; ch_idx < CENTER_CH_2G_NUM; ch_idx++) {
1158*4882a593Smuzhiyun 			u8 cck_group;
1159*4882a593Smuzhiyun 
1160*4882a593Smuzhiyun 			if (rtw_get_ch_group(ch_idx + 1, &group, &cck_group) != BAND_ON_2_4G)
1161*4882a593Smuzhiyun 				continue;
1162*4882a593Smuzhiyun 
1163*4882a593Smuzhiyun 			hal_data->Index24G_CCK_Base[rfpath][ch_idx] = pwr_info_2g->IndexCCK_Base[rfpath][cck_group];
1164*4882a593Smuzhiyun 			hal_data->Index24G_BW40_Base[rfpath][ch_idx] = pwr_info_2g->IndexBW40_Base[rfpath][group];
1165*4882a593Smuzhiyun 		}
1166*4882a593Smuzhiyun 
1167*4882a593Smuzhiyun 		/* 2.4G diff */
1168*4882a593Smuzhiyun 		for (tx_idx = 0; tx_idx < MAX_TX_COUNT; tx_idx++) {
1169*4882a593Smuzhiyun 			if (tx_idx + 1 > max_tx_cnt)
1170*4882a593Smuzhiyun 				break;
1171*4882a593Smuzhiyun 
1172*4882a593Smuzhiyun 			hal_data->CCK_24G_Diff[rfpath][tx_idx] = pwr_info_2g->CCK_Diff[rfpath][tx_idx] * hal_spec->pg_txgi_diff_factor;
1173*4882a593Smuzhiyun 			hal_data->OFDM_24G_Diff[rfpath][tx_idx] = pwr_info_2g->OFDM_Diff[rfpath][tx_idx] * hal_spec->pg_txgi_diff_factor;
1174*4882a593Smuzhiyun 			hal_data->BW20_24G_Diff[rfpath][tx_idx] = pwr_info_2g->BW20_Diff[rfpath][tx_idx] * hal_spec->pg_txgi_diff_factor;
1175*4882a593Smuzhiyun 			hal_data->BW40_24G_Diff[rfpath][tx_idx] = pwr_info_2g->BW40_Diff[rfpath][tx_idx] * hal_spec->pg_txgi_diff_factor;
1176*4882a593Smuzhiyun 		}
1177*4882a593Smuzhiyun bypass_2g:
1178*4882a593Smuzhiyun 		;
1179*4882a593Smuzhiyun 
1180*4882a593Smuzhiyun #if CONFIG_IEEE80211_BAND_5GHZ
1181*4882a593Smuzhiyun 		if (!pwr_info_5g || !HAL_SPEC_CHK_RF_PATH_5G(hal_spec, rfpath))
1182*4882a593Smuzhiyun 			goto bypass_5g;
1183*4882a593Smuzhiyun 
1184*4882a593Smuzhiyun 		/* 5G base */
1185*4882a593Smuzhiyun 		for (ch_idx = 0; ch_idx < CENTER_CH_5G_ALL_NUM; ch_idx++) {
1186*4882a593Smuzhiyun 			if (rtw_get_ch_group(center_ch_5g_all[ch_idx], &group, NULL) != BAND_ON_5G)
1187*4882a593Smuzhiyun 				continue;
1188*4882a593Smuzhiyun 			hal_data->Index5G_BW40_Base[rfpath][ch_idx] = pwr_info_5g->IndexBW40_Base[rfpath][group];
1189*4882a593Smuzhiyun 		}
1190*4882a593Smuzhiyun 
1191*4882a593Smuzhiyun 		for (ch_idx = 0 ; ch_idx < CENTER_CH_5G_80M_NUM; ch_idx++) {
1192*4882a593Smuzhiyun 			u8 upper, lower;
1193*4882a593Smuzhiyun 
1194*4882a593Smuzhiyun 			if (rtw_get_ch_group(center_ch_5g_80m[ch_idx], &group, NULL) != BAND_ON_5G)
1195*4882a593Smuzhiyun 				continue;
1196*4882a593Smuzhiyun 
1197*4882a593Smuzhiyun 			upper = pwr_info_5g->IndexBW40_Base[rfpath][group];
1198*4882a593Smuzhiyun 			lower = pwr_info_5g->IndexBW40_Base[rfpath][group + 1];
1199*4882a593Smuzhiyun 			hal_data->Index5G_BW80_Base[rfpath][ch_idx] = (upper + lower) / 2;
1200*4882a593Smuzhiyun 		}
1201*4882a593Smuzhiyun 
1202*4882a593Smuzhiyun 		/* 5G diff */
1203*4882a593Smuzhiyun 		for (tx_idx = 0; tx_idx < MAX_TX_COUNT; tx_idx++) {
1204*4882a593Smuzhiyun 			if (tx_idx + 1 > max_tx_cnt)
1205*4882a593Smuzhiyun 				break;
1206*4882a593Smuzhiyun 
1207*4882a593Smuzhiyun 			hal_data->OFDM_5G_Diff[rfpath][tx_idx] = pwr_info_5g->OFDM_Diff[rfpath][tx_idx] * hal_spec->pg_txgi_diff_factor;
1208*4882a593Smuzhiyun 			hal_data->BW20_5G_Diff[rfpath][tx_idx] = pwr_info_5g->BW20_Diff[rfpath][tx_idx] * hal_spec->pg_txgi_diff_factor;
1209*4882a593Smuzhiyun 			hal_data->BW40_5G_Diff[rfpath][tx_idx] = pwr_info_5g->BW40_Diff[rfpath][tx_idx] * hal_spec->pg_txgi_diff_factor;
1210*4882a593Smuzhiyun 			hal_data->BW80_5G_Diff[rfpath][tx_idx] = pwr_info_5g->BW80_Diff[rfpath][tx_idx] * hal_spec->pg_txgi_diff_factor;
1211*4882a593Smuzhiyun 		}
1212*4882a593Smuzhiyun bypass_5g:
1213*4882a593Smuzhiyun 		;
1214*4882a593Smuzhiyun #endif /* CONFIG_IEEE80211_BAND_5GHZ */
1215*4882a593Smuzhiyun 	}
1216*4882a593Smuzhiyun 
1217*4882a593Smuzhiyun 	if (pwr_info_2g)
1218*4882a593Smuzhiyun 		rtw_vmfree(pwr_info_2g, sizeof(TxPowerInfo24G));
1219*4882a593Smuzhiyun 	if (pwr_info_5g)
1220*4882a593Smuzhiyun 		rtw_vmfree(pwr_info_5g, sizeof(TxPowerInfo5G));
1221*4882a593Smuzhiyun }
1222*4882a593Smuzhiyun 
dump_hal_txpwr_info_2g(void * sel,_adapter * adapter,u8 rfpath_num,u8 max_tx_cnt)1223*4882a593Smuzhiyun void dump_hal_txpwr_info_2g(void *sel, _adapter *adapter, u8 rfpath_num, u8 max_tx_cnt)
1224*4882a593Smuzhiyun {
1225*4882a593Smuzhiyun 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1226*4882a593Smuzhiyun 	int path, ch_idx, tx_idx;
1227*4882a593Smuzhiyun 
1228*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "2.4G\n");
1229*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "CCK-1T base:\n");
1230*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "%4s ", "");
1231*4882a593Smuzhiyun 	for (ch_idx = 0; ch_idx < CENTER_CH_2G_NUM; ch_idx++)
1232*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "%3d ", center_ch_2g[ch_idx]);
1233*4882a593Smuzhiyun 	_RTW_PRINT_SEL(sel, "\n");
1234*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
1235*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
1236*4882a593Smuzhiyun 		for (ch_idx = 0; ch_idx < CENTER_CH_2G_NUM; ch_idx++)
1237*4882a593Smuzhiyun 			_RTW_PRINT_SEL(sel, "%3u ", hal_data->Index24G_CCK_Base[path][ch_idx]);
1238*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "\n");
1239*4882a593Smuzhiyun 	}
1240*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "\n");
1241*4882a593Smuzhiyun 
1242*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "CCK diff:\n");
1243*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "%4s ", "");
1244*4882a593Smuzhiyun 	for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1245*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "%dT ", tx_idx + 1);
1246*4882a593Smuzhiyun 	_RTW_PRINT_SEL(sel, "\n");
1247*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
1248*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
1249*4882a593Smuzhiyun 		for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1250*4882a593Smuzhiyun 			_RTW_PRINT_SEL(sel, "%2d ", hal_data->CCK_24G_Diff[path][tx_idx]);
1251*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "\n");
1252*4882a593Smuzhiyun 	}
1253*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "\n");
1254*4882a593Smuzhiyun 
1255*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "BW40-1S base:\n");
1256*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "%4s ", "");
1257*4882a593Smuzhiyun 	for (ch_idx = 0; ch_idx < CENTER_CH_2G_NUM; ch_idx++)
1258*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "%3d ", center_ch_2g[ch_idx]);
1259*4882a593Smuzhiyun 	_RTW_PRINT_SEL(sel, "\n");
1260*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
1261*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
1262*4882a593Smuzhiyun 		for (ch_idx = 0; ch_idx < CENTER_CH_2G_NUM; ch_idx++)
1263*4882a593Smuzhiyun 			_RTW_PRINT_SEL(sel, "%3u ", hal_data->Index24G_BW40_Base[path][ch_idx]);
1264*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "\n");
1265*4882a593Smuzhiyun 	}
1266*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "\n");
1267*4882a593Smuzhiyun 
1268*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "OFDM diff:\n");
1269*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "%4s ", "");
1270*4882a593Smuzhiyun 	for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1271*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "%dT ", tx_idx + 1);
1272*4882a593Smuzhiyun 	_RTW_PRINT_SEL(sel, "\n");
1273*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
1274*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
1275*4882a593Smuzhiyun 		for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1276*4882a593Smuzhiyun 			_RTW_PRINT_SEL(sel, "%2d ", hal_data->OFDM_24G_Diff[path][tx_idx]);
1277*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "\n");
1278*4882a593Smuzhiyun 	}
1279*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "\n");
1280*4882a593Smuzhiyun 
1281*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "BW20 diff:\n");
1282*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "%4s ", "");
1283*4882a593Smuzhiyun 	for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1284*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "%dS ", tx_idx + 1);
1285*4882a593Smuzhiyun 	_RTW_PRINT_SEL(sel, "\n");
1286*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
1287*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
1288*4882a593Smuzhiyun 		for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1289*4882a593Smuzhiyun 			_RTW_PRINT_SEL(sel, "%2d ", hal_data->BW20_24G_Diff[path][tx_idx]);
1290*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "\n");
1291*4882a593Smuzhiyun 	}
1292*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "\n");
1293*4882a593Smuzhiyun 
1294*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "BW40 diff:\n");
1295*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "%4s ", "");
1296*4882a593Smuzhiyun 	for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1297*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "%dS ", tx_idx + 1);
1298*4882a593Smuzhiyun 	_RTW_PRINT_SEL(sel, "\n");
1299*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
1300*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
1301*4882a593Smuzhiyun 		for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1302*4882a593Smuzhiyun 			_RTW_PRINT_SEL(sel, "%2d ", hal_data->BW40_24G_Diff[path][tx_idx]);
1303*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "\n");
1304*4882a593Smuzhiyun 	}
1305*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "\n");
1306*4882a593Smuzhiyun }
1307*4882a593Smuzhiyun 
dump_hal_txpwr_info_5g(void * sel,_adapter * adapter,u8 rfpath_num,u8 max_tx_cnt)1308*4882a593Smuzhiyun void dump_hal_txpwr_info_5g(void *sel, _adapter *adapter, u8 rfpath_num, u8 max_tx_cnt)
1309*4882a593Smuzhiyun {
1310*4882a593Smuzhiyun #if CONFIG_IEEE80211_BAND_5GHZ
1311*4882a593Smuzhiyun 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1312*4882a593Smuzhiyun 	int path, ch_idx, tx_idx;
1313*4882a593Smuzhiyun 	u8 dump_section = 0;
1314*4882a593Smuzhiyun 	u8 ch_idx_s = 0;
1315*4882a593Smuzhiyun 
1316*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "5G\n");
1317*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "BW40-1S base:\n");
1318*4882a593Smuzhiyun 	do {
1319*4882a593Smuzhiyun 		#define DUMP_5G_BW40_BASE_SECTION_NUM 3
1320*4882a593Smuzhiyun 		u8 end[DUMP_5G_BW40_BASE_SECTION_NUM] = {64, 144, 177};
1321*4882a593Smuzhiyun 
1322*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "%4s ", "");
1323*4882a593Smuzhiyun 		for (ch_idx = ch_idx_s; ch_idx < CENTER_CH_5G_ALL_NUM; ch_idx++) {
1324*4882a593Smuzhiyun 			_RTW_PRINT_SEL(sel, "%3d ", center_ch_5g_all[ch_idx]);
1325*4882a593Smuzhiyun 			if (end[dump_section] == center_ch_5g_all[ch_idx])
1326*4882a593Smuzhiyun 				break;
1327*4882a593Smuzhiyun 		}
1328*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "\n");
1329*4882a593Smuzhiyun 		for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
1330*4882a593Smuzhiyun 			RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
1331*4882a593Smuzhiyun 			for (ch_idx = ch_idx_s; ch_idx < CENTER_CH_5G_ALL_NUM; ch_idx++) {
1332*4882a593Smuzhiyun 				_RTW_PRINT_SEL(sel, "%3u ", hal_data->Index5G_BW40_Base[path][ch_idx]);
1333*4882a593Smuzhiyun 				if (end[dump_section] == center_ch_5g_all[ch_idx])
1334*4882a593Smuzhiyun 					break;
1335*4882a593Smuzhiyun 			}
1336*4882a593Smuzhiyun 			_RTW_PRINT_SEL(sel, "\n");
1337*4882a593Smuzhiyun 		}
1338*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "\n");
1339*4882a593Smuzhiyun 
1340*4882a593Smuzhiyun 		ch_idx_s = ch_idx + 1;
1341*4882a593Smuzhiyun 		dump_section++;
1342*4882a593Smuzhiyun 		if (dump_section >= DUMP_5G_BW40_BASE_SECTION_NUM)
1343*4882a593Smuzhiyun 			break;
1344*4882a593Smuzhiyun 	} while (1);
1345*4882a593Smuzhiyun 
1346*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "BW80-1S base:\n");
1347*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "%4s ", "");
1348*4882a593Smuzhiyun 	for (ch_idx = 0; ch_idx < CENTER_CH_5G_80M_NUM; ch_idx++)
1349*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "%3d ", center_ch_5g_80m[ch_idx]);
1350*4882a593Smuzhiyun 	_RTW_PRINT_SEL(sel, "\n");
1351*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
1352*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
1353*4882a593Smuzhiyun 		for (ch_idx = 0; ch_idx < CENTER_CH_5G_80M_NUM; ch_idx++)
1354*4882a593Smuzhiyun 			_RTW_PRINT_SEL(sel, "%3u ", hal_data->Index5G_BW80_Base[path][ch_idx]);
1355*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "\n");
1356*4882a593Smuzhiyun 	}
1357*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "\n");
1358*4882a593Smuzhiyun 
1359*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "OFDM diff:\n");
1360*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "%4s ", "");
1361*4882a593Smuzhiyun 	for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1362*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "%dT ", tx_idx + 1);
1363*4882a593Smuzhiyun 	_RTW_PRINT_SEL(sel, "\n");
1364*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
1365*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
1366*4882a593Smuzhiyun 		for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1367*4882a593Smuzhiyun 			_RTW_PRINT_SEL(sel, "%2d ", hal_data->OFDM_5G_Diff[path][tx_idx]);
1368*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "\n");
1369*4882a593Smuzhiyun 	}
1370*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "\n");
1371*4882a593Smuzhiyun 
1372*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "BW20 diff:\n");
1373*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "%4s ", "");
1374*4882a593Smuzhiyun 	for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1375*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "%dS ", tx_idx + 1);
1376*4882a593Smuzhiyun 	_RTW_PRINT_SEL(sel, "\n");
1377*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
1378*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
1379*4882a593Smuzhiyun 		for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1380*4882a593Smuzhiyun 			_RTW_PRINT_SEL(sel, "%2d ", hal_data->BW20_5G_Diff[path][tx_idx]);
1381*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "\n");
1382*4882a593Smuzhiyun 	}
1383*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "\n");
1384*4882a593Smuzhiyun 
1385*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "BW40 diff:\n");
1386*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "%4s ", "");
1387*4882a593Smuzhiyun 	for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1388*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "%dS ", tx_idx + 1);
1389*4882a593Smuzhiyun 	_RTW_PRINT_SEL(sel, "\n");
1390*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
1391*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
1392*4882a593Smuzhiyun 		for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1393*4882a593Smuzhiyun 			_RTW_PRINT_SEL(sel, "%2d ", hal_data->BW40_5G_Diff[path][tx_idx]);
1394*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "\n");
1395*4882a593Smuzhiyun 	}
1396*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "\n");
1397*4882a593Smuzhiyun 
1398*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "BW80 diff:\n");
1399*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "%4s ", "");
1400*4882a593Smuzhiyun 	for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1401*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "%dS ", tx_idx + 1);
1402*4882a593Smuzhiyun 	_RTW_PRINT_SEL(sel, "\n");
1403*4882a593Smuzhiyun 	for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
1404*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
1405*4882a593Smuzhiyun 		for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1406*4882a593Smuzhiyun 			_RTW_PRINT_SEL(sel, "%2d ", hal_data->BW80_5G_Diff[path][tx_idx]);
1407*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, "\n");
1408*4882a593Smuzhiyun 	}
1409*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "\n");
1410*4882a593Smuzhiyun #endif /* CONFIG_IEEE80211_BAND_5GHZ */
1411*4882a593Smuzhiyun }
1412*4882a593Smuzhiyun #endif /* CONFIG_TXPWR_PG_WITH_PWR_IDX */
1413*4882a593Smuzhiyun 
1414*4882a593Smuzhiyun /*
1415*4882a593Smuzhiyun * rtw_regsty_get_target_tx_power -
1416*4882a593Smuzhiyun *
1417*4882a593Smuzhiyun * Return dBm or -1 for undefined
1418*4882a593Smuzhiyun */
rtw_regsty_get_target_tx_power(PADAPTER Adapter,u8 Band,u8 RfPath,RATE_SECTION RateSection)1419*4882a593Smuzhiyun s8 rtw_regsty_get_target_tx_power(
1420*4882a593Smuzhiyun 		PADAPTER		Adapter,
1421*4882a593Smuzhiyun 		u8				Band,
1422*4882a593Smuzhiyun 		u8				RfPath,
1423*4882a593Smuzhiyun 		RATE_SECTION	RateSection
1424*4882a593Smuzhiyun )
1425*4882a593Smuzhiyun {
1426*4882a593Smuzhiyun 	struct registry_priv *regsty = adapter_to_regsty(Adapter);
1427*4882a593Smuzhiyun 	s8 value = 0;
1428*4882a593Smuzhiyun 
1429*4882a593Smuzhiyun 	if (RfPath > RF_PATH_D) {
1430*4882a593Smuzhiyun 		RTW_PRINT("%s invalid RfPath:%d\n", __func__, RfPath);
1431*4882a593Smuzhiyun 		return -1;
1432*4882a593Smuzhiyun 	}
1433*4882a593Smuzhiyun 
1434*4882a593Smuzhiyun 	if (Band != BAND_ON_2_4G
1435*4882a593Smuzhiyun 		#if CONFIG_IEEE80211_BAND_5GHZ
1436*4882a593Smuzhiyun 		&& Band != BAND_ON_5G
1437*4882a593Smuzhiyun 		#endif
1438*4882a593Smuzhiyun 	) {
1439*4882a593Smuzhiyun 		RTW_PRINT("%s invalid Band:%d\n", __func__, Band);
1440*4882a593Smuzhiyun 		return -1;
1441*4882a593Smuzhiyun 	}
1442*4882a593Smuzhiyun 
1443*4882a593Smuzhiyun 	if (RateSection >= RATE_SECTION_NUM
1444*4882a593Smuzhiyun 		#if CONFIG_IEEE80211_BAND_5GHZ
1445*4882a593Smuzhiyun 		|| (Band == BAND_ON_5G && RateSection == CCK)
1446*4882a593Smuzhiyun 		#endif
1447*4882a593Smuzhiyun 	) {
1448*4882a593Smuzhiyun 		RTW_PRINT("%s invalid RateSection:%d in Band:%d, RfPath:%d\n", __func__
1449*4882a593Smuzhiyun 			, RateSection, Band, RfPath);
1450*4882a593Smuzhiyun 		return -1;
1451*4882a593Smuzhiyun 	}
1452*4882a593Smuzhiyun 
1453*4882a593Smuzhiyun 	if (Band == BAND_ON_2_4G)
1454*4882a593Smuzhiyun 		value = regsty->target_tx_pwr_2g[RfPath][RateSection];
1455*4882a593Smuzhiyun #if CONFIG_IEEE80211_BAND_5GHZ
1456*4882a593Smuzhiyun 	else /* BAND_ON_5G */
1457*4882a593Smuzhiyun 		value = regsty->target_tx_pwr_5g[RfPath][RateSection - 1];
1458*4882a593Smuzhiyun #endif
1459*4882a593Smuzhiyun 
1460*4882a593Smuzhiyun 	return value;
1461*4882a593Smuzhiyun }
1462*4882a593Smuzhiyun 
rtw_regsty_chk_target_tx_power_valid(_adapter * adapter)1463*4882a593Smuzhiyun bool rtw_regsty_chk_target_tx_power_valid(_adapter *adapter)
1464*4882a593Smuzhiyun {
1465*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
1466*4882a593Smuzhiyun 	int path, tx_num, band, rs;
1467*4882a593Smuzhiyun 	s8 target;
1468*4882a593Smuzhiyun 
1469*4882a593Smuzhiyun 	for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
1470*4882a593Smuzhiyun 		if (!hal_is_band_support(adapter, band))
1471*4882a593Smuzhiyun 			continue;
1472*4882a593Smuzhiyun 
1473*4882a593Smuzhiyun 		for (path = 0; path < RF_PATH_MAX; path++) {
1474*4882a593Smuzhiyun 			if (!HAL_SPEC_CHK_RF_PATH(hal_spec, band, path))
1475*4882a593Smuzhiyun 				break;
1476*4882a593Smuzhiyun 
1477*4882a593Smuzhiyun 			for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
1478*4882a593Smuzhiyun 				tx_num = rate_section_to_tx_num(rs);
1479*4882a593Smuzhiyun 				if (tx_num + 1 > GET_HAL_TX_NSS(adapter))
1480*4882a593Smuzhiyun 					continue;
1481*4882a593Smuzhiyun 
1482*4882a593Smuzhiyun 				if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
1483*4882a593Smuzhiyun 					continue;
1484*4882a593Smuzhiyun 
1485*4882a593Smuzhiyun 				if (IS_VHT_RATE_SECTION(rs) && !IS_HARDWARE_TYPE_JAGUAR_ALL(adapter))
1486*4882a593Smuzhiyun 					continue;
1487*4882a593Smuzhiyun 
1488*4882a593Smuzhiyun 				target = rtw_regsty_get_target_tx_power(adapter, band, path, rs);
1489*4882a593Smuzhiyun 				if (target == -1) {
1490*4882a593Smuzhiyun 					RTW_PRINT("%s return _FALSE for band:%d, path:%d, rs:%d, t:%d\n", __func__, band, path, rs, target);
1491*4882a593Smuzhiyun 					return _FALSE;
1492*4882a593Smuzhiyun 				}
1493*4882a593Smuzhiyun 			}
1494*4882a593Smuzhiyun 		}
1495*4882a593Smuzhiyun 	}
1496*4882a593Smuzhiyun 
1497*4882a593Smuzhiyun 	return _TRUE;
1498*4882a593Smuzhiyun }
1499*4882a593Smuzhiyun 
1500*4882a593Smuzhiyun /*
1501*4882a593Smuzhiyun * phy_get_target_txpwr -
1502*4882a593Smuzhiyun *
1503*4882a593Smuzhiyun * Return value in unit of TX Gain Index
1504*4882a593Smuzhiyun */
phy_get_target_txpwr(PADAPTER Adapter,u8 Band,u8 RfPath,RATE_SECTION RateSection)1505*4882a593Smuzhiyun u8 phy_get_target_txpwr(
1506*4882a593Smuzhiyun 		PADAPTER		Adapter,
1507*4882a593Smuzhiyun 		u8				Band,
1508*4882a593Smuzhiyun 		u8				RfPath,
1509*4882a593Smuzhiyun 		RATE_SECTION	RateSection
1510*4882a593Smuzhiyun )
1511*4882a593Smuzhiyun {
1512*4882a593Smuzhiyun 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
1513*4882a593Smuzhiyun 	u8 value = 0;
1514*4882a593Smuzhiyun 
1515*4882a593Smuzhiyun 	if (RfPath > RF_PATH_D) {
1516*4882a593Smuzhiyun 		RTW_PRINT("%s invalid RfPath:%d\n", __func__, RfPath);
1517*4882a593Smuzhiyun 		return 0;
1518*4882a593Smuzhiyun 	}
1519*4882a593Smuzhiyun 
1520*4882a593Smuzhiyun 	if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) {
1521*4882a593Smuzhiyun 		RTW_PRINT("%s invalid Band:%d\n", __func__, Band);
1522*4882a593Smuzhiyun 		return 0;
1523*4882a593Smuzhiyun 	}
1524*4882a593Smuzhiyun 
1525*4882a593Smuzhiyun 	if (RateSection >= RATE_SECTION_NUM
1526*4882a593Smuzhiyun 		|| (Band == BAND_ON_5G && RateSection == CCK)
1527*4882a593Smuzhiyun 	) {
1528*4882a593Smuzhiyun 		RTW_PRINT("%s invalid RateSection:%d in Band:%d, RfPath:%d\n", __func__
1529*4882a593Smuzhiyun 			, RateSection, Band, RfPath);
1530*4882a593Smuzhiyun 		return 0;
1531*4882a593Smuzhiyun 	}
1532*4882a593Smuzhiyun 
1533*4882a593Smuzhiyun 	if (Band == BAND_ON_2_4G)
1534*4882a593Smuzhiyun 		value = pHalData->target_txpwr_2g[RfPath][RateSection];
1535*4882a593Smuzhiyun 	else if (Band == BAND_ON_5G)
1536*4882a593Smuzhiyun 		value = pHalData->target_txpwr_5g[RfPath][RateSection - 1];
1537*4882a593Smuzhiyun 
1538*4882a593Smuzhiyun 	return value;
1539*4882a593Smuzhiyun }
1540*4882a593Smuzhiyun 
phy_set_target_txpwr(PADAPTER Adapter,u8 Band,u8 RfPath,RATE_SECTION RateSection,u8 Value)1541*4882a593Smuzhiyun static void phy_set_target_txpwr(
1542*4882a593Smuzhiyun 		PADAPTER		Adapter,
1543*4882a593Smuzhiyun 		u8				Band,
1544*4882a593Smuzhiyun 		u8				RfPath,
1545*4882a593Smuzhiyun 		RATE_SECTION	RateSection,
1546*4882a593Smuzhiyun 		u8				Value
1547*4882a593Smuzhiyun )
1548*4882a593Smuzhiyun {
1549*4882a593Smuzhiyun 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
1550*4882a593Smuzhiyun 
1551*4882a593Smuzhiyun 	if (RfPath > RF_PATH_D) {
1552*4882a593Smuzhiyun 		RTW_PRINT("%s invalid RfPath:%d\n", __func__, RfPath);
1553*4882a593Smuzhiyun 		return;
1554*4882a593Smuzhiyun 	}
1555*4882a593Smuzhiyun 
1556*4882a593Smuzhiyun 	if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) {
1557*4882a593Smuzhiyun 		RTW_PRINT("%s invalid Band:%d\n", __func__, Band);
1558*4882a593Smuzhiyun 		return;
1559*4882a593Smuzhiyun 	}
1560*4882a593Smuzhiyun 
1561*4882a593Smuzhiyun 	if (RateSection >= RATE_SECTION_NUM
1562*4882a593Smuzhiyun 		|| (Band == BAND_ON_5G && RateSection == CCK)
1563*4882a593Smuzhiyun 	) {
1564*4882a593Smuzhiyun 		RTW_PRINT("%s invalid RateSection:%d in %sG, RfPath:%d\n", __func__
1565*4882a593Smuzhiyun 			, RateSection, (Band == BAND_ON_2_4G) ? "2.4" : "5", RfPath);
1566*4882a593Smuzhiyun 		return;
1567*4882a593Smuzhiyun 	}
1568*4882a593Smuzhiyun 
1569*4882a593Smuzhiyun 	if (Band == BAND_ON_2_4G)
1570*4882a593Smuzhiyun 		pHalData->target_txpwr_2g[RfPath][RateSection] = Value;
1571*4882a593Smuzhiyun 	else /* BAND_ON_5G */
1572*4882a593Smuzhiyun 		pHalData->target_txpwr_5g[RfPath][RateSection - 1] = Value;
1573*4882a593Smuzhiyun }
1574*4882a593Smuzhiyun 
phy_is_txpwr_by_rate_undefined_of_band_path(_adapter * adapter,u8 band,u8 path)1575*4882a593Smuzhiyun static inline BOOLEAN phy_is_txpwr_by_rate_undefined_of_band_path(_adapter *adapter, u8 band, u8 path)
1576*4882a593Smuzhiyun {
1577*4882a593Smuzhiyun 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1578*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
1579*4882a593Smuzhiyun 	u8 rate_idx = 0;
1580*4882a593Smuzhiyun 
1581*4882a593Smuzhiyun 	for (rate_idx = 0; rate_idx < TX_PWR_BY_RATE_NUM_RATE; rate_idx++) {
1582*4882a593Smuzhiyun 		if (hal_data->TxPwrByRate[band][path][rate_idx] != hal_spec->txgi_max)
1583*4882a593Smuzhiyun 			goto exit;
1584*4882a593Smuzhiyun 	}
1585*4882a593Smuzhiyun 
1586*4882a593Smuzhiyun exit:
1587*4882a593Smuzhiyun 	return rate_idx >= TX_PWR_BY_RATE_NUM_RATE ? _TRUE : _FALSE;
1588*4882a593Smuzhiyun }
1589*4882a593Smuzhiyun 
phy_txpwr_by_rate_duplicate_band_path(_adapter * adapter,u8 band,u8 s_path,u8 t_path)1590*4882a593Smuzhiyun static inline void phy_txpwr_by_rate_duplicate_band_path(_adapter *adapter, u8 band, u8 s_path, u8 t_path)
1591*4882a593Smuzhiyun {
1592*4882a593Smuzhiyun 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1593*4882a593Smuzhiyun 	u8 rate_idx = 0;
1594*4882a593Smuzhiyun 
1595*4882a593Smuzhiyun 	for (rate_idx = 0; rate_idx < TX_PWR_BY_RATE_NUM_RATE; rate_idx++)
1596*4882a593Smuzhiyun 		hal_data->TxPwrByRate[band][t_path][rate_idx] = hal_data->TxPwrByRate[band][s_path][rate_idx];
1597*4882a593Smuzhiyun }
1598*4882a593Smuzhiyun 
phy_txpwr_by_rate_chk_for_path_dup(_adapter * adapter)1599*4882a593Smuzhiyun static void phy_txpwr_by_rate_chk_for_path_dup(_adapter *adapter)
1600*4882a593Smuzhiyun {
1601*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
1602*4882a593Smuzhiyun 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1603*4882a593Smuzhiyun 	u8 band, path;
1604*4882a593Smuzhiyun 	s8 src_path;
1605*4882a593Smuzhiyun 
1606*4882a593Smuzhiyun 	for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++)
1607*4882a593Smuzhiyun 		for (path = RF_PATH_A; path < RF_PATH_MAX; path++)
1608*4882a593Smuzhiyun 			hal_data->txpwr_by_rate_undefined_band_path[band][path] = 0;
1609*4882a593Smuzhiyun 
1610*4882a593Smuzhiyun 	for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
1611*4882a593Smuzhiyun 		if (!hal_is_band_support(adapter, band))
1612*4882a593Smuzhiyun 			continue;
1613*4882a593Smuzhiyun 
1614*4882a593Smuzhiyun 		for (path = RF_PATH_A; path < RF_PATH_MAX; path++) {
1615*4882a593Smuzhiyun 			if (!HAL_SPEC_CHK_RF_PATH(hal_spec, band, path))
1616*4882a593Smuzhiyun 				continue;
1617*4882a593Smuzhiyun 
1618*4882a593Smuzhiyun 			if (phy_is_txpwr_by_rate_undefined_of_band_path(adapter, band, path))
1619*4882a593Smuzhiyun 				hal_data->txpwr_by_rate_undefined_band_path[band][path] = 1;
1620*4882a593Smuzhiyun 		}
1621*4882a593Smuzhiyun 	}
1622*4882a593Smuzhiyun 
1623*4882a593Smuzhiyun 	for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
1624*4882a593Smuzhiyun 		if (!hal_is_band_support(adapter, band))
1625*4882a593Smuzhiyun 			continue;
1626*4882a593Smuzhiyun 
1627*4882a593Smuzhiyun 		src_path = -1;
1628*4882a593Smuzhiyun 		for (path = RF_PATH_A; path < RF_PATH_MAX; path++) {
1629*4882a593Smuzhiyun 			if (!HAL_SPEC_CHK_RF_PATH(hal_spec, band, path))
1630*4882a593Smuzhiyun 				continue;
1631*4882a593Smuzhiyun 
1632*4882a593Smuzhiyun 			/* find src */
1633*4882a593Smuzhiyun 			if (src_path == -1 && hal_data->txpwr_by_rate_undefined_band_path[band][path] == 0)
1634*4882a593Smuzhiyun 				src_path = path;
1635*4882a593Smuzhiyun 		}
1636*4882a593Smuzhiyun 
1637*4882a593Smuzhiyun 		if (src_path == -1) {
1638*4882a593Smuzhiyun 			RTW_ERR("%s all power by rate undefined\n", __func__);
1639*4882a593Smuzhiyun 			continue;
1640*4882a593Smuzhiyun 		}
1641*4882a593Smuzhiyun 
1642*4882a593Smuzhiyun 		for (path = RF_PATH_A; path < RF_PATH_MAX; path++) {
1643*4882a593Smuzhiyun 			if (!HAL_SPEC_CHK_RF_PATH(hal_spec, band, path))
1644*4882a593Smuzhiyun 				continue;
1645*4882a593Smuzhiyun 
1646*4882a593Smuzhiyun 			/* duplicate src to undefined one */
1647*4882a593Smuzhiyun 			if (hal_data->txpwr_by_rate_undefined_band_path[band][path] == 1) {
1648*4882a593Smuzhiyun 				RTW_INFO("%s duplicate %s [%c] to [%c]\n", __func__
1649*4882a593Smuzhiyun 					, band_str(band), rf_path_char(src_path), rf_path_char(path));
1650*4882a593Smuzhiyun 				phy_txpwr_by_rate_duplicate_band_path(adapter, band, src_path, path);
1651*4882a593Smuzhiyun 			}
1652*4882a593Smuzhiyun 		}
1653*4882a593Smuzhiyun 	}
1654*4882a593Smuzhiyun }
1655*4882a593Smuzhiyun 
phy_store_target_tx_power(PADAPTER pAdapter)1656*4882a593Smuzhiyun void phy_store_target_tx_power(PADAPTER	pAdapter)
1657*4882a593Smuzhiyun {
1658*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(pAdapter);
1659*4882a593Smuzhiyun 	struct registry_priv *regsty = adapter_to_regsty(pAdapter);
1660*4882a593Smuzhiyun 
1661*4882a593Smuzhiyun 	u8 band, path, rs, tx_num, base;
1662*4882a593Smuzhiyun 
1663*4882a593Smuzhiyun 	for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
1664*4882a593Smuzhiyun 		if (!hal_is_band_support(pAdapter, band))
1665*4882a593Smuzhiyun 			continue;
1666*4882a593Smuzhiyun 
1667*4882a593Smuzhiyun 		for (path = RF_PATH_A; path < RF_PATH_MAX; path++) {
1668*4882a593Smuzhiyun 			if (!HAL_SPEC_CHK_RF_PATH(hal_spec, band, path))
1669*4882a593Smuzhiyun 				break;
1670*4882a593Smuzhiyun 
1671*4882a593Smuzhiyun 			for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
1672*4882a593Smuzhiyun 				tx_num = rate_section_to_tx_num(rs);
1673*4882a593Smuzhiyun 				if (tx_num + 1 > GET_HAL_TX_NSS(pAdapter))
1674*4882a593Smuzhiyun 					continue;
1675*4882a593Smuzhiyun 
1676*4882a593Smuzhiyun 				if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
1677*4882a593Smuzhiyun 					continue;
1678*4882a593Smuzhiyun 
1679*4882a593Smuzhiyun 				if (IS_VHT_RATE_SECTION(rs) && !IS_HARDWARE_TYPE_JAGUAR_ALL(pAdapter))
1680*4882a593Smuzhiyun 					continue;
1681*4882a593Smuzhiyun 
1682*4882a593Smuzhiyun 				if (regsty->target_tx_pwr_valid == _TRUE)
1683*4882a593Smuzhiyun 					base = hal_spec->txgi_pdbm * rtw_regsty_get_target_tx_power(pAdapter, band, path, rs);
1684*4882a593Smuzhiyun 				else
1685*4882a593Smuzhiyun 					base = _PHY_GetTxPowerByRate(pAdapter, band, path, rate_sec_base[rs]);
1686*4882a593Smuzhiyun 				phy_set_target_txpwr(pAdapter, band, path, rs, base);
1687*4882a593Smuzhiyun 			}
1688*4882a593Smuzhiyun 		}
1689*4882a593Smuzhiyun 	}
1690*4882a593Smuzhiyun }
1691*4882a593Smuzhiyun 
get_val_from_dhex(u32 dhex,u8 i)1692*4882a593Smuzhiyun static u8 get_val_from_dhex(u32 dhex, u8 i)
1693*4882a593Smuzhiyun {
1694*4882a593Smuzhiyun 	return (((dhex >> (i * 8 + 4)) & 0xF)) * 10 + ((dhex >> (i * 8)) & 0xF);
1695*4882a593Smuzhiyun }
1696*4882a593Smuzhiyun 
get_val_from_hex(u32 hex,u8 i)1697*4882a593Smuzhiyun static u8 get_val_from_hex(u32 hex, u8 i)
1698*4882a593Smuzhiyun {
1699*4882a593Smuzhiyun 	return (hex >> (i * 8)) & 0xFF;
1700*4882a593Smuzhiyun }
1701*4882a593Smuzhiyun 
1702*4882a593Smuzhiyun void
PHY_GetRateValuesOfTxPowerByRate(PADAPTER pAdapter,u32 RegAddr,u32 BitMask,u32 Value,u8 * Rate,s8 * PwrByRateVal,u8 * RateNum)1703*4882a593Smuzhiyun PHY_GetRateValuesOfTxPowerByRate(
1704*4882a593Smuzhiyun 		PADAPTER pAdapter,
1705*4882a593Smuzhiyun 		u32 RegAddr,
1706*4882a593Smuzhiyun 		u32 BitMask,
1707*4882a593Smuzhiyun 		u32 Value,
1708*4882a593Smuzhiyun 		u8 *Rate,
1709*4882a593Smuzhiyun 		s8 *PwrByRateVal,
1710*4882a593Smuzhiyun 		u8 *RateNum
1711*4882a593Smuzhiyun )
1712*4882a593Smuzhiyun {
1713*4882a593Smuzhiyun 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(pAdapter);
1714*4882a593Smuzhiyun 	struct dm_struct		*pDM_Odm = &pHalData->odmpriv;
1715*4882a593Smuzhiyun 	u8 i = 0;
1716*4882a593Smuzhiyun 	u8 (*get_val)(u32, u8);
1717*4882a593Smuzhiyun 
1718*4882a593Smuzhiyun 	if (pDM_Odm->phy_reg_pg_version == 1)
1719*4882a593Smuzhiyun 		get_val = get_val_from_dhex;
1720*4882a593Smuzhiyun 	else
1721*4882a593Smuzhiyun 		get_val = get_val_from_hex;
1722*4882a593Smuzhiyun 
1723*4882a593Smuzhiyun 	switch (RegAddr) {
1724*4882a593Smuzhiyun 	case rTxAGC_A_Rate18_06:
1725*4882a593Smuzhiyun 	case rTxAGC_B_Rate18_06:
1726*4882a593Smuzhiyun 		Rate[0] = MGN_6M;
1727*4882a593Smuzhiyun 		Rate[1] = MGN_9M;
1728*4882a593Smuzhiyun 		Rate[2] = MGN_12M;
1729*4882a593Smuzhiyun 		Rate[3] = MGN_18M;
1730*4882a593Smuzhiyun 		for (i = 0; i < 4; ++i)
1731*4882a593Smuzhiyun 			PwrByRateVal[i] = (s8)get_val(Value, i);
1732*4882a593Smuzhiyun 		*RateNum = 4;
1733*4882a593Smuzhiyun 		break;
1734*4882a593Smuzhiyun 
1735*4882a593Smuzhiyun 	case rTxAGC_A_Rate54_24:
1736*4882a593Smuzhiyun 	case rTxAGC_B_Rate54_24:
1737*4882a593Smuzhiyun 		Rate[0] = MGN_24M;
1738*4882a593Smuzhiyun 		Rate[1] = MGN_36M;
1739*4882a593Smuzhiyun 		Rate[2] = MGN_48M;
1740*4882a593Smuzhiyun 		Rate[3] = MGN_54M;
1741*4882a593Smuzhiyun 		for (i = 0; i < 4; ++i)
1742*4882a593Smuzhiyun 			PwrByRateVal[i] = (s8)get_val(Value, i);
1743*4882a593Smuzhiyun 		*RateNum = 4;
1744*4882a593Smuzhiyun 		break;
1745*4882a593Smuzhiyun 
1746*4882a593Smuzhiyun 	case rTxAGC_A_CCK1_Mcs32:
1747*4882a593Smuzhiyun 		Rate[0] = MGN_1M;
1748*4882a593Smuzhiyun 		PwrByRateVal[0] = (s8)get_val(Value, 1);
1749*4882a593Smuzhiyun 		*RateNum = 1;
1750*4882a593Smuzhiyun 		break;
1751*4882a593Smuzhiyun 
1752*4882a593Smuzhiyun 	case rTxAGC_B_CCK11_A_CCK2_11:
1753*4882a593Smuzhiyun 		if (BitMask == 0xffffff00) {
1754*4882a593Smuzhiyun 			Rate[0] = MGN_2M;
1755*4882a593Smuzhiyun 			Rate[1] = MGN_5_5M;
1756*4882a593Smuzhiyun 			Rate[2] = MGN_11M;
1757*4882a593Smuzhiyun 			for (i = 1; i < 4; ++i)
1758*4882a593Smuzhiyun 				PwrByRateVal[i - 1] = (s8)get_val(Value, i);
1759*4882a593Smuzhiyun 			*RateNum = 3;
1760*4882a593Smuzhiyun 		} else if (BitMask == 0x000000ff) {
1761*4882a593Smuzhiyun 			Rate[0] = MGN_11M;
1762*4882a593Smuzhiyun 			PwrByRateVal[0] = (s8)get_val(Value, 0);
1763*4882a593Smuzhiyun 			*RateNum = 1;
1764*4882a593Smuzhiyun 		}
1765*4882a593Smuzhiyun 		break;
1766*4882a593Smuzhiyun 
1767*4882a593Smuzhiyun 	case rTxAGC_A_Mcs03_Mcs00:
1768*4882a593Smuzhiyun 	case rTxAGC_B_Mcs03_Mcs00:
1769*4882a593Smuzhiyun 		Rate[0] = MGN_MCS0;
1770*4882a593Smuzhiyun 		Rate[1] = MGN_MCS1;
1771*4882a593Smuzhiyun 		Rate[2] = MGN_MCS2;
1772*4882a593Smuzhiyun 		Rate[3] = MGN_MCS3;
1773*4882a593Smuzhiyun 		for (i = 0; i < 4; ++i)
1774*4882a593Smuzhiyun 			PwrByRateVal[i] = (s8)get_val(Value, i);
1775*4882a593Smuzhiyun 		*RateNum = 4;
1776*4882a593Smuzhiyun 		break;
1777*4882a593Smuzhiyun 
1778*4882a593Smuzhiyun 	case rTxAGC_A_Mcs07_Mcs04:
1779*4882a593Smuzhiyun 	case rTxAGC_B_Mcs07_Mcs04:
1780*4882a593Smuzhiyun 		Rate[0] = MGN_MCS4;
1781*4882a593Smuzhiyun 		Rate[1] = MGN_MCS5;
1782*4882a593Smuzhiyun 		Rate[2] = MGN_MCS6;
1783*4882a593Smuzhiyun 		Rate[3] = MGN_MCS7;
1784*4882a593Smuzhiyun 		for (i = 0; i < 4; ++i)
1785*4882a593Smuzhiyun 			PwrByRateVal[i] = (s8)get_val(Value, i);
1786*4882a593Smuzhiyun 		*RateNum = 4;
1787*4882a593Smuzhiyun 		break;
1788*4882a593Smuzhiyun 
1789*4882a593Smuzhiyun 	case rTxAGC_A_Mcs11_Mcs08:
1790*4882a593Smuzhiyun 	case rTxAGC_B_Mcs11_Mcs08:
1791*4882a593Smuzhiyun 		Rate[0] = MGN_MCS8;
1792*4882a593Smuzhiyun 		Rate[1] = MGN_MCS9;
1793*4882a593Smuzhiyun 		Rate[2] = MGN_MCS10;
1794*4882a593Smuzhiyun 		Rate[3] = MGN_MCS11;
1795*4882a593Smuzhiyun 		for (i = 0; i < 4; ++i)
1796*4882a593Smuzhiyun 			PwrByRateVal[i] = (s8)get_val(Value, i);
1797*4882a593Smuzhiyun 		*RateNum = 4;
1798*4882a593Smuzhiyun 		break;
1799*4882a593Smuzhiyun 
1800*4882a593Smuzhiyun 	case rTxAGC_A_Mcs15_Mcs12:
1801*4882a593Smuzhiyun 	case rTxAGC_B_Mcs15_Mcs12:
1802*4882a593Smuzhiyun 		Rate[0] = MGN_MCS12;
1803*4882a593Smuzhiyun 		Rate[1] = MGN_MCS13;
1804*4882a593Smuzhiyun 		Rate[2] = MGN_MCS14;
1805*4882a593Smuzhiyun 		Rate[3] = MGN_MCS15;
1806*4882a593Smuzhiyun 		for (i = 0; i < 4; ++i)
1807*4882a593Smuzhiyun 			PwrByRateVal[i] = (s8)get_val(Value, i);
1808*4882a593Smuzhiyun 		*RateNum = 4;
1809*4882a593Smuzhiyun 		break;
1810*4882a593Smuzhiyun 
1811*4882a593Smuzhiyun 	case rTxAGC_B_CCK1_55_Mcs32:
1812*4882a593Smuzhiyun 		Rate[0] = MGN_1M;
1813*4882a593Smuzhiyun 		Rate[1] = MGN_2M;
1814*4882a593Smuzhiyun 		Rate[2] = MGN_5_5M;
1815*4882a593Smuzhiyun 		for (i = 1; i < 4; ++i)
1816*4882a593Smuzhiyun 			PwrByRateVal[i - 1] = (s8)get_val(Value, i);
1817*4882a593Smuzhiyun 		*RateNum = 3;
1818*4882a593Smuzhiyun 		break;
1819*4882a593Smuzhiyun 
1820*4882a593Smuzhiyun 	case 0xC20:
1821*4882a593Smuzhiyun 	case 0xE20:
1822*4882a593Smuzhiyun 	case 0x1820:
1823*4882a593Smuzhiyun 	case 0x1a20:
1824*4882a593Smuzhiyun 		Rate[0] = MGN_1M;
1825*4882a593Smuzhiyun 		Rate[1] = MGN_2M;
1826*4882a593Smuzhiyun 		Rate[2] = MGN_5_5M;
1827*4882a593Smuzhiyun 		Rate[3] = MGN_11M;
1828*4882a593Smuzhiyun 		for (i = 0; i < 4; ++i)
1829*4882a593Smuzhiyun 			PwrByRateVal[i] = (s8)get_val(Value, i);
1830*4882a593Smuzhiyun 		*RateNum = 4;
1831*4882a593Smuzhiyun 		break;
1832*4882a593Smuzhiyun 
1833*4882a593Smuzhiyun 	case 0xC24:
1834*4882a593Smuzhiyun 	case 0xE24:
1835*4882a593Smuzhiyun 	case 0x1824:
1836*4882a593Smuzhiyun 	case 0x1a24:
1837*4882a593Smuzhiyun 		Rate[0] = MGN_6M;
1838*4882a593Smuzhiyun 		Rate[1] = MGN_9M;
1839*4882a593Smuzhiyun 		Rate[2] = MGN_12M;
1840*4882a593Smuzhiyun 		Rate[3] = MGN_18M;
1841*4882a593Smuzhiyun 		for (i = 0; i < 4; ++i)
1842*4882a593Smuzhiyun 			PwrByRateVal[i] = (s8)get_val(Value, i);
1843*4882a593Smuzhiyun 		*RateNum = 4;
1844*4882a593Smuzhiyun 		break;
1845*4882a593Smuzhiyun 
1846*4882a593Smuzhiyun 	case 0xC28:
1847*4882a593Smuzhiyun 	case 0xE28:
1848*4882a593Smuzhiyun 	case 0x1828:
1849*4882a593Smuzhiyun 	case 0x1a28:
1850*4882a593Smuzhiyun 		Rate[0] = MGN_24M;
1851*4882a593Smuzhiyun 		Rate[1] = MGN_36M;
1852*4882a593Smuzhiyun 		Rate[2] = MGN_48M;
1853*4882a593Smuzhiyun 		Rate[3] = MGN_54M;
1854*4882a593Smuzhiyun 		for (i = 0; i < 4; ++i)
1855*4882a593Smuzhiyun 			PwrByRateVal[i] = (s8)get_val(Value, i);
1856*4882a593Smuzhiyun 		*RateNum = 4;
1857*4882a593Smuzhiyun 		break;
1858*4882a593Smuzhiyun 
1859*4882a593Smuzhiyun 	case 0xC2C:
1860*4882a593Smuzhiyun 	case 0xE2C:
1861*4882a593Smuzhiyun 	case 0x182C:
1862*4882a593Smuzhiyun 	case 0x1a2C:
1863*4882a593Smuzhiyun 		Rate[0] = MGN_MCS0;
1864*4882a593Smuzhiyun 		Rate[1] = MGN_MCS1;
1865*4882a593Smuzhiyun 		Rate[2] = MGN_MCS2;
1866*4882a593Smuzhiyun 		Rate[3] = MGN_MCS3;
1867*4882a593Smuzhiyun 		for (i = 0; i < 4; ++i)
1868*4882a593Smuzhiyun 			PwrByRateVal[i] = (s8)get_val(Value, i);
1869*4882a593Smuzhiyun 		*RateNum = 4;
1870*4882a593Smuzhiyun 		break;
1871*4882a593Smuzhiyun 
1872*4882a593Smuzhiyun 	case 0xC30:
1873*4882a593Smuzhiyun 	case 0xE30:
1874*4882a593Smuzhiyun 	case 0x1830:
1875*4882a593Smuzhiyun 	case 0x1a30:
1876*4882a593Smuzhiyun 		Rate[0] = MGN_MCS4;
1877*4882a593Smuzhiyun 		Rate[1] = MGN_MCS5;
1878*4882a593Smuzhiyun 		Rate[2] = MGN_MCS6;
1879*4882a593Smuzhiyun 		Rate[3] = MGN_MCS7;
1880*4882a593Smuzhiyun 		for (i = 0; i < 4; ++i)
1881*4882a593Smuzhiyun 			PwrByRateVal[i] = (s8)get_val(Value, i);
1882*4882a593Smuzhiyun 		*RateNum = 4;
1883*4882a593Smuzhiyun 		break;
1884*4882a593Smuzhiyun 
1885*4882a593Smuzhiyun 	case 0xC34:
1886*4882a593Smuzhiyun 	case 0xE34:
1887*4882a593Smuzhiyun 	case 0x1834:
1888*4882a593Smuzhiyun 	case 0x1a34:
1889*4882a593Smuzhiyun 		Rate[0] = MGN_MCS8;
1890*4882a593Smuzhiyun 		Rate[1] = MGN_MCS9;
1891*4882a593Smuzhiyun 		Rate[2] = MGN_MCS10;
1892*4882a593Smuzhiyun 		Rate[3] = MGN_MCS11;
1893*4882a593Smuzhiyun 		for (i = 0; i < 4; ++i)
1894*4882a593Smuzhiyun 			PwrByRateVal[i] = (s8)get_val(Value, i);
1895*4882a593Smuzhiyun 		*RateNum = 4;
1896*4882a593Smuzhiyun 		break;
1897*4882a593Smuzhiyun 
1898*4882a593Smuzhiyun 	case 0xC38:
1899*4882a593Smuzhiyun 	case 0xE38:
1900*4882a593Smuzhiyun 	case 0x1838:
1901*4882a593Smuzhiyun 	case 0x1a38:
1902*4882a593Smuzhiyun 		Rate[0] = MGN_MCS12;
1903*4882a593Smuzhiyun 		Rate[1] = MGN_MCS13;
1904*4882a593Smuzhiyun 		Rate[2] = MGN_MCS14;
1905*4882a593Smuzhiyun 		Rate[3] = MGN_MCS15;
1906*4882a593Smuzhiyun 		for (i = 0; i < 4; ++i)
1907*4882a593Smuzhiyun 			PwrByRateVal[i] = (s8)get_val(Value, i);
1908*4882a593Smuzhiyun 		*RateNum = 4;
1909*4882a593Smuzhiyun 		break;
1910*4882a593Smuzhiyun 
1911*4882a593Smuzhiyun 	case 0xC3C:
1912*4882a593Smuzhiyun 	case 0xE3C:
1913*4882a593Smuzhiyun 	case 0x183C:
1914*4882a593Smuzhiyun 	case 0x1a3C:
1915*4882a593Smuzhiyun 		Rate[0] = MGN_VHT1SS_MCS0;
1916*4882a593Smuzhiyun 		Rate[1] = MGN_VHT1SS_MCS1;
1917*4882a593Smuzhiyun 		Rate[2] = MGN_VHT1SS_MCS2;
1918*4882a593Smuzhiyun 		Rate[3] = MGN_VHT1SS_MCS3;
1919*4882a593Smuzhiyun 		for (i = 0; i < 4; ++i)
1920*4882a593Smuzhiyun 			PwrByRateVal[i] = (s8)get_val(Value, i);
1921*4882a593Smuzhiyun 		*RateNum = 4;
1922*4882a593Smuzhiyun 		break;
1923*4882a593Smuzhiyun 
1924*4882a593Smuzhiyun 	case 0xC40:
1925*4882a593Smuzhiyun 	case 0xE40:
1926*4882a593Smuzhiyun 	case 0x1840:
1927*4882a593Smuzhiyun 	case 0x1a40:
1928*4882a593Smuzhiyun 		Rate[0] = MGN_VHT1SS_MCS4;
1929*4882a593Smuzhiyun 		Rate[1] = MGN_VHT1SS_MCS5;
1930*4882a593Smuzhiyun 		Rate[2] = MGN_VHT1SS_MCS6;
1931*4882a593Smuzhiyun 		Rate[3] = MGN_VHT1SS_MCS7;
1932*4882a593Smuzhiyun 		for (i = 0; i < 4; ++i)
1933*4882a593Smuzhiyun 			PwrByRateVal[i] = (s8)get_val(Value, i);
1934*4882a593Smuzhiyun 		*RateNum = 4;
1935*4882a593Smuzhiyun 		break;
1936*4882a593Smuzhiyun 
1937*4882a593Smuzhiyun 	case 0xC44:
1938*4882a593Smuzhiyun 	case 0xE44:
1939*4882a593Smuzhiyun 	case 0x1844:
1940*4882a593Smuzhiyun 	case 0x1a44:
1941*4882a593Smuzhiyun 		Rate[0] = MGN_VHT1SS_MCS8;
1942*4882a593Smuzhiyun 		Rate[1] = MGN_VHT1SS_MCS9;
1943*4882a593Smuzhiyun 		Rate[2] = MGN_VHT2SS_MCS0;
1944*4882a593Smuzhiyun 		Rate[3] = MGN_VHT2SS_MCS1;
1945*4882a593Smuzhiyun 		for (i = 0; i < 4; ++i)
1946*4882a593Smuzhiyun 			PwrByRateVal[i] = (s8)get_val(Value, i);
1947*4882a593Smuzhiyun 		*RateNum = 4;
1948*4882a593Smuzhiyun 		break;
1949*4882a593Smuzhiyun 
1950*4882a593Smuzhiyun 	case 0xC48:
1951*4882a593Smuzhiyun 	case 0xE48:
1952*4882a593Smuzhiyun 	case 0x1848:
1953*4882a593Smuzhiyun 	case 0x1a48:
1954*4882a593Smuzhiyun 		Rate[0] = MGN_VHT2SS_MCS2;
1955*4882a593Smuzhiyun 		Rate[1] = MGN_VHT2SS_MCS3;
1956*4882a593Smuzhiyun 		Rate[2] = MGN_VHT2SS_MCS4;
1957*4882a593Smuzhiyun 		Rate[3] = MGN_VHT2SS_MCS5;
1958*4882a593Smuzhiyun 		for (i = 0; i < 4; ++i)
1959*4882a593Smuzhiyun 			PwrByRateVal[i] = (s8)get_val(Value, i);
1960*4882a593Smuzhiyun 		*RateNum = 4;
1961*4882a593Smuzhiyun 		break;
1962*4882a593Smuzhiyun 
1963*4882a593Smuzhiyun 	case 0xC4C:
1964*4882a593Smuzhiyun 	case 0xE4C:
1965*4882a593Smuzhiyun 	case 0x184C:
1966*4882a593Smuzhiyun 	case 0x1a4C:
1967*4882a593Smuzhiyun 		Rate[0] = MGN_VHT2SS_MCS6;
1968*4882a593Smuzhiyun 		Rate[1] = MGN_VHT2SS_MCS7;
1969*4882a593Smuzhiyun 		Rate[2] = MGN_VHT2SS_MCS8;
1970*4882a593Smuzhiyun 		Rate[3] = MGN_VHT2SS_MCS9;
1971*4882a593Smuzhiyun 		for (i = 0; i < 4; ++i)
1972*4882a593Smuzhiyun 			PwrByRateVal[i] = (s8)get_val(Value, i);
1973*4882a593Smuzhiyun 		*RateNum = 4;
1974*4882a593Smuzhiyun 		break;
1975*4882a593Smuzhiyun 
1976*4882a593Smuzhiyun 	case 0xCD8:
1977*4882a593Smuzhiyun 	case 0xED8:
1978*4882a593Smuzhiyun 	case 0x18D8:
1979*4882a593Smuzhiyun 	case 0x1aD8:
1980*4882a593Smuzhiyun 		Rate[0] = MGN_MCS16;
1981*4882a593Smuzhiyun 		Rate[1] = MGN_MCS17;
1982*4882a593Smuzhiyun 		Rate[2] = MGN_MCS18;
1983*4882a593Smuzhiyun 		Rate[3] = MGN_MCS19;
1984*4882a593Smuzhiyun 		for (i = 0; i < 4; ++i)
1985*4882a593Smuzhiyun 			PwrByRateVal[i] = (s8)get_val(Value, i);
1986*4882a593Smuzhiyun 		*RateNum = 4;
1987*4882a593Smuzhiyun 		break;
1988*4882a593Smuzhiyun 
1989*4882a593Smuzhiyun 	case 0xCDC:
1990*4882a593Smuzhiyun 	case 0xEDC:
1991*4882a593Smuzhiyun 	case 0x18DC:
1992*4882a593Smuzhiyun 	case 0x1aDC:
1993*4882a593Smuzhiyun 		Rate[0] = MGN_MCS20;
1994*4882a593Smuzhiyun 		Rate[1] = MGN_MCS21;
1995*4882a593Smuzhiyun 		Rate[2] = MGN_MCS22;
1996*4882a593Smuzhiyun 		Rate[3] = MGN_MCS23;
1997*4882a593Smuzhiyun 		for (i = 0; i < 4; ++i)
1998*4882a593Smuzhiyun 			PwrByRateVal[i] = (s8)get_val(Value, i);
1999*4882a593Smuzhiyun 		*RateNum = 4;
2000*4882a593Smuzhiyun 		break;
2001*4882a593Smuzhiyun 
2002*4882a593Smuzhiyun 	case 0x3a24: /* HT MCS24-27 */
2003*4882a593Smuzhiyun 		Rate[0] = MGN_MCS24;
2004*4882a593Smuzhiyun 		Rate[1] = MGN_MCS25;
2005*4882a593Smuzhiyun 		Rate[2] = MGN_MCS26;
2006*4882a593Smuzhiyun 		Rate[3] = MGN_MCS27;
2007*4882a593Smuzhiyun 		for (i = 0; i < 4; ++i)
2008*4882a593Smuzhiyun 			PwrByRateVal[i] = (s8)get_val(Value, i);
2009*4882a593Smuzhiyun 		*RateNum = 4;
2010*4882a593Smuzhiyun 		break;
2011*4882a593Smuzhiyun 
2012*4882a593Smuzhiyun 	case 0x3a28: /* HT MCS28-31 */
2013*4882a593Smuzhiyun 		Rate[0] = MGN_MCS28;
2014*4882a593Smuzhiyun 		Rate[1] = MGN_MCS29;
2015*4882a593Smuzhiyun 		Rate[2] = MGN_MCS30;
2016*4882a593Smuzhiyun 		Rate[3] = MGN_MCS31;
2017*4882a593Smuzhiyun 		for (i = 0; i < 4; ++i)
2018*4882a593Smuzhiyun 			PwrByRateVal[i] = (s8)get_val(Value, i);
2019*4882a593Smuzhiyun 		*RateNum = 4;
2020*4882a593Smuzhiyun 		break;
2021*4882a593Smuzhiyun 
2022*4882a593Smuzhiyun 	case 0xCE0:
2023*4882a593Smuzhiyun 	case 0xEE0:
2024*4882a593Smuzhiyun 	case 0x18E0:
2025*4882a593Smuzhiyun 	case 0x1aE0:
2026*4882a593Smuzhiyun 		Rate[0] = MGN_VHT3SS_MCS0;
2027*4882a593Smuzhiyun 		Rate[1] = MGN_VHT3SS_MCS1;
2028*4882a593Smuzhiyun 		Rate[2] = MGN_VHT3SS_MCS2;
2029*4882a593Smuzhiyun 		Rate[3] = MGN_VHT3SS_MCS3;
2030*4882a593Smuzhiyun 		for (i = 0; i < 4; ++i)
2031*4882a593Smuzhiyun 			PwrByRateVal[i] = (s8)get_val(Value, i);
2032*4882a593Smuzhiyun 		*RateNum = 4;
2033*4882a593Smuzhiyun 		break;
2034*4882a593Smuzhiyun 
2035*4882a593Smuzhiyun 	case 0xCE4:
2036*4882a593Smuzhiyun 	case 0xEE4:
2037*4882a593Smuzhiyun 	case 0x18E4:
2038*4882a593Smuzhiyun 	case 0x1aE4:
2039*4882a593Smuzhiyun 		Rate[0] = MGN_VHT3SS_MCS4;
2040*4882a593Smuzhiyun 		Rate[1] = MGN_VHT3SS_MCS5;
2041*4882a593Smuzhiyun 		Rate[2] = MGN_VHT3SS_MCS6;
2042*4882a593Smuzhiyun 		Rate[3] = MGN_VHT3SS_MCS7;
2043*4882a593Smuzhiyun 		for (i = 0; i < 4; ++i)
2044*4882a593Smuzhiyun 			PwrByRateVal[i] = (s8)get_val(Value, i);
2045*4882a593Smuzhiyun 		*RateNum = 4;
2046*4882a593Smuzhiyun 		break;
2047*4882a593Smuzhiyun 
2048*4882a593Smuzhiyun 	case 0xCE8:
2049*4882a593Smuzhiyun 	case 0xEE8:
2050*4882a593Smuzhiyun 	case 0x18E8:
2051*4882a593Smuzhiyun 	case 0x1aE8:
2052*4882a593Smuzhiyun 	case 0x3a48:
2053*4882a593Smuzhiyun 		Rate[0] = MGN_VHT3SS_MCS8;
2054*4882a593Smuzhiyun 		Rate[1] = MGN_VHT3SS_MCS9;
2055*4882a593Smuzhiyun 		Rate[2] = MGN_VHT4SS_MCS0;
2056*4882a593Smuzhiyun 		Rate[3] = MGN_VHT4SS_MCS1;
2057*4882a593Smuzhiyun 		for (i = 0; i < 4; ++i)
2058*4882a593Smuzhiyun 			PwrByRateVal[i] = (s8)get_val(Value, i);
2059*4882a593Smuzhiyun 		*RateNum = 4;
2060*4882a593Smuzhiyun 		break;
2061*4882a593Smuzhiyun 
2062*4882a593Smuzhiyun 	case 0x3a4c:
2063*4882a593Smuzhiyun 		Rate[0] = MGN_VHT4SS_MCS2;
2064*4882a593Smuzhiyun 		Rate[1] = MGN_VHT4SS_MCS3;
2065*4882a593Smuzhiyun 		Rate[2] = MGN_VHT4SS_MCS4;
2066*4882a593Smuzhiyun 		Rate[3] = MGN_VHT4SS_MCS5;
2067*4882a593Smuzhiyun 		for (i = 0; i < 4; ++i)
2068*4882a593Smuzhiyun 			PwrByRateVal[i] = (s8)get_val(Value, i);
2069*4882a593Smuzhiyun 		*RateNum = 4;
2070*4882a593Smuzhiyun 		break;
2071*4882a593Smuzhiyun 
2072*4882a593Smuzhiyun 	case 0x3a50:
2073*4882a593Smuzhiyun 		Rate[0] = MGN_VHT4SS_MCS6;
2074*4882a593Smuzhiyun 		Rate[1] = MGN_VHT4SS_MCS7;
2075*4882a593Smuzhiyun 		Rate[2] = MGN_VHT4SS_MCS8;
2076*4882a593Smuzhiyun 		Rate[3] = MGN_VHT4SS_MCS9;
2077*4882a593Smuzhiyun 		for (i = 0; i < 4; ++i)
2078*4882a593Smuzhiyun 			PwrByRateVal[i] = (s8)get_val(Value, i);
2079*4882a593Smuzhiyun 		*RateNum = 4;
2080*4882a593Smuzhiyun 		break;
2081*4882a593Smuzhiyun 
2082*4882a593Smuzhiyun 	default:
2083*4882a593Smuzhiyun 		RTW_PRINT("Invalid RegAddr 0x%x in %s()\n", RegAddr, __func__);
2084*4882a593Smuzhiyun 		break;
2085*4882a593Smuzhiyun 	};
2086*4882a593Smuzhiyun }
2087*4882a593Smuzhiyun 
2088*4882a593Smuzhiyun void
PHY_StoreTxPowerByRateNew(PADAPTER pAdapter,u32 Band,u32 RfPath,u32 RegAddr,u32 BitMask,u32 Data)2089*4882a593Smuzhiyun PHY_StoreTxPowerByRateNew(
2090*4882a593Smuzhiyun 		PADAPTER	pAdapter,
2091*4882a593Smuzhiyun 		u32			Band,
2092*4882a593Smuzhiyun 		u32			RfPath,
2093*4882a593Smuzhiyun 		u32			RegAddr,
2094*4882a593Smuzhiyun 		u32			BitMask,
2095*4882a593Smuzhiyun 		u32			Data
2096*4882a593Smuzhiyun )
2097*4882a593Smuzhiyun {
2098*4882a593Smuzhiyun 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
2099*4882a593Smuzhiyun 	u8	i = 0, rates[4] = {0}, rateNum = 0;
2100*4882a593Smuzhiyun 	s8	PwrByRateVal[4] = {0};
2101*4882a593Smuzhiyun 
2102*4882a593Smuzhiyun 	PHY_GetRateValuesOfTxPowerByRate(pAdapter, RegAddr, BitMask, Data, rates, PwrByRateVal, &rateNum);
2103*4882a593Smuzhiyun 
2104*4882a593Smuzhiyun 	if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) {
2105*4882a593Smuzhiyun 		RTW_PRINT("Invalid Band %d\n", Band);
2106*4882a593Smuzhiyun 		return;
2107*4882a593Smuzhiyun 	}
2108*4882a593Smuzhiyun 
2109*4882a593Smuzhiyun 	if (RfPath > RF_PATH_D) {
2110*4882a593Smuzhiyun 		RTW_PRINT("Invalid RfPath %d\n", RfPath);
2111*4882a593Smuzhiyun 		return;
2112*4882a593Smuzhiyun 	}
2113*4882a593Smuzhiyun 
2114*4882a593Smuzhiyun 	for (i = 0; i < rateNum; ++i) {
2115*4882a593Smuzhiyun 		u8 rate_idx = PHY_GetRateIndexOfTxPowerByRate(rates[i]);
2116*4882a593Smuzhiyun 
2117*4882a593Smuzhiyun 		pHalData->TxPwrByRate[Band][RfPath][rate_idx] = PwrByRateVal[i];
2118*4882a593Smuzhiyun 	}
2119*4882a593Smuzhiyun }
2120*4882a593Smuzhiyun 
2121*4882a593Smuzhiyun void
PHY_InitTxPowerByRate(PADAPTER pAdapter)2122*4882a593Smuzhiyun PHY_InitTxPowerByRate(
2123*4882a593Smuzhiyun 		PADAPTER	pAdapter
2124*4882a593Smuzhiyun )
2125*4882a593Smuzhiyun {
2126*4882a593Smuzhiyun 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(pAdapter);
2127*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(pAdapter);
2128*4882a593Smuzhiyun 	u8	band = 0, rfPath = 0, rate = 0;
2129*4882a593Smuzhiyun 
2130*4882a593Smuzhiyun 	for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band)
2131*4882a593Smuzhiyun 		for (rfPath = 0; rfPath < TX_PWR_BY_RATE_NUM_RF; ++rfPath)
2132*4882a593Smuzhiyun 				for (rate = 0; rate < TX_PWR_BY_RATE_NUM_RATE; ++rate)
2133*4882a593Smuzhiyun 					pHalData->TxPwrByRate[band][rfPath][rate] = hal_spec->txgi_max;
2134*4882a593Smuzhiyun }
2135*4882a593Smuzhiyun 
2136*4882a593Smuzhiyun void
phy_store_tx_power_by_rate(PADAPTER pAdapter,u32 Band,u32 RfPath,u32 TxNum,u32 RegAddr,u32 BitMask,u32 Data)2137*4882a593Smuzhiyun phy_store_tx_power_by_rate(
2138*4882a593Smuzhiyun 		PADAPTER	pAdapter,
2139*4882a593Smuzhiyun 		u32			Band,
2140*4882a593Smuzhiyun 		u32			RfPath,
2141*4882a593Smuzhiyun 		u32			TxNum,
2142*4882a593Smuzhiyun 		u32			RegAddr,
2143*4882a593Smuzhiyun 		u32			BitMask,
2144*4882a593Smuzhiyun 		u32			Data
2145*4882a593Smuzhiyun )
2146*4882a593Smuzhiyun {
2147*4882a593Smuzhiyun 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(pAdapter);
2148*4882a593Smuzhiyun 	struct dm_struct		*pDM_Odm = &pHalData->odmpriv;
2149*4882a593Smuzhiyun 
2150*4882a593Smuzhiyun 	if (pDM_Odm->phy_reg_pg_version > 0)
2151*4882a593Smuzhiyun 		PHY_StoreTxPowerByRateNew(pAdapter, Band, RfPath, RegAddr, BitMask, Data);
2152*4882a593Smuzhiyun 	else
2153*4882a593Smuzhiyun 		RTW_INFO("Invalid PHY_REG_PG.txt version %d\n",  pDM_Odm->phy_reg_pg_version);
2154*4882a593Smuzhiyun 
2155*4882a593Smuzhiyun }
2156*4882a593Smuzhiyun 
2157*4882a593Smuzhiyun /*
2158*4882a593Smuzhiyun   * This function must be called if the value in the PHY_REG_PG.txt(or header)
2159*4882a593Smuzhiyun   * is exact dBm values
2160*4882a593Smuzhiyun   */
2161*4882a593Smuzhiyun void
PHY_TxPowerByRateConfiguration(PADAPTER pAdapter)2162*4882a593Smuzhiyun PHY_TxPowerByRateConfiguration(
2163*4882a593Smuzhiyun 		PADAPTER			pAdapter
2164*4882a593Smuzhiyun )
2165*4882a593Smuzhiyun {
2166*4882a593Smuzhiyun 	phy_txpwr_by_rate_chk_for_path_dup(pAdapter);
2167*4882a593Smuzhiyun 	phy_store_target_tx_power(pAdapter);
2168*4882a593Smuzhiyun }
2169*4882a593Smuzhiyun 
2170*4882a593Smuzhiyun #ifdef CONFIG_FW_OFFLOAD_SET_TXPWR_IDX
2171*4882a593Smuzhiyun extern bool phy_set_txpwr_idx_offload(_adapter *adapter);
2172*4882a593Smuzhiyun #endif
2173*4882a593Smuzhiyun 
2174*4882a593Smuzhiyun void
phy_set_tx_power_index_by_rate_section(PADAPTER pAdapter,enum rf_path RFPath,u8 Channel,u8 rs)2175*4882a593Smuzhiyun phy_set_tx_power_index_by_rate_section(
2176*4882a593Smuzhiyun 		PADAPTER		pAdapter,
2177*4882a593Smuzhiyun 		enum rf_path		RFPath,
2178*4882a593Smuzhiyun 		u8				Channel,
2179*4882a593Smuzhiyun 		u8				rs
2180*4882a593Smuzhiyun )
2181*4882a593Smuzhiyun {
2182*4882a593Smuzhiyun 	PHAL_DATA_TYPE	hal_data = GET_HAL_DATA(pAdapter);
2183*4882a593Smuzhiyun 	u8 band = hal_data->current_band_type;
2184*4882a593Smuzhiyun 	u8 bw = hal_data->current_channel_bw;
2185*4882a593Smuzhiyun 	u32	powerIndex = 0;
2186*4882a593Smuzhiyun 	int	i = 0;
2187*4882a593Smuzhiyun 
2188*4882a593Smuzhiyun 	if (rs >= RATE_SECTION_NUM) {
2189*4882a593Smuzhiyun 		RTW_INFO("Invalid RateSection %d in %s", rs, __func__);
2190*4882a593Smuzhiyun 		rtw_warn_on(1);
2191*4882a593Smuzhiyun 		goto exit;
2192*4882a593Smuzhiyun 	}
2193*4882a593Smuzhiyun 
2194*4882a593Smuzhiyun 	if (rs == CCK && bw != BAND_ON_2_4G)
2195*4882a593Smuzhiyun 		goto exit;
2196*4882a593Smuzhiyun 
2197*4882a593Smuzhiyun 	for (i = 0; i < rates_by_sections[rs].rate_num; ++i) {
2198*4882a593Smuzhiyun #if DBG_TX_POWER_IDX
2199*4882a593Smuzhiyun 		struct txpwr_idx_comp tic;
2200*4882a593Smuzhiyun 
2201*4882a593Smuzhiyun 		powerIndex = rtw_hal_get_tx_power_index(pAdapter, RFPath
2202*4882a593Smuzhiyun 			, rs, rates_by_sections[rs].rates[i], bw, band, Channel, 0, &tic);
2203*4882a593Smuzhiyun 		dump_tx_power_index_inline(RTW_DBGDUMP, pAdapter, RFPath, bw, Channel
2204*4882a593Smuzhiyun 			, rates_by_sections[rs].rates[i], powerIndex, &tic);
2205*4882a593Smuzhiyun #else
2206*4882a593Smuzhiyun 		powerIndex = phy_get_tx_power_index_ex(pAdapter, RFPath
2207*4882a593Smuzhiyun 			, rs, rates_by_sections[rs].rates[i], bw, band, Channel, 0);
2208*4882a593Smuzhiyun #endif
2209*4882a593Smuzhiyun 		PHY_SetTxPowerIndex(pAdapter, powerIndex, RFPath, rates_by_sections[rs].rates[i]);
2210*4882a593Smuzhiyun 	}
2211*4882a593Smuzhiyun 
2212*4882a593Smuzhiyun #ifdef CONFIG_FW_OFFLOAD_SET_TXPWR_IDX
2213*4882a593Smuzhiyun 	if (!hal_data->set_entire_txpwr
2214*4882a593Smuzhiyun 		&& phy_set_txpwr_idx_offload(pAdapter))
2215*4882a593Smuzhiyun 		rtw_hal_set_txpwr_done(pAdapter);
2216*4882a593Smuzhiyun #endif
2217*4882a593Smuzhiyun 
2218*4882a593Smuzhiyun exit:
2219*4882a593Smuzhiyun 	return;
2220*4882a593Smuzhiyun }
2221*4882a593Smuzhiyun 
phy_get_ch_idx(u8 ch,u8 * ch_idx)2222*4882a593Smuzhiyun bool phy_get_ch_idx(u8 ch, u8 *ch_idx)
2223*4882a593Smuzhiyun {
2224*4882a593Smuzhiyun 	u8  i = 0;
2225*4882a593Smuzhiyun 	BOOLEAN bIn24G = _TRUE;
2226*4882a593Smuzhiyun 
2227*4882a593Smuzhiyun 	if (ch > 0 && ch <= 14) {
2228*4882a593Smuzhiyun 		bIn24G = _TRUE;
2229*4882a593Smuzhiyun 		*ch_idx = ch - 1;
2230*4882a593Smuzhiyun 	} else {
2231*4882a593Smuzhiyun 		bIn24G = _FALSE;
2232*4882a593Smuzhiyun 
2233*4882a593Smuzhiyun 		for (i = 0; i < CENTER_CH_5G_ALL_NUM; ++i) {
2234*4882a593Smuzhiyun 			if (center_ch_5g_all[i] == ch) {
2235*4882a593Smuzhiyun 				*ch_idx = i;
2236*4882a593Smuzhiyun 				break;
2237*4882a593Smuzhiyun 			}
2238*4882a593Smuzhiyun 		}
2239*4882a593Smuzhiyun 	}
2240*4882a593Smuzhiyun 
2241*4882a593Smuzhiyun 	return bIn24G;
2242*4882a593Smuzhiyun }
2243*4882a593Smuzhiyun 
phy_chk_ch_setting_consistency(_adapter * adapter,u8 ch)2244*4882a593Smuzhiyun bool phy_chk_ch_setting_consistency(_adapter *adapter, u8 ch)
2245*4882a593Smuzhiyun {
2246*4882a593Smuzhiyun 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
2247*4882a593Smuzhiyun 	u8 ch_idx = 0xFF;
2248*4882a593Smuzhiyun 	u8 ret = _FAIL;
2249*4882a593Smuzhiyun 
2250*4882a593Smuzhiyun 	phy_get_ch_idx(ch, &ch_idx);
2251*4882a593Smuzhiyun 	if (ch_idx == 0xFF) {
2252*4882a593Smuzhiyun 		rtw_warn_on(1);
2253*4882a593Smuzhiyun 		goto exit;
2254*4882a593Smuzhiyun 	}
2255*4882a593Smuzhiyun 
2256*4882a593Smuzhiyun 	if (ch != hal_data->current_channel) {
2257*4882a593Smuzhiyun 		rtw_warn_on(1);
2258*4882a593Smuzhiyun 		goto exit;
2259*4882a593Smuzhiyun 	}
2260*4882a593Smuzhiyun 
2261*4882a593Smuzhiyun 	if (ch <= 14) {
2262*4882a593Smuzhiyun 		if (hal_data->current_band_type != BAND_ON_2_4G) {
2263*4882a593Smuzhiyun 			rtw_warn_on(1);
2264*4882a593Smuzhiyun 			goto exit;
2265*4882a593Smuzhiyun 		}
2266*4882a593Smuzhiyun 		if (hal_data->current_channel_bw > CHANNEL_WIDTH_40) {
2267*4882a593Smuzhiyun 			rtw_warn_on(1);
2268*4882a593Smuzhiyun 			goto exit;
2269*4882a593Smuzhiyun 		}
2270*4882a593Smuzhiyun 	}
2271*4882a593Smuzhiyun 	if (ch > 14) {
2272*4882a593Smuzhiyun 		if (hal_data->current_band_type != BAND_ON_5G) {
2273*4882a593Smuzhiyun 			rtw_warn_on(1);
2274*4882a593Smuzhiyun 			goto exit;
2275*4882a593Smuzhiyun 		}
2276*4882a593Smuzhiyun 		if (hal_data->current_channel_bw > CHANNEL_WIDTH_160) {
2277*4882a593Smuzhiyun 			rtw_warn_on(1);
2278*4882a593Smuzhiyun 			goto exit;
2279*4882a593Smuzhiyun 		}
2280*4882a593Smuzhiyun 	}
2281*4882a593Smuzhiyun 
2282*4882a593Smuzhiyun 	ret = _SUCCESS;
2283*4882a593Smuzhiyun 
2284*4882a593Smuzhiyun exit:
2285*4882a593Smuzhiyun 	if (ret != _SUCCESS)
2286*4882a593Smuzhiyun 		RTW_WARN("ch:%u, hal band:%u, ch:%u, bw:%u\n", ch
2287*4882a593Smuzhiyun 			, hal_data->current_band_type, hal_data->current_channel, hal_data->current_channel_bw);
2288*4882a593Smuzhiyun 
2289*4882a593Smuzhiyun 	return ret;
2290*4882a593Smuzhiyun }
2291*4882a593Smuzhiyun 
2292*4882a593Smuzhiyun #ifdef CONFIG_TXPWR_PG_WITH_PWR_IDX
phy_get_pg_txpwr_idx(_adapter * pAdapter,enum rf_path RFPath,RATE_SECTION rs,u8 ntx_idx,enum channel_width BandWidth,u8 band,u8 Channel)2293*4882a593Smuzhiyun u8 phy_get_pg_txpwr_idx(_adapter *pAdapter
2294*4882a593Smuzhiyun 	, enum rf_path RFPath, RATE_SECTION rs, u8 ntx_idx
2295*4882a593Smuzhiyun 	, enum channel_width BandWidth, u8 band, u8 Channel)
2296*4882a593Smuzhiyun {
2297*4882a593Smuzhiyun 	PHAL_DATA_TYPE		pHalData = GET_HAL_DATA(pAdapter);
2298*4882a593Smuzhiyun 	u8					i;
2299*4882a593Smuzhiyun 	u8					txPower = 0;
2300*4882a593Smuzhiyun 	u8					chnlIdx = (Channel - 1);
2301*4882a593Smuzhiyun 
2302*4882a593Smuzhiyun 	if (HAL_IsLegalChannel(pAdapter, Channel) == _FALSE) {
2303*4882a593Smuzhiyun 		chnlIdx = 0;
2304*4882a593Smuzhiyun 		RTW_INFO("Illegal channel!!\n");
2305*4882a593Smuzhiyun 	}
2306*4882a593Smuzhiyun 
2307*4882a593Smuzhiyun 	phy_get_ch_idx(Channel, &chnlIdx);
2308*4882a593Smuzhiyun 
2309*4882a593Smuzhiyun 	if (0)
2310*4882a593Smuzhiyun 		RTW_INFO("[%s] Channel Index: %d\n", band_str(band), chnlIdx);
2311*4882a593Smuzhiyun 
2312*4882a593Smuzhiyun 	if (band == BAND_ON_2_4G) {
2313*4882a593Smuzhiyun 		if (IS_CCK_RATE_SECTION(rs)) {
2314*4882a593Smuzhiyun 			/* CCK-nTX */
2315*4882a593Smuzhiyun 			txPower = pHalData->Index24G_CCK_Base[RFPath][chnlIdx];
2316*4882a593Smuzhiyun 			txPower += pHalData->CCK_24G_Diff[RFPath][RF_1TX];
2317*4882a593Smuzhiyun 			if (ntx_idx >= RF_2TX)
2318*4882a593Smuzhiyun 				txPower += pHalData->CCK_24G_Diff[RFPath][RF_2TX];
2319*4882a593Smuzhiyun 			if (ntx_idx >= RF_3TX)
2320*4882a593Smuzhiyun 				txPower += pHalData->CCK_24G_Diff[RFPath][RF_3TX];
2321*4882a593Smuzhiyun 			if (ntx_idx >= RF_4TX)
2322*4882a593Smuzhiyun 				txPower += pHalData->CCK_24G_Diff[RFPath][RF_4TX];
2323*4882a593Smuzhiyun 			goto exit;
2324*4882a593Smuzhiyun 		}
2325*4882a593Smuzhiyun 
2326*4882a593Smuzhiyun 		txPower = pHalData->Index24G_BW40_Base[RFPath][chnlIdx];
2327*4882a593Smuzhiyun 
2328*4882a593Smuzhiyun 		/* OFDM-nTX */
2329*4882a593Smuzhiyun 		if (IS_OFDM_RATE_SECTION(rs)) {
2330*4882a593Smuzhiyun 			txPower += pHalData->OFDM_24G_Diff[RFPath][RF_1TX];
2331*4882a593Smuzhiyun 			if (ntx_idx >= RF_2TX)
2332*4882a593Smuzhiyun 				txPower += pHalData->OFDM_24G_Diff[RFPath][RF_2TX];
2333*4882a593Smuzhiyun 			if (ntx_idx >= RF_3TX)
2334*4882a593Smuzhiyun 				txPower += pHalData->OFDM_24G_Diff[RFPath][RF_3TX];
2335*4882a593Smuzhiyun 			if (ntx_idx >= RF_4TX)
2336*4882a593Smuzhiyun 				txPower += pHalData->OFDM_24G_Diff[RFPath][RF_4TX];
2337*4882a593Smuzhiyun 			goto exit;
2338*4882a593Smuzhiyun 		}
2339*4882a593Smuzhiyun 
2340*4882a593Smuzhiyun 		/* BW20-nS */
2341*4882a593Smuzhiyun 		if (BandWidth == CHANNEL_WIDTH_20) {
2342*4882a593Smuzhiyun 			txPower += pHalData->BW20_24G_Diff[RFPath][RF_1TX];
2343*4882a593Smuzhiyun 			if (rate_section_to_tx_num(rs) >= RF_2TX)
2344*4882a593Smuzhiyun 				txPower += pHalData->BW20_24G_Diff[RFPath][RF_2TX];
2345*4882a593Smuzhiyun 			if (rate_section_to_tx_num(rs) >= RF_3TX)
2346*4882a593Smuzhiyun 				txPower += pHalData->BW20_24G_Diff[RFPath][RF_3TX];
2347*4882a593Smuzhiyun 			if (rate_section_to_tx_num(rs) >= RF_4TX)
2348*4882a593Smuzhiyun 				txPower += pHalData->BW20_24G_Diff[RFPath][RF_4TX];
2349*4882a593Smuzhiyun 			goto exit;
2350*4882a593Smuzhiyun 		}
2351*4882a593Smuzhiyun 
2352*4882a593Smuzhiyun 		/* BW40-nS */
2353*4882a593Smuzhiyun 		if (BandWidth == CHANNEL_WIDTH_40
2354*4882a593Smuzhiyun 			/* Willis suggest adopt BW 40M power index while in BW 80 mode */
2355*4882a593Smuzhiyun 			|| BandWidth == CHANNEL_WIDTH_80
2356*4882a593Smuzhiyun 		) {
2357*4882a593Smuzhiyun 			txPower += pHalData->BW40_24G_Diff[RFPath][RF_1TX];
2358*4882a593Smuzhiyun 			if (rate_section_to_tx_num(rs) >= RF_2TX)
2359*4882a593Smuzhiyun 				txPower += pHalData->BW40_24G_Diff[RFPath][RF_2TX];
2360*4882a593Smuzhiyun 			if (rate_section_to_tx_num(rs) >= RF_3TX)
2361*4882a593Smuzhiyun 				txPower += pHalData->BW40_24G_Diff[RFPath][RF_3TX];
2362*4882a593Smuzhiyun 			if (rate_section_to_tx_num(rs) >= RF_4TX)
2363*4882a593Smuzhiyun 				txPower += pHalData->BW40_24G_Diff[RFPath][RF_4TX];
2364*4882a593Smuzhiyun 			goto exit;
2365*4882a593Smuzhiyun 		}
2366*4882a593Smuzhiyun 	}
2367*4882a593Smuzhiyun #if CONFIG_IEEE80211_BAND_5GHZ
2368*4882a593Smuzhiyun 	else if (band == BAND_ON_5G) {
2369*4882a593Smuzhiyun 		if (IS_CCK_RATE_SECTION(rs)) {
2370*4882a593Smuzhiyun 			RTW_WARN("===>%s: INVALID, CCK on 5G\n", __func__);
2371*4882a593Smuzhiyun 			goto exit;
2372*4882a593Smuzhiyun 		}
2373*4882a593Smuzhiyun 
2374*4882a593Smuzhiyun 		txPower = pHalData->Index5G_BW40_Base[RFPath][chnlIdx];
2375*4882a593Smuzhiyun 
2376*4882a593Smuzhiyun 		/* OFDM-nTX */
2377*4882a593Smuzhiyun 		if (IS_OFDM_RATE_SECTION(rs)) {
2378*4882a593Smuzhiyun 			txPower += pHalData->OFDM_5G_Diff[RFPath][RF_1TX];
2379*4882a593Smuzhiyun 			if (ntx_idx >= RF_2TX)
2380*4882a593Smuzhiyun 				txPower += pHalData->OFDM_5G_Diff[RFPath][RF_2TX];
2381*4882a593Smuzhiyun 			if (ntx_idx >= RF_3TX)
2382*4882a593Smuzhiyun 				txPower += pHalData->OFDM_5G_Diff[RFPath][RF_3TX];
2383*4882a593Smuzhiyun 			if (ntx_idx >= RF_4TX)
2384*4882a593Smuzhiyun 				txPower += pHalData->OFDM_5G_Diff[RFPath][RF_4TX];
2385*4882a593Smuzhiyun 			goto exit;
2386*4882a593Smuzhiyun 		}
2387*4882a593Smuzhiyun 
2388*4882a593Smuzhiyun 		/* BW20-nS */
2389*4882a593Smuzhiyun 		if (BandWidth == CHANNEL_WIDTH_20) {
2390*4882a593Smuzhiyun 			txPower += pHalData->BW20_5G_Diff[RFPath][RF_1TX];
2391*4882a593Smuzhiyun 			if (rate_section_to_tx_num(rs) >= RF_2TX)
2392*4882a593Smuzhiyun 				txPower += pHalData->BW20_5G_Diff[RFPath][RF_2TX];
2393*4882a593Smuzhiyun 			if (rate_section_to_tx_num(rs) >= RF_3TX)
2394*4882a593Smuzhiyun 				txPower += pHalData->BW20_5G_Diff[RFPath][RF_3TX];
2395*4882a593Smuzhiyun 			if (rate_section_to_tx_num(rs) >= RF_4TX)
2396*4882a593Smuzhiyun 				txPower += pHalData->BW20_5G_Diff[RFPath][RF_4TX];
2397*4882a593Smuzhiyun 			goto exit;
2398*4882a593Smuzhiyun 		}
2399*4882a593Smuzhiyun 
2400*4882a593Smuzhiyun 		/* BW40-nS */
2401*4882a593Smuzhiyun 		if (BandWidth == CHANNEL_WIDTH_40) {
2402*4882a593Smuzhiyun 			txPower += pHalData->BW40_5G_Diff[RFPath][RF_1TX];
2403*4882a593Smuzhiyun 			if (rate_section_to_tx_num(rs) >= RF_2TX)
2404*4882a593Smuzhiyun 				txPower += pHalData->BW40_5G_Diff[RFPath][RF_2TX];
2405*4882a593Smuzhiyun 			if (rate_section_to_tx_num(rs) >= RF_3TX)
2406*4882a593Smuzhiyun 				txPower += pHalData->BW40_5G_Diff[RFPath][RF_3TX];
2407*4882a593Smuzhiyun 			if (rate_section_to_tx_num(rs) >= RF_4TX)
2408*4882a593Smuzhiyun 				txPower += pHalData->BW40_5G_Diff[RFPath][RF_4TX];
2409*4882a593Smuzhiyun 			goto exit;
2410*4882a593Smuzhiyun 		}
2411*4882a593Smuzhiyun 
2412*4882a593Smuzhiyun 		/* BW80-nS */
2413*4882a593Smuzhiyun 		if (BandWidth == CHANNEL_WIDTH_80) {
2414*4882a593Smuzhiyun 			/* get 80MHz cch index */
2415*4882a593Smuzhiyun 			for (i = 0; i < CENTER_CH_5G_80M_NUM; ++i) {
2416*4882a593Smuzhiyun 				if (center_ch_5g_80m[i] == Channel) {
2417*4882a593Smuzhiyun 					chnlIdx = i;
2418*4882a593Smuzhiyun 					break;
2419*4882a593Smuzhiyun 				}
2420*4882a593Smuzhiyun 			}
2421*4882a593Smuzhiyun 			if (i >= CENTER_CH_5G_80M_NUM) {
2422*4882a593Smuzhiyun 			#ifdef CONFIG_MP_INCLUDED
2423*4882a593Smuzhiyun 				if (rtw_mp_mode_check(pAdapter) == _FALSE)
2424*4882a593Smuzhiyun 			#endif
2425*4882a593Smuzhiyun 					rtw_warn_on(1);
2426*4882a593Smuzhiyun 				txPower = 0;
2427*4882a593Smuzhiyun 				goto exit;
2428*4882a593Smuzhiyun 			}
2429*4882a593Smuzhiyun 
2430*4882a593Smuzhiyun 			txPower = pHalData->Index5G_BW80_Base[RFPath][chnlIdx];
2431*4882a593Smuzhiyun 
2432*4882a593Smuzhiyun 			txPower += + pHalData->BW80_5G_Diff[RFPath][RF_1TX];
2433*4882a593Smuzhiyun 			if (rate_section_to_tx_num(rs) >= RF_2TX)
2434*4882a593Smuzhiyun 				txPower += pHalData->BW80_5G_Diff[RFPath][RF_2TX];
2435*4882a593Smuzhiyun 			if (rate_section_to_tx_num(rs) >= RF_3TX)
2436*4882a593Smuzhiyun 				txPower += pHalData->BW80_5G_Diff[RFPath][RF_3TX];
2437*4882a593Smuzhiyun 			if (rate_section_to_tx_num(rs) >= RF_4TX)
2438*4882a593Smuzhiyun 				txPower += pHalData->BW80_5G_Diff[RFPath][RF_4TX];
2439*4882a593Smuzhiyun 			goto exit;
2440*4882a593Smuzhiyun 		}
2441*4882a593Smuzhiyun 
2442*4882a593Smuzhiyun 		/* TODO: BW160-nS */
2443*4882a593Smuzhiyun 		rtw_warn_on(1);
2444*4882a593Smuzhiyun 	}
2445*4882a593Smuzhiyun #endif /* CONFIG_IEEE80211_BAND_5GHZ */
2446*4882a593Smuzhiyun 
2447*4882a593Smuzhiyun exit:
2448*4882a593Smuzhiyun 	return txPower;
2449*4882a593Smuzhiyun }
2450*4882a593Smuzhiyun #endif /* CONFIG_TXPWR_PG_WITH_PWR_IDX */
2451*4882a593Smuzhiyun 
2452*4882a593Smuzhiyun s8
PHY_GetTxPowerTrackingOffset(PADAPTER pAdapter,enum rf_path RFPath,u8 Rate)2453*4882a593Smuzhiyun PHY_GetTxPowerTrackingOffset(
2454*4882a593Smuzhiyun 	PADAPTER	pAdapter,
2455*4882a593Smuzhiyun 	enum rf_path	RFPath,
2456*4882a593Smuzhiyun 	u8			Rate
2457*4882a593Smuzhiyun )
2458*4882a593Smuzhiyun {
2459*4882a593Smuzhiyun 	PHAL_DATA_TYPE		pHalData = GET_HAL_DATA(pAdapter);
2460*4882a593Smuzhiyun 	struct dm_struct			*pDM_Odm = &pHalData->odmpriv;
2461*4882a593Smuzhiyun 	s8	offset = 0;
2462*4882a593Smuzhiyun 
2463*4882a593Smuzhiyun 	if (pDM_Odm->rf_calibrate_info.txpowertrack_control  == _FALSE)
2464*4882a593Smuzhiyun 		return offset;
2465*4882a593Smuzhiyun 
2466*4882a593Smuzhiyun 	if ((Rate == MGN_1M) || (Rate == MGN_2M) || (Rate == MGN_5_5M) || (Rate == MGN_11M)) {
2467*4882a593Smuzhiyun 		offset = pDM_Odm->rf_calibrate_info.remnant_cck_swing_idx;
2468*4882a593Smuzhiyun 		/*RTW_INFO("+Remnant_CCKSwingIdx = 0x%x\n", RFPath, Rate, pRFCalibrateInfo->Remnant_CCKSwingIdx);*/
2469*4882a593Smuzhiyun 	} else {
2470*4882a593Smuzhiyun 		offset = pDM_Odm->rf_calibrate_info.remnant_ofdm_swing_idx[RFPath];
2471*4882a593Smuzhiyun 		/*RTW_INFO("+Remanant_OFDMSwingIdx[RFPath %u][Rate 0x%x] = 0x%x\n", RFPath, Rate, pRFCalibrateInfo->Remnant_OFDMSwingIdx[RFPath]);	*/
2472*4882a593Smuzhiyun 
2473*4882a593Smuzhiyun 	}
2474*4882a593Smuzhiyun 
2475*4882a593Smuzhiyun 	return offset;
2476*4882a593Smuzhiyun }
2477*4882a593Smuzhiyun 
2478*4882a593Smuzhiyun /*The same as MRateToHwRate in hal_com.c*/
2479*4882a593Smuzhiyun u8
PHY_GetRateIndexOfTxPowerByRate(u8 Rate)2480*4882a593Smuzhiyun PHY_GetRateIndexOfTxPowerByRate(
2481*4882a593Smuzhiyun 		u8		Rate
2482*4882a593Smuzhiyun )
2483*4882a593Smuzhiyun {
2484*4882a593Smuzhiyun 	u8	index = 0;
2485*4882a593Smuzhiyun 	switch (Rate) {
2486*4882a593Smuzhiyun 	case MGN_1M:
2487*4882a593Smuzhiyun 		index = 0;
2488*4882a593Smuzhiyun 		break;
2489*4882a593Smuzhiyun 	case MGN_2M:
2490*4882a593Smuzhiyun 		index = 1;
2491*4882a593Smuzhiyun 		break;
2492*4882a593Smuzhiyun 	case MGN_5_5M:
2493*4882a593Smuzhiyun 		index = 2;
2494*4882a593Smuzhiyun 		break;
2495*4882a593Smuzhiyun 	case MGN_11M:
2496*4882a593Smuzhiyun 		index = 3;
2497*4882a593Smuzhiyun 		break;
2498*4882a593Smuzhiyun 	case MGN_6M:
2499*4882a593Smuzhiyun 		index = 4;
2500*4882a593Smuzhiyun 		break;
2501*4882a593Smuzhiyun 	case MGN_9M:
2502*4882a593Smuzhiyun 		index = 5;
2503*4882a593Smuzhiyun 		break;
2504*4882a593Smuzhiyun 	case MGN_12M:
2505*4882a593Smuzhiyun 		index = 6;
2506*4882a593Smuzhiyun 		break;
2507*4882a593Smuzhiyun 	case MGN_18M:
2508*4882a593Smuzhiyun 		index = 7;
2509*4882a593Smuzhiyun 		break;
2510*4882a593Smuzhiyun 	case MGN_24M:
2511*4882a593Smuzhiyun 		index = 8;
2512*4882a593Smuzhiyun 		break;
2513*4882a593Smuzhiyun 	case MGN_36M:
2514*4882a593Smuzhiyun 		index = 9;
2515*4882a593Smuzhiyun 		break;
2516*4882a593Smuzhiyun 	case MGN_48M:
2517*4882a593Smuzhiyun 		index = 10;
2518*4882a593Smuzhiyun 		break;
2519*4882a593Smuzhiyun 	case MGN_54M:
2520*4882a593Smuzhiyun 		index = 11;
2521*4882a593Smuzhiyun 		break;
2522*4882a593Smuzhiyun 	case MGN_MCS0:
2523*4882a593Smuzhiyun 		index = 12;
2524*4882a593Smuzhiyun 		break;
2525*4882a593Smuzhiyun 	case MGN_MCS1:
2526*4882a593Smuzhiyun 		index = 13;
2527*4882a593Smuzhiyun 		break;
2528*4882a593Smuzhiyun 	case MGN_MCS2:
2529*4882a593Smuzhiyun 		index = 14;
2530*4882a593Smuzhiyun 		break;
2531*4882a593Smuzhiyun 	case MGN_MCS3:
2532*4882a593Smuzhiyun 		index = 15;
2533*4882a593Smuzhiyun 		break;
2534*4882a593Smuzhiyun 	case MGN_MCS4:
2535*4882a593Smuzhiyun 		index = 16;
2536*4882a593Smuzhiyun 		break;
2537*4882a593Smuzhiyun 	case MGN_MCS5:
2538*4882a593Smuzhiyun 		index = 17;
2539*4882a593Smuzhiyun 		break;
2540*4882a593Smuzhiyun 	case MGN_MCS6:
2541*4882a593Smuzhiyun 		index = 18;
2542*4882a593Smuzhiyun 		break;
2543*4882a593Smuzhiyun 	case MGN_MCS7:
2544*4882a593Smuzhiyun 		index = 19;
2545*4882a593Smuzhiyun 		break;
2546*4882a593Smuzhiyun 	case MGN_MCS8:
2547*4882a593Smuzhiyun 		index = 20;
2548*4882a593Smuzhiyun 		break;
2549*4882a593Smuzhiyun 	case MGN_MCS9:
2550*4882a593Smuzhiyun 		index = 21;
2551*4882a593Smuzhiyun 		break;
2552*4882a593Smuzhiyun 	case MGN_MCS10:
2553*4882a593Smuzhiyun 		index = 22;
2554*4882a593Smuzhiyun 		break;
2555*4882a593Smuzhiyun 	case MGN_MCS11:
2556*4882a593Smuzhiyun 		index = 23;
2557*4882a593Smuzhiyun 		break;
2558*4882a593Smuzhiyun 	case MGN_MCS12:
2559*4882a593Smuzhiyun 		index = 24;
2560*4882a593Smuzhiyun 		break;
2561*4882a593Smuzhiyun 	case MGN_MCS13:
2562*4882a593Smuzhiyun 		index = 25;
2563*4882a593Smuzhiyun 		break;
2564*4882a593Smuzhiyun 	case MGN_MCS14:
2565*4882a593Smuzhiyun 		index = 26;
2566*4882a593Smuzhiyun 		break;
2567*4882a593Smuzhiyun 	case MGN_MCS15:
2568*4882a593Smuzhiyun 		index = 27;
2569*4882a593Smuzhiyun 		break;
2570*4882a593Smuzhiyun 	case MGN_MCS16:
2571*4882a593Smuzhiyun 		index = 28;
2572*4882a593Smuzhiyun 		break;
2573*4882a593Smuzhiyun 	case MGN_MCS17:
2574*4882a593Smuzhiyun 		index = 29;
2575*4882a593Smuzhiyun 		break;
2576*4882a593Smuzhiyun 	case MGN_MCS18:
2577*4882a593Smuzhiyun 		index = 30;
2578*4882a593Smuzhiyun 		break;
2579*4882a593Smuzhiyun 	case MGN_MCS19:
2580*4882a593Smuzhiyun 		index = 31;
2581*4882a593Smuzhiyun 		break;
2582*4882a593Smuzhiyun 	case MGN_MCS20:
2583*4882a593Smuzhiyun 		index = 32;
2584*4882a593Smuzhiyun 		break;
2585*4882a593Smuzhiyun 	case MGN_MCS21:
2586*4882a593Smuzhiyun 		index = 33;
2587*4882a593Smuzhiyun 		break;
2588*4882a593Smuzhiyun 	case MGN_MCS22:
2589*4882a593Smuzhiyun 		index = 34;
2590*4882a593Smuzhiyun 		break;
2591*4882a593Smuzhiyun 	case MGN_MCS23:
2592*4882a593Smuzhiyun 		index = 35;
2593*4882a593Smuzhiyun 		break;
2594*4882a593Smuzhiyun 	case MGN_MCS24:
2595*4882a593Smuzhiyun 		index = 36;
2596*4882a593Smuzhiyun 		break;
2597*4882a593Smuzhiyun 	case MGN_MCS25:
2598*4882a593Smuzhiyun 		index = 37;
2599*4882a593Smuzhiyun 		break;
2600*4882a593Smuzhiyun 	case MGN_MCS26:
2601*4882a593Smuzhiyun 		index = 38;
2602*4882a593Smuzhiyun 		break;
2603*4882a593Smuzhiyun 	case MGN_MCS27:
2604*4882a593Smuzhiyun 		index = 39;
2605*4882a593Smuzhiyun 		break;
2606*4882a593Smuzhiyun 	case MGN_MCS28:
2607*4882a593Smuzhiyun 		index = 40;
2608*4882a593Smuzhiyun 		break;
2609*4882a593Smuzhiyun 	case MGN_MCS29:
2610*4882a593Smuzhiyun 		index = 41;
2611*4882a593Smuzhiyun 		break;
2612*4882a593Smuzhiyun 	case MGN_MCS30:
2613*4882a593Smuzhiyun 		index = 42;
2614*4882a593Smuzhiyun 		break;
2615*4882a593Smuzhiyun 	case MGN_MCS31:
2616*4882a593Smuzhiyun 		index = 43;
2617*4882a593Smuzhiyun 		break;
2618*4882a593Smuzhiyun 	case MGN_VHT1SS_MCS0:
2619*4882a593Smuzhiyun 		index = 44;
2620*4882a593Smuzhiyun 		break;
2621*4882a593Smuzhiyun 	case MGN_VHT1SS_MCS1:
2622*4882a593Smuzhiyun 		index = 45;
2623*4882a593Smuzhiyun 		break;
2624*4882a593Smuzhiyun 	case MGN_VHT1SS_MCS2:
2625*4882a593Smuzhiyun 		index = 46;
2626*4882a593Smuzhiyun 		break;
2627*4882a593Smuzhiyun 	case MGN_VHT1SS_MCS3:
2628*4882a593Smuzhiyun 		index = 47;
2629*4882a593Smuzhiyun 		break;
2630*4882a593Smuzhiyun 	case MGN_VHT1SS_MCS4:
2631*4882a593Smuzhiyun 		index = 48;
2632*4882a593Smuzhiyun 		break;
2633*4882a593Smuzhiyun 	case MGN_VHT1SS_MCS5:
2634*4882a593Smuzhiyun 		index = 49;
2635*4882a593Smuzhiyun 		break;
2636*4882a593Smuzhiyun 	case MGN_VHT1SS_MCS6:
2637*4882a593Smuzhiyun 		index = 50;
2638*4882a593Smuzhiyun 		break;
2639*4882a593Smuzhiyun 	case MGN_VHT1SS_MCS7:
2640*4882a593Smuzhiyun 		index = 51;
2641*4882a593Smuzhiyun 		break;
2642*4882a593Smuzhiyun 	case MGN_VHT1SS_MCS8:
2643*4882a593Smuzhiyun 		index = 52;
2644*4882a593Smuzhiyun 		break;
2645*4882a593Smuzhiyun 	case MGN_VHT1SS_MCS9:
2646*4882a593Smuzhiyun 		index = 53;
2647*4882a593Smuzhiyun 		break;
2648*4882a593Smuzhiyun 	case MGN_VHT2SS_MCS0:
2649*4882a593Smuzhiyun 		index = 54;
2650*4882a593Smuzhiyun 		break;
2651*4882a593Smuzhiyun 	case MGN_VHT2SS_MCS1:
2652*4882a593Smuzhiyun 		index = 55;
2653*4882a593Smuzhiyun 		break;
2654*4882a593Smuzhiyun 	case MGN_VHT2SS_MCS2:
2655*4882a593Smuzhiyun 		index = 56;
2656*4882a593Smuzhiyun 		break;
2657*4882a593Smuzhiyun 	case MGN_VHT2SS_MCS3:
2658*4882a593Smuzhiyun 		index = 57;
2659*4882a593Smuzhiyun 		break;
2660*4882a593Smuzhiyun 	case MGN_VHT2SS_MCS4:
2661*4882a593Smuzhiyun 		index = 58;
2662*4882a593Smuzhiyun 		break;
2663*4882a593Smuzhiyun 	case MGN_VHT2SS_MCS5:
2664*4882a593Smuzhiyun 		index = 59;
2665*4882a593Smuzhiyun 		break;
2666*4882a593Smuzhiyun 	case MGN_VHT2SS_MCS6:
2667*4882a593Smuzhiyun 		index = 60;
2668*4882a593Smuzhiyun 		break;
2669*4882a593Smuzhiyun 	case MGN_VHT2SS_MCS7:
2670*4882a593Smuzhiyun 		index = 61;
2671*4882a593Smuzhiyun 		break;
2672*4882a593Smuzhiyun 	case MGN_VHT2SS_MCS8:
2673*4882a593Smuzhiyun 		index = 62;
2674*4882a593Smuzhiyun 		break;
2675*4882a593Smuzhiyun 	case MGN_VHT2SS_MCS9:
2676*4882a593Smuzhiyun 		index = 63;
2677*4882a593Smuzhiyun 		break;
2678*4882a593Smuzhiyun 	case MGN_VHT3SS_MCS0:
2679*4882a593Smuzhiyun 		index = 64;
2680*4882a593Smuzhiyun 		break;
2681*4882a593Smuzhiyun 	case MGN_VHT3SS_MCS1:
2682*4882a593Smuzhiyun 		index = 65;
2683*4882a593Smuzhiyun 		break;
2684*4882a593Smuzhiyun 	case MGN_VHT3SS_MCS2:
2685*4882a593Smuzhiyun 		index = 66;
2686*4882a593Smuzhiyun 		break;
2687*4882a593Smuzhiyun 	case MGN_VHT3SS_MCS3:
2688*4882a593Smuzhiyun 		index = 67;
2689*4882a593Smuzhiyun 		break;
2690*4882a593Smuzhiyun 	case MGN_VHT3SS_MCS4:
2691*4882a593Smuzhiyun 		index = 68;
2692*4882a593Smuzhiyun 		break;
2693*4882a593Smuzhiyun 	case MGN_VHT3SS_MCS5:
2694*4882a593Smuzhiyun 		index = 69;
2695*4882a593Smuzhiyun 		break;
2696*4882a593Smuzhiyun 	case MGN_VHT3SS_MCS6:
2697*4882a593Smuzhiyun 		index = 70;
2698*4882a593Smuzhiyun 		break;
2699*4882a593Smuzhiyun 	case MGN_VHT3SS_MCS7:
2700*4882a593Smuzhiyun 		index = 71;
2701*4882a593Smuzhiyun 		break;
2702*4882a593Smuzhiyun 	case MGN_VHT3SS_MCS8:
2703*4882a593Smuzhiyun 		index = 72;
2704*4882a593Smuzhiyun 		break;
2705*4882a593Smuzhiyun 	case MGN_VHT3SS_MCS9:
2706*4882a593Smuzhiyun 		index = 73;
2707*4882a593Smuzhiyun 		break;
2708*4882a593Smuzhiyun 	case MGN_VHT4SS_MCS0:
2709*4882a593Smuzhiyun 		index = 74;
2710*4882a593Smuzhiyun 		break;
2711*4882a593Smuzhiyun 	case MGN_VHT4SS_MCS1:
2712*4882a593Smuzhiyun 		index = 75;
2713*4882a593Smuzhiyun 		break;
2714*4882a593Smuzhiyun 	case MGN_VHT4SS_MCS2:
2715*4882a593Smuzhiyun 		index = 76;
2716*4882a593Smuzhiyun 		break;
2717*4882a593Smuzhiyun 	case MGN_VHT4SS_MCS3:
2718*4882a593Smuzhiyun 		index = 77;
2719*4882a593Smuzhiyun 		break;
2720*4882a593Smuzhiyun 	case MGN_VHT4SS_MCS4:
2721*4882a593Smuzhiyun 		index = 78;
2722*4882a593Smuzhiyun 		break;
2723*4882a593Smuzhiyun 	case MGN_VHT4SS_MCS5:
2724*4882a593Smuzhiyun 		index = 79;
2725*4882a593Smuzhiyun 		break;
2726*4882a593Smuzhiyun 	case MGN_VHT4SS_MCS6:
2727*4882a593Smuzhiyun 		index = 80;
2728*4882a593Smuzhiyun 		break;
2729*4882a593Smuzhiyun 	case MGN_VHT4SS_MCS7:
2730*4882a593Smuzhiyun 		index = 81;
2731*4882a593Smuzhiyun 		break;
2732*4882a593Smuzhiyun 	case MGN_VHT4SS_MCS8:
2733*4882a593Smuzhiyun 		index = 82;
2734*4882a593Smuzhiyun 		break;
2735*4882a593Smuzhiyun 	case MGN_VHT4SS_MCS9:
2736*4882a593Smuzhiyun 		index = 83;
2737*4882a593Smuzhiyun 		break;
2738*4882a593Smuzhiyun 	default:
2739*4882a593Smuzhiyun 		RTW_INFO("Invalid rate 0x%x in %s\n", Rate, __FUNCTION__);
2740*4882a593Smuzhiyun 		break;
2741*4882a593Smuzhiyun 	};
2742*4882a593Smuzhiyun 
2743*4882a593Smuzhiyun 	return index;
2744*4882a593Smuzhiyun }
2745*4882a593Smuzhiyun 
2746*4882a593Smuzhiyun s8
_PHY_GetTxPowerByRate(PADAPTER pAdapter,u8 Band,enum rf_path RFPath,u8 Rate)2747*4882a593Smuzhiyun _PHY_GetTxPowerByRate(
2748*4882a593Smuzhiyun 		PADAPTER	pAdapter,
2749*4882a593Smuzhiyun 		u8			Band,
2750*4882a593Smuzhiyun 		enum rf_path	RFPath,
2751*4882a593Smuzhiyun 		u8			Rate
2752*4882a593Smuzhiyun )
2753*4882a593Smuzhiyun {
2754*4882a593Smuzhiyun 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
2755*4882a593Smuzhiyun 	s8 value = 0;
2756*4882a593Smuzhiyun 	u8 rateIndex = PHY_GetRateIndexOfTxPowerByRate(Rate);
2757*4882a593Smuzhiyun 
2758*4882a593Smuzhiyun 	if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) {
2759*4882a593Smuzhiyun 		RTW_INFO("Invalid band %d in %s\n", Band, __func__);
2760*4882a593Smuzhiyun 		goto exit;
2761*4882a593Smuzhiyun 	}
2762*4882a593Smuzhiyun 	if (RFPath > RF_PATH_D) {
2763*4882a593Smuzhiyun 		RTW_INFO("Invalid RfPath %d in %s\n", RFPath, __func__);
2764*4882a593Smuzhiyun 		goto exit;
2765*4882a593Smuzhiyun 	}
2766*4882a593Smuzhiyun 	if (rateIndex >= TX_PWR_BY_RATE_NUM_RATE) {
2767*4882a593Smuzhiyun 		RTW_INFO("Invalid RateIndex %d in %s\n", rateIndex, __func__);
2768*4882a593Smuzhiyun 		goto exit;
2769*4882a593Smuzhiyun 	}
2770*4882a593Smuzhiyun 
2771*4882a593Smuzhiyun 	value = pHalData->TxPwrByRate[Band][RFPath][rateIndex];
2772*4882a593Smuzhiyun 
2773*4882a593Smuzhiyun exit:
2774*4882a593Smuzhiyun 	return value;
2775*4882a593Smuzhiyun }
2776*4882a593Smuzhiyun 
2777*4882a593Smuzhiyun 
2778*4882a593Smuzhiyun s8
PHY_GetTxPowerByRate(PADAPTER pAdapter,u8 Band,enum rf_path RFPath,RATE_SECTION rs,enum MGN_RATE rate)2779*4882a593Smuzhiyun PHY_GetTxPowerByRate(
2780*4882a593Smuzhiyun 		PADAPTER	pAdapter,
2781*4882a593Smuzhiyun 		u8			Band,
2782*4882a593Smuzhiyun 		enum rf_path	RFPath,
2783*4882a593Smuzhiyun 		RATE_SECTION rs,
2784*4882a593Smuzhiyun 		enum MGN_RATE rate
2785*4882a593Smuzhiyun )
2786*4882a593Smuzhiyun {
2787*4882a593Smuzhiyun 	if (phy_is_tx_power_by_rate_needed(pAdapter))
2788*4882a593Smuzhiyun 		return _PHY_GetTxPowerByRate(pAdapter, Band, RFPath, rate);
2789*4882a593Smuzhiyun 	return phy_get_target_txpwr(pAdapter, Band, RFPath, rs);
2790*4882a593Smuzhiyun }
2791*4882a593Smuzhiyun 
2792*4882a593Smuzhiyun void
PHY_SetTxPowerByRate(PADAPTER pAdapter,u8 Band,enum rf_path RFPath,u8 Rate,s8 Value)2793*4882a593Smuzhiyun PHY_SetTxPowerByRate(
2794*4882a593Smuzhiyun 		PADAPTER	pAdapter,
2795*4882a593Smuzhiyun 		u8			Band,
2796*4882a593Smuzhiyun 		enum rf_path	RFPath,
2797*4882a593Smuzhiyun 		u8			Rate,
2798*4882a593Smuzhiyun 		s8			Value
2799*4882a593Smuzhiyun )
2800*4882a593Smuzhiyun {
2801*4882a593Smuzhiyun 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(pAdapter);
2802*4882a593Smuzhiyun 	u8	rateIndex = PHY_GetRateIndexOfTxPowerByRate(Rate);
2803*4882a593Smuzhiyun 
2804*4882a593Smuzhiyun 	if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) {
2805*4882a593Smuzhiyun 		RTW_INFO("Invalid band %d in %s\n", Band, __FUNCTION__);
2806*4882a593Smuzhiyun 		return;
2807*4882a593Smuzhiyun 	}
2808*4882a593Smuzhiyun 	if (RFPath > RF_PATH_D) {
2809*4882a593Smuzhiyun 		RTW_INFO("Invalid RfPath %d in %s\n", RFPath, __FUNCTION__);
2810*4882a593Smuzhiyun 		return;
2811*4882a593Smuzhiyun 	}
2812*4882a593Smuzhiyun 	if (rateIndex >= TX_PWR_BY_RATE_NUM_RATE) {
2813*4882a593Smuzhiyun 		RTW_INFO("Invalid RateIndex %d in %s\n", rateIndex, __FUNCTION__);
2814*4882a593Smuzhiyun 		return;
2815*4882a593Smuzhiyun 	}
2816*4882a593Smuzhiyun 
2817*4882a593Smuzhiyun 	pHalData->TxPwrByRate[Band][RFPath][rateIndex] = Value;
2818*4882a593Smuzhiyun }
2819*4882a593Smuzhiyun 
phy_check_under_survey_ch(_adapter * adapter)2820*4882a593Smuzhiyun u8 phy_check_under_survey_ch(_adapter *adapter)
2821*4882a593Smuzhiyun {
2822*4882a593Smuzhiyun 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2823*4882a593Smuzhiyun 	_adapter *iface;
2824*4882a593Smuzhiyun 	struct mlme_ext_priv *mlmeext;
2825*4882a593Smuzhiyun 	u8 ret = _FALSE;
2826*4882a593Smuzhiyun 	int i;
2827*4882a593Smuzhiyun 
2828*4882a593Smuzhiyun 	for (i = 0; i < dvobj->iface_nums; i++) {
2829*4882a593Smuzhiyun 		iface = dvobj->padapters[i];
2830*4882a593Smuzhiyun 		if (!iface)
2831*4882a593Smuzhiyun 			continue;
2832*4882a593Smuzhiyun 		mlmeext = &iface->mlmeextpriv;
2833*4882a593Smuzhiyun 
2834*4882a593Smuzhiyun 		/* check scan state */
2835*4882a593Smuzhiyun 		if (mlmeext_scan_state(mlmeext) != SCAN_DISABLE
2836*4882a593Smuzhiyun 			&& mlmeext_scan_state(mlmeext) != SCAN_COMPLETE
2837*4882a593Smuzhiyun 				&& mlmeext_scan_state(mlmeext) != SCAN_BACKING_OP) {
2838*4882a593Smuzhiyun 			ret = _TRUE;
2839*4882a593Smuzhiyun 		} else if (mlmeext_scan_state(mlmeext) == SCAN_BACKING_OP
2840*4882a593Smuzhiyun 			&& !mlmeext_chk_scan_backop_flags(mlmeext, SS_BACKOP_TX_RESUME)) {
2841*4882a593Smuzhiyun 			ret = _TRUE;
2842*4882a593Smuzhiyun 		}
2843*4882a593Smuzhiyun 	}
2844*4882a593Smuzhiyun 
2845*4882a593Smuzhiyun 	return ret;
2846*4882a593Smuzhiyun }
2847*4882a593Smuzhiyun 
2848*4882a593Smuzhiyun void
phy_set_tx_power_level_by_path(PADAPTER Adapter,u8 channel,u8 path)2849*4882a593Smuzhiyun phy_set_tx_power_level_by_path(
2850*4882a593Smuzhiyun 		PADAPTER	Adapter,
2851*4882a593Smuzhiyun 		u8			channel,
2852*4882a593Smuzhiyun 		u8			path
2853*4882a593Smuzhiyun )
2854*4882a593Smuzhiyun {
2855*4882a593Smuzhiyun 	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(Adapter);
2856*4882a593Smuzhiyun 	BOOLEAN bIsIn24G = (pHalData->current_band_type == BAND_ON_2_4G);
2857*4882a593Smuzhiyun 	u8 under_survey_ch = phy_check_under_survey_ch(Adapter);
2858*4882a593Smuzhiyun 
2859*4882a593Smuzhiyun 
2860*4882a593Smuzhiyun 	/* if ( pMgntInfo->RegNByteAccess == 0 ) */
2861*4882a593Smuzhiyun 	{
2862*4882a593Smuzhiyun 		if (bIsIn24G)
2863*4882a593Smuzhiyun 			phy_set_tx_power_index_by_rate_section(Adapter, path, channel, CCK);
2864*4882a593Smuzhiyun 
2865*4882a593Smuzhiyun 		phy_set_tx_power_index_by_rate_section(Adapter, path, channel, OFDM);
2866*4882a593Smuzhiyun 
2867*4882a593Smuzhiyun 		if (!under_survey_ch) {
2868*4882a593Smuzhiyun 			phy_set_tx_power_index_by_rate_section(Adapter, path, channel, HT_MCS0_MCS7);
2869*4882a593Smuzhiyun 
2870*4882a593Smuzhiyun 			if (IS_HARDWARE_TYPE_JAGUAR(Adapter) || IS_HARDWARE_TYPE_8814A(Adapter))
2871*4882a593Smuzhiyun 				phy_set_tx_power_index_by_rate_section(Adapter, path, channel, VHT_1SSMCS0_1SSMCS9);
2872*4882a593Smuzhiyun 
2873*4882a593Smuzhiyun 			if (pHalData->tx_nss >= 2) {
2874*4882a593Smuzhiyun 				phy_set_tx_power_index_by_rate_section(Adapter, path, channel, HT_MCS8_MCS15);
2875*4882a593Smuzhiyun 
2876*4882a593Smuzhiyun 				if (IS_HARDWARE_TYPE_JAGUAR(Adapter) || IS_HARDWARE_TYPE_8814A(Adapter))
2877*4882a593Smuzhiyun 					phy_set_tx_power_index_by_rate_section(Adapter, path, channel, VHT_2SSMCS0_2SSMCS9);
2878*4882a593Smuzhiyun 
2879*4882a593Smuzhiyun 				if (IS_HARDWARE_TYPE_8814A(Adapter)) {
2880*4882a593Smuzhiyun 					phy_set_tx_power_index_by_rate_section(Adapter, path, channel, HT_MCS16_MCS23);
2881*4882a593Smuzhiyun 					phy_set_tx_power_index_by_rate_section(Adapter, path, channel, VHT_3SSMCS0_3SSMCS9);
2882*4882a593Smuzhiyun 				}
2883*4882a593Smuzhiyun 			}
2884*4882a593Smuzhiyun 		}
2885*4882a593Smuzhiyun 	}
2886*4882a593Smuzhiyun }
2887*4882a593Smuzhiyun 
2888*4882a593Smuzhiyun #if CONFIG_TXPWR_LIMIT
2889*4882a593Smuzhiyun const char *const _txpwr_lmt_rs_str[] = {
2890*4882a593Smuzhiyun 	"CCK",
2891*4882a593Smuzhiyun 	"OFDM",
2892*4882a593Smuzhiyun 	"HT",
2893*4882a593Smuzhiyun 	"VHT",
2894*4882a593Smuzhiyun 	"UNKNOWN",
2895*4882a593Smuzhiyun };
2896*4882a593Smuzhiyun 
2897*4882a593Smuzhiyun static s8
phy_GetChannelIndexOfTxPowerLimit(u8 Band,u8 Channel)2898*4882a593Smuzhiyun phy_GetChannelIndexOfTxPowerLimit(
2899*4882a593Smuzhiyun 		u8			Band,
2900*4882a593Smuzhiyun 		u8			Channel
2901*4882a593Smuzhiyun )
2902*4882a593Smuzhiyun {
2903*4882a593Smuzhiyun 	s8	channelIndex = -1;
2904*4882a593Smuzhiyun 	u8	i = 0;
2905*4882a593Smuzhiyun 
2906*4882a593Smuzhiyun 	if (Band == BAND_ON_2_4G)
2907*4882a593Smuzhiyun 		channelIndex = Channel - 1;
2908*4882a593Smuzhiyun 	else if (Band == BAND_ON_5G) {
2909*4882a593Smuzhiyun 		for (i = 0; i < CENTER_CH_5G_ALL_NUM; ++i) {
2910*4882a593Smuzhiyun 			if (center_ch_5g_all[i] == Channel)
2911*4882a593Smuzhiyun 				channelIndex = i;
2912*4882a593Smuzhiyun 		}
2913*4882a593Smuzhiyun 	} else
2914*4882a593Smuzhiyun 		RTW_PRINT("Invalid Band %d in %s\n", Band, __func__);
2915*4882a593Smuzhiyun 
2916*4882a593Smuzhiyun 	if (channelIndex == -1)
2917*4882a593Smuzhiyun 		RTW_PRINT("Invalid Channel %d of Band %d in %s\n", Channel, Band, __func__);
2918*4882a593Smuzhiyun 
2919*4882a593Smuzhiyun 	return channelIndex;
2920*4882a593Smuzhiyun }
2921*4882a593Smuzhiyun 
phy_txpwr_ww_lmt_value(_adapter * adapter)2922*4882a593Smuzhiyun static s8 phy_txpwr_ww_lmt_value(_adapter *adapter)
2923*4882a593Smuzhiyun {
2924*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
2925*4882a593Smuzhiyun 
2926*4882a593Smuzhiyun 	if (hal_spec->txgi_max == 63)
2927*4882a593Smuzhiyun 		return -63;
2928*4882a593Smuzhiyun 	else if (hal_spec->txgi_max == 127)
2929*4882a593Smuzhiyun 		return -128;
2930*4882a593Smuzhiyun 
2931*4882a593Smuzhiyun 	rtw_warn_on(1);
2932*4882a593Smuzhiyun 	return -128;
2933*4882a593Smuzhiyun }
2934*4882a593Smuzhiyun 
2935*4882a593Smuzhiyun /*
2936*4882a593Smuzhiyun * return txpwr limit in unit of TX Gain Index
2937*4882a593Smuzhiyun * hsl_spec->txgi_max is returned when NO limit
2938*4882a593Smuzhiyun */
phy_get_txpwr_lmt(PADAPTER Adapter,const char * regd_name,BAND_TYPE Band,enum channel_width bw,u8 tlrs,u8 ntx_idx,u8 cch,u8 lock)2939*4882a593Smuzhiyun s8 phy_get_txpwr_lmt(
2940*4882a593Smuzhiyun 		PADAPTER			Adapter,
2941*4882a593Smuzhiyun 		const char			*regd_name,
2942*4882a593Smuzhiyun 		BAND_TYPE			Band,
2943*4882a593Smuzhiyun 		enum channel_width		bw,
2944*4882a593Smuzhiyun 	u8 tlrs,
2945*4882a593Smuzhiyun 	u8 ntx_idx,
2946*4882a593Smuzhiyun 	u8 cch,
2947*4882a593Smuzhiyun 	u8 lock
2948*4882a593Smuzhiyun )
2949*4882a593Smuzhiyun {
2950*4882a593Smuzhiyun 	struct dvobj_priv *dvobj = adapter_to_dvobj(Adapter);
2951*4882a593Smuzhiyun 	struct rf_ctl_t *rfctl = adapter_to_rfctl(Adapter);
2952*4882a593Smuzhiyun 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(Adapter);
2953*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(Adapter);
2954*4882a593Smuzhiyun 	struct txpwr_lmt_ent *ent = NULL;
2955*4882a593Smuzhiyun 	_irqL irqL;
2956*4882a593Smuzhiyun 	_list *cur, *head;
2957*4882a593Smuzhiyun 	s8 ch_idx;
2958*4882a593Smuzhiyun 	u8 is_ww_regd = 0;
2959*4882a593Smuzhiyun 	s8 ww_lmt_val = phy_txpwr_ww_lmt_value(Adapter);
2960*4882a593Smuzhiyun 	s8 lmt = hal_spec->txgi_max;
2961*4882a593Smuzhiyun 
2962*4882a593Smuzhiyun 	if ((Adapter->registrypriv.RegEnableTxPowerLimit == 2 && hal_data->EEPROMRegulatory != 1) ||
2963*4882a593Smuzhiyun 		Adapter->registrypriv.RegEnableTxPowerLimit == 0)
2964*4882a593Smuzhiyun 		goto exit;
2965*4882a593Smuzhiyun 
2966*4882a593Smuzhiyun 	if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) {
2967*4882a593Smuzhiyun 		RTW_ERR("%s invalid band:%u\n", __func__, Band);
2968*4882a593Smuzhiyun 		rtw_warn_on(1);
2969*4882a593Smuzhiyun 		goto exit;
2970*4882a593Smuzhiyun 	}
2971*4882a593Smuzhiyun 
2972*4882a593Smuzhiyun 	if (Band == BAND_ON_5G  && tlrs == TXPWR_LMT_RS_CCK) {
2973*4882a593Smuzhiyun 		RTW_ERR("5G has no CCK\n");
2974*4882a593Smuzhiyun 		goto exit;
2975*4882a593Smuzhiyun 	}
2976*4882a593Smuzhiyun 
2977*4882a593Smuzhiyun 	if (lock)
2978*4882a593Smuzhiyun 		_enter_critical_mutex(&rfctl->txpwr_lmt_mutex, &irqL);
2979*4882a593Smuzhiyun 
2980*4882a593Smuzhiyun 	if (!regd_name) /* no regd_name specified, use currnet */
2981*4882a593Smuzhiyun 		regd_name = rfctl->regd_name;
2982*4882a593Smuzhiyun 
2983*4882a593Smuzhiyun 	if (rfctl->txpwr_regd_num == 0
2984*4882a593Smuzhiyun 		|| strcmp(regd_name, regd_str(TXPWR_LMT_NONE)) == 0)
2985*4882a593Smuzhiyun 		goto release_lock;
2986*4882a593Smuzhiyun 
2987*4882a593Smuzhiyun 	if (strcmp(regd_name, regd_str(TXPWR_LMT_WW)) == 0)
2988*4882a593Smuzhiyun 		is_ww_regd = 1;
2989*4882a593Smuzhiyun 
2990*4882a593Smuzhiyun 	if (!is_ww_regd) {
2991*4882a593Smuzhiyun 		ent = _rtw_txpwr_lmt_get_by_name(rfctl, regd_name);
2992*4882a593Smuzhiyun 		if (!ent)
2993*4882a593Smuzhiyun 			goto release_lock;
2994*4882a593Smuzhiyun 	}
2995*4882a593Smuzhiyun 
2996*4882a593Smuzhiyun 	ch_idx = phy_GetChannelIndexOfTxPowerLimit(Band, cch);
2997*4882a593Smuzhiyun 	if (ch_idx == -1)
2998*4882a593Smuzhiyun 		goto release_lock;
2999*4882a593Smuzhiyun 
3000*4882a593Smuzhiyun 	if (Band == BAND_ON_2_4G) {
3001*4882a593Smuzhiyun 		if (!is_ww_regd) {
3002*4882a593Smuzhiyun 			lmt = ent->lmt_2g[bw][tlrs][ch_idx][ntx_idx];
3003*4882a593Smuzhiyun 			if (lmt != ww_lmt_val)
3004*4882a593Smuzhiyun 				goto release_lock;
3005*4882a593Smuzhiyun 		}
3006*4882a593Smuzhiyun 
3007*4882a593Smuzhiyun 		/* search for min value for WW regd or WW limit */
3008*4882a593Smuzhiyun 		lmt = hal_spec->txgi_max;
3009*4882a593Smuzhiyun 		head = &rfctl->txpwr_lmt_list;
3010*4882a593Smuzhiyun 		cur = get_next(head);
3011*4882a593Smuzhiyun 		while ((rtw_end_of_queue_search(head, cur)) == _FALSE) {
3012*4882a593Smuzhiyun 			ent = LIST_CONTAINOR(cur, struct txpwr_lmt_ent, list);
3013*4882a593Smuzhiyun 			cur = get_next(cur);
3014*4882a593Smuzhiyun 			if (ent->lmt_2g[bw][tlrs][ch_idx][ntx_idx] != ww_lmt_val)
3015*4882a593Smuzhiyun 				lmt = rtw_min(lmt, ent->lmt_2g[bw][tlrs][ch_idx][ntx_idx]);
3016*4882a593Smuzhiyun 		}
3017*4882a593Smuzhiyun 	}
3018*4882a593Smuzhiyun 	#if CONFIG_IEEE80211_BAND_5GHZ
3019*4882a593Smuzhiyun 	else if (Band == BAND_ON_5G) {
3020*4882a593Smuzhiyun 		if (!is_ww_regd) {
3021*4882a593Smuzhiyun 			lmt = ent->lmt_5g[bw][tlrs - 1][ch_idx][ntx_idx];
3022*4882a593Smuzhiyun 			if (lmt != ww_lmt_val)
3023*4882a593Smuzhiyun 				goto release_lock;
3024*4882a593Smuzhiyun 		}
3025*4882a593Smuzhiyun 
3026*4882a593Smuzhiyun 		/* search for min value for WW regd or WW limit */
3027*4882a593Smuzhiyun 		lmt = hal_spec->txgi_max;
3028*4882a593Smuzhiyun 		head = &rfctl->txpwr_lmt_list;
3029*4882a593Smuzhiyun 		cur = get_next(head);
3030*4882a593Smuzhiyun 		while ((rtw_end_of_queue_search(head, cur)) == _FALSE) {
3031*4882a593Smuzhiyun 			ent = LIST_CONTAINOR(cur, struct txpwr_lmt_ent, list);
3032*4882a593Smuzhiyun 			cur = get_next(cur);
3033*4882a593Smuzhiyun 			if (ent->lmt_5g[bw][tlrs - 1][ch_idx][ntx_idx] != ww_lmt_val)
3034*4882a593Smuzhiyun 				lmt = rtw_min(lmt, ent->lmt_5g[bw][tlrs - 1][ch_idx][ntx_idx]);
3035*4882a593Smuzhiyun 		}
3036*4882a593Smuzhiyun 	}
3037*4882a593Smuzhiyun 	#endif
3038*4882a593Smuzhiyun 
3039*4882a593Smuzhiyun release_lock:
3040*4882a593Smuzhiyun 	if (lock)
3041*4882a593Smuzhiyun 		_exit_critical_mutex(&rfctl->txpwr_lmt_mutex, &irqL);
3042*4882a593Smuzhiyun 
3043*4882a593Smuzhiyun exit:
3044*4882a593Smuzhiyun 	return lmt;
3045*4882a593Smuzhiyun }
3046*4882a593Smuzhiyun 
3047*4882a593Smuzhiyun /*
3048*4882a593Smuzhiyun * return txpwr limit diff value to target of its rate section in unit of TX Gain Index
3049*4882a593Smuzhiyun * hal_spec->txgi_max is returned when NO limit
3050*4882a593Smuzhiyun */
phy_get_txpwr_lmt_diff(_adapter * adapter,const char * regd_name,BAND_TYPE band,enum channel_width bw,u8 rfpath,u8 rs,u8 tlrs,u8 ntx_idx,u8 cch,u8 lock)3051*4882a593Smuzhiyun inline s8 phy_get_txpwr_lmt_diff(_adapter *adapter
3052*4882a593Smuzhiyun 	, const char *regd_name
3053*4882a593Smuzhiyun 	, BAND_TYPE band, enum channel_width bw
3054*4882a593Smuzhiyun 	, u8 rfpath, u8 rs, u8 tlrs, u8 ntx_idx, u8 cch, u8 lock
3055*4882a593Smuzhiyun )
3056*4882a593Smuzhiyun {
3057*4882a593Smuzhiyun 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
3058*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3059*4882a593Smuzhiyun 	s8 lmt = phy_get_txpwr_lmt(adapter, regd_name, band, bw, tlrs, ntx_idx, cch, lock);
3060*4882a593Smuzhiyun 
3061*4882a593Smuzhiyun 	if (lmt != hal_spec->txgi_max) {
3062*4882a593Smuzhiyun 		/* return diff value */
3063*4882a593Smuzhiyun 		lmt = lmt - phy_get_target_txpwr(adapter, band, rfpath, rs);
3064*4882a593Smuzhiyun 	}
3065*4882a593Smuzhiyun 
3066*4882a593Smuzhiyun 	return lmt;
3067*4882a593Smuzhiyun }
3068*4882a593Smuzhiyun 
3069*4882a593Smuzhiyun /*
3070*4882a593Smuzhiyun * May search for secondary channels for min limit
3071*4882a593Smuzhiyun * @opch: used to specify operating channel position to get
3072*4882a593Smuzhiyun * cch of every bandwidths which differ from current hal_data.cch20, 40, 80...
3073*4882a593Smuzhiyun *
3074*4882a593Smuzhiyun * return txpwr limit in unit of TX Gain Index
3075*4882a593Smuzhiyun * hsl_spec->txgi_max is returned when NO limit
3076*4882a593Smuzhiyun */
phy_get_txpwr_lmt_sub_chs(_adapter * adapter,const char * regd_name,BAND_TYPE band,enum channel_width bw,u8 rfpath,u8 rate,u8 ntx_idx,u8 cch,u8 opch)3077*4882a593Smuzhiyun s8 phy_get_txpwr_lmt_sub_chs(_adapter *adapter
3078*4882a593Smuzhiyun 	, const char *regd_name
3079*4882a593Smuzhiyun 	, BAND_TYPE band, enum channel_width bw
3080*4882a593Smuzhiyun 	, u8 rfpath, u8 rate, u8 ntx_idx, u8 cch, u8 opch)
3081*4882a593Smuzhiyun {
3082*4882a593Smuzhiyun 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3083*4882a593Smuzhiyun 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
3084*4882a593Smuzhiyun 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
3085*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3086*4882a593Smuzhiyun 	BOOLEAN no_sc = _FALSE;
3087*4882a593Smuzhiyun 	u8 cch_20 = hal_data->cch_20, cch_40 = hal_data->cch_40, cch_80 = hal_data->cch_80;
3088*4882a593Smuzhiyun 	s8 tlrs = -1;
3089*4882a593Smuzhiyun 	s8 lmt = hal_spec->txgi_max;
3090*4882a593Smuzhiyun 	u8 tmp_cch = 0;
3091*4882a593Smuzhiyun 	u8 tmp_bw;
3092*4882a593Smuzhiyun 	u8 bw_bmp = 0;
3093*4882a593Smuzhiyun 	s8 min_lmt = hal_spec->txgi_max;
3094*4882a593Smuzhiyun 	u8 final_bw = bw, final_cch = cch;
3095*4882a593Smuzhiyun 	_irqL irqL;
3096*4882a593Smuzhiyun 
3097*4882a593Smuzhiyun #ifdef CONFIG_MP_INCLUDED
3098*4882a593Smuzhiyun 	/* MP mode channel don't use secondary channel */
3099*4882a593Smuzhiyun 	if (rtw_mp_mode_check(adapter) == _TRUE)
3100*4882a593Smuzhiyun 		no_sc = _TRUE;
3101*4882a593Smuzhiyun #endif
3102*4882a593Smuzhiyun 	if (IS_CCK_RATE(rate))
3103*4882a593Smuzhiyun 		tlrs = TXPWR_LMT_RS_CCK;
3104*4882a593Smuzhiyun 	else if (IS_OFDM_RATE(rate))
3105*4882a593Smuzhiyun 		tlrs = TXPWR_LMT_RS_OFDM;
3106*4882a593Smuzhiyun 	else if (IS_HT_RATE(rate))
3107*4882a593Smuzhiyun 		tlrs = TXPWR_LMT_RS_HT;
3108*4882a593Smuzhiyun 	else if (IS_VHT_RATE(rate))
3109*4882a593Smuzhiyun 		tlrs = TXPWR_LMT_RS_VHT;
3110*4882a593Smuzhiyun 	else {
3111*4882a593Smuzhiyun 		RTW_ERR("%s invalid rate 0x%x\n", __func__, rate);
3112*4882a593Smuzhiyun 		rtw_warn_on(1);
3113*4882a593Smuzhiyun 		goto exit;
3114*4882a593Smuzhiyun 	}
3115*4882a593Smuzhiyun 
3116*4882a593Smuzhiyun 	if (no_sc == _TRUE) {
3117*4882a593Smuzhiyun 		/* use the input center channel and bandwidth directly */
3118*4882a593Smuzhiyun 		tmp_cch = cch;
3119*4882a593Smuzhiyun 		bw_bmp = ch_width_to_bw_cap(bw);
3120*4882a593Smuzhiyun 	} else {
3121*4882a593Smuzhiyun 		/* decide center channel of each bandwidth */
3122*4882a593Smuzhiyun 		if (opch != 0) {
3123*4882a593Smuzhiyun 			cch_80 = bw == CHANNEL_WIDTH_80 ? cch : 0;
3124*4882a593Smuzhiyun 			cch_40 = bw == CHANNEL_WIDTH_40 ? cch : 0;
3125*4882a593Smuzhiyun 			cch_20 = bw == CHANNEL_WIDTH_20 ? cch : 0;
3126*4882a593Smuzhiyun 			if (cch_80 != 0)
3127*4882a593Smuzhiyun 				cch_40 = rtw_get_scch_by_cch_opch(cch_80, CHANNEL_WIDTH_80, opch);
3128*4882a593Smuzhiyun 			if (cch_40 != 0)
3129*4882a593Smuzhiyun 				cch_20 = rtw_get_scch_by_cch_opch(cch_40, CHANNEL_WIDTH_40, opch);
3130*4882a593Smuzhiyun 		}
3131*4882a593Smuzhiyun 
3132*4882a593Smuzhiyun 		/*
3133*4882a593Smuzhiyun 		* find the possible tx bandwidth bmp for this rate, and then will get center channel for each bandwidth
3134*4882a593Smuzhiyun 		* if no possible tx bandwidth bmp, select valid bandwidth up to current RF bandwidth into bmp
3135*4882a593Smuzhiyun 		*/
3136*4882a593Smuzhiyun 		if (tlrs == TXPWR_LMT_RS_CCK || tlrs == TXPWR_LMT_RS_OFDM)
3137*4882a593Smuzhiyun 			bw_bmp = BW_CAP_20M; /* CCK, OFDM only BW 20M */
3138*4882a593Smuzhiyun 		else if (tlrs == TXPWR_LMT_RS_HT) {
3139*4882a593Smuzhiyun 			bw_bmp = rtw_get_tx_bw_bmp_of_ht_rate(dvobj, rate, bw);
3140*4882a593Smuzhiyun 			if (bw_bmp == 0)
3141*4882a593Smuzhiyun 				bw_bmp = ch_width_to_bw_cap(bw > CHANNEL_WIDTH_40 ? CHANNEL_WIDTH_40 : bw);
3142*4882a593Smuzhiyun 		} else if (tlrs == TXPWR_LMT_RS_VHT) {
3143*4882a593Smuzhiyun 			bw_bmp = rtw_get_tx_bw_bmp_of_vht_rate(dvobj, rate, bw);
3144*4882a593Smuzhiyun 			if (bw_bmp == 0)
3145*4882a593Smuzhiyun 				bw_bmp = ch_width_to_bw_cap(bw > CHANNEL_WIDTH_160 ? CHANNEL_WIDTH_160 : bw);
3146*4882a593Smuzhiyun 		} else
3147*4882a593Smuzhiyun 			rtw_warn_on(1);
3148*4882a593Smuzhiyun 	}
3149*4882a593Smuzhiyun 
3150*4882a593Smuzhiyun 	if (bw_bmp == 0)
3151*4882a593Smuzhiyun 		goto exit;
3152*4882a593Smuzhiyun 
3153*4882a593Smuzhiyun 	_enter_critical_mutex(&rfctl->txpwr_lmt_mutex, &irqL);
3154*4882a593Smuzhiyun 
3155*4882a593Smuzhiyun 	/* loop for each possible tx bandwidth to find minimum limit */
3156*4882a593Smuzhiyun 	for (tmp_bw = CHANNEL_WIDTH_20; tmp_bw <= bw; tmp_bw++) {
3157*4882a593Smuzhiyun 		if (!(ch_width_to_bw_cap(tmp_bw) & bw_bmp))
3158*4882a593Smuzhiyun 			continue;
3159*4882a593Smuzhiyun 
3160*4882a593Smuzhiyun 		if (no_sc == _FALSE) {
3161*4882a593Smuzhiyun 			if (tmp_bw == CHANNEL_WIDTH_20)
3162*4882a593Smuzhiyun 				tmp_cch = cch_20;
3163*4882a593Smuzhiyun 			else if (tmp_bw == CHANNEL_WIDTH_40)
3164*4882a593Smuzhiyun 				tmp_cch = cch_40;
3165*4882a593Smuzhiyun 			else if (tmp_bw == CHANNEL_WIDTH_80)
3166*4882a593Smuzhiyun 				tmp_cch = cch_80;
3167*4882a593Smuzhiyun 			else {
3168*4882a593Smuzhiyun 				tmp_cch = 0;
3169*4882a593Smuzhiyun 				rtw_warn_on(1);
3170*4882a593Smuzhiyun 			}
3171*4882a593Smuzhiyun 		}
3172*4882a593Smuzhiyun 
3173*4882a593Smuzhiyun 		lmt = phy_get_txpwr_lmt(adapter, regd_name, band, tmp_bw, tlrs, ntx_idx, tmp_cch, 0);
3174*4882a593Smuzhiyun 
3175*4882a593Smuzhiyun 		if (min_lmt >= lmt) {
3176*4882a593Smuzhiyun 			min_lmt = lmt;
3177*4882a593Smuzhiyun 			final_cch = tmp_cch;
3178*4882a593Smuzhiyun 			final_bw = tmp_bw;
3179*4882a593Smuzhiyun 		}
3180*4882a593Smuzhiyun 
3181*4882a593Smuzhiyun 	}
3182*4882a593Smuzhiyun 
3183*4882a593Smuzhiyun 	_exit_critical_mutex(&rfctl->txpwr_lmt_mutex, &irqL);
3184*4882a593Smuzhiyun 
3185*4882a593Smuzhiyun exit:
3186*4882a593Smuzhiyun 
3187*4882a593Smuzhiyun 	if (0) {
3188*4882a593Smuzhiyun 		if (final_bw != bw && (IS_HT_RATE(rate) || IS_VHT_RATE(rate)))
3189*4882a593Smuzhiyun 			RTW_INFO("%s min_lmt: %s ch%u -> %s ch%u\n"
3190*4882a593Smuzhiyun 				, MGN_RATE_STR(rate)
3191*4882a593Smuzhiyun 				, ch_width_str(bw), cch
3192*4882a593Smuzhiyun 				, ch_width_str(final_bw), final_cch);
3193*4882a593Smuzhiyun 	}
3194*4882a593Smuzhiyun 
3195*4882a593Smuzhiyun 	return min_lmt;
3196*4882a593Smuzhiyun }
3197*4882a593Smuzhiyun 
phy_txpwr_lmt_cck_ofdm_mt_chk(_adapter * adapter)3198*4882a593Smuzhiyun static void phy_txpwr_lmt_cck_ofdm_mt_chk(_adapter *adapter)
3199*4882a593Smuzhiyun {
3200*4882a593Smuzhiyun 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
3201*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3202*4882a593Smuzhiyun 	struct txpwr_lmt_ent *ent;
3203*4882a593Smuzhiyun 	_list *cur, *head;
3204*4882a593Smuzhiyun 	u8 channel, tlrs, ntx_idx;
3205*4882a593Smuzhiyun 
3206*4882a593Smuzhiyun 	rfctl->txpwr_lmt_2g_cck_ofdm_state = 0;
3207*4882a593Smuzhiyun #if CONFIG_IEEE80211_BAND_5GHZ
3208*4882a593Smuzhiyun 	rfctl->txpwr_lmt_5g_cck_ofdm_state = 0;
3209*4882a593Smuzhiyun #endif
3210*4882a593Smuzhiyun 
3211*4882a593Smuzhiyun 	head = &rfctl->txpwr_lmt_list;
3212*4882a593Smuzhiyun 	cur = get_next(head);
3213*4882a593Smuzhiyun 
3214*4882a593Smuzhiyun 	while ((rtw_end_of_queue_search(head, cur)) == _FALSE) {
3215*4882a593Smuzhiyun 		ent = LIST_CONTAINOR(cur, struct txpwr_lmt_ent, list);
3216*4882a593Smuzhiyun 		cur = get_next(cur);
3217*4882a593Smuzhiyun 
3218*4882a593Smuzhiyun 		/* check 2G CCK, OFDM state*/
3219*4882a593Smuzhiyun 		for (tlrs = TXPWR_LMT_RS_CCK; tlrs <= TXPWR_LMT_RS_OFDM; tlrs++) {
3220*4882a593Smuzhiyun 			for (ntx_idx = RF_1TX; ntx_idx < MAX_TX_COUNT; ntx_idx++) {
3221*4882a593Smuzhiyun 				for (channel = 0; channel < CENTER_CH_2G_NUM; ++channel) {
3222*4882a593Smuzhiyun 					if (ent->lmt_2g[CHANNEL_WIDTH_20][tlrs][channel][ntx_idx] != hal_spec->txgi_max) {
3223*4882a593Smuzhiyun 						if (tlrs == TXPWR_LMT_RS_CCK)
3224*4882a593Smuzhiyun 							rfctl->txpwr_lmt_2g_cck_ofdm_state |= TXPWR_LMT_HAS_CCK_1T << ntx_idx;
3225*4882a593Smuzhiyun 						else
3226*4882a593Smuzhiyun 							rfctl->txpwr_lmt_2g_cck_ofdm_state |= TXPWR_LMT_HAS_OFDM_1T << ntx_idx;
3227*4882a593Smuzhiyun 						break;
3228*4882a593Smuzhiyun 					}
3229*4882a593Smuzhiyun 				}
3230*4882a593Smuzhiyun 			}
3231*4882a593Smuzhiyun 		}
3232*4882a593Smuzhiyun 
3233*4882a593Smuzhiyun 		/* if 2G OFDM multi-TX is not defined, reference HT20 */
3234*4882a593Smuzhiyun 		for (channel = 0; channel < CENTER_CH_2G_NUM; ++channel) {
3235*4882a593Smuzhiyun 			for (ntx_idx = RF_2TX; ntx_idx < MAX_TX_COUNT; ntx_idx++) {
3236*4882a593Smuzhiyun 				if (rfctl->txpwr_lmt_2g_cck_ofdm_state & (TXPWR_LMT_HAS_OFDM_1T << ntx_idx))
3237*4882a593Smuzhiyun 					continue;
3238*4882a593Smuzhiyun 				ent->lmt_2g[CHANNEL_WIDTH_20][TXPWR_LMT_RS_OFDM][channel][ntx_idx] =
3239*4882a593Smuzhiyun 					ent->lmt_2g[CHANNEL_WIDTH_20][TXPWR_LMT_RS_HT][channel][ntx_idx];
3240*4882a593Smuzhiyun 			}
3241*4882a593Smuzhiyun 		}
3242*4882a593Smuzhiyun 
3243*4882a593Smuzhiyun #if CONFIG_IEEE80211_BAND_5GHZ
3244*4882a593Smuzhiyun 		/* check 5G OFDM state*/
3245*4882a593Smuzhiyun 		for (ntx_idx = RF_1TX; ntx_idx < MAX_TX_COUNT; ntx_idx++) {
3246*4882a593Smuzhiyun 			for (channel = 0; channel < CENTER_CH_5G_ALL_NUM; ++channel) {
3247*4882a593Smuzhiyun 				if (ent->lmt_5g[CHANNEL_WIDTH_20][TXPWR_LMT_RS_OFDM - 1][channel][ntx_idx] != hal_spec->txgi_max) {
3248*4882a593Smuzhiyun 					rfctl->txpwr_lmt_5g_cck_ofdm_state |= TXPWR_LMT_HAS_OFDM_1T << ntx_idx;
3249*4882a593Smuzhiyun 					break;
3250*4882a593Smuzhiyun 				}
3251*4882a593Smuzhiyun 			}
3252*4882a593Smuzhiyun 		}
3253*4882a593Smuzhiyun 
3254*4882a593Smuzhiyun 		for (channel = 0; channel < CENTER_CH_5G_ALL_NUM; ++channel) {
3255*4882a593Smuzhiyun 			for (ntx_idx = RF_2TX; ntx_idx < MAX_TX_COUNT; ntx_idx++) {
3256*4882a593Smuzhiyun 				if (rfctl->txpwr_lmt_5g_cck_ofdm_state & (TXPWR_LMT_HAS_OFDM_1T << ntx_idx))
3257*4882a593Smuzhiyun 					continue;
3258*4882a593Smuzhiyun 				/* if 5G OFDM multi-TX is not defined, reference HT20 */
3259*4882a593Smuzhiyun 				ent->lmt_5g[CHANNEL_WIDTH_20][TXPWR_LMT_RS_OFDM - 1][channel][ntx_idx] =
3260*4882a593Smuzhiyun 					ent->lmt_5g[CHANNEL_WIDTH_20][TXPWR_LMT_RS_HT - 1][channel][ntx_idx];
3261*4882a593Smuzhiyun 			}
3262*4882a593Smuzhiyun 		}
3263*4882a593Smuzhiyun #endif /* CONFIG_IEEE80211_BAND_5GHZ */
3264*4882a593Smuzhiyun 	}
3265*4882a593Smuzhiyun }
3266*4882a593Smuzhiyun 
3267*4882a593Smuzhiyun #if CONFIG_IEEE80211_BAND_5GHZ
phy_txpwr_lmt_cross_ref_ht_vht(_adapter * adapter)3268*4882a593Smuzhiyun static void phy_txpwr_lmt_cross_ref_ht_vht(_adapter *adapter)
3269*4882a593Smuzhiyun {
3270*4882a593Smuzhiyun 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
3271*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3272*4882a593Smuzhiyun 	struct txpwr_lmt_ent *ent;
3273*4882a593Smuzhiyun 	_list *cur, *head;
3274*4882a593Smuzhiyun 	u8 bw, channel, tlrs, ref_tlrs, ntx_idx;
3275*4882a593Smuzhiyun 	int ht_ref_vht_5g_20_40 = 0;
3276*4882a593Smuzhiyun 	int vht_ref_ht_5g_20_40 = 0;
3277*4882a593Smuzhiyun 	int ht_has_ref_5g_20_40 = 0;
3278*4882a593Smuzhiyun 	int vht_has_ref_5g_20_40 = 0;
3279*4882a593Smuzhiyun 
3280*4882a593Smuzhiyun 	rfctl->txpwr_lmt_5g_20_40_ref = 0;
3281*4882a593Smuzhiyun 
3282*4882a593Smuzhiyun 	head = &rfctl->txpwr_lmt_list;
3283*4882a593Smuzhiyun 	cur = get_next(head);
3284*4882a593Smuzhiyun 
3285*4882a593Smuzhiyun 	while ((rtw_end_of_queue_search(head, cur)) == _FALSE) {
3286*4882a593Smuzhiyun 		ent = LIST_CONTAINOR(cur, struct txpwr_lmt_ent, list);
3287*4882a593Smuzhiyun 		cur = get_next(cur);
3288*4882a593Smuzhiyun 
3289*4882a593Smuzhiyun 		for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; ++bw) {
3290*4882a593Smuzhiyun 
3291*4882a593Smuzhiyun 			for (channel = 0; channel < CENTER_CH_5G_ALL_NUM; ++channel) {
3292*4882a593Smuzhiyun 
3293*4882a593Smuzhiyun 				for (tlrs = TXPWR_LMT_RS_HT; tlrs < TXPWR_LMT_RS_NUM; ++tlrs) {
3294*4882a593Smuzhiyun 
3295*4882a593Smuzhiyun 					/* 5G 20M 40M VHT and HT can cross reference */
3296*4882a593Smuzhiyun 					if (bw == CHANNEL_WIDTH_20 || bw == CHANNEL_WIDTH_40) {
3297*4882a593Smuzhiyun 						if (tlrs == TXPWR_LMT_RS_HT)
3298*4882a593Smuzhiyun 							ref_tlrs = TXPWR_LMT_RS_VHT;
3299*4882a593Smuzhiyun 						else if (tlrs == TXPWR_LMT_RS_VHT)
3300*4882a593Smuzhiyun 							ref_tlrs = TXPWR_LMT_RS_HT;
3301*4882a593Smuzhiyun 						else
3302*4882a593Smuzhiyun 							continue;
3303*4882a593Smuzhiyun 
3304*4882a593Smuzhiyun 						for (ntx_idx = RF_1TX; ntx_idx < MAX_TX_COUNT; ntx_idx++) {
3305*4882a593Smuzhiyun 
3306*4882a593Smuzhiyun 							if (ent->lmt_5g[bw][ref_tlrs - 1][channel][ntx_idx] == hal_spec->txgi_max)
3307*4882a593Smuzhiyun 								continue;
3308*4882a593Smuzhiyun 
3309*4882a593Smuzhiyun 							if (tlrs == TXPWR_LMT_RS_HT)
3310*4882a593Smuzhiyun 								ht_has_ref_5g_20_40++;
3311*4882a593Smuzhiyun 							else if (tlrs == TXPWR_LMT_RS_VHT)
3312*4882a593Smuzhiyun 								vht_has_ref_5g_20_40++;
3313*4882a593Smuzhiyun 							else
3314*4882a593Smuzhiyun 								continue;
3315*4882a593Smuzhiyun 
3316*4882a593Smuzhiyun 							if (ent->lmt_5g[bw][tlrs - 1][channel][ntx_idx] != hal_spec->txgi_max)
3317*4882a593Smuzhiyun 								continue;
3318*4882a593Smuzhiyun 
3319*4882a593Smuzhiyun 							if (tlrs == TXPWR_LMT_RS_HT && ref_tlrs == TXPWR_LMT_RS_VHT)
3320*4882a593Smuzhiyun 								ht_ref_vht_5g_20_40++;
3321*4882a593Smuzhiyun 							else if (tlrs == TXPWR_LMT_RS_VHT && ref_tlrs == TXPWR_LMT_RS_HT)
3322*4882a593Smuzhiyun 								vht_ref_ht_5g_20_40++;
3323*4882a593Smuzhiyun 
3324*4882a593Smuzhiyun 							if (0)
3325*4882a593Smuzhiyun 								RTW_INFO("reg:%s, bw:%u, ch:%u, %s-%uT ref %s-%uT\n"
3326*4882a593Smuzhiyun 									, ent->regd_name, bw, channel
3327*4882a593Smuzhiyun 									, txpwr_lmt_rs_str(tlrs), ntx_idx + 1
3328*4882a593Smuzhiyun 									, txpwr_lmt_rs_str(ref_tlrs), ntx_idx + 1);
3329*4882a593Smuzhiyun 
3330*4882a593Smuzhiyun 							ent->lmt_5g[bw][tlrs - 1][channel][ntx_idx] =
3331*4882a593Smuzhiyun 								ent->lmt_5g[bw][ref_tlrs - 1][channel][ntx_idx];
3332*4882a593Smuzhiyun 						}
3333*4882a593Smuzhiyun 					}
3334*4882a593Smuzhiyun 
3335*4882a593Smuzhiyun 				}
3336*4882a593Smuzhiyun 			}
3337*4882a593Smuzhiyun 		}
3338*4882a593Smuzhiyun 	}
3339*4882a593Smuzhiyun 
3340*4882a593Smuzhiyun 	if (0) {
3341*4882a593Smuzhiyun 		RTW_INFO("ht_ref_vht_5g_20_40:%d, ht_has_ref_5g_20_40:%d\n", ht_ref_vht_5g_20_40, ht_has_ref_5g_20_40);
3342*4882a593Smuzhiyun 		RTW_INFO("vht_ref_ht_5g_20_40:%d, vht_has_ref_5g_20_40:%d\n", vht_ref_ht_5g_20_40, vht_has_ref_5g_20_40);
3343*4882a593Smuzhiyun 	}
3344*4882a593Smuzhiyun 
3345*4882a593Smuzhiyun 	/* 5G 20M&40M HT all come from VHT*/
3346*4882a593Smuzhiyun 	if (ht_ref_vht_5g_20_40 && ht_has_ref_5g_20_40 == ht_ref_vht_5g_20_40)
3347*4882a593Smuzhiyun 		rfctl->txpwr_lmt_5g_20_40_ref |= TXPWR_LMT_REF_HT_FROM_VHT;
3348*4882a593Smuzhiyun 
3349*4882a593Smuzhiyun 	/* 5G 20M&40M VHT all come from HT*/
3350*4882a593Smuzhiyun 	if (vht_ref_ht_5g_20_40 && vht_has_ref_5g_20_40 == vht_ref_ht_5g_20_40)
3351*4882a593Smuzhiyun 		rfctl->txpwr_lmt_5g_20_40_ref |= TXPWR_LMT_REF_VHT_FROM_HT;
3352*4882a593Smuzhiyun }
3353*4882a593Smuzhiyun #endif /* CONFIG_IEEE80211_BAND_5GHZ */
3354*4882a593Smuzhiyun 
3355*4882a593Smuzhiyun #ifndef DBG_TXPWR_LMT_BAND_CHK
3356*4882a593Smuzhiyun #define DBG_TXPWR_LMT_BAND_CHK 0
3357*4882a593Smuzhiyun #endif
3358*4882a593Smuzhiyun 
3359*4882a593Smuzhiyun #if DBG_TXPWR_LMT_BAND_CHK
3360*4882a593Smuzhiyun /* check if larger bandwidth limit is less than smaller bandwidth for HT & VHT rate */
phy_txpwr_limit_bandwidth_chk(_adapter * adapter)3361*4882a593Smuzhiyun void phy_txpwr_limit_bandwidth_chk(_adapter *adapter)
3362*4882a593Smuzhiyun {
3363*4882a593Smuzhiyun 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
3364*4882a593Smuzhiyun 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
3365*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3366*4882a593Smuzhiyun 	u8 band, bw, path, tlrs, ntx_idx, cch, offset, scch;
3367*4882a593Smuzhiyun 	u8 ch_num, n, i;
3368*4882a593Smuzhiyun 
3369*4882a593Smuzhiyun 	for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
3370*4882a593Smuzhiyun 		if (!hal_is_band_support(adapter, band))
3371*4882a593Smuzhiyun 			continue;
3372*4882a593Smuzhiyun 
3373*4882a593Smuzhiyun 		for (bw = CHANNEL_WIDTH_40; bw <= CHANNEL_WIDTH_80; bw++) {
3374*4882a593Smuzhiyun 			if (bw >= CHANNEL_WIDTH_160)
3375*4882a593Smuzhiyun 				continue;
3376*4882a593Smuzhiyun 			if (band == BAND_ON_2_4G && bw >= CHANNEL_WIDTH_80)
3377*4882a593Smuzhiyun 				continue;
3378*4882a593Smuzhiyun 
3379*4882a593Smuzhiyun 			if (band == BAND_ON_2_4G)
3380*4882a593Smuzhiyun 				ch_num = center_chs_2g_num(bw);
3381*4882a593Smuzhiyun 			else
3382*4882a593Smuzhiyun 				ch_num = center_chs_5g_num(bw);
3383*4882a593Smuzhiyun 
3384*4882a593Smuzhiyun 			if (ch_num == 0) {
3385*4882a593Smuzhiyun 				rtw_warn_on(1);
3386*4882a593Smuzhiyun 				break;
3387*4882a593Smuzhiyun 			}
3388*4882a593Smuzhiyun 
3389*4882a593Smuzhiyun 			for (tlrs = TXPWR_LMT_RS_HT; tlrs < TXPWR_LMT_RS_NUM; tlrs++) {
3390*4882a593Smuzhiyun 
3391*4882a593Smuzhiyun 				if (band == BAND_ON_2_4G && tlrs == TXPWR_LMT_RS_VHT)
3392*4882a593Smuzhiyun 					continue;
3393*4882a593Smuzhiyun 				if (band == BAND_ON_5G && tlrs == TXPWR_LMT_RS_CCK)
3394*4882a593Smuzhiyun 					continue;
3395*4882a593Smuzhiyun 				if (bw > CHANNEL_WIDTH_20 && (tlrs == TXPWR_LMT_RS_CCK || tlrs == TXPWR_LMT_RS_OFDM))
3396*4882a593Smuzhiyun 					continue;
3397*4882a593Smuzhiyun 				if (bw > CHANNEL_WIDTH_40 && tlrs == TXPWR_LMT_RS_HT)
3398*4882a593Smuzhiyun 					continue;
3399*4882a593Smuzhiyun 				if (tlrs == TXPWR_LMT_RS_VHT && !IS_HARDWARE_TYPE_JAGUAR_ALL(adapter))
3400*4882a593Smuzhiyun 					continue;
3401*4882a593Smuzhiyun 
3402*4882a593Smuzhiyun 				for (ntx_idx = RF_1TX; ntx_idx < MAX_TX_COUNT; ntx_idx++) {
3403*4882a593Smuzhiyun 					struct txpwr_lmt_ent *ent;
3404*4882a593Smuzhiyun 					_list *cur, *head;
3405*4882a593Smuzhiyun 
3406*4882a593Smuzhiyun 					if (ntx_idx + 1 > hal_data->max_tx_cnt)
3407*4882a593Smuzhiyun 						continue;
3408*4882a593Smuzhiyun 
3409*4882a593Smuzhiyun 					/* bypass CCK multi-TX is not defined */
3410*4882a593Smuzhiyun 					if (tlrs == TXPWR_LMT_RS_CCK && ntx_idx > RF_1TX) {
3411*4882a593Smuzhiyun 						if (band == BAND_ON_2_4G
3412*4882a593Smuzhiyun 							&& !(rfctl->txpwr_lmt_2g_cck_ofdm_state & (TXPWR_LMT_HAS_CCK_1T << ntx_idx)))
3413*4882a593Smuzhiyun 							continue;
3414*4882a593Smuzhiyun 					}
3415*4882a593Smuzhiyun 
3416*4882a593Smuzhiyun 					/* bypass OFDM multi-TX is not defined */
3417*4882a593Smuzhiyun 					if (tlrs == TXPWR_LMT_RS_OFDM && ntx_idx > RF_1TX) {
3418*4882a593Smuzhiyun 						if (band == BAND_ON_2_4G
3419*4882a593Smuzhiyun 							&& !(rfctl->txpwr_lmt_2g_cck_ofdm_state & (TXPWR_LMT_HAS_OFDM_1T << ntx_idx)))
3420*4882a593Smuzhiyun 							continue;
3421*4882a593Smuzhiyun 						#if CONFIG_IEEE80211_BAND_5GHZ
3422*4882a593Smuzhiyun 						if (band == BAND_ON_5G
3423*4882a593Smuzhiyun 							&& !(rfctl->txpwr_lmt_5g_cck_ofdm_state & (TXPWR_LMT_HAS_OFDM_1T << ntx_idx)))
3424*4882a593Smuzhiyun 							continue;
3425*4882a593Smuzhiyun 						#endif
3426*4882a593Smuzhiyun 					}
3427*4882a593Smuzhiyun 
3428*4882a593Smuzhiyun 					/* bypass 5G 20M, 40M pure reference */
3429*4882a593Smuzhiyun 					#if CONFIG_IEEE80211_BAND_5GHZ
3430*4882a593Smuzhiyun 					if (band == BAND_ON_5G && (bw == CHANNEL_WIDTH_20 || bw == CHANNEL_WIDTH_40)) {
3431*4882a593Smuzhiyun 						if (rfctl->txpwr_lmt_5g_20_40_ref == TXPWR_LMT_REF_HT_FROM_VHT) {
3432*4882a593Smuzhiyun 							if (tlrs == TXPWR_LMT_RS_HT)
3433*4882a593Smuzhiyun 								continue;
3434*4882a593Smuzhiyun 						} else if (rfctl->txpwr_lmt_5g_20_40_ref == TXPWR_LMT_REF_VHT_FROM_HT) {
3435*4882a593Smuzhiyun 							if (tlrs == TXPWR_LMT_RS_VHT && bw <= CHANNEL_WIDTH_40)
3436*4882a593Smuzhiyun 								continue;
3437*4882a593Smuzhiyun 						}
3438*4882a593Smuzhiyun 					}
3439*4882a593Smuzhiyun 					#endif
3440*4882a593Smuzhiyun 
3441*4882a593Smuzhiyun 					for (n = 0; n < ch_num; n++) {
3442*4882a593Smuzhiyun 						u8 cch_by_bw[3];
3443*4882a593Smuzhiyun 						u8 offset_by_bw; /* bitmap, 0 for lower, 1 for upper */
3444*4882a593Smuzhiyun 						u8 bw_pos;
3445*4882a593Smuzhiyun 						s8 lmt[3];
3446*4882a593Smuzhiyun 
3447*4882a593Smuzhiyun 						if (band == BAND_ON_2_4G)
3448*4882a593Smuzhiyun 							cch = center_chs_2g(bw, n);
3449*4882a593Smuzhiyun 						else
3450*4882a593Smuzhiyun 							cch = center_chs_5g(bw, n);
3451*4882a593Smuzhiyun 
3452*4882a593Smuzhiyun 						if (cch == 0) {
3453*4882a593Smuzhiyun 							rtw_warn_on(1);
3454*4882a593Smuzhiyun 							break;
3455*4882a593Smuzhiyun 						}
3456*4882a593Smuzhiyun 
3457*4882a593Smuzhiyun 						_rtw_memset(cch_by_bw, 0, 3);
3458*4882a593Smuzhiyun 						cch_by_bw[bw] = cch;
3459*4882a593Smuzhiyun 						offset_by_bw = 0x01;
3460*4882a593Smuzhiyun 
3461*4882a593Smuzhiyun 						do {
3462*4882a593Smuzhiyun 							for (bw_pos = bw; bw_pos >= CHANNEL_WIDTH_40; bw_pos--)
3463*4882a593Smuzhiyun 								cch_by_bw[bw_pos - 1] = rtw_get_scch_by_cch_offset(cch_by_bw[bw_pos], bw_pos, offset_by_bw & BIT(bw_pos) ? HAL_PRIME_CHNL_OFFSET_UPPER : HAL_PRIME_CHNL_OFFSET_LOWER);
3464*4882a593Smuzhiyun 
3465*4882a593Smuzhiyun 							head = &rfctl->txpwr_lmt_list;
3466*4882a593Smuzhiyun 							cur = get_next(head);
3467*4882a593Smuzhiyun 							while ((rtw_end_of_queue_search(head, cur)) == _FALSE) {
3468*4882a593Smuzhiyun 								ent = LIST_CONTAINOR(cur, struct txpwr_lmt_ent, list);
3469*4882a593Smuzhiyun 								cur = get_next(cur);
3470*4882a593Smuzhiyun 
3471*4882a593Smuzhiyun 								for (bw_pos = bw; bw_pos < CHANNEL_WIDTH_160; bw_pos--)
3472*4882a593Smuzhiyun 									lmt[bw_pos] = phy_get_txpwr_lmt(adapter, ent->regd_name, band, bw_pos, tlrs, ntx_idx, cch_by_bw[bw_pos], 0);
3473*4882a593Smuzhiyun 
3474*4882a593Smuzhiyun 								for (bw_pos = bw; bw_pos > CHANNEL_WIDTH_20; bw_pos--)
3475*4882a593Smuzhiyun 									if (lmt[bw_pos] > lmt[bw_pos - 1])
3476*4882a593Smuzhiyun 										break;
3477*4882a593Smuzhiyun 								if (bw_pos == CHANNEL_WIDTH_20)
3478*4882a593Smuzhiyun 									continue;
3479*4882a593Smuzhiyun 
3480*4882a593Smuzhiyun 								RTW_PRINT_SEL(RTW_DBGDUMP, "[%s][%s][%s][%uT][%-4s] cch:"
3481*4882a593Smuzhiyun 									, band_str(band)
3482*4882a593Smuzhiyun 									, ch_width_str(bw)
3483*4882a593Smuzhiyun 									, txpwr_lmt_rs_str(tlrs)
3484*4882a593Smuzhiyun 									, ntx_idx + 1
3485*4882a593Smuzhiyun 									, ent->regd_name
3486*4882a593Smuzhiyun 								);
3487*4882a593Smuzhiyun 								for (bw_pos = bw; bw_pos < CHANNEL_WIDTH_160; bw_pos--)
3488*4882a593Smuzhiyun 									_RTW_PRINT_SEL(RTW_DBGDUMP, "%03u ", cch_by_bw[bw_pos]);
3489*4882a593Smuzhiyun 								_RTW_PRINT_SEL(RTW_DBGDUMP, "limit:");
3490*4882a593Smuzhiyun 								for (bw_pos = bw; bw_pos < CHANNEL_WIDTH_160; bw_pos--) {
3491*4882a593Smuzhiyun 									if (lmt[bw_pos] == hal_spec->txgi_max)
3492*4882a593Smuzhiyun 										_RTW_PRINT_SEL(RTW_DBGDUMP, "N/A ");
3493*4882a593Smuzhiyun 									else if (lmt[bw_pos] > -hal_spec->txgi_pdbm && lmt[bw_pos] < 0) /* -1 < value < 0 */
3494*4882a593Smuzhiyun 										_RTW_PRINT_SEL(RTW_DBGDUMP, "-0.%d", (rtw_abs(lmt[bw_pos]) % hal_spec->txgi_pdbm) * 100 / hal_spec->txgi_pdbm);
3495*4882a593Smuzhiyun 									else if (lmt[bw_pos] % hal_spec->txgi_pdbm)
3496*4882a593Smuzhiyun 										_RTW_PRINT_SEL(RTW_DBGDUMP, "%2d.%d ", lmt[bw_pos] / hal_spec->txgi_pdbm, (rtw_abs(lmt[bw_pos]) % hal_spec->txgi_pdbm) * 100 / hal_spec->txgi_pdbm);
3497*4882a593Smuzhiyun 									else
3498*4882a593Smuzhiyun 										_RTW_PRINT_SEL(RTW_DBGDUMP, "%2d ", lmt[bw_pos] / hal_spec->txgi_pdbm);
3499*4882a593Smuzhiyun 								}
3500*4882a593Smuzhiyun 								_RTW_PRINT_SEL(RTW_DBGDUMP, "\n");
3501*4882a593Smuzhiyun 							}
3502*4882a593Smuzhiyun 							for (bw_pos = bw; bw_pos < CHANNEL_WIDTH_160; bw_pos--)
3503*4882a593Smuzhiyun 								lmt[bw_pos] = phy_get_txpwr_lmt(adapter, regd_str(TXPWR_LMT_WW), band, bw_pos, tlrs, ntx_idx, cch_by_bw[bw_pos], 0);
3504*4882a593Smuzhiyun 
3505*4882a593Smuzhiyun 							for (bw_pos = bw; bw_pos > CHANNEL_WIDTH_20; bw_pos--)
3506*4882a593Smuzhiyun 								if (lmt[bw_pos] > lmt[bw_pos - 1])
3507*4882a593Smuzhiyun 									break;
3508*4882a593Smuzhiyun 							if (bw_pos != CHANNEL_WIDTH_20) {
3509*4882a593Smuzhiyun 								RTW_PRINT_SEL(RTW_DBGDUMP, "[%s][%s][%s][%uT][%-4s] cch:"
3510*4882a593Smuzhiyun 									, band_str(band)
3511*4882a593Smuzhiyun 									, ch_width_str(bw)
3512*4882a593Smuzhiyun 									, txpwr_lmt_rs_str(tlrs)
3513*4882a593Smuzhiyun 									, ntx_idx + 1
3514*4882a593Smuzhiyun 									, regd_str(TXPWR_LMT_WW)
3515*4882a593Smuzhiyun 								);
3516*4882a593Smuzhiyun 								for (bw_pos = bw; bw_pos < CHANNEL_WIDTH_160; bw_pos--)
3517*4882a593Smuzhiyun 									_RTW_PRINT_SEL(RTW_DBGDUMP, "%03u ", cch_by_bw[bw_pos]);
3518*4882a593Smuzhiyun 								_RTW_PRINT_SEL(RTW_DBGDUMP, "limit:");
3519*4882a593Smuzhiyun 								for (bw_pos = bw; bw_pos < CHANNEL_WIDTH_160; bw_pos--) {
3520*4882a593Smuzhiyun 									if (lmt[bw_pos] == hal_spec->txgi_max)
3521*4882a593Smuzhiyun 										_RTW_PRINT_SEL(RTW_DBGDUMP, "N/A ");
3522*4882a593Smuzhiyun 									else if (lmt[bw_pos] > -hal_spec->txgi_pdbm && lmt[bw_pos] < 0) /* -1 < value < 0 */
3523*4882a593Smuzhiyun 										_RTW_PRINT_SEL(RTW_DBGDUMP, "-0.%d", (rtw_abs(lmt[bw_pos]) % hal_spec->txgi_pdbm) * 100 / hal_spec->txgi_pdbm);
3524*4882a593Smuzhiyun 									else if (lmt[bw_pos] % hal_spec->txgi_pdbm)
3525*4882a593Smuzhiyun 										_RTW_PRINT_SEL(RTW_DBGDUMP, "%2d.%d ", lmt[bw_pos] / hal_spec->txgi_pdbm, (rtw_abs(lmt[bw_pos]) % hal_spec->txgi_pdbm) * 100 / hal_spec->txgi_pdbm);
3526*4882a593Smuzhiyun 									else
3527*4882a593Smuzhiyun 										_RTW_PRINT_SEL(RTW_DBGDUMP, "%2d ", lmt[bw_pos] / hal_spec->txgi_pdbm);
3528*4882a593Smuzhiyun 								}
3529*4882a593Smuzhiyun 								_RTW_PRINT_SEL(RTW_DBGDUMP, "\n");
3530*4882a593Smuzhiyun 							}
3531*4882a593Smuzhiyun 
3532*4882a593Smuzhiyun 							offset_by_bw += 2;
3533*4882a593Smuzhiyun 							if (offset_by_bw & BIT(bw + 1))
3534*4882a593Smuzhiyun 								break;
3535*4882a593Smuzhiyun 						} while (1); /* loop for all ch combinations */
3536*4882a593Smuzhiyun 					} /* loop for center channels */
3537*4882a593Smuzhiyun 				} /* loop fo each ntx_idx */
3538*4882a593Smuzhiyun 			} /* loop for tlrs */
3539*4882a593Smuzhiyun 		} /* loop for bandwidth */
3540*4882a593Smuzhiyun 	} /* loop for band */
3541*4882a593Smuzhiyun }
3542*4882a593Smuzhiyun #endif /* DBG_TXPWR_LMT_BAND_CHK */
3543*4882a593Smuzhiyun 
phy_txpwr_lmt_post_hdl(_adapter * adapter)3544*4882a593Smuzhiyun static void phy_txpwr_lmt_post_hdl(_adapter *adapter)
3545*4882a593Smuzhiyun {
3546*4882a593Smuzhiyun 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
3547*4882a593Smuzhiyun 	_irqL irqL;
3548*4882a593Smuzhiyun 
3549*4882a593Smuzhiyun 	_enter_critical_mutex(&rfctl->txpwr_lmt_mutex, &irqL);
3550*4882a593Smuzhiyun 
3551*4882a593Smuzhiyun #if CONFIG_IEEE80211_BAND_5GHZ
3552*4882a593Smuzhiyun 	if (IS_HARDWARE_TYPE_JAGUAR_ALL(adapter))
3553*4882a593Smuzhiyun 		phy_txpwr_lmt_cross_ref_ht_vht(adapter);
3554*4882a593Smuzhiyun #endif
3555*4882a593Smuzhiyun 	phy_txpwr_lmt_cck_ofdm_mt_chk(adapter);
3556*4882a593Smuzhiyun 
3557*4882a593Smuzhiyun #if DBG_TXPWR_LMT_BAND_CHK
3558*4882a593Smuzhiyun 	phy_txpwr_limit_bandwidth_chk(adapter);
3559*4882a593Smuzhiyun #endif
3560*4882a593Smuzhiyun 
3561*4882a593Smuzhiyun 	_exit_critical_mutex(&rfctl->txpwr_lmt_mutex, &irqL);
3562*4882a593Smuzhiyun }
3563*4882a593Smuzhiyun 
3564*4882a593Smuzhiyun BOOLEAN
GetS1ByteIntegerFromStringInDecimal(char * str,s8 * val)3565*4882a593Smuzhiyun GetS1ByteIntegerFromStringInDecimal(
3566*4882a593Smuzhiyun 			char	*str,
3567*4882a593Smuzhiyun 			s8		*val
3568*4882a593Smuzhiyun )
3569*4882a593Smuzhiyun {
3570*4882a593Smuzhiyun 	u8 negative = 0;
3571*4882a593Smuzhiyun 	u16 i = 0;
3572*4882a593Smuzhiyun 
3573*4882a593Smuzhiyun 	*val = 0;
3574*4882a593Smuzhiyun 
3575*4882a593Smuzhiyun 	while (str[i] != '\0') {
3576*4882a593Smuzhiyun 		if (i == 0 && (str[i] == '+' || str[i] == '-')) {
3577*4882a593Smuzhiyun 			if (str[i] == '-')
3578*4882a593Smuzhiyun 				negative = 1;
3579*4882a593Smuzhiyun 		} else if (str[i] >= '0' && str[i] <= '9') {
3580*4882a593Smuzhiyun 			*val *= 10;
3581*4882a593Smuzhiyun 			*val += (str[i] - '0');
3582*4882a593Smuzhiyun 		} else
3583*4882a593Smuzhiyun 			return _FALSE;
3584*4882a593Smuzhiyun 		++i;
3585*4882a593Smuzhiyun 	}
3586*4882a593Smuzhiyun 
3587*4882a593Smuzhiyun 	if (negative)
3588*4882a593Smuzhiyun 		*val = -*val;
3589*4882a593Smuzhiyun 
3590*4882a593Smuzhiyun 	return _TRUE;
3591*4882a593Smuzhiyun }
3592*4882a593Smuzhiyun #endif /* CONFIG_TXPWR_LIMIT */
3593*4882a593Smuzhiyun 
3594*4882a593Smuzhiyun /*
3595*4882a593Smuzhiyun * phy_set_tx_power_limit - Parsing TX power limit from phydm array, called by odm_ConfigBB_TXPWR_LMT_XXX in phydm
3596*4882a593Smuzhiyun */
3597*4882a593Smuzhiyun void
phy_set_tx_power_limit(struct dm_struct * pDM_Odm,u8 * Regulation,u8 * Band,u8 * Bandwidth,u8 * RateSection,u8 * ntx,u8 * Channel,u8 * PowerLimit)3598*4882a593Smuzhiyun phy_set_tx_power_limit(
3599*4882a593Smuzhiyun 		struct dm_struct		*pDM_Odm,
3600*4882a593Smuzhiyun 		u8				*Regulation,
3601*4882a593Smuzhiyun 		u8				*Band,
3602*4882a593Smuzhiyun 		u8				*Bandwidth,
3603*4882a593Smuzhiyun 		u8				*RateSection,
3604*4882a593Smuzhiyun 		u8				*ntx,
3605*4882a593Smuzhiyun 		u8				*Channel,
3606*4882a593Smuzhiyun 		u8				*PowerLimit
3607*4882a593Smuzhiyun )
3608*4882a593Smuzhiyun {
3609*4882a593Smuzhiyun #if CONFIG_TXPWR_LIMIT
3610*4882a593Smuzhiyun 	PADAPTER Adapter = pDM_Odm->adapter;
3611*4882a593Smuzhiyun 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
3612*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(Adapter);
3613*4882a593Smuzhiyun 	u8 band = 0, bandwidth = 0, tlrs = 0, channel;
3614*4882a593Smuzhiyun 	u8 ntx_idx;
3615*4882a593Smuzhiyun 	s8 powerLimit = 0, prevPowerLimit, channelIndex;
3616*4882a593Smuzhiyun 	s8 ww_lmt_val = phy_txpwr_ww_lmt_value(Adapter);
3617*4882a593Smuzhiyun 
3618*4882a593Smuzhiyun 	if (0)
3619*4882a593Smuzhiyun 		RTW_INFO("Index of power limit table [regulation %s][band %s][bw %s][rate section %s][ntx %s][chnl %s][val %s]\n"
3620*4882a593Smuzhiyun 			, Regulation, Band, Bandwidth, RateSection, ntx, Channel, PowerLimit);
3621*4882a593Smuzhiyun 
3622*4882a593Smuzhiyun 	if (GetU1ByteIntegerFromStringInDecimal((char *)Channel, &channel) == _FALSE
3623*4882a593Smuzhiyun 		|| GetS1ByteIntegerFromStringInDecimal((char *)PowerLimit, &powerLimit) == _FALSE
3624*4882a593Smuzhiyun 	) {
3625*4882a593Smuzhiyun 		RTW_PRINT("Illegal index of power limit table [ch %s][val %s]\n", Channel, PowerLimit);
3626*4882a593Smuzhiyun 		return;
3627*4882a593Smuzhiyun 	}
3628*4882a593Smuzhiyun 
3629*4882a593Smuzhiyun 	if (powerLimit != ww_lmt_val) {
3630*4882a593Smuzhiyun 		if (powerLimit < -hal_spec->txgi_max || powerLimit > hal_spec->txgi_max)
3631*4882a593Smuzhiyun 			RTW_PRINT("Illegal power limit value [ch %s][val %s]\n", Channel, PowerLimit);
3632*4882a593Smuzhiyun 
3633*4882a593Smuzhiyun 		if (powerLimit > hal_spec->txgi_max)
3634*4882a593Smuzhiyun 			powerLimit = hal_spec->txgi_max;
3635*4882a593Smuzhiyun 		else if (powerLimit < -hal_spec->txgi_max)
3636*4882a593Smuzhiyun 			powerLimit =  ww_lmt_val + 1;
3637*4882a593Smuzhiyun 	}
3638*4882a593Smuzhiyun 
3639*4882a593Smuzhiyun 	if (strncmp(RateSection, "CCK", 3) == 0)
3640*4882a593Smuzhiyun 		tlrs = TXPWR_LMT_RS_CCK;
3641*4882a593Smuzhiyun 	else if (strncmp(RateSection, "OFDM", 4) == 0)
3642*4882a593Smuzhiyun 		tlrs = TXPWR_LMT_RS_OFDM;
3643*4882a593Smuzhiyun 	else if (strncmp(RateSection, "HT", 2) == 0)
3644*4882a593Smuzhiyun 		tlrs = TXPWR_LMT_RS_HT;
3645*4882a593Smuzhiyun 	else if (strncmp(RateSection, "VHT", 3) == 0)
3646*4882a593Smuzhiyun 		tlrs = TXPWR_LMT_RS_VHT;
3647*4882a593Smuzhiyun 	else {
3648*4882a593Smuzhiyun 		RTW_PRINT("Wrong rate section:%s\n", RateSection);
3649*4882a593Smuzhiyun 		return;
3650*4882a593Smuzhiyun 	}
3651*4882a593Smuzhiyun 
3652*4882a593Smuzhiyun 	if (strncmp(ntx, "1T", 2) == 0)
3653*4882a593Smuzhiyun 		ntx_idx = RF_1TX;
3654*4882a593Smuzhiyun 	else if (strncmp(ntx, "2T", 2) == 0)
3655*4882a593Smuzhiyun 		ntx_idx = RF_2TX;
3656*4882a593Smuzhiyun 	else if (strncmp(ntx, "3T", 2) == 0)
3657*4882a593Smuzhiyun 		ntx_idx = RF_3TX;
3658*4882a593Smuzhiyun 	else if (strncmp(ntx, "4T", 2) == 0)
3659*4882a593Smuzhiyun 		ntx_idx = RF_4TX;
3660*4882a593Smuzhiyun 	else {
3661*4882a593Smuzhiyun 		RTW_PRINT("Wrong tx num:%s\n", ntx);
3662*4882a593Smuzhiyun 		return;
3663*4882a593Smuzhiyun 	}
3664*4882a593Smuzhiyun 
3665*4882a593Smuzhiyun 	if (strncmp(Bandwidth, "20M", 3) == 0)
3666*4882a593Smuzhiyun 		bandwidth = CHANNEL_WIDTH_20;
3667*4882a593Smuzhiyun 	else if (strncmp(Bandwidth, "40M", 3) == 0)
3668*4882a593Smuzhiyun 		bandwidth = CHANNEL_WIDTH_40;
3669*4882a593Smuzhiyun 	else if (strncmp(Bandwidth, "80M", 3) == 0)
3670*4882a593Smuzhiyun 		bandwidth = CHANNEL_WIDTH_80;
3671*4882a593Smuzhiyun 	else if (strncmp(Bandwidth, "160M", 4) == 0)
3672*4882a593Smuzhiyun 		bandwidth = CHANNEL_WIDTH_160;
3673*4882a593Smuzhiyun 	else {
3674*4882a593Smuzhiyun 		RTW_PRINT("unknown bandwidth: %s\n", Bandwidth);
3675*4882a593Smuzhiyun 		return;
3676*4882a593Smuzhiyun 	}
3677*4882a593Smuzhiyun 
3678*4882a593Smuzhiyun 	if (strncmp(Band, "2.4G", 4) == 0) {
3679*4882a593Smuzhiyun 		band = BAND_ON_2_4G;
3680*4882a593Smuzhiyun 		channelIndex = phy_GetChannelIndexOfTxPowerLimit(BAND_ON_2_4G, channel);
3681*4882a593Smuzhiyun 
3682*4882a593Smuzhiyun 		if (channelIndex == -1) {
3683*4882a593Smuzhiyun 			RTW_PRINT("unsupported channel: %d at 2.4G\n", channel);
3684*4882a593Smuzhiyun 			return;
3685*4882a593Smuzhiyun 		}
3686*4882a593Smuzhiyun 
3687*4882a593Smuzhiyun 		if (bandwidth >= MAX_2_4G_BANDWIDTH_NUM) {
3688*4882a593Smuzhiyun 			RTW_PRINT("unsupported bandwidth: %s at 2.4G\n", Bandwidth);
3689*4882a593Smuzhiyun 			return;
3690*4882a593Smuzhiyun 		}
3691*4882a593Smuzhiyun 
3692*4882a593Smuzhiyun 		rtw_txpwr_lmt_add(adapter_to_rfctl(Adapter), Regulation, band, bandwidth, tlrs, ntx_idx, channelIndex, powerLimit);
3693*4882a593Smuzhiyun 	}
3694*4882a593Smuzhiyun #if CONFIG_IEEE80211_BAND_5GHZ
3695*4882a593Smuzhiyun 	else if (strncmp(Band, "5G", 2) == 0) {
3696*4882a593Smuzhiyun 		band = BAND_ON_5G;
3697*4882a593Smuzhiyun 		channelIndex = phy_GetChannelIndexOfTxPowerLimit(BAND_ON_5G, channel);
3698*4882a593Smuzhiyun 
3699*4882a593Smuzhiyun 		if (channelIndex == -1) {
3700*4882a593Smuzhiyun 			RTW_PRINT("unsupported channel: %d at 5G\n", channel);
3701*4882a593Smuzhiyun 			return;
3702*4882a593Smuzhiyun 		}
3703*4882a593Smuzhiyun 
3704*4882a593Smuzhiyun 		rtw_txpwr_lmt_add(adapter_to_rfctl(Adapter), Regulation, band, bandwidth, tlrs, ntx_idx, channelIndex, powerLimit);
3705*4882a593Smuzhiyun 	}
3706*4882a593Smuzhiyun #endif
3707*4882a593Smuzhiyun 	else {
3708*4882a593Smuzhiyun 		RTW_PRINT("unknown/unsupported band:%s\n", Band);
3709*4882a593Smuzhiyun 		return;
3710*4882a593Smuzhiyun 	}
3711*4882a593Smuzhiyun #endif
3712*4882a593Smuzhiyun }
3713*4882a593Smuzhiyun 
3714*4882a593Smuzhiyun void
phy_set_tx_power_limit_ex(struct dm_struct * pDM_Odm,u8 Regulation,u8 Band,u8 Bandwidth,u8 RateSection,u8 ntx,u8 channel,s8 powerLimit)3715*4882a593Smuzhiyun phy_set_tx_power_limit_ex(
3716*4882a593Smuzhiyun 		struct dm_struct		*pDM_Odm,
3717*4882a593Smuzhiyun 		u8				Regulation,
3718*4882a593Smuzhiyun 		u8				Band,
3719*4882a593Smuzhiyun 		u8				Bandwidth,
3720*4882a593Smuzhiyun 		u8				RateSection,
3721*4882a593Smuzhiyun 		u8				ntx,
3722*4882a593Smuzhiyun 		u8				channel,
3723*4882a593Smuzhiyun 		s8				powerLimit
3724*4882a593Smuzhiyun )
3725*4882a593Smuzhiyun {
3726*4882a593Smuzhiyun #if CONFIG_TXPWR_LIMIT
3727*4882a593Smuzhiyun 	PADAPTER Adapter = pDM_Odm->adapter;
3728*4882a593Smuzhiyun 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
3729*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(Adapter);
3730*4882a593Smuzhiyun 	u8 regd;
3731*4882a593Smuzhiyun 	u8 band = 0, bandwidth = 0, tlrs = 0;
3732*4882a593Smuzhiyun 	u8 ntx_idx;
3733*4882a593Smuzhiyun 	s8 prevPowerLimit, channelIndex;
3734*4882a593Smuzhiyun 	s8 ww_lmt_val = phy_txpwr_ww_lmt_value(Adapter);
3735*4882a593Smuzhiyun 
3736*4882a593Smuzhiyun 	if (0)
3737*4882a593Smuzhiyun 		RTW_INFO("Index of power limit table [regulation %d][band %d][bw %d][rate section %d][ntx %d][chnl %d][val %d]\n"
3738*4882a593Smuzhiyun 			, Regulation, Band, Bandwidth, RateSection, ntx, channel, powerLimit);
3739*4882a593Smuzhiyun 
3740*4882a593Smuzhiyun 	if (powerLimit != ww_lmt_val) {
3741*4882a593Smuzhiyun 		if (powerLimit < -hal_spec->txgi_max || powerLimit > hal_spec->txgi_max)
3742*4882a593Smuzhiyun 			RTW_PRINT("Illegal power limit value [ch %d][val %d]\n", channel, powerLimit);
3743*4882a593Smuzhiyun 
3744*4882a593Smuzhiyun 		if (powerLimit > hal_spec->txgi_max)
3745*4882a593Smuzhiyun 			powerLimit = hal_spec->txgi_max;
3746*4882a593Smuzhiyun 		else if (powerLimit < -hal_spec->txgi_max)
3747*4882a593Smuzhiyun 			powerLimit =  ww_lmt_val + 1;
3748*4882a593Smuzhiyun 	}
3749*4882a593Smuzhiyun 
3750*4882a593Smuzhiyun 	switch (Regulation) {
3751*4882a593Smuzhiyun 	case PW_LMT_REGU_FCC:
3752*4882a593Smuzhiyun 		regd = TXPWR_LMT_FCC;
3753*4882a593Smuzhiyun 		break;
3754*4882a593Smuzhiyun 	case PW_LMT_REGU_ETSI:
3755*4882a593Smuzhiyun 		regd = TXPWR_LMT_ETSI;
3756*4882a593Smuzhiyun 		break;
3757*4882a593Smuzhiyun 	case PW_LMT_REGU_MKK:
3758*4882a593Smuzhiyun 		regd = TXPWR_LMT_MKK;
3759*4882a593Smuzhiyun 		break;
3760*4882a593Smuzhiyun 	case PW_LMT_REGU_IC:
3761*4882a593Smuzhiyun 		regd = TXPWR_LMT_IC;
3762*4882a593Smuzhiyun 		break;
3763*4882a593Smuzhiyun 	case PW_LMT_REGU_KCC:
3764*4882a593Smuzhiyun 		regd = TXPWR_LMT_KCC;
3765*4882a593Smuzhiyun 		break;
3766*4882a593Smuzhiyun 	case PW_LMT_REGU_ACMA:
3767*4882a593Smuzhiyun 		regd = TXPWR_LMT_ACMA;
3768*4882a593Smuzhiyun 		break;
3769*4882a593Smuzhiyun 	case PW_LMT_REGU_CHILE:
3770*4882a593Smuzhiyun 		regd = TXPWR_LMT_CHILE;
3771*4882a593Smuzhiyun 		break;
3772*4882a593Smuzhiyun 	case PW_LMT_REGU_UKRAINE:
3773*4882a593Smuzhiyun 		regd = TXPWR_LMT_UKRAINE;
3774*4882a593Smuzhiyun 		break;
3775*4882a593Smuzhiyun 	case PW_LMT_REGU_MEXICO:
3776*4882a593Smuzhiyun 		regd = TXPWR_LMT_MEXICO;
3777*4882a593Smuzhiyun 		break;
3778*4882a593Smuzhiyun 	case PW_LMT_REGU_CN:
3779*4882a593Smuzhiyun 		regd = TXPWR_LMT_CN;
3780*4882a593Smuzhiyun 		break;
3781*4882a593Smuzhiyun 	case PW_LMT_REGU_WW13:
3782*4882a593Smuzhiyun 	default:
3783*4882a593Smuzhiyun 		RTW_PRINT("Wrong regulation:%d\n", Regulation);
3784*4882a593Smuzhiyun 		return;
3785*4882a593Smuzhiyun 	}
3786*4882a593Smuzhiyun 
3787*4882a593Smuzhiyun 	switch (RateSection) {
3788*4882a593Smuzhiyun 	case PW_LMT_RS_CCK:
3789*4882a593Smuzhiyun 		tlrs = TXPWR_LMT_RS_CCK;
3790*4882a593Smuzhiyun 		break;
3791*4882a593Smuzhiyun 	case PW_LMT_RS_OFDM:
3792*4882a593Smuzhiyun 		tlrs = TXPWR_LMT_RS_OFDM;
3793*4882a593Smuzhiyun 		break;
3794*4882a593Smuzhiyun 	case PW_LMT_RS_HT:
3795*4882a593Smuzhiyun 		tlrs = TXPWR_LMT_RS_HT;
3796*4882a593Smuzhiyun 		break;
3797*4882a593Smuzhiyun 	case PW_LMT_RS_VHT:
3798*4882a593Smuzhiyun 		tlrs = TXPWR_LMT_RS_VHT;
3799*4882a593Smuzhiyun 		break;
3800*4882a593Smuzhiyun 	default:
3801*4882a593Smuzhiyun 		RTW_PRINT("Wrong rate section:%d\n", RateSection);
3802*4882a593Smuzhiyun 		return;
3803*4882a593Smuzhiyun 	}
3804*4882a593Smuzhiyun 
3805*4882a593Smuzhiyun 	switch (ntx) {
3806*4882a593Smuzhiyun 	case PW_LMT_PH_1T:
3807*4882a593Smuzhiyun 		ntx_idx = RF_1TX;
3808*4882a593Smuzhiyun 		break;
3809*4882a593Smuzhiyun 	case PW_LMT_PH_2T:
3810*4882a593Smuzhiyun 		ntx_idx = RF_2TX;
3811*4882a593Smuzhiyun 		break;
3812*4882a593Smuzhiyun 	case PW_LMT_PH_3T:
3813*4882a593Smuzhiyun 		ntx_idx = RF_3TX;
3814*4882a593Smuzhiyun 		break;
3815*4882a593Smuzhiyun 	case PW_LMT_PH_4T:
3816*4882a593Smuzhiyun 		ntx_idx = RF_4TX;
3817*4882a593Smuzhiyun 		break;
3818*4882a593Smuzhiyun 	default:
3819*4882a593Smuzhiyun 		RTW_PRINT("Wrong tx num:%d\n", ntx);
3820*4882a593Smuzhiyun 		return;
3821*4882a593Smuzhiyun 	}
3822*4882a593Smuzhiyun 
3823*4882a593Smuzhiyun 	switch (Bandwidth) {
3824*4882a593Smuzhiyun 	case PW_LMT_BW_20M:
3825*4882a593Smuzhiyun 		bandwidth = CHANNEL_WIDTH_20;
3826*4882a593Smuzhiyun 		break;
3827*4882a593Smuzhiyun 	case PW_LMT_BW_40M:
3828*4882a593Smuzhiyun 		bandwidth = CHANNEL_WIDTH_40;
3829*4882a593Smuzhiyun 		break;
3830*4882a593Smuzhiyun 	case PW_LMT_BW_80M:
3831*4882a593Smuzhiyun 		bandwidth = CHANNEL_WIDTH_80;
3832*4882a593Smuzhiyun 		break;
3833*4882a593Smuzhiyun 	case PW_LMT_BW_160M:
3834*4882a593Smuzhiyun 		bandwidth = CHANNEL_WIDTH_160;
3835*4882a593Smuzhiyun 		break;
3836*4882a593Smuzhiyun 	default:
3837*4882a593Smuzhiyun 		RTW_PRINT("unknown bandwidth: %d\n", Bandwidth);
3838*4882a593Smuzhiyun 		return;
3839*4882a593Smuzhiyun 	}
3840*4882a593Smuzhiyun 
3841*4882a593Smuzhiyun 	if (Band == PW_LMT_BAND_2_4G) {
3842*4882a593Smuzhiyun 		band = BAND_ON_2_4G;
3843*4882a593Smuzhiyun 		channelIndex = phy_GetChannelIndexOfTxPowerLimit(BAND_ON_2_4G, channel);
3844*4882a593Smuzhiyun 
3845*4882a593Smuzhiyun 		if (channelIndex == -1) {
3846*4882a593Smuzhiyun 			RTW_PRINT("unsupported channel: %d at 2.4G\n", channel);
3847*4882a593Smuzhiyun 			return;
3848*4882a593Smuzhiyun 		}
3849*4882a593Smuzhiyun 
3850*4882a593Smuzhiyun 		if (bandwidth >= MAX_2_4G_BANDWIDTH_NUM) {
3851*4882a593Smuzhiyun 			RTW_PRINT("unsupported bandwidth: %s at 2.4G\n", ch_width_str(bandwidth));
3852*4882a593Smuzhiyun 			return;
3853*4882a593Smuzhiyun 		}
3854*4882a593Smuzhiyun 
3855*4882a593Smuzhiyun 		rtw_txpwr_lmt_add(adapter_to_rfctl(Adapter), regd_str(regd), band, bandwidth, tlrs, ntx_idx, channelIndex, powerLimit);
3856*4882a593Smuzhiyun 	}
3857*4882a593Smuzhiyun #if CONFIG_IEEE80211_BAND_5GHZ
3858*4882a593Smuzhiyun 	else if (Band == PW_LMT_BAND_5G) {
3859*4882a593Smuzhiyun 		band = BAND_ON_5G;
3860*4882a593Smuzhiyun 		channelIndex = phy_GetChannelIndexOfTxPowerLimit(BAND_ON_5G, channel);
3861*4882a593Smuzhiyun 
3862*4882a593Smuzhiyun 		if (channelIndex == -1) {
3863*4882a593Smuzhiyun 			RTW_PRINT("unsupported channel: %d at 5G\n", channel);
3864*4882a593Smuzhiyun 			return;
3865*4882a593Smuzhiyun 		}
3866*4882a593Smuzhiyun 
3867*4882a593Smuzhiyun 		rtw_txpwr_lmt_add(adapter_to_rfctl(Adapter), regd_str(regd), band, bandwidth, tlrs, ntx_idx, channelIndex, powerLimit);
3868*4882a593Smuzhiyun 	}
3869*4882a593Smuzhiyun #endif
3870*4882a593Smuzhiyun 	else {
3871*4882a593Smuzhiyun 		RTW_PRINT("unknown/unsupported band:%d\n", Band);
3872*4882a593Smuzhiyun 		return;
3873*4882a593Smuzhiyun 	}
3874*4882a593Smuzhiyun #endif
3875*4882a593Smuzhiyun }
3876*4882a593Smuzhiyun 
phy_get_tx_power_index_ex(_adapter * adapter,enum rf_path rfpath,RATE_SECTION rs,enum MGN_RATE rate,enum channel_width bw,BAND_TYPE band,u8 cch,u8 opch)3877*4882a593Smuzhiyun u8 phy_get_tx_power_index_ex(_adapter *adapter
3878*4882a593Smuzhiyun 	, enum rf_path rfpath, RATE_SECTION rs, enum MGN_RATE rate
3879*4882a593Smuzhiyun 	, enum channel_width bw, BAND_TYPE band, u8 cch, u8 opch)
3880*4882a593Smuzhiyun {
3881*4882a593Smuzhiyun 	return rtw_hal_get_tx_power_index(adapter, rfpath, rs, rate, bw, band, cch, opch, NULL);
3882*4882a593Smuzhiyun }
3883*4882a593Smuzhiyun 
phy_get_tx_power_index(PADAPTER pAdapter,enum rf_path RFPath,u8 Rate,enum channel_width BandWidth,u8 Channel)3884*4882a593Smuzhiyun u8 phy_get_tx_power_index(
3885*4882a593Smuzhiyun 		PADAPTER			pAdapter,
3886*4882a593Smuzhiyun 		enum rf_path		RFPath,
3887*4882a593Smuzhiyun 		u8					Rate,
3888*4882a593Smuzhiyun 		enum channel_width	BandWidth,
3889*4882a593Smuzhiyun 		u8					Channel
3890*4882a593Smuzhiyun )
3891*4882a593Smuzhiyun {
3892*4882a593Smuzhiyun 	RATE_SECTION rs = mgn_rate_to_rs(Rate);
3893*4882a593Smuzhiyun 	BAND_TYPE band = Channel <= 14 ? BAND_ON_2_4G : BAND_ON_5G;
3894*4882a593Smuzhiyun 
3895*4882a593Smuzhiyun 	return rtw_hal_get_tx_power_index(pAdapter, RFPath, rs, Rate, BandWidth, band, Channel, 0, NULL);
3896*4882a593Smuzhiyun }
3897*4882a593Smuzhiyun 
3898*4882a593Smuzhiyun void
PHY_SetTxPowerIndex(PADAPTER pAdapter,u32 PowerIndex,enum rf_path RFPath,u8 Rate)3899*4882a593Smuzhiyun PHY_SetTxPowerIndex(
3900*4882a593Smuzhiyun 		PADAPTER		pAdapter,
3901*4882a593Smuzhiyun 		u32				PowerIndex,
3902*4882a593Smuzhiyun 		enum rf_path		RFPath,
3903*4882a593Smuzhiyun 		u8				Rate
3904*4882a593Smuzhiyun )
3905*4882a593Smuzhiyun {
3906*4882a593Smuzhiyun 	rtw_hal_set_tx_power_index(pAdapter, PowerIndex, RFPath, Rate);
3907*4882a593Smuzhiyun }
3908*4882a593Smuzhiyun 
dump_tx_power_index_inline(void * sel,_adapter * adapter,u8 rfpath,enum channel_width bw,u8 cch,enum MGN_RATE rate,u8 pwr_idx,struct txpwr_idx_comp * tic)3909*4882a593Smuzhiyun void dump_tx_power_index_inline(void *sel, _adapter *adapter, u8 rfpath, enum channel_width bw, u8 cch, enum MGN_RATE rate, u8 pwr_idx, struct txpwr_idx_comp *tic)
3910*4882a593Smuzhiyun {
3911*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3912*4882a593Smuzhiyun 
3913*4882a593Smuzhiyun 	if (tic->utarget == hal_spec->txgi_max) {
3914*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "TXPWR: [%c][%s]cch:%u, %s %uT, idx:%u(0x%02x) = base(%d) + min((byr(%d) + btc(%d) + extra(%d)), lmt(%d), ulmt(%d)) + tpc(%d) + tpt(%d) + dpd(%d)\n"
3915*4882a593Smuzhiyun 			, rf_path_char(rfpath), ch_width_str(bw), cch
3916*4882a593Smuzhiyun 			, MGN_RATE_STR(rate), tic->ntx_idx + 1
3917*4882a593Smuzhiyun 			, pwr_idx, pwr_idx, tic->base
3918*4882a593Smuzhiyun 			, tic->by_rate, tic->btc, tic->extra, tic->limit, tic->ulimit
3919*4882a593Smuzhiyun 			, tic->tpc
3920*4882a593Smuzhiyun 			, tic->tpt, tic->dpd);
3921*4882a593Smuzhiyun 	} else {
3922*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "TXPWR: [%c][%s]cch:%u, %s %uT, idx:%u(0x%02x) = base(%d) + min(utgt(%d), lmt(%d), ulmt(%d)) + tpc(%d) + tpt(%d) + dpd(%d)\n"
3923*4882a593Smuzhiyun 			, rf_path_char(rfpath), ch_width_str(bw), cch
3924*4882a593Smuzhiyun 			, MGN_RATE_STR(rate), tic->ntx_idx + 1
3925*4882a593Smuzhiyun 			, pwr_idx, pwr_idx, tic->base
3926*4882a593Smuzhiyun 			, tic->utarget, tic->limit, tic->ulimit
3927*4882a593Smuzhiyun 			, tic->tpc
3928*4882a593Smuzhiyun 			, tic->tpt, tic->dpd);
3929*4882a593Smuzhiyun 	}
3930*4882a593Smuzhiyun }
3931*4882a593Smuzhiyun 
3932*4882a593Smuzhiyun #ifdef CONFIG_PROC_DEBUG
dump_tx_power_idx_value(void * sel,_adapter * adapter,u8 rfpath,enum MGN_RATE rate,u8 pwr_idx,struct txpwr_idx_comp * tic)3933*4882a593Smuzhiyun void dump_tx_power_idx_value(void *sel, _adapter *adapter, u8 rfpath, enum MGN_RATE rate, u8 pwr_idx, struct txpwr_idx_comp *tic)
3934*4882a593Smuzhiyun {
3935*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3936*4882a593Smuzhiyun 	char tmp_str[8];
3937*4882a593Smuzhiyun 
3938*4882a593Smuzhiyun 	txpwr_idx_get_dbm_str(tic->target, hal_spec->txgi_max, hal_spec->txgi_pdbm, 0, tmp_str, 8);
3939*4882a593Smuzhiyun 
3940*4882a593Smuzhiyun 	if (tic->utarget == hal_spec->txgi_max) {
3941*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "%4c %9s %uT %s %3u(0x%02x)"
3942*4882a593Smuzhiyun 			"   %4d      ((%4d   %3d   %5d)  %4d  %4d)   %3d   %3d   %3d\n"
3943*4882a593Smuzhiyun 			, rf_path_char(rfpath), MGN_RATE_STR(rate), tic->ntx_idx + 1
3944*4882a593Smuzhiyun 			, tmp_str, pwr_idx, pwr_idx
3945*4882a593Smuzhiyun 			, tic->base, tic->by_rate, tic->btc, tic->extra, tic->limit, tic->ulimit
3946*4882a593Smuzhiyun 			, tic->tpc
3947*4882a593Smuzhiyun 			, tic->tpt, tic->dpd);
3948*4882a593Smuzhiyun 	} else {
3949*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "%4c %9s %uT %s %3u(0x%02x)"
3950*4882a593Smuzhiyun 			"   %4d      (%4d  %4d  %4d)   %3d   %3d   %3d\n"
3951*4882a593Smuzhiyun 			, rf_path_char(rfpath), MGN_RATE_STR(rate), tic->ntx_idx + 1
3952*4882a593Smuzhiyun 			, tmp_str, pwr_idx, pwr_idx
3953*4882a593Smuzhiyun 			, tic->base, tic->utarget, tic->limit, tic->ulimit
3954*4882a593Smuzhiyun 			, tic->tpc
3955*4882a593Smuzhiyun 			, tic->tpt, tic->dpd);
3956*4882a593Smuzhiyun 	}
3957*4882a593Smuzhiyun }
3958*4882a593Smuzhiyun 
dump_tx_power_idx_title(void * sel,_adapter * adapter,enum channel_width bw,u8 cch,u8 opch)3959*4882a593Smuzhiyun void dump_tx_power_idx_title(void *sel, _adapter *adapter, enum channel_width bw, u8 cch, u8 opch)
3960*4882a593Smuzhiyun {
3961*4882a593Smuzhiyun 	u8 cch_20, cch_40, cch_80;
3962*4882a593Smuzhiyun 
3963*4882a593Smuzhiyun 	cch_80 = bw == CHANNEL_WIDTH_80 ? cch : 0;
3964*4882a593Smuzhiyun 	cch_40 = bw == CHANNEL_WIDTH_40 ? cch : 0;
3965*4882a593Smuzhiyun 	cch_20 = bw == CHANNEL_WIDTH_20 ? cch : 0;
3966*4882a593Smuzhiyun 	if (cch_80 != 0)
3967*4882a593Smuzhiyun 		cch_40 = rtw_get_scch_by_cch_opch(cch_80, CHANNEL_WIDTH_80, opch);
3968*4882a593Smuzhiyun 	if (cch_40 != 0)
3969*4882a593Smuzhiyun 		cch_20 = rtw_get_scch_by_cch_opch(cch_40, CHANNEL_WIDTH_40, opch);
3970*4882a593Smuzhiyun 
3971*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "%s", ch_width_str(bw));
3972*4882a593Smuzhiyun 	if (bw >= CHANNEL_WIDTH_80)
3973*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, ", cch80:%u", cch_80);
3974*4882a593Smuzhiyun 	if (bw >= CHANNEL_WIDTH_40)
3975*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, ", cch40:%u", cch_40);
3976*4882a593Smuzhiyun 	_RTW_PRINT_SEL(sel, ", cch20:%u\n", cch_20);
3977*4882a593Smuzhiyun 
3978*4882a593Smuzhiyun 	if (!phy_is_txpwr_user_target_specified(adapter)) {
3979*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "%-4s %-9s %2s %-6s %-3s%6s"
3980*4882a593Smuzhiyun 			" = %-4s + min((%-4s + %-3s + %-5s), %-4s, %-4s) + %-3s + %-3s + %-3s\n"
3981*4882a593Smuzhiyun 			, "path", "rate", "", "dBm", "idx", ""
3982*4882a593Smuzhiyun 			, "base", "byr", "btc", "extra", "lmt", "ulmt"
3983*4882a593Smuzhiyun 			, "tpc"
3984*4882a593Smuzhiyun 			, "tpt", "dpd");
3985*4882a593Smuzhiyun 	} else {
3986*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "%-4s %-9s %2s %-6s %-3s%6s"
3987*4882a593Smuzhiyun 			" = %-4s + min(%-4s, %-4s, %-4s) + %-3s + %-3s + %-3s\n"
3988*4882a593Smuzhiyun 			, "path", "rate", "", "dBm", "idx", ""
3989*4882a593Smuzhiyun 			, "base", "utgt", "lmt", "ulmt"
3990*4882a593Smuzhiyun 			, "tpc"
3991*4882a593Smuzhiyun 			, "tpt", "dpd");
3992*4882a593Smuzhiyun 	}
3993*4882a593Smuzhiyun }
3994*4882a593Smuzhiyun 
dump_tx_power_idx_by_path_rs(void * sel,_adapter * adapter,u8 rfpath,RATE_SECTION rs,enum channel_width bw,u8 cch,u8 opch)3995*4882a593Smuzhiyun void dump_tx_power_idx_by_path_rs(void *sel, _adapter *adapter, u8 rfpath
3996*4882a593Smuzhiyun 	, RATE_SECTION rs, enum channel_width bw, u8 cch, u8 opch)
3997*4882a593Smuzhiyun {
3998*4882a593Smuzhiyun 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
3999*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
4000*4882a593Smuzhiyun 	u8 power_idx;
4001*4882a593Smuzhiyun 	struct txpwr_idx_comp tic;
4002*4882a593Smuzhiyun 	u8 tx_num, i;
4003*4882a593Smuzhiyun 	u8 band = cch > 14 ? BAND_ON_5G : BAND_ON_2_4G;
4004*4882a593Smuzhiyun 
4005*4882a593Smuzhiyun 	if (!HAL_SPEC_CHK_RF_PATH(hal_spec, band, rfpath))
4006*4882a593Smuzhiyun 		return;
4007*4882a593Smuzhiyun 
4008*4882a593Smuzhiyun 	if (rs >= RATE_SECTION_NUM)
4009*4882a593Smuzhiyun 		return;
4010*4882a593Smuzhiyun 
4011*4882a593Smuzhiyun 	tx_num = rate_section_to_tx_num(rs);
4012*4882a593Smuzhiyun 	if (tx_num + 1 > hal_data->tx_nss)
4013*4882a593Smuzhiyun 		return;
4014*4882a593Smuzhiyun 
4015*4882a593Smuzhiyun 	if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
4016*4882a593Smuzhiyun 		return;
4017*4882a593Smuzhiyun 
4018*4882a593Smuzhiyun 	if (IS_VHT_RATE_SECTION(rs) && !IS_HARDWARE_TYPE_JAGUAR_ALL(adapter))
4019*4882a593Smuzhiyun 		return;
4020*4882a593Smuzhiyun 
4021*4882a593Smuzhiyun 	for (i = 0; i < rates_by_sections[rs].rate_num; i++) {
4022*4882a593Smuzhiyun 		power_idx = rtw_hal_get_tx_power_index(adapter, rfpath, rs, rates_by_sections[rs].rates[i], bw, band, cch, opch, &tic);
4023*4882a593Smuzhiyun 		dump_tx_power_idx_value(sel, adapter, rfpath, rates_by_sections[rs].rates[i], power_idx, &tic);
4024*4882a593Smuzhiyun 	}
4025*4882a593Smuzhiyun }
4026*4882a593Smuzhiyun 
dump_tx_power_idx(void * sel,_adapter * adapter,enum channel_width bw,u8 cch,u8 opch)4027*4882a593Smuzhiyun void dump_tx_power_idx(void *sel, _adapter *adapter, enum channel_width bw, u8 cch, u8 opch)
4028*4882a593Smuzhiyun {
4029*4882a593Smuzhiyun 	u8 rfpath, rs;
4030*4882a593Smuzhiyun 
4031*4882a593Smuzhiyun 	dump_tx_power_idx_title(sel, adapter, bw, cch, opch);
4032*4882a593Smuzhiyun 	for (rfpath = RF_PATH_A; rfpath < RF_PATH_MAX; rfpath++)
4033*4882a593Smuzhiyun 		for (rs = CCK; rs < RATE_SECTION_NUM; rs++)
4034*4882a593Smuzhiyun 			dump_tx_power_idx_by_path_rs(sel, adapter, rfpath, rs, bw, cch, opch);
4035*4882a593Smuzhiyun }
4036*4882a593Smuzhiyun 
dump_txpwr_total_dbm_value(void * sel,_adapter * adapter,enum MGN_RATE rate,u8 ntx_idx,s16 target,s16 byr,s16 btc,s16 extra,s16 lmt,s16 ulmt,s16 tpc)4037*4882a593Smuzhiyun void dump_txpwr_total_dbm_value(void *sel, _adapter *adapter, enum MGN_RATE rate, u8 ntx_idx
4038*4882a593Smuzhiyun 	, s16 target, s16 byr, s16 btc, s16 extra, s16 lmt, s16 ulmt, s16 tpc)
4039*4882a593Smuzhiyun {
4040*4882a593Smuzhiyun 	char target_str[8];
4041*4882a593Smuzhiyun 	char byr_str[8];
4042*4882a593Smuzhiyun 	char btc_str[8];
4043*4882a593Smuzhiyun 	char extra_str[8];
4044*4882a593Smuzhiyun 	char lmt_str[8];
4045*4882a593Smuzhiyun 	char ulmt_str[8];
4046*4882a593Smuzhiyun 	char tpc_str[8];
4047*4882a593Smuzhiyun 
4048*4882a593Smuzhiyun 	txpwr_mbm_get_dbm_str(target, 0, target_str, 8);
4049*4882a593Smuzhiyun 	txpwr_mbm_get_dbm_str(byr, 0, byr_str, 8);
4050*4882a593Smuzhiyun 	txpwr_mbm_get_dbm_str(btc, 0, btc_str, 8);
4051*4882a593Smuzhiyun 	txpwr_mbm_get_dbm_str(extra, 0, extra_str, 8);
4052*4882a593Smuzhiyun 	txpwr_mbm_get_dbm_str(lmt, 0, lmt_str, 8);
4053*4882a593Smuzhiyun 	txpwr_mbm_get_dbm_str(ulmt, 0, ulmt_str, 8);
4054*4882a593Smuzhiyun 	txpwr_mbm_get_dbm_str(tpc, 0, tpc_str, 8);
4055*4882a593Smuzhiyun 
4056*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "%9s %uT %s =    ((%s   %s   %s), %s, %s)   %s\n"
4057*4882a593Smuzhiyun 		, MGN_RATE_STR(rate), ntx_idx + 1
4058*4882a593Smuzhiyun 		, target_str, byr_str, btc_str, extra_str, lmt_str, ulmt_str, tpc_str);
4059*4882a593Smuzhiyun }
4060*4882a593Smuzhiyun 
dump_txpwr_total_dbm_value_utgt(void * sel,_adapter * adapter,enum MGN_RATE rate,u8 ntx_idx,s16 target,s16 utgt,s16 lmt,s16 ulmt,s16 tpc)4061*4882a593Smuzhiyun void dump_txpwr_total_dbm_value_utgt(void *sel, _adapter *adapter, enum MGN_RATE rate, u8 ntx_idx
4062*4882a593Smuzhiyun 	, s16 target, s16 utgt, s16 lmt, s16 ulmt, s16 tpc)
4063*4882a593Smuzhiyun {
4064*4882a593Smuzhiyun 	char target_str[8];
4065*4882a593Smuzhiyun 	char utgt_str[8];
4066*4882a593Smuzhiyun 	char lmt_str[8];
4067*4882a593Smuzhiyun 	char ulmt_str[8];
4068*4882a593Smuzhiyun 	char tpc_str[8];
4069*4882a593Smuzhiyun 
4070*4882a593Smuzhiyun 	txpwr_mbm_get_dbm_str(target, 0, target_str, 8);
4071*4882a593Smuzhiyun 	txpwr_mbm_get_dbm_str(utgt, 0, utgt_str, 8);
4072*4882a593Smuzhiyun 	txpwr_mbm_get_dbm_str(lmt, 0, lmt_str, 8);
4073*4882a593Smuzhiyun 	txpwr_mbm_get_dbm_str(ulmt, 0, ulmt_str, 8);
4074*4882a593Smuzhiyun 	txpwr_mbm_get_dbm_str(tpc, 0, tpc_str, 8);
4075*4882a593Smuzhiyun 
4076*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "%9s %uT %s =    (%s, %s, %s)   %s\n"
4077*4882a593Smuzhiyun 		, MGN_RATE_STR(rate), ntx_idx + 1
4078*4882a593Smuzhiyun 		, target_str, utgt_str, lmt_str, ulmt_str, tpc_str);
4079*4882a593Smuzhiyun }
4080*4882a593Smuzhiyun 
dump_txpwr_total_dbm_title(void * sel,_adapter * adapter,enum channel_width bw,u8 cch,u8 opch)4081*4882a593Smuzhiyun void dump_txpwr_total_dbm_title(void *sel, _adapter *adapter, enum channel_width bw, u8 cch, u8 opch)
4082*4882a593Smuzhiyun {
4083*4882a593Smuzhiyun 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
4084*4882a593Smuzhiyun 	char antenna_gain_str[8];
4085*4882a593Smuzhiyun 	u8 cch_20, cch_40, cch_80;
4086*4882a593Smuzhiyun 
4087*4882a593Smuzhiyun 	txpwr_mbm_get_dbm_str(rfctl->antenna_gain, 0, antenna_gain_str, 8);
4088*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "antenna_gain:%s\n", antenna_gain_str);
4089*4882a593Smuzhiyun 
4090*4882a593Smuzhiyun 	cch_80 = bw == CHANNEL_WIDTH_80 ? cch : 0;
4091*4882a593Smuzhiyun 	cch_40 = bw == CHANNEL_WIDTH_40 ? cch : 0;
4092*4882a593Smuzhiyun 	cch_20 = bw == CHANNEL_WIDTH_20 ? cch : 0;
4093*4882a593Smuzhiyun 	if (cch_80 != 0)
4094*4882a593Smuzhiyun 		cch_40 = rtw_get_scch_by_cch_opch(cch_80, CHANNEL_WIDTH_80, opch);
4095*4882a593Smuzhiyun 	if (cch_40 != 0)
4096*4882a593Smuzhiyun 		cch_20 = rtw_get_scch_by_cch_opch(cch_40, CHANNEL_WIDTH_40, opch);
4097*4882a593Smuzhiyun 
4098*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "%s", ch_width_str(bw));
4099*4882a593Smuzhiyun 	if (bw >= CHANNEL_WIDTH_80)
4100*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, ", cch80:%u", cch_80);
4101*4882a593Smuzhiyun 	if (bw >= CHANNEL_WIDTH_40)
4102*4882a593Smuzhiyun 		_RTW_PRINT_SEL(sel, ", cch40:%u", cch_40);
4103*4882a593Smuzhiyun 	_RTW_PRINT_SEL(sel, ", cch20:%u\n", cch_20);
4104*4882a593Smuzhiyun 
4105*4882a593Smuzhiyun 	if (!phy_is_txpwr_user_target_specified(adapter)) {
4106*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "%-9s %2s %-6s = min((%-6s + %-6s + %-6s), %-6s, %-6s) + %-6s\n"
4107*4882a593Smuzhiyun 			, "rate", "", "target", "byr", "btc", "extra", "lmt", "ulmt", "tpc");
4108*4882a593Smuzhiyun 	} else {
4109*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "%-9s %2s %-6s = min(%-6s, %-6s, %-6s) + %-6s\n"
4110*4882a593Smuzhiyun 			, "rate", "", "target", "utgt", "lmt", "ulmt", "tpc");
4111*4882a593Smuzhiyun 	}
4112*4882a593Smuzhiyun }
4113*4882a593Smuzhiyun 
dump_txpwr_total_dbm_by_rs(void * sel,_adapter * adapter,u8 rs,enum channel_width bw,u8 cch,u8 opch)4114*4882a593Smuzhiyun void dump_txpwr_total_dbm_by_rs(void *sel, _adapter *adapter, u8 rs, enum channel_width bw, u8 cch, u8 opch)
4115*4882a593Smuzhiyun {
4116*4882a593Smuzhiyun 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
4117*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
4118*4882a593Smuzhiyun 	u8 i;
4119*4882a593Smuzhiyun 	u8 band = cch > 14 ? BAND_ON_5G : BAND_ON_2_4G;
4120*4882a593Smuzhiyun 
4121*4882a593Smuzhiyun 	if (rs >= RATE_SECTION_NUM)
4122*4882a593Smuzhiyun 		return;
4123*4882a593Smuzhiyun 
4124*4882a593Smuzhiyun 	if (rate_section_to_tx_num(rs) + 1 > hal_data->tx_nss)
4125*4882a593Smuzhiyun 		return;
4126*4882a593Smuzhiyun 
4127*4882a593Smuzhiyun 	if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
4128*4882a593Smuzhiyun 		return;
4129*4882a593Smuzhiyun 
4130*4882a593Smuzhiyun 	if (IS_VHT_RATE_SECTION(rs) && !IS_HARDWARE_TYPE_JAGUAR_ALL(adapter))
4131*4882a593Smuzhiyun 		return;
4132*4882a593Smuzhiyun 
4133*4882a593Smuzhiyun 	for (i = 0; i < rates_by_sections[rs].rate_num; i++) {
4134*4882a593Smuzhiyun 		struct txpwr_idx_comp tic;
4135*4882a593Smuzhiyun 		s16 target, byr, tpc, btc, extra, utgt, lmt, ulmt;
4136*4882a593Smuzhiyun 		u8 tx_num;
4137*4882a593Smuzhiyun 
4138*4882a593Smuzhiyun 		target = phy_get_txpwr_total_mbm(adapter, rs, rates_by_sections[rs].rates[i], bw, cch, opch, 0, &tic);
4139*4882a593Smuzhiyun 		tx_num = tic.ntx_idx + 1;
4140*4882a593Smuzhiyun 		if (tic.limit == hal_spec->txgi_max)
4141*4882a593Smuzhiyun 			lmt = UNSPECIFIED_MBM;
4142*4882a593Smuzhiyun 		else
4143*4882a593Smuzhiyun 			lmt = ((tic.limit * MBM_PDBM) / hal_spec->txgi_pdbm) + mb_of_ntx(tx_num);
4144*4882a593Smuzhiyun 		if (tic.ulimit == hal_spec->txgi_max)
4145*4882a593Smuzhiyun 			ulmt = UNSPECIFIED_MBM;
4146*4882a593Smuzhiyun 		else
4147*4882a593Smuzhiyun 			ulmt = ((tic.ulimit * MBM_PDBM) / hal_spec->txgi_pdbm) + mb_of_ntx(tx_num);
4148*4882a593Smuzhiyun 		tpc = (tic.tpc * MBM_PDBM) / hal_spec->txgi_pdbm;
4149*4882a593Smuzhiyun 
4150*4882a593Smuzhiyun 		if (tic.utarget == hal_spec->txgi_max) {
4151*4882a593Smuzhiyun 			byr = ((tic.by_rate * MBM_PDBM) / hal_spec->txgi_pdbm) + mb_of_ntx(tx_num);
4152*4882a593Smuzhiyun 			btc = (tic.btc * MBM_PDBM) / hal_spec->txgi_pdbm;
4153*4882a593Smuzhiyun 			extra = (tic.extra * MBM_PDBM) / hal_spec->txgi_pdbm;
4154*4882a593Smuzhiyun 			dump_txpwr_total_dbm_value(sel, adapter, rates_by_sections[rs].rates[i], tic.ntx_idx
4155*4882a593Smuzhiyun 				, target, byr, btc, extra, lmt, ulmt, tpc);
4156*4882a593Smuzhiyun 		} else {
4157*4882a593Smuzhiyun 			utgt = ((tic.utarget * MBM_PDBM) / hal_spec->txgi_pdbm) + mb_of_ntx(tx_num);
4158*4882a593Smuzhiyun 			dump_txpwr_total_dbm_value_utgt(sel, adapter, rates_by_sections[rs].rates[i], tic.ntx_idx
4159*4882a593Smuzhiyun 				, target, utgt, lmt, ulmt, tpc);
4160*4882a593Smuzhiyun 		}
4161*4882a593Smuzhiyun 	}
4162*4882a593Smuzhiyun }
4163*4882a593Smuzhiyun 
4164*4882a593Smuzhiyun /* dump txpowr in dBm with effect of N-TX */
dump_txpwr_total_dbm(void * sel,_adapter * adapter,enum channel_width bw,u8 cch,u8 opch)4165*4882a593Smuzhiyun void dump_txpwr_total_dbm(void *sel, _adapter *adapter, enum channel_width bw, u8 cch, u8 opch)
4166*4882a593Smuzhiyun {
4167*4882a593Smuzhiyun 	u8 rs;
4168*4882a593Smuzhiyun 
4169*4882a593Smuzhiyun 	dump_txpwr_total_dbm_title(sel, adapter, bw, cch, opch);
4170*4882a593Smuzhiyun 	for (rs = CCK; rs < RATE_SECTION_NUM; rs++)
4171*4882a593Smuzhiyun 		dump_txpwr_total_dbm_by_rs(sel, adapter, rs, bw, cch, opch);
4172*4882a593Smuzhiyun }
4173*4882a593Smuzhiyun #endif
4174*4882a593Smuzhiyun 
phy_is_tx_power_limit_needed(_adapter * adapter)4175*4882a593Smuzhiyun bool phy_is_tx_power_limit_needed(_adapter *adapter)
4176*4882a593Smuzhiyun {
4177*4882a593Smuzhiyun #if CONFIG_TXPWR_LIMIT
4178*4882a593Smuzhiyun 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
4179*4882a593Smuzhiyun 	struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
4180*4882a593Smuzhiyun 
4181*4882a593Smuzhiyun 	if (regsty->RegEnableTxPowerLimit == 1
4182*4882a593Smuzhiyun 		|| (regsty->RegEnableTxPowerLimit == 2 && hal_data->EEPROMRegulatory == 1))
4183*4882a593Smuzhiyun 		return _TRUE;
4184*4882a593Smuzhiyun #endif
4185*4882a593Smuzhiyun 
4186*4882a593Smuzhiyun 	return _FALSE;
4187*4882a593Smuzhiyun }
4188*4882a593Smuzhiyun 
phy_is_tx_power_by_rate_needed(_adapter * adapter)4189*4882a593Smuzhiyun bool phy_is_tx_power_by_rate_needed(_adapter *adapter)
4190*4882a593Smuzhiyun {
4191*4882a593Smuzhiyun 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
4192*4882a593Smuzhiyun 	struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
4193*4882a593Smuzhiyun 
4194*4882a593Smuzhiyun 	if (regsty->RegEnableTxPowerByRate == 1
4195*4882a593Smuzhiyun 		|| (regsty->RegEnableTxPowerByRate == 2 && hal_data->EEPROMRegulatory != 2))
4196*4882a593Smuzhiyun 		return _TRUE;
4197*4882a593Smuzhiyun 
4198*4882a593Smuzhiyun 	return _FALSE;
4199*4882a593Smuzhiyun }
4200*4882a593Smuzhiyun 
phy_load_tx_power_by_rate(_adapter * adapter,u8 chk_file)4201*4882a593Smuzhiyun int phy_load_tx_power_by_rate(_adapter *adapter, u8 chk_file)
4202*4882a593Smuzhiyun {
4203*4882a593Smuzhiyun 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
4204*4882a593Smuzhiyun 	int ret = _FAIL;
4205*4882a593Smuzhiyun 
4206*4882a593Smuzhiyun 	hal_data->txpwr_by_rate_loaded = 0;
4207*4882a593Smuzhiyun 	PHY_InitTxPowerByRate(adapter);
4208*4882a593Smuzhiyun 
4209*4882a593Smuzhiyun 	/* tx power limit is based on tx power by rate */
4210*4882a593Smuzhiyun 	hal_data->txpwr_limit_loaded = 0;
4211*4882a593Smuzhiyun 
4212*4882a593Smuzhiyun #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
4213*4882a593Smuzhiyun 	if (chk_file
4214*4882a593Smuzhiyun 		&& phy_ConfigBBWithPgParaFile(adapter, PHY_FILE_PHY_REG_PG) == _SUCCESS
4215*4882a593Smuzhiyun 	) {
4216*4882a593Smuzhiyun 		hal_data->txpwr_by_rate_from_file = 1;
4217*4882a593Smuzhiyun 		goto post_hdl;
4218*4882a593Smuzhiyun 	}
4219*4882a593Smuzhiyun #endif
4220*4882a593Smuzhiyun 
4221*4882a593Smuzhiyun #ifdef CONFIG_EMBEDDED_FWIMG
4222*4882a593Smuzhiyun 	if (HAL_STATUS_SUCCESS == odm_config_bb_with_header_file(&hal_data->odmpriv, CONFIG_BB_PHY_REG_PG)) {
4223*4882a593Smuzhiyun 		RTW_INFO("default power by rate loaded\n");
4224*4882a593Smuzhiyun 		hal_data->txpwr_by_rate_from_file = 0;
4225*4882a593Smuzhiyun 		goto post_hdl;
4226*4882a593Smuzhiyun 	}
4227*4882a593Smuzhiyun #endif
4228*4882a593Smuzhiyun 
4229*4882a593Smuzhiyun 	RTW_ERR("%s():Read Tx power by rate fail\n", __func__);
4230*4882a593Smuzhiyun 	goto exit;
4231*4882a593Smuzhiyun 
4232*4882a593Smuzhiyun post_hdl:
4233*4882a593Smuzhiyun 	if (hal_data->odmpriv.phy_reg_pg_value_type != PHY_REG_PG_EXACT_VALUE) {
4234*4882a593Smuzhiyun 		rtw_warn_on(1);
4235*4882a593Smuzhiyun 		goto exit;
4236*4882a593Smuzhiyun 	}
4237*4882a593Smuzhiyun 
4238*4882a593Smuzhiyun 	PHY_TxPowerByRateConfiguration(adapter);
4239*4882a593Smuzhiyun 	hal_data->txpwr_by_rate_loaded = 1;
4240*4882a593Smuzhiyun 
4241*4882a593Smuzhiyun 	ret = _SUCCESS;
4242*4882a593Smuzhiyun 
4243*4882a593Smuzhiyun exit:
4244*4882a593Smuzhiyun 	return ret;
4245*4882a593Smuzhiyun }
4246*4882a593Smuzhiyun 
4247*4882a593Smuzhiyun #if CONFIG_TXPWR_LIMIT
phy_load_tx_power_limit(_adapter * adapter,u8 chk_file)4248*4882a593Smuzhiyun int phy_load_tx_power_limit(_adapter *adapter, u8 chk_file)
4249*4882a593Smuzhiyun {
4250*4882a593Smuzhiyun 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
4251*4882a593Smuzhiyun 	struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
4252*4882a593Smuzhiyun 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
4253*4882a593Smuzhiyun 	int ret = _FAIL;
4254*4882a593Smuzhiyun 
4255*4882a593Smuzhiyun 	hal_data->txpwr_limit_loaded = 0;
4256*4882a593Smuzhiyun 	rtw_regd_exc_list_free(rfctl);
4257*4882a593Smuzhiyun 	rtw_txpwr_lmt_list_free(rfctl);
4258*4882a593Smuzhiyun 
4259*4882a593Smuzhiyun 	if (!hal_data->txpwr_by_rate_loaded && regsty->target_tx_pwr_valid != _TRUE) {
4260*4882a593Smuzhiyun 		RTW_ERR("%s():Read Tx power limit before target tx power is specify\n", __func__);
4261*4882a593Smuzhiyun 		goto exit;
4262*4882a593Smuzhiyun 	}
4263*4882a593Smuzhiyun 
4264*4882a593Smuzhiyun #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
4265*4882a593Smuzhiyun 	if (chk_file
4266*4882a593Smuzhiyun 		&& PHY_ConfigRFWithPowerLimitTableParaFile(adapter, PHY_FILE_TXPWR_LMT) == _SUCCESS
4267*4882a593Smuzhiyun 	) {
4268*4882a593Smuzhiyun 		hal_data->txpwr_limit_from_file = 1;
4269*4882a593Smuzhiyun 		goto post_hdl;
4270*4882a593Smuzhiyun 	}
4271*4882a593Smuzhiyun #endif
4272*4882a593Smuzhiyun 
4273*4882a593Smuzhiyun #ifdef CONFIG_EMBEDDED_FWIMG
4274*4882a593Smuzhiyun 	if (odm_config_rf_with_header_file(&hal_data->odmpriv, CONFIG_RF_TXPWR_LMT, RF_PATH_A) == HAL_STATUS_SUCCESS) {
4275*4882a593Smuzhiyun 		RTW_INFO("default power limit loaded\n");
4276*4882a593Smuzhiyun 		hal_data->txpwr_limit_from_file = 0;
4277*4882a593Smuzhiyun 		goto post_hdl;
4278*4882a593Smuzhiyun 	}
4279*4882a593Smuzhiyun #endif
4280*4882a593Smuzhiyun 
4281*4882a593Smuzhiyun 	RTW_ERR("%s():Read Tx power limit fail\n", __func__);
4282*4882a593Smuzhiyun 	goto exit;
4283*4882a593Smuzhiyun 
4284*4882a593Smuzhiyun post_hdl:
4285*4882a593Smuzhiyun 	phy_txpwr_lmt_post_hdl(adapter);
4286*4882a593Smuzhiyun 	rtw_txpwr_init_regd(rfctl);
4287*4882a593Smuzhiyun 	hal_data->txpwr_limit_loaded = 1;
4288*4882a593Smuzhiyun 	ret = _SUCCESS;
4289*4882a593Smuzhiyun 
4290*4882a593Smuzhiyun exit:
4291*4882a593Smuzhiyun 	return ret;
4292*4882a593Smuzhiyun }
4293*4882a593Smuzhiyun #endif /* CONFIG_TXPWR_LIMIT */
4294*4882a593Smuzhiyun 
phy_load_tx_power_ext_info(_adapter * adapter,u8 chk_file)4295*4882a593Smuzhiyun void phy_load_tx_power_ext_info(_adapter *adapter, u8 chk_file)
4296*4882a593Smuzhiyun {
4297*4882a593Smuzhiyun 	struct registry_priv *regsty = adapter_to_regsty(adapter);
4298*4882a593Smuzhiyun 
4299*4882a593Smuzhiyun 	/* check registy target tx power */
4300*4882a593Smuzhiyun 	regsty->target_tx_pwr_valid = rtw_regsty_chk_target_tx_power_valid(adapter);
4301*4882a593Smuzhiyun 
4302*4882a593Smuzhiyun 	/* power by rate */
4303*4882a593Smuzhiyun 	if (phy_is_tx_power_by_rate_needed(adapter)
4304*4882a593Smuzhiyun 		|| regsty->target_tx_pwr_valid != _TRUE /* need target tx power from by rate table */
4305*4882a593Smuzhiyun 	)
4306*4882a593Smuzhiyun 		phy_load_tx_power_by_rate(adapter, chk_file);
4307*4882a593Smuzhiyun 
4308*4882a593Smuzhiyun 	/* power limit */
4309*4882a593Smuzhiyun #if CONFIG_TXPWR_LIMIT
4310*4882a593Smuzhiyun 	if (phy_is_tx_power_limit_needed(adapter))
4311*4882a593Smuzhiyun 		phy_load_tx_power_limit(adapter, chk_file);
4312*4882a593Smuzhiyun #endif
4313*4882a593Smuzhiyun }
4314*4882a593Smuzhiyun 
phy_reload_tx_power_ext_info(_adapter * adapter)4315*4882a593Smuzhiyun inline void phy_reload_tx_power_ext_info(_adapter *adapter)
4316*4882a593Smuzhiyun {
4317*4882a593Smuzhiyun 	phy_load_tx_power_ext_info(adapter, 1);
4318*4882a593Smuzhiyun }
4319*4882a593Smuzhiyun 
phy_reload_default_tx_power_ext_info(_adapter * adapter)4320*4882a593Smuzhiyun inline void phy_reload_default_tx_power_ext_info(_adapter *adapter)
4321*4882a593Smuzhiyun {
4322*4882a593Smuzhiyun 	phy_load_tx_power_ext_info(adapter, 0);
4323*4882a593Smuzhiyun }
4324*4882a593Smuzhiyun 
4325*4882a593Smuzhiyun #ifdef CONFIG_PROC_DEBUG
dump_tx_power_ext_info(void * sel,_adapter * adapter)4326*4882a593Smuzhiyun void dump_tx_power_ext_info(void *sel, _adapter *adapter)
4327*4882a593Smuzhiyun {
4328*4882a593Smuzhiyun 	struct registry_priv *regsty = adapter_to_regsty(adapter);
4329*4882a593Smuzhiyun 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
4330*4882a593Smuzhiyun 
4331*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "txpwr_pg_mode: %s\n", txpwr_pg_mode_str(hal_data->txpwr_pg_mode));
4332*4882a593Smuzhiyun 
4333*4882a593Smuzhiyun 	if (regsty->target_tx_pwr_valid == _TRUE)
4334*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "target_tx_power: from registry\n");
4335*4882a593Smuzhiyun 	else if (hal_data->txpwr_by_rate_loaded)
4336*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "target_tx_power: from power by rate\n");
4337*4882a593Smuzhiyun 	else
4338*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "target_tx_power: unavailable\n");
4339*4882a593Smuzhiyun 
4340*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "tx_power_by_rate: %s, %s, %s\n"
4341*4882a593Smuzhiyun 		, phy_is_tx_power_by_rate_needed(adapter) ? "enabled" : "disabled"
4342*4882a593Smuzhiyun 		, hal_data->txpwr_by_rate_loaded ? "loaded" : "unloaded"
4343*4882a593Smuzhiyun 		, hal_data->txpwr_by_rate_from_file ? "file" : "default"
4344*4882a593Smuzhiyun 	);
4345*4882a593Smuzhiyun 
4346*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "tx_power_limit: %s, %s, %s\n"
4347*4882a593Smuzhiyun 		, phy_is_tx_power_limit_needed(adapter) ? "enabled" : "disabled"
4348*4882a593Smuzhiyun 		, hal_data->txpwr_limit_loaded ? "loaded" : "unloaded"
4349*4882a593Smuzhiyun 		, hal_data->txpwr_limit_from_file ? "file" : "default"
4350*4882a593Smuzhiyun 	);
4351*4882a593Smuzhiyun }
4352*4882a593Smuzhiyun 
dump_target_tx_power(void * sel,_adapter * adapter)4353*4882a593Smuzhiyun void dump_target_tx_power(void *sel, _adapter *adapter)
4354*4882a593Smuzhiyun {
4355*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
4356*4882a593Smuzhiyun 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
4357*4882a593Smuzhiyun 	struct registry_priv *regsty = adapter_to_regsty(adapter);
4358*4882a593Smuzhiyun 	int path, tx_num, band, rs;
4359*4882a593Smuzhiyun 	u8 target;
4360*4882a593Smuzhiyun 
4361*4882a593Smuzhiyun 	for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
4362*4882a593Smuzhiyun 		if (!hal_is_band_support(adapter, band))
4363*4882a593Smuzhiyun 			continue;
4364*4882a593Smuzhiyun 
4365*4882a593Smuzhiyun 		for (path = 0; path < RF_PATH_MAX; path++) {
4366*4882a593Smuzhiyun 			if (!HAL_SPEC_CHK_RF_PATH(hal_spec, band, path))
4367*4882a593Smuzhiyun 				break;
4368*4882a593Smuzhiyun 
4369*4882a593Smuzhiyun 			RTW_PRINT_SEL(sel, "[%s][%c]%s\n", band_str(band), rf_path_char(path)
4370*4882a593Smuzhiyun 				, (regsty->target_tx_pwr_valid == _FALSE && hal_data->txpwr_by_rate_undefined_band_path[band][path]) ? "(dup)" : "");
4371*4882a593Smuzhiyun 
4372*4882a593Smuzhiyun 			for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
4373*4882a593Smuzhiyun 				tx_num = rate_section_to_tx_num(rs);
4374*4882a593Smuzhiyun 				if (tx_num + 1 > hal_data->tx_nss)
4375*4882a593Smuzhiyun 					continue;
4376*4882a593Smuzhiyun 
4377*4882a593Smuzhiyun 				if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
4378*4882a593Smuzhiyun 					continue;
4379*4882a593Smuzhiyun 
4380*4882a593Smuzhiyun 				if (IS_VHT_RATE_SECTION(rs) && !IS_HARDWARE_TYPE_JAGUAR_ALL(adapter))
4381*4882a593Smuzhiyun 					continue;
4382*4882a593Smuzhiyun 
4383*4882a593Smuzhiyun 				target = phy_get_target_txpwr(adapter, band, path, rs);
4384*4882a593Smuzhiyun 
4385*4882a593Smuzhiyun 				if (target % hal_spec->txgi_pdbm) {
4386*4882a593Smuzhiyun 					_RTW_PRINT_SEL(sel, "%7s: %2d.%d\n", rate_section_str(rs)
4387*4882a593Smuzhiyun 						, target / hal_spec->txgi_pdbm, (target % hal_spec->txgi_pdbm) * 100 / hal_spec->txgi_pdbm);
4388*4882a593Smuzhiyun 				} else {
4389*4882a593Smuzhiyun 					_RTW_PRINT_SEL(sel, "%7s: %5d\n", rate_section_str(rs)
4390*4882a593Smuzhiyun 						, target / hal_spec->txgi_pdbm);
4391*4882a593Smuzhiyun 				}
4392*4882a593Smuzhiyun 			}
4393*4882a593Smuzhiyun 		}
4394*4882a593Smuzhiyun 	}
4395*4882a593Smuzhiyun 
4396*4882a593Smuzhiyun 	return;
4397*4882a593Smuzhiyun }
4398*4882a593Smuzhiyun 
dump_tx_power_by_rate(void * sel,_adapter * adapter)4399*4882a593Smuzhiyun void dump_tx_power_by_rate(void *sel, _adapter *adapter)
4400*4882a593Smuzhiyun {
4401*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
4402*4882a593Smuzhiyun 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
4403*4882a593Smuzhiyun 	int path, tx_num, band, n, rs;
4404*4882a593Smuzhiyun 	u8 rate_num, max_rate_num, base;
4405*4882a593Smuzhiyun 	s8 by_rate;
4406*4882a593Smuzhiyun 
4407*4882a593Smuzhiyun 	for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
4408*4882a593Smuzhiyun 		if (!hal_is_band_support(adapter, band))
4409*4882a593Smuzhiyun 			continue;
4410*4882a593Smuzhiyun 
4411*4882a593Smuzhiyun 		for (path = 0; path < RF_PATH_MAX; path++) {
4412*4882a593Smuzhiyun 			if (!HAL_SPEC_CHK_RF_PATH(hal_spec, band, path))
4413*4882a593Smuzhiyun 				break;
4414*4882a593Smuzhiyun 
4415*4882a593Smuzhiyun 			RTW_PRINT_SEL(sel, "[%s][%c]%s\n", band_str(band), rf_path_char(path)
4416*4882a593Smuzhiyun 				, hal_data->txpwr_by_rate_undefined_band_path[band][path] ? "(dup)" : "");
4417*4882a593Smuzhiyun 
4418*4882a593Smuzhiyun 			for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
4419*4882a593Smuzhiyun 				tx_num = rate_section_to_tx_num(rs);
4420*4882a593Smuzhiyun 				if (tx_num + 1 > hal_data->tx_nss)
4421*4882a593Smuzhiyun 					continue;
4422*4882a593Smuzhiyun 
4423*4882a593Smuzhiyun 				if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
4424*4882a593Smuzhiyun 					continue;
4425*4882a593Smuzhiyun 
4426*4882a593Smuzhiyun 				if (IS_VHT_RATE_SECTION(rs) && !IS_HARDWARE_TYPE_JAGUAR_ALL(adapter))
4427*4882a593Smuzhiyun 					continue;
4428*4882a593Smuzhiyun 
4429*4882a593Smuzhiyun 				if (IS_HARDWARE_TYPE_JAGUAR_ALL(adapter))
4430*4882a593Smuzhiyun 					max_rate_num = 10;
4431*4882a593Smuzhiyun 				else
4432*4882a593Smuzhiyun 					max_rate_num = 8;
4433*4882a593Smuzhiyun 				rate_num = rate_section_rate_num(rs);
4434*4882a593Smuzhiyun 
4435*4882a593Smuzhiyun 				RTW_PRINT_SEL(sel, "%7s: ", rate_section_str(rs));
4436*4882a593Smuzhiyun 
4437*4882a593Smuzhiyun 				/* dump power by rate in db */
4438*4882a593Smuzhiyun 				for (n = rate_num - 1; n >= 0; n--) {
4439*4882a593Smuzhiyun 					by_rate = PHY_GetTxPowerByRate(adapter, band, path, rs, rates_by_sections[rs].rates[n]);
4440*4882a593Smuzhiyun 					if (by_rate % hal_spec->txgi_pdbm) {
4441*4882a593Smuzhiyun 						_RTW_PRINT_SEL(sel, "%2d.%d ", by_rate / hal_spec->txgi_pdbm
4442*4882a593Smuzhiyun 							, (by_rate % hal_spec->txgi_pdbm) * 100 / hal_spec->txgi_pdbm);
4443*4882a593Smuzhiyun 					} else
4444*4882a593Smuzhiyun 						_RTW_PRINT_SEL(sel, "%5d ", by_rate / hal_spec->txgi_pdbm);
4445*4882a593Smuzhiyun 				}
4446*4882a593Smuzhiyun 				for (n = 0; n < max_rate_num - rate_num; n++)
4447*4882a593Smuzhiyun 					_RTW_PRINT_SEL(sel, "%5s ", "");
4448*4882a593Smuzhiyun 
4449*4882a593Smuzhiyun 				_RTW_PRINT_SEL(sel, "|");
4450*4882a593Smuzhiyun 
4451*4882a593Smuzhiyun 				/* dump power by rate in offset */
4452*4882a593Smuzhiyun 				for (n = rate_num - 1; n >= 0; n--) {
4453*4882a593Smuzhiyun 					by_rate = PHY_GetTxPowerByRate(adapter, band, path, rs, rates_by_sections[rs].rates[n]);
4454*4882a593Smuzhiyun 					base = phy_get_target_txpwr(adapter, band, path, rs);
4455*4882a593Smuzhiyun 					_RTW_PRINT_SEL(sel, "%3d ", by_rate - base);
4456*4882a593Smuzhiyun 				}
4457*4882a593Smuzhiyun 				RTW_PRINT_SEL(sel, "\n");
4458*4882a593Smuzhiyun 
4459*4882a593Smuzhiyun 			}
4460*4882a593Smuzhiyun 		}
4461*4882a593Smuzhiyun 	}
4462*4882a593Smuzhiyun }
4463*4882a593Smuzhiyun #endif
4464*4882a593Smuzhiyun /*
4465*4882a593Smuzhiyun  * phy file path is stored in global char array rtw_phy_para_file_path
4466*4882a593Smuzhiyun  * need to care about racing
4467*4882a593Smuzhiyun  */
rtw_get_phy_file_path(_adapter * adapter,const char * file_name)4468*4882a593Smuzhiyun int rtw_get_phy_file_path(_adapter *adapter, const char *file_name)
4469*4882a593Smuzhiyun {
4470*4882a593Smuzhiyun #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
4471*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
4472*4882a593Smuzhiyun 	int len = 0;
4473*4882a593Smuzhiyun 
4474*4882a593Smuzhiyun 	if (file_name) {
4475*4882a593Smuzhiyun 		len += snprintf(rtw_phy_para_file_path, PATH_LENGTH_MAX, "%s", rtw_phy_file_path);
4476*4882a593Smuzhiyun 		#if defined(CONFIG_MULTIDRV) || defined(REALTEK_CONFIG_PATH_WITH_IC_NAME_FOLDER)
4477*4882a593Smuzhiyun 		len += snprintf(rtw_phy_para_file_path + len, PATH_LENGTH_MAX - len, "%s/", hal_spec->ic_name);
4478*4882a593Smuzhiyun 		#endif
4479*4882a593Smuzhiyun 		len += snprintf(rtw_phy_para_file_path + len, PATH_LENGTH_MAX - len, "%s", file_name);
4480*4882a593Smuzhiyun 
4481*4882a593Smuzhiyun 		return _TRUE;
4482*4882a593Smuzhiyun 	}
4483*4882a593Smuzhiyun #endif
4484*4882a593Smuzhiyun 	return _FALSE;
4485*4882a593Smuzhiyun }
4486*4882a593Smuzhiyun 
4487*4882a593Smuzhiyun #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
4488*4882a593Smuzhiyun int
phy_ConfigMACWithParaFile(PADAPTER Adapter,char * pFileName)4489*4882a593Smuzhiyun phy_ConfigMACWithParaFile(
4490*4882a593Smuzhiyun 		PADAPTER	Adapter,
4491*4882a593Smuzhiyun 		char		*pFileName
4492*4882a593Smuzhiyun )
4493*4882a593Smuzhiyun {
4494*4882a593Smuzhiyun 	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(Adapter);
4495*4882a593Smuzhiyun 	int	rlen = 0, rtStatus = _FAIL;
4496*4882a593Smuzhiyun 	char	*szLine, *ptmp;
4497*4882a593Smuzhiyun 	u32	u4bRegOffset, u4bRegValue, u4bMove;
4498*4882a593Smuzhiyun 
4499*4882a593Smuzhiyun 	if (!(Adapter->registrypriv.load_phy_file & LOAD_MAC_PARA_FILE))
4500*4882a593Smuzhiyun 		return rtStatus;
4501*4882a593Smuzhiyun 
4502*4882a593Smuzhiyun 	_rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
4503*4882a593Smuzhiyun 
4504*4882a593Smuzhiyun 	if ((pHalData->mac_reg_len == 0) && (pHalData->mac_reg == NULL)) {
4505*4882a593Smuzhiyun 		rtw_get_phy_file_path(Adapter, pFileName);
4506*4882a593Smuzhiyun 		if (rtw_readable_file_sz_chk(rtw_phy_para_file_path,
4507*4882a593Smuzhiyun 			MAX_PARA_FILE_BUF_LEN) == _TRUE) {
4508*4882a593Smuzhiyun 			rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
4509*4882a593Smuzhiyun 			if (rlen > 0) {
4510*4882a593Smuzhiyun 				rtStatus = _SUCCESS;
4511*4882a593Smuzhiyun 				pHalData->mac_reg = rtw_zvmalloc(rlen);
4512*4882a593Smuzhiyun 				if (pHalData->mac_reg) {
4513*4882a593Smuzhiyun 					_rtw_memcpy(pHalData->mac_reg, pHalData->para_file_buf, rlen);
4514*4882a593Smuzhiyun 					pHalData->mac_reg_len = rlen;
4515*4882a593Smuzhiyun 				} else
4516*4882a593Smuzhiyun 					RTW_INFO("%s mac_reg alloc fail !\n", __FUNCTION__);
4517*4882a593Smuzhiyun 			}
4518*4882a593Smuzhiyun 		}
4519*4882a593Smuzhiyun 	} else {
4520*4882a593Smuzhiyun 		if ((pHalData->mac_reg_len != 0) && (pHalData->mac_reg != NULL)) {
4521*4882a593Smuzhiyun 			_rtw_memcpy(pHalData->para_file_buf, pHalData->mac_reg, pHalData->mac_reg_len);
4522*4882a593Smuzhiyun 			rtStatus = _SUCCESS;
4523*4882a593Smuzhiyun 		} else
4524*4882a593Smuzhiyun 			RTW_INFO("%s(): Critical Error !!!\n", __FUNCTION__);
4525*4882a593Smuzhiyun 	}
4526*4882a593Smuzhiyun 
4527*4882a593Smuzhiyun 	if (rtStatus == _SUCCESS) {
4528*4882a593Smuzhiyun 		ptmp = pHalData->para_file_buf;
4529*4882a593Smuzhiyun 		for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
4530*4882a593Smuzhiyun 			if (!IsCommentString(szLine)) {
4531*4882a593Smuzhiyun 				/* Get 1st hex value as register offset */
4532*4882a593Smuzhiyun 				if (GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove)) {
4533*4882a593Smuzhiyun 					if (u4bRegOffset == 0xffff) {
4534*4882a593Smuzhiyun 						/* Ending. */
4535*4882a593Smuzhiyun 						break;
4536*4882a593Smuzhiyun 					}
4537*4882a593Smuzhiyun 
4538*4882a593Smuzhiyun 					/* Get 2nd hex value as register value. */
4539*4882a593Smuzhiyun 					szLine += u4bMove;
4540*4882a593Smuzhiyun 					if (GetHexValueFromString(szLine, &u4bRegValue, &u4bMove))
4541*4882a593Smuzhiyun 						rtw_write8(Adapter, u4bRegOffset, (u8)u4bRegValue);
4542*4882a593Smuzhiyun 				}
4543*4882a593Smuzhiyun 			}
4544*4882a593Smuzhiyun 		}
4545*4882a593Smuzhiyun 	} else
4546*4882a593Smuzhiyun 		RTW_INFO("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
4547*4882a593Smuzhiyun 
4548*4882a593Smuzhiyun 	return rtStatus;
4549*4882a593Smuzhiyun }
4550*4882a593Smuzhiyun 
4551*4882a593Smuzhiyun int
phy_ConfigBBWithParaFile(PADAPTER Adapter,char * pFileName,u32 ConfigType)4552*4882a593Smuzhiyun phy_ConfigBBWithParaFile(
4553*4882a593Smuzhiyun 		PADAPTER	Adapter,
4554*4882a593Smuzhiyun 		char		*pFileName,
4555*4882a593Smuzhiyun 		u32			ConfigType
4556*4882a593Smuzhiyun )
4557*4882a593Smuzhiyun {
4558*4882a593Smuzhiyun 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
4559*4882a593Smuzhiyun 	int	rlen = 0, rtStatus = _FAIL;
4560*4882a593Smuzhiyun 	char	*szLine, *ptmp;
4561*4882a593Smuzhiyun 	u32	u4bRegOffset, u4bRegValue, u4bMove;
4562*4882a593Smuzhiyun 	char	*pBuf = NULL;
4563*4882a593Smuzhiyun 	u32	*pBufLen = NULL;
4564*4882a593Smuzhiyun 
4565*4882a593Smuzhiyun 	if (!(Adapter->registrypriv.load_phy_file & LOAD_BB_PARA_FILE))
4566*4882a593Smuzhiyun 		return rtStatus;
4567*4882a593Smuzhiyun 
4568*4882a593Smuzhiyun 	switch (ConfigType) {
4569*4882a593Smuzhiyun 	case CONFIG_BB_PHY_REG:
4570*4882a593Smuzhiyun 		pBuf = pHalData->bb_phy_reg;
4571*4882a593Smuzhiyun 		pBufLen = &pHalData->bb_phy_reg_len;
4572*4882a593Smuzhiyun 		break;
4573*4882a593Smuzhiyun 	case CONFIG_BB_AGC_TAB:
4574*4882a593Smuzhiyun 		pBuf = pHalData->bb_agc_tab;
4575*4882a593Smuzhiyun 		pBufLen = &pHalData->bb_agc_tab_len;
4576*4882a593Smuzhiyun 		break;
4577*4882a593Smuzhiyun 	default:
4578*4882a593Smuzhiyun 		RTW_INFO("Unknown ConfigType!! %d\r\n", ConfigType);
4579*4882a593Smuzhiyun 		break;
4580*4882a593Smuzhiyun 	}
4581*4882a593Smuzhiyun 
4582*4882a593Smuzhiyun 	_rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
4583*4882a593Smuzhiyun 
4584*4882a593Smuzhiyun 	if ((pBufLen != NULL) && (*pBufLen == 0) && (pBuf == NULL)) {
4585*4882a593Smuzhiyun 		rtw_get_phy_file_path(Adapter, pFileName);
4586*4882a593Smuzhiyun 		if (rtw_readable_file_sz_chk(rtw_phy_para_file_path,
4587*4882a593Smuzhiyun 			MAX_PARA_FILE_BUF_LEN) == _TRUE) {
4588*4882a593Smuzhiyun 			rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
4589*4882a593Smuzhiyun 			if (rlen > 0) {
4590*4882a593Smuzhiyun 				rtStatus = _SUCCESS;
4591*4882a593Smuzhiyun 				pBuf = rtw_zvmalloc(rlen);
4592*4882a593Smuzhiyun 				if (pBuf) {
4593*4882a593Smuzhiyun 					_rtw_memcpy(pBuf, pHalData->para_file_buf, rlen);
4594*4882a593Smuzhiyun 					*pBufLen = rlen;
4595*4882a593Smuzhiyun 
4596*4882a593Smuzhiyun 					switch (ConfigType) {
4597*4882a593Smuzhiyun 					case CONFIG_BB_PHY_REG:
4598*4882a593Smuzhiyun 						pHalData->bb_phy_reg = pBuf;
4599*4882a593Smuzhiyun 						break;
4600*4882a593Smuzhiyun 					case CONFIG_BB_AGC_TAB:
4601*4882a593Smuzhiyun 						pHalData->bb_agc_tab = pBuf;
4602*4882a593Smuzhiyun 						break;
4603*4882a593Smuzhiyun 					}
4604*4882a593Smuzhiyun 				} else
4605*4882a593Smuzhiyun 					RTW_INFO("%s(): ConfigType %d  alloc fail !\n", __FUNCTION__, ConfigType);
4606*4882a593Smuzhiyun 			}
4607*4882a593Smuzhiyun 		}
4608*4882a593Smuzhiyun 	} else {
4609*4882a593Smuzhiyun 		if ((pBufLen != NULL) && (*pBufLen != 0) && (pBuf != NULL)) {
4610*4882a593Smuzhiyun 			_rtw_memcpy(pHalData->para_file_buf, pBuf, *pBufLen);
4611*4882a593Smuzhiyun 			rtStatus = _SUCCESS;
4612*4882a593Smuzhiyun 		} else
4613*4882a593Smuzhiyun 			RTW_INFO("%s(): Critical Error !!!\n", __FUNCTION__);
4614*4882a593Smuzhiyun 	}
4615*4882a593Smuzhiyun 
4616*4882a593Smuzhiyun 	if (rtStatus == _SUCCESS) {
4617*4882a593Smuzhiyun 		ptmp = pHalData->para_file_buf;
4618*4882a593Smuzhiyun 		for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
4619*4882a593Smuzhiyun 			if (!IsCommentString(szLine)) {
4620*4882a593Smuzhiyun 				/* Get 1st hex value as register offset. */
4621*4882a593Smuzhiyun 				if (GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove)) {
4622*4882a593Smuzhiyun 					if (u4bRegOffset == 0xffff) {
4623*4882a593Smuzhiyun 						/* Ending. */
4624*4882a593Smuzhiyun 						break;
4625*4882a593Smuzhiyun 					} else if (u4bRegOffset == 0xfe || u4bRegOffset == 0xffe) {
4626*4882a593Smuzhiyun #ifdef CONFIG_LONG_DELAY_ISSUE
4627*4882a593Smuzhiyun 						rtw_msleep_os(50);
4628*4882a593Smuzhiyun #else
4629*4882a593Smuzhiyun 						rtw_mdelay_os(50);
4630*4882a593Smuzhiyun #endif
4631*4882a593Smuzhiyun 					} else if (u4bRegOffset == 0xfd)
4632*4882a593Smuzhiyun 						rtw_mdelay_os(5);
4633*4882a593Smuzhiyun 					else if (u4bRegOffset == 0xfc)
4634*4882a593Smuzhiyun 						rtw_mdelay_os(1);
4635*4882a593Smuzhiyun 					else if (u4bRegOffset == 0xfb)
4636*4882a593Smuzhiyun 						rtw_udelay_os(50);
4637*4882a593Smuzhiyun 					else if (u4bRegOffset == 0xfa)
4638*4882a593Smuzhiyun 						rtw_udelay_os(5);
4639*4882a593Smuzhiyun 					else if (u4bRegOffset == 0xf9)
4640*4882a593Smuzhiyun 						rtw_udelay_os(1);
4641*4882a593Smuzhiyun 
4642*4882a593Smuzhiyun 					/* Get 2nd hex value as register value. */
4643*4882a593Smuzhiyun 					szLine += u4bMove;
4644*4882a593Smuzhiyun 					if (GetHexValueFromString(szLine, &u4bRegValue, &u4bMove)) {
4645*4882a593Smuzhiyun 						/* RTW_INFO("[BB-ADDR]%03lX=%08lX\n", u4bRegOffset, u4bRegValue); */
4646*4882a593Smuzhiyun 						phy_set_bb_reg(Adapter, u4bRegOffset, bMaskDWord, u4bRegValue);
4647*4882a593Smuzhiyun 
4648*4882a593Smuzhiyun 						if (u4bRegOffset == 0xa24)
4649*4882a593Smuzhiyun 							pHalData->odmpriv.rf_calibrate_info.rega24 = u4bRegValue;
4650*4882a593Smuzhiyun 
4651*4882a593Smuzhiyun 						/* Add 1us delay between BB/RF register setting. */
4652*4882a593Smuzhiyun 						rtw_udelay_os(1);
4653*4882a593Smuzhiyun 					}
4654*4882a593Smuzhiyun 				}
4655*4882a593Smuzhiyun 			}
4656*4882a593Smuzhiyun 		}
4657*4882a593Smuzhiyun 	} else
4658*4882a593Smuzhiyun 		RTW_INFO("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
4659*4882a593Smuzhiyun 
4660*4882a593Smuzhiyun 	return rtStatus;
4661*4882a593Smuzhiyun }
4662*4882a593Smuzhiyun 
4663*4882a593Smuzhiyun void
phy_DecryptBBPgParaFile(PADAPTER Adapter,char * buffer)4664*4882a593Smuzhiyun phy_DecryptBBPgParaFile(
4665*4882a593Smuzhiyun 	PADAPTER		Adapter,
4666*4882a593Smuzhiyun 	char			*buffer
4667*4882a593Smuzhiyun )
4668*4882a593Smuzhiyun {
4669*4882a593Smuzhiyun 	u32	i = 0, j = 0;
4670*4882a593Smuzhiyun 	u8	map[95] = {0};
4671*4882a593Smuzhiyun 	u8	currentChar;
4672*4882a593Smuzhiyun 	char	*BufOfLines, *ptmp;
4673*4882a593Smuzhiyun 
4674*4882a593Smuzhiyun 	/* RTW_INFO("=====>phy_DecryptBBPgParaFile()\n"); */
4675*4882a593Smuzhiyun 	/* 32 the ascii code of the first visable char, 126 the last one */
4676*4882a593Smuzhiyun 	for (i = 0; i < 95; ++i)
4677*4882a593Smuzhiyun 		map[i] = (u8)(94 - i);
4678*4882a593Smuzhiyun 
4679*4882a593Smuzhiyun 	ptmp = buffer;
4680*4882a593Smuzhiyun 	i = 0;
4681*4882a593Smuzhiyun 	for (BufOfLines = GetLineFromBuffer(ptmp); BufOfLines != NULL; BufOfLines = GetLineFromBuffer(ptmp)) {
4682*4882a593Smuzhiyun 		/* RTW_INFO("Encrypted Line: %s\n", BufOfLines); */
4683*4882a593Smuzhiyun 
4684*4882a593Smuzhiyun 		for (j = 0; j < strlen(BufOfLines); ++j) {
4685*4882a593Smuzhiyun 			currentChar = BufOfLines[j];
4686*4882a593Smuzhiyun 
4687*4882a593Smuzhiyun 			if (currentChar == '\0')
4688*4882a593Smuzhiyun 				break;
4689*4882a593Smuzhiyun 
4690*4882a593Smuzhiyun 			currentChar -= (u8)((((i + j) * 3) % 128));
4691*4882a593Smuzhiyun 
4692*4882a593Smuzhiyun 			BufOfLines[j] = map[currentChar - 32] + 32;
4693*4882a593Smuzhiyun 		}
4694*4882a593Smuzhiyun 		/* RTW_INFO("Decrypted Line: %s\n", BufOfLines ); */
4695*4882a593Smuzhiyun 		if (strlen(BufOfLines) != 0)
4696*4882a593Smuzhiyun 			i++;
4697*4882a593Smuzhiyun 		BufOfLines[strlen(BufOfLines)] = '\n';
4698*4882a593Smuzhiyun 	}
4699*4882a593Smuzhiyun }
4700*4882a593Smuzhiyun 
4701*4882a593Smuzhiyun #ifndef DBG_TXPWR_BY_RATE_FILE_PARSE
4702*4882a593Smuzhiyun #define DBG_TXPWR_BY_RATE_FILE_PARSE 0
4703*4882a593Smuzhiyun #endif
4704*4882a593Smuzhiyun 
4705*4882a593Smuzhiyun int
phy_ParseBBPgParaFile(PADAPTER Adapter,char * buffer)4706*4882a593Smuzhiyun phy_ParseBBPgParaFile(
4707*4882a593Smuzhiyun 	PADAPTER		Adapter,
4708*4882a593Smuzhiyun 	char			*buffer
4709*4882a593Smuzhiyun )
4710*4882a593Smuzhiyun {
4711*4882a593Smuzhiyun 	int	rtStatus = _FAIL;
4712*4882a593Smuzhiyun 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
4713*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(Adapter);
4714*4882a593Smuzhiyun 	char	*szLine, *ptmp;
4715*4882a593Smuzhiyun 	u32	u4bRegOffset, u4bRegMask;
4716*4882a593Smuzhiyun 	u32	u4bMove;
4717*4882a593Smuzhiyun 	BOOLEAN firstLine = _TRUE;
4718*4882a593Smuzhiyun 	u8	tx_num = 0;
4719*4882a593Smuzhiyun 	u8	band = 0, rf_path = 0;
4720*4882a593Smuzhiyun 
4721*4882a593Smuzhiyun 	if (Adapter->registrypriv.RegDecryptCustomFile == 1)
4722*4882a593Smuzhiyun 		phy_DecryptBBPgParaFile(Adapter, buffer);
4723*4882a593Smuzhiyun 
4724*4882a593Smuzhiyun 	ptmp = buffer;
4725*4882a593Smuzhiyun 	for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
4726*4882a593Smuzhiyun 		if (isAllSpaceOrTab(szLine, sizeof(*szLine)))
4727*4882a593Smuzhiyun 			continue;
4728*4882a593Smuzhiyun 
4729*4882a593Smuzhiyun 		if (!IsCommentString(szLine)) {
4730*4882a593Smuzhiyun 			/* Get header info (relative value or exact value) */
4731*4882a593Smuzhiyun 			if (firstLine) {
4732*4882a593Smuzhiyun 				if (strncmp(szLine, "#[v1]", 5) == 0
4733*4882a593Smuzhiyun 					|| strncmp(szLine, "#[v2]", 5) == 0)
4734*4882a593Smuzhiyun 					pHalData->odmpriv.phy_reg_pg_version = szLine[3] - '0';
4735*4882a593Smuzhiyun 				else {
4736*4882a593Smuzhiyun 					RTW_ERR("The format in PHY_REG_PG are invalid %s\n", szLine);
4737*4882a593Smuzhiyun 					goto exit;
4738*4882a593Smuzhiyun 				}
4739*4882a593Smuzhiyun 
4740*4882a593Smuzhiyun 				if (strncmp(szLine + 5, "[Exact]#", 8) == 0) {
4741*4882a593Smuzhiyun 					pHalData->odmpriv.phy_reg_pg_value_type = PHY_REG_PG_EXACT_VALUE;
4742*4882a593Smuzhiyun 					firstLine = _FALSE;
4743*4882a593Smuzhiyun 					continue;
4744*4882a593Smuzhiyun 				} else {
4745*4882a593Smuzhiyun 					RTW_ERR("The values in PHY_REG_PG are invalid %s\n", szLine);
4746*4882a593Smuzhiyun 					goto exit;
4747*4882a593Smuzhiyun 				}
4748*4882a593Smuzhiyun 			}
4749*4882a593Smuzhiyun 
4750*4882a593Smuzhiyun 			if (pHalData->odmpriv.phy_reg_pg_version > 0) {
4751*4882a593Smuzhiyun 				u32	index = 0;
4752*4882a593Smuzhiyun 
4753*4882a593Smuzhiyun 				if (strncmp(szLine, "0xffff", 6) == 0)
4754*4882a593Smuzhiyun 					break;
4755*4882a593Smuzhiyun 
4756*4882a593Smuzhiyun 				if (strncmp(szLine, "#[END]#", 7)) {
4757*4882a593Smuzhiyun 					/* load the table label info */
4758*4882a593Smuzhiyun 					if (szLine[0] == '#') {
4759*4882a593Smuzhiyun 						index = 0;
4760*4882a593Smuzhiyun 						if (strncmp(szLine, "#[2.4G]", 7) == 0) {
4761*4882a593Smuzhiyun 							band = BAND_ON_2_4G;
4762*4882a593Smuzhiyun 							index += 8;
4763*4882a593Smuzhiyun 						} else if (strncmp(szLine, "#[5G]", 5) == 0) {
4764*4882a593Smuzhiyun 							band = BAND_ON_5G;
4765*4882a593Smuzhiyun 							index += 6;
4766*4882a593Smuzhiyun 						} else {
4767*4882a593Smuzhiyun 							RTW_ERR("Invalid band %s in PHY_REG_PG.txt\n", szLine);
4768*4882a593Smuzhiyun 							goto exit;
4769*4882a593Smuzhiyun 						}
4770*4882a593Smuzhiyun 
4771*4882a593Smuzhiyun 						rf_path = szLine[index] - 'A';
4772*4882a593Smuzhiyun 						if (DBG_TXPWR_BY_RATE_FILE_PARSE)
4773*4882a593Smuzhiyun 							RTW_INFO(" Table label Band %d, RfPath %d\n", band, rf_path );
4774*4882a593Smuzhiyun 					} else { /* load rows of tables */
4775*4882a593Smuzhiyun 						if (szLine[1] == '1')
4776*4882a593Smuzhiyun 							tx_num = RF_1TX;
4777*4882a593Smuzhiyun 						else if (szLine[1] == '2')
4778*4882a593Smuzhiyun 							tx_num = RF_2TX;
4779*4882a593Smuzhiyun 						else if (szLine[1] == '3')
4780*4882a593Smuzhiyun 							tx_num = RF_3TX;
4781*4882a593Smuzhiyun 						else if (szLine[1] == '4')
4782*4882a593Smuzhiyun 							tx_num = RF_4TX;
4783*4882a593Smuzhiyun 						else {
4784*4882a593Smuzhiyun 							RTW_ERR("Invalid row in PHY_REG_PG.txt '%c'(%d)\n", szLine[1], szLine[1]);
4785*4882a593Smuzhiyun 							goto exit;
4786*4882a593Smuzhiyun 						}
4787*4882a593Smuzhiyun 
4788*4882a593Smuzhiyun 						while (szLine[index] != ']')
4789*4882a593Smuzhiyun 							++index;
4790*4882a593Smuzhiyun 						++index;/* skip ] */
4791*4882a593Smuzhiyun 
4792*4882a593Smuzhiyun 						/* Get 2nd hex value as register offset. */
4793*4882a593Smuzhiyun 						szLine += index;
4794*4882a593Smuzhiyun 						if (GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove))
4795*4882a593Smuzhiyun 							szLine += u4bMove;
4796*4882a593Smuzhiyun 						else
4797*4882a593Smuzhiyun 							goto exit;
4798*4882a593Smuzhiyun 
4799*4882a593Smuzhiyun 						/* Get 2nd hex value as register mask. */
4800*4882a593Smuzhiyun 						if (GetHexValueFromString(szLine, &u4bRegMask, &u4bMove))
4801*4882a593Smuzhiyun 							szLine += u4bMove;
4802*4882a593Smuzhiyun 						else
4803*4882a593Smuzhiyun 							goto exit;
4804*4882a593Smuzhiyun 
4805*4882a593Smuzhiyun 						if (pHalData->odmpriv.phy_reg_pg_value_type == PHY_REG_PG_EXACT_VALUE) {
4806*4882a593Smuzhiyun 							u32	combineValue = 0;
4807*4882a593Smuzhiyun 							u8	integer = 0, fraction = 0;
4808*4882a593Smuzhiyun 
4809*4882a593Smuzhiyun 							if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
4810*4882a593Smuzhiyun 								szLine += u4bMove;
4811*4882a593Smuzhiyun 							else
4812*4882a593Smuzhiyun 								goto exit;
4813*4882a593Smuzhiyun 
4814*4882a593Smuzhiyun 							integer *= hal_spec->txgi_pdbm;
4815*4882a593Smuzhiyun 							integer += ((u16)fraction * (u16)hal_spec->txgi_pdbm) / 100;
4816*4882a593Smuzhiyun 							if (pHalData->odmpriv.phy_reg_pg_version == 1)
4817*4882a593Smuzhiyun 								combineValue |= (((integer / 10) << 4) + (integer % 10));
4818*4882a593Smuzhiyun 							else
4819*4882a593Smuzhiyun 								combineValue |= integer;
4820*4882a593Smuzhiyun 
4821*4882a593Smuzhiyun 							if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
4822*4882a593Smuzhiyun 								szLine += u4bMove;
4823*4882a593Smuzhiyun 							else
4824*4882a593Smuzhiyun 								goto exit;
4825*4882a593Smuzhiyun 
4826*4882a593Smuzhiyun 							integer *= hal_spec->txgi_pdbm;
4827*4882a593Smuzhiyun 							integer += ((u16)fraction * (u16)hal_spec->txgi_pdbm) / 100;
4828*4882a593Smuzhiyun 							combineValue <<= 8;
4829*4882a593Smuzhiyun 							if (pHalData->odmpriv.phy_reg_pg_version == 1)
4830*4882a593Smuzhiyun 								combineValue |= (((integer / 10) << 4) + (integer % 10));
4831*4882a593Smuzhiyun 							else
4832*4882a593Smuzhiyun 								combineValue |= integer;
4833*4882a593Smuzhiyun 
4834*4882a593Smuzhiyun 							if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
4835*4882a593Smuzhiyun 								szLine += u4bMove;
4836*4882a593Smuzhiyun 							else
4837*4882a593Smuzhiyun 								goto exit;
4838*4882a593Smuzhiyun 
4839*4882a593Smuzhiyun 							integer *= hal_spec->txgi_pdbm;
4840*4882a593Smuzhiyun 							integer += ((u16)fraction * (u16)hal_spec->txgi_pdbm) / 100;
4841*4882a593Smuzhiyun 							combineValue <<= 8;
4842*4882a593Smuzhiyun 							if (pHalData->odmpriv.phy_reg_pg_version == 1)
4843*4882a593Smuzhiyun 								combineValue |= (((integer / 10) << 4) + (integer % 10));
4844*4882a593Smuzhiyun 							else
4845*4882a593Smuzhiyun 								combineValue |= integer;
4846*4882a593Smuzhiyun 
4847*4882a593Smuzhiyun 							if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
4848*4882a593Smuzhiyun 								szLine += u4bMove;
4849*4882a593Smuzhiyun 							else
4850*4882a593Smuzhiyun 								goto exit;
4851*4882a593Smuzhiyun 
4852*4882a593Smuzhiyun 							integer *= hal_spec->txgi_pdbm;
4853*4882a593Smuzhiyun 							integer += ((u16)fraction * (u16)hal_spec->txgi_pdbm) / 100;
4854*4882a593Smuzhiyun 							combineValue <<= 8;
4855*4882a593Smuzhiyun 							if (pHalData->odmpriv.phy_reg_pg_version == 1)
4856*4882a593Smuzhiyun 								combineValue |= (((integer / 10) << 4) + (integer % 10));
4857*4882a593Smuzhiyun 							else
4858*4882a593Smuzhiyun 								combineValue |= integer;
4859*4882a593Smuzhiyun 
4860*4882a593Smuzhiyun 							phy_store_tx_power_by_rate(Adapter, band, rf_path, tx_num, u4bRegOffset, u4bRegMask, combineValue);
4861*4882a593Smuzhiyun 
4862*4882a593Smuzhiyun 							if (DBG_TXPWR_BY_RATE_FILE_PARSE)
4863*4882a593Smuzhiyun 								RTW_INFO("addr:0x%3x mask:0x%08x %dTx = 0x%08x\n", u4bRegOffset, u4bRegMask, tx_num + 1, combineValue);
4864*4882a593Smuzhiyun 						}
4865*4882a593Smuzhiyun 					}
4866*4882a593Smuzhiyun 				}
4867*4882a593Smuzhiyun 			}
4868*4882a593Smuzhiyun 		}
4869*4882a593Smuzhiyun 	}
4870*4882a593Smuzhiyun 
4871*4882a593Smuzhiyun 	rtStatus = _SUCCESS;
4872*4882a593Smuzhiyun 
4873*4882a593Smuzhiyun exit:
4874*4882a593Smuzhiyun 	RTW_INFO("%s return %d\n", __func__, rtStatus);
4875*4882a593Smuzhiyun 	return rtStatus;
4876*4882a593Smuzhiyun }
4877*4882a593Smuzhiyun 
4878*4882a593Smuzhiyun int
phy_ConfigBBWithPgParaFile(PADAPTER Adapter,const char * pFileName)4879*4882a593Smuzhiyun phy_ConfigBBWithPgParaFile(
4880*4882a593Smuzhiyun 		PADAPTER	Adapter,
4881*4882a593Smuzhiyun 		const char	*pFileName)
4882*4882a593Smuzhiyun {
4883*4882a593Smuzhiyun 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
4884*4882a593Smuzhiyun 	int	rlen = 0, rtStatus = _FAIL;
4885*4882a593Smuzhiyun 
4886*4882a593Smuzhiyun 	if (!(Adapter->registrypriv.load_phy_file & LOAD_BB_PG_PARA_FILE))
4887*4882a593Smuzhiyun 		return rtStatus;
4888*4882a593Smuzhiyun 
4889*4882a593Smuzhiyun 	_rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
4890*4882a593Smuzhiyun 
4891*4882a593Smuzhiyun 	if (pHalData->bb_phy_reg_pg == NULL) {
4892*4882a593Smuzhiyun 		rtw_get_phy_file_path(Adapter, pFileName);
4893*4882a593Smuzhiyun 		if (rtw_readable_file_sz_chk(rtw_phy_para_file_path,
4894*4882a593Smuzhiyun 			MAX_PARA_FILE_BUF_LEN) == _TRUE) {
4895*4882a593Smuzhiyun 			rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
4896*4882a593Smuzhiyun 			if (rlen > 0) {
4897*4882a593Smuzhiyun 				rtStatus = _SUCCESS;
4898*4882a593Smuzhiyun 				pHalData->bb_phy_reg_pg = rtw_zvmalloc(rlen);
4899*4882a593Smuzhiyun 				if (pHalData->bb_phy_reg_pg) {
4900*4882a593Smuzhiyun 					_rtw_memcpy(pHalData->bb_phy_reg_pg, pHalData->para_file_buf, rlen);
4901*4882a593Smuzhiyun 					pHalData->bb_phy_reg_pg_len = rlen;
4902*4882a593Smuzhiyun 				} else
4903*4882a593Smuzhiyun 					RTW_INFO("%s bb_phy_reg_pg alloc fail !\n", __FUNCTION__);
4904*4882a593Smuzhiyun 			}
4905*4882a593Smuzhiyun 		}
4906*4882a593Smuzhiyun 	} else {
4907*4882a593Smuzhiyun 		if ((pHalData->bb_phy_reg_pg_len != 0) && (pHalData->bb_phy_reg_pg != NULL)) {
4908*4882a593Smuzhiyun 			_rtw_memcpy(pHalData->para_file_buf, pHalData->bb_phy_reg_pg, pHalData->bb_phy_reg_pg_len);
4909*4882a593Smuzhiyun 			rtStatus = _SUCCESS;
4910*4882a593Smuzhiyun 		} else
4911*4882a593Smuzhiyun 			RTW_INFO("%s(): Critical Error !!!\n", __FUNCTION__);
4912*4882a593Smuzhiyun 	}
4913*4882a593Smuzhiyun 
4914*4882a593Smuzhiyun 	if (rtStatus == _SUCCESS) {
4915*4882a593Smuzhiyun 		/* RTW_INFO("phy_ConfigBBWithPgParaFile(): read %s ok\n", pFileName); */
4916*4882a593Smuzhiyun 		rtStatus = phy_ParseBBPgParaFile(Adapter, pHalData->para_file_buf);
4917*4882a593Smuzhiyun 	} else
4918*4882a593Smuzhiyun 		RTW_INFO("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
4919*4882a593Smuzhiyun 
4920*4882a593Smuzhiyun 	return rtStatus;
4921*4882a593Smuzhiyun }
4922*4882a593Smuzhiyun 
4923*4882a593Smuzhiyun #if (MP_DRIVER == 1)
4924*4882a593Smuzhiyun 
4925*4882a593Smuzhiyun int
phy_ConfigBBWithMpParaFile(PADAPTER Adapter,char * pFileName)4926*4882a593Smuzhiyun phy_ConfigBBWithMpParaFile(
4927*4882a593Smuzhiyun 		PADAPTER	Adapter,
4928*4882a593Smuzhiyun 		char		*pFileName
4929*4882a593Smuzhiyun )
4930*4882a593Smuzhiyun {
4931*4882a593Smuzhiyun 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
4932*4882a593Smuzhiyun 	int	rlen = 0, rtStatus = _FAIL;
4933*4882a593Smuzhiyun 	char	*szLine, *ptmp;
4934*4882a593Smuzhiyun 	u32	u4bRegOffset, u4bRegValue, u4bMove;
4935*4882a593Smuzhiyun 
4936*4882a593Smuzhiyun 	if (!(Adapter->registrypriv.load_phy_file & LOAD_BB_MP_PARA_FILE))
4937*4882a593Smuzhiyun 		return rtStatus;
4938*4882a593Smuzhiyun 
4939*4882a593Smuzhiyun 	_rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
4940*4882a593Smuzhiyun 
4941*4882a593Smuzhiyun 	if ((pHalData->bb_phy_reg_mp_len == 0) && (pHalData->bb_phy_reg_mp == NULL)) {
4942*4882a593Smuzhiyun 		rtw_get_phy_file_path(Adapter, pFileName);
4943*4882a593Smuzhiyun 		if (rtw_readable_file_sz_chk(rtw_phy_para_file_path,
4944*4882a593Smuzhiyun 			MAX_PARA_FILE_BUF_LEN) == _TRUE) {
4945*4882a593Smuzhiyun 			rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
4946*4882a593Smuzhiyun 			if (rlen > 0) {
4947*4882a593Smuzhiyun 				rtStatus = _SUCCESS;
4948*4882a593Smuzhiyun 				pHalData->bb_phy_reg_mp = rtw_zvmalloc(rlen);
4949*4882a593Smuzhiyun 				if (pHalData->bb_phy_reg_mp) {
4950*4882a593Smuzhiyun 					_rtw_memcpy(pHalData->bb_phy_reg_mp, pHalData->para_file_buf, rlen);
4951*4882a593Smuzhiyun 					pHalData->bb_phy_reg_mp_len = rlen;
4952*4882a593Smuzhiyun 				} else
4953*4882a593Smuzhiyun 					RTW_INFO("%s bb_phy_reg_mp alloc fail !\n", __FUNCTION__);
4954*4882a593Smuzhiyun 			}
4955*4882a593Smuzhiyun 		}
4956*4882a593Smuzhiyun 	} else {
4957*4882a593Smuzhiyun 		if ((pHalData->bb_phy_reg_mp_len != 0) && (pHalData->bb_phy_reg_mp != NULL)) {
4958*4882a593Smuzhiyun 			_rtw_memcpy(pHalData->para_file_buf, pHalData->bb_phy_reg_mp, pHalData->bb_phy_reg_mp_len);
4959*4882a593Smuzhiyun 			rtStatus = _SUCCESS;
4960*4882a593Smuzhiyun 		} else
4961*4882a593Smuzhiyun 			RTW_INFO("%s(): Critical Error !!!\n", __FUNCTION__);
4962*4882a593Smuzhiyun 	}
4963*4882a593Smuzhiyun 
4964*4882a593Smuzhiyun 	if (rtStatus == _SUCCESS) {
4965*4882a593Smuzhiyun 		/* RTW_INFO("phy_ConfigBBWithMpParaFile(): read %s ok\n", pFileName); */
4966*4882a593Smuzhiyun 
4967*4882a593Smuzhiyun 		ptmp = pHalData->para_file_buf;
4968*4882a593Smuzhiyun 		for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
4969*4882a593Smuzhiyun 			if (!IsCommentString(szLine)) {
4970*4882a593Smuzhiyun 				/* Get 1st hex value as register offset. */
4971*4882a593Smuzhiyun 				if (GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove)) {
4972*4882a593Smuzhiyun 					if (u4bRegOffset == 0xffff) {
4973*4882a593Smuzhiyun 						/* Ending. */
4974*4882a593Smuzhiyun 						break;
4975*4882a593Smuzhiyun 					} else if (u4bRegOffset == 0xfe || u4bRegOffset == 0xffe) {
4976*4882a593Smuzhiyun #ifdef CONFIG_LONG_DELAY_ISSUE
4977*4882a593Smuzhiyun 						rtw_msleep_os(50);
4978*4882a593Smuzhiyun #else
4979*4882a593Smuzhiyun 						rtw_mdelay_os(50);
4980*4882a593Smuzhiyun #endif
4981*4882a593Smuzhiyun 					} else if (u4bRegOffset == 0xfd)
4982*4882a593Smuzhiyun 						rtw_mdelay_os(5);
4983*4882a593Smuzhiyun 					else if (u4bRegOffset == 0xfc)
4984*4882a593Smuzhiyun 						rtw_mdelay_os(1);
4985*4882a593Smuzhiyun 					else if (u4bRegOffset == 0xfb)
4986*4882a593Smuzhiyun 						rtw_udelay_os(50);
4987*4882a593Smuzhiyun 					else if (u4bRegOffset == 0xfa)
4988*4882a593Smuzhiyun 						rtw_udelay_os(5);
4989*4882a593Smuzhiyun 					else if (u4bRegOffset == 0xf9)
4990*4882a593Smuzhiyun 						rtw_udelay_os(1);
4991*4882a593Smuzhiyun 
4992*4882a593Smuzhiyun 					/* Get 2nd hex value as register value. */
4993*4882a593Smuzhiyun 					szLine += u4bMove;
4994*4882a593Smuzhiyun 					if (GetHexValueFromString(szLine, &u4bRegValue, &u4bMove)) {
4995*4882a593Smuzhiyun 						/* RTW_INFO("[ADDR]%03lX=%08lX\n", u4bRegOffset, u4bRegValue); */
4996*4882a593Smuzhiyun 						phy_set_bb_reg(Adapter, u4bRegOffset, bMaskDWord, u4bRegValue);
4997*4882a593Smuzhiyun 
4998*4882a593Smuzhiyun 						/* Add 1us delay between BB/RF register setting. */
4999*4882a593Smuzhiyun 						rtw_udelay_os(1);
5000*4882a593Smuzhiyun 					}
5001*4882a593Smuzhiyun 				}
5002*4882a593Smuzhiyun 			}
5003*4882a593Smuzhiyun 		}
5004*4882a593Smuzhiyun 	} else
5005*4882a593Smuzhiyun 		RTW_INFO("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
5006*4882a593Smuzhiyun 
5007*4882a593Smuzhiyun 	return rtStatus;
5008*4882a593Smuzhiyun }
5009*4882a593Smuzhiyun 
5010*4882a593Smuzhiyun #endif
5011*4882a593Smuzhiyun 
5012*4882a593Smuzhiyun int
PHY_ConfigRFWithParaFile(PADAPTER Adapter,char * pFileName,enum rf_path eRFPath)5013*4882a593Smuzhiyun PHY_ConfigRFWithParaFile(
5014*4882a593Smuzhiyun 		PADAPTER	Adapter,
5015*4882a593Smuzhiyun 		char		*pFileName,
5016*4882a593Smuzhiyun 		enum rf_path		eRFPath
5017*4882a593Smuzhiyun )
5018*4882a593Smuzhiyun {
5019*4882a593Smuzhiyun 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
5020*4882a593Smuzhiyun 	int	rlen = 0, rtStatus = _FAIL;
5021*4882a593Smuzhiyun 	char	*szLine, *ptmp;
5022*4882a593Smuzhiyun 	u32	u4bRegOffset, u4bRegValue, u4bMove;
5023*4882a593Smuzhiyun 	u16	i;
5024*4882a593Smuzhiyun 	char	*pBuf = NULL;
5025*4882a593Smuzhiyun 	u32	*pBufLen = NULL;
5026*4882a593Smuzhiyun 
5027*4882a593Smuzhiyun 	if (!(Adapter->registrypriv.load_phy_file & LOAD_RF_PARA_FILE))
5028*4882a593Smuzhiyun 		return rtStatus;
5029*4882a593Smuzhiyun 
5030*4882a593Smuzhiyun 	switch (eRFPath) {
5031*4882a593Smuzhiyun 	case RF_PATH_A:
5032*4882a593Smuzhiyun 		pBuf = pHalData->rf_radio_a;
5033*4882a593Smuzhiyun 		pBufLen = &pHalData->rf_radio_a_len;
5034*4882a593Smuzhiyun 		break;
5035*4882a593Smuzhiyun 	case RF_PATH_B:
5036*4882a593Smuzhiyun 		pBuf = pHalData->rf_radio_b;
5037*4882a593Smuzhiyun 		pBufLen = &pHalData->rf_radio_b_len;
5038*4882a593Smuzhiyun 		break;
5039*4882a593Smuzhiyun 	default:
5040*4882a593Smuzhiyun 		RTW_INFO("Unknown RF path!! %d\r\n", eRFPath);
5041*4882a593Smuzhiyun 		break;
5042*4882a593Smuzhiyun 	}
5043*4882a593Smuzhiyun 
5044*4882a593Smuzhiyun 	_rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
5045*4882a593Smuzhiyun 
5046*4882a593Smuzhiyun 	if ((pBufLen != NULL) && (*pBufLen == 0) && (pBuf == NULL)) {
5047*4882a593Smuzhiyun 		rtw_get_phy_file_path(Adapter, pFileName);
5048*4882a593Smuzhiyun 		if (rtw_readable_file_sz_chk(rtw_phy_para_file_path,
5049*4882a593Smuzhiyun 			MAX_PARA_FILE_BUF_LEN) == _TRUE) {
5050*4882a593Smuzhiyun 			rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
5051*4882a593Smuzhiyun 			if (rlen > 0) {
5052*4882a593Smuzhiyun 				rtStatus = _SUCCESS;
5053*4882a593Smuzhiyun 				pBuf = rtw_zvmalloc(rlen);
5054*4882a593Smuzhiyun 				if (pBuf) {
5055*4882a593Smuzhiyun 					_rtw_memcpy(pBuf, pHalData->para_file_buf, rlen);
5056*4882a593Smuzhiyun 					*pBufLen = rlen;
5057*4882a593Smuzhiyun 
5058*4882a593Smuzhiyun 					switch (eRFPath) {
5059*4882a593Smuzhiyun 					case RF_PATH_A:
5060*4882a593Smuzhiyun 						pHalData->rf_radio_a = pBuf;
5061*4882a593Smuzhiyun 						break;
5062*4882a593Smuzhiyun 					case RF_PATH_B:
5063*4882a593Smuzhiyun 						pHalData->rf_radio_b = pBuf;
5064*4882a593Smuzhiyun 						break;
5065*4882a593Smuzhiyun 					default:
5066*4882a593Smuzhiyun 						RTW_INFO("Unknown RF path!! %d\r\n", eRFPath);
5067*4882a593Smuzhiyun 						break;
5068*4882a593Smuzhiyun 					}
5069*4882a593Smuzhiyun 				} else
5070*4882a593Smuzhiyun 					RTW_INFO("%s(): eRFPath=%d  alloc fail !\n", __FUNCTION__, eRFPath);
5071*4882a593Smuzhiyun 			}
5072*4882a593Smuzhiyun 		}
5073*4882a593Smuzhiyun 	} else {
5074*4882a593Smuzhiyun 		if ((pBufLen != NULL) && (*pBufLen != 0) && (pBuf != NULL)) {
5075*4882a593Smuzhiyun 			_rtw_memcpy(pHalData->para_file_buf, pBuf, *pBufLen);
5076*4882a593Smuzhiyun 			rtStatus = _SUCCESS;
5077*4882a593Smuzhiyun 		} else
5078*4882a593Smuzhiyun 			RTW_INFO("%s(): Critical Error !!!\n", __FUNCTION__);
5079*4882a593Smuzhiyun 	}
5080*4882a593Smuzhiyun 
5081*4882a593Smuzhiyun 	if (rtStatus == _SUCCESS) {
5082*4882a593Smuzhiyun 		/* RTW_INFO("%s(): read %s successfully\n", __FUNCTION__, pFileName); */
5083*4882a593Smuzhiyun 
5084*4882a593Smuzhiyun 		ptmp = pHalData->para_file_buf;
5085*4882a593Smuzhiyun 		for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
5086*4882a593Smuzhiyun 			if (!IsCommentString(szLine)) {
5087*4882a593Smuzhiyun 				/* Get 1st hex value as register offset. */
5088*4882a593Smuzhiyun 				if (GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove)) {
5089*4882a593Smuzhiyun 					if (u4bRegOffset == 0xfe || u4bRegOffset == 0xffe) {
5090*4882a593Smuzhiyun 						/* Deay specific ms. Only RF configuration require delay.												 */
5091*4882a593Smuzhiyun #ifdef CONFIG_LONG_DELAY_ISSUE
5092*4882a593Smuzhiyun 						rtw_msleep_os(50);
5093*4882a593Smuzhiyun #else
5094*4882a593Smuzhiyun 						rtw_mdelay_os(50);
5095*4882a593Smuzhiyun #endif
5096*4882a593Smuzhiyun 					} else if (u4bRegOffset == 0xfd) {
5097*4882a593Smuzhiyun 						/* delay_ms(5); */
5098*4882a593Smuzhiyun 						for (i = 0; i < 100; i++)
5099*4882a593Smuzhiyun 							rtw_udelay_os(MAX_STALL_TIME);
5100*4882a593Smuzhiyun 					} else if (u4bRegOffset == 0xfc) {
5101*4882a593Smuzhiyun 						/* delay_ms(1); */
5102*4882a593Smuzhiyun 						for (i = 0; i < 20; i++)
5103*4882a593Smuzhiyun 							rtw_udelay_os(MAX_STALL_TIME);
5104*4882a593Smuzhiyun 					} else if (u4bRegOffset == 0xfb)
5105*4882a593Smuzhiyun 						rtw_udelay_os(50);
5106*4882a593Smuzhiyun 					else if (u4bRegOffset == 0xfa)
5107*4882a593Smuzhiyun 						rtw_udelay_os(5);
5108*4882a593Smuzhiyun 					else if (u4bRegOffset == 0xf9)
5109*4882a593Smuzhiyun 						rtw_udelay_os(1);
5110*4882a593Smuzhiyun 					else if (u4bRegOffset == 0xffff)
5111*4882a593Smuzhiyun 						break;
5112*4882a593Smuzhiyun 
5113*4882a593Smuzhiyun 					/* Get 2nd hex value as register value. */
5114*4882a593Smuzhiyun 					szLine += u4bMove;
5115*4882a593Smuzhiyun 					if (GetHexValueFromString(szLine, &u4bRegValue, &u4bMove)) {
5116*4882a593Smuzhiyun 						phy_set_rf_reg(Adapter, eRFPath, u4bRegOffset, bRFRegOffsetMask, u4bRegValue);
5117*4882a593Smuzhiyun 
5118*4882a593Smuzhiyun 						/* Temp add, for frequency lock, if no delay, that may cause */
5119*4882a593Smuzhiyun 						/* frequency shift, ex: 2412MHz => 2417MHz */
5120*4882a593Smuzhiyun 						/* If frequency shift, the following action may works. */
5121*4882a593Smuzhiyun 						/* Fractional-N table in radio_a.txt */
5122*4882a593Smuzhiyun 						/* 0x2a 0x00001		 */ /* channel 1 */
5123*4882a593Smuzhiyun 						/* 0x2b 0x00808		frequency divider. */
5124*4882a593Smuzhiyun 						/* 0x2b 0x53333 */
5125*4882a593Smuzhiyun 						/* 0x2c 0x0000c */
5126*4882a593Smuzhiyun 						rtw_udelay_os(1);
5127*4882a593Smuzhiyun 					}
5128*4882a593Smuzhiyun 				}
5129*4882a593Smuzhiyun 			}
5130*4882a593Smuzhiyun 		}
5131*4882a593Smuzhiyun 	} else
5132*4882a593Smuzhiyun 		RTW_INFO("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
5133*4882a593Smuzhiyun 
5134*4882a593Smuzhiyun 	return rtStatus;
5135*4882a593Smuzhiyun }
5136*4882a593Smuzhiyun 
5137*4882a593Smuzhiyun void
initDeltaSwingIndexTables(PADAPTER Adapter,char * Band,char * Path,char * Sign,char * Channel,char * Rate,char * Data)5138*4882a593Smuzhiyun initDeltaSwingIndexTables(
5139*4882a593Smuzhiyun 	PADAPTER	Adapter,
5140*4882a593Smuzhiyun 	char		*Band,
5141*4882a593Smuzhiyun 	char		*Path,
5142*4882a593Smuzhiyun 	char		*Sign,
5143*4882a593Smuzhiyun 	char		*Channel,
5144*4882a593Smuzhiyun 	char		*Rate,
5145*4882a593Smuzhiyun 	char		*Data
5146*4882a593Smuzhiyun )
5147*4882a593Smuzhiyun {
5148*4882a593Smuzhiyun #define STR_EQUAL_5G(_band, _path, _sign, _rate, _chnl) \
5149*4882a593Smuzhiyun 	((strcmp(Band, _band) == 0) && (strcmp(Path, _path) == 0) && (strcmp(Sign, _sign) == 0) &&\
5150*4882a593Smuzhiyun 	 (strcmp(Rate, _rate) == 0) && (strcmp(Channel, _chnl) == 0)\
5151*4882a593Smuzhiyun 	)
5152*4882a593Smuzhiyun #define STR_EQUAL_2G(_band, _path, _sign, _rate) \
5153*4882a593Smuzhiyun 	((strcmp(Band, _band) == 0) && (strcmp(Path, _path) == 0) && (strcmp(Sign, _sign) == 0) &&\
5154*4882a593Smuzhiyun 	 (strcmp(Rate, _rate) == 0)\
5155*4882a593Smuzhiyun 	)
5156*4882a593Smuzhiyun 
5157*4882a593Smuzhiyun #define STORE_SWING_TABLE(_array, _iteratedIdx) \
5158*4882a593Smuzhiyun 	do {	\
5159*4882a593Smuzhiyun 	for (token = strsep(&Data, delim); token != NULL; token = strsep(&Data, delim)) {\
5160*4882a593Smuzhiyun 		sscanf(token, "%d", &idx);\
5161*4882a593Smuzhiyun 		_array[_iteratedIdx++] = (u8)idx;\
5162*4882a593Smuzhiyun 	} } while (0)\
5163*4882a593Smuzhiyun 
5164*4882a593Smuzhiyun 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
5165*4882a593Smuzhiyun 	struct dm_struct		*pDM_Odm = &pHalData->odmpriv;
5166*4882a593Smuzhiyun 	struct dm_rf_calibration_struct	*pRFCalibrateInfo = &(pDM_Odm->rf_calibrate_info);
5167*4882a593Smuzhiyun 	u32	j = 0;
5168*4882a593Smuzhiyun 	char	*token;
5169*4882a593Smuzhiyun 	char	delim[] = ",";
5170*4882a593Smuzhiyun 	u32	idx = 0;
5171*4882a593Smuzhiyun 
5172*4882a593Smuzhiyun 	/* RTW_INFO("===>initDeltaSwingIndexTables(): Band: %s;\nPath: %s;\nSign: %s;\nChannel: %s;\nRate: %s;\n, Data: %s;\n",  */
5173*4882a593Smuzhiyun 	/*	Band, Path, Sign, Channel, Rate, Data); */
5174*4882a593Smuzhiyun 
5175*4882a593Smuzhiyun 	if (STR_EQUAL_2G("2G", "A", "+", "CCK"))
5176*4882a593Smuzhiyun 		STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2g_cck_a_p, j);
5177*4882a593Smuzhiyun 	else if (STR_EQUAL_2G("2G", "A", "-", "CCK"))
5178*4882a593Smuzhiyun 		STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2g_cck_a_n, j);
5179*4882a593Smuzhiyun 	else if (STR_EQUAL_2G("2G", "B", "+", "CCK"))
5180*4882a593Smuzhiyun 		STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2g_cck_b_p, j);
5181*4882a593Smuzhiyun 	else if (STR_EQUAL_2G("2G", "B", "-", "CCK"))
5182*4882a593Smuzhiyun 		STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2g_cck_b_n, j);
5183*4882a593Smuzhiyun 	else if (STR_EQUAL_2G("2G", "A", "+", "ALL"))
5184*4882a593Smuzhiyun 		STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2ga_p, j);
5185*4882a593Smuzhiyun 	else if (STR_EQUAL_2G("2G", "A", "-", "ALL"))
5186*4882a593Smuzhiyun 		STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2ga_n, j);
5187*4882a593Smuzhiyun 	else if (STR_EQUAL_2G("2G", "B", "+", "ALL"))
5188*4882a593Smuzhiyun 		STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2gb_p, j);
5189*4882a593Smuzhiyun 	else if (STR_EQUAL_2G("2G", "B", "-", "ALL"))
5190*4882a593Smuzhiyun 		STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2gb_n, j);
5191*4882a593Smuzhiyun 	else if (STR_EQUAL_5G("5G", "A", "+", "ALL", "0"))
5192*4882a593Smuzhiyun 		STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_p[0], j);
5193*4882a593Smuzhiyun 	else if (STR_EQUAL_5G("5G", "A", "-", "ALL", "0"))
5194*4882a593Smuzhiyun 		STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_n[0], j);
5195*4882a593Smuzhiyun 	else if (STR_EQUAL_5G("5G", "B", "+", "ALL", "0"))
5196*4882a593Smuzhiyun 		STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_p[0], j);
5197*4882a593Smuzhiyun 	else if (STR_EQUAL_5G("5G", "B", "-", "ALL", "0"))
5198*4882a593Smuzhiyun 		STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_n[0], j);
5199*4882a593Smuzhiyun 	else if (STR_EQUAL_5G("5G", "A", "+", "ALL", "1"))
5200*4882a593Smuzhiyun 		STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_p[1], j);
5201*4882a593Smuzhiyun 	else if (STR_EQUAL_5G("5G", "A", "-", "ALL", "1"))
5202*4882a593Smuzhiyun 		STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_n[1], j);
5203*4882a593Smuzhiyun 	else if (STR_EQUAL_5G("5G", "B", "+", "ALL", "1"))
5204*4882a593Smuzhiyun 		STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_p[1], j);
5205*4882a593Smuzhiyun 	else if (STR_EQUAL_5G("5G", "B", "-", "ALL", "1"))
5206*4882a593Smuzhiyun 		STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_n[1], j);
5207*4882a593Smuzhiyun 	else if (STR_EQUAL_5G("5G", "A", "+", "ALL", "2"))
5208*4882a593Smuzhiyun 		STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_p[2], j);
5209*4882a593Smuzhiyun 	else if (STR_EQUAL_5G("5G", "A", "-", "ALL", "2"))
5210*4882a593Smuzhiyun 		STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_n[2], j);
5211*4882a593Smuzhiyun 	else if (STR_EQUAL_5G("5G", "B", "+", "ALL", "2"))
5212*4882a593Smuzhiyun 		STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_p[2], j);
5213*4882a593Smuzhiyun 	else if (STR_EQUAL_5G("5G", "B", "-", "ALL", "2"))
5214*4882a593Smuzhiyun 		STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_n[2], j);
5215*4882a593Smuzhiyun 	else if (STR_EQUAL_5G("5G", "A", "+", "ALL", "3"))
5216*4882a593Smuzhiyun 		STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_p[3], j);
5217*4882a593Smuzhiyun 	else if (STR_EQUAL_5G("5G", "A", "-", "ALL", "3"))
5218*4882a593Smuzhiyun 		STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_n[3], j);
5219*4882a593Smuzhiyun 	else if (STR_EQUAL_5G("5G", "B", "+", "ALL", "3"))
5220*4882a593Smuzhiyun 		STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_p[3], j);
5221*4882a593Smuzhiyun 	else if (STR_EQUAL_5G("5G", "B", "-", "ALL", "3"))
5222*4882a593Smuzhiyun 		STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_n[3], j);
5223*4882a593Smuzhiyun 	else
5224*4882a593Smuzhiyun 		RTW_INFO("===>initDeltaSwingIndexTables(): The input is invalid!!\n");
5225*4882a593Smuzhiyun }
5226*4882a593Smuzhiyun 
5227*4882a593Smuzhiyun int
PHY_ConfigRFWithTxPwrTrackParaFile(PADAPTER Adapter,char * pFileName)5228*4882a593Smuzhiyun PHY_ConfigRFWithTxPwrTrackParaFile(
5229*4882a593Smuzhiyun 		PADAPTER		Adapter,
5230*4882a593Smuzhiyun 		char			*pFileName
5231*4882a593Smuzhiyun )
5232*4882a593Smuzhiyun {
5233*4882a593Smuzhiyun 	HAL_DATA_TYPE		*pHalData = GET_HAL_DATA(Adapter);
5234*4882a593Smuzhiyun 	struct dm_struct			*pDM_Odm = &pHalData->odmpriv;
5235*4882a593Smuzhiyun 	int	rlen = 0, rtStatus = _FAIL;
5236*4882a593Smuzhiyun 	char	*szLine, *ptmp;
5237*4882a593Smuzhiyun 	u32	i = 0;
5238*4882a593Smuzhiyun 
5239*4882a593Smuzhiyun 	if (!(Adapter->registrypriv.load_phy_file & LOAD_RF_TXPWR_TRACK_PARA_FILE))
5240*4882a593Smuzhiyun 		return rtStatus;
5241*4882a593Smuzhiyun 
5242*4882a593Smuzhiyun 	_rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
5243*4882a593Smuzhiyun 
5244*4882a593Smuzhiyun 	if ((pHalData->rf_tx_pwr_track_len == 0) && (pHalData->rf_tx_pwr_track == NULL)) {
5245*4882a593Smuzhiyun 		rtw_get_phy_file_path(Adapter, pFileName);
5246*4882a593Smuzhiyun 		if (rtw_readable_file_sz_chk(rtw_phy_para_file_path,
5247*4882a593Smuzhiyun 			MAX_PARA_FILE_BUF_LEN) == _TRUE) {
5248*4882a593Smuzhiyun 			rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
5249*4882a593Smuzhiyun 			if (rlen > 0) {
5250*4882a593Smuzhiyun 				rtStatus = _SUCCESS;
5251*4882a593Smuzhiyun 				pHalData->rf_tx_pwr_track = rtw_zvmalloc(rlen);
5252*4882a593Smuzhiyun 				if (pHalData->rf_tx_pwr_track) {
5253*4882a593Smuzhiyun 					_rtw_memcpy(pHalData->rf_tx_pwr_track, pHalData->para_file_buf, rlen);
5254*4882a593Smuzhiyun 					pHalData->rf_tx_pwr_track_len = rlen;
5255*4882a593Smuzhiyun 				} else
5256*4882a593Smuzhiyun 					RTW_INFO("%s rf_tx_pwr_track alloc fail !\n", __FUNCTION__);
5257*4882a593Smuzhiyun 			}
5258*4882a593Smuzhiyun 		}
5259*4882a593Smuzhiyun 	} else {
5260*4882a593Smuzhiyun 		if ((pHalData->rf_tx_pwr_track_len != 0) && (pHalData->rf_tx_pwr_track != NULL)) {
5261*4882a593Smuzhiyun 			_rtw_memcpy(pHalData->para_file_buf, pHalData->rf_tx_pwr_track, pHalData->rf_tx_pwr_track_len);
5262*4882a593Smuzhiyun 			rtStatus = _SUCCESS;
5263*4882a593Smuzhiyun 		} else
5264*4882a593Smuzhiyun 			RTW_INFO("%s(): Critical Error !!!\n", __FUNCTION__);
5265*4882a593Smuzhiyun 	}
5266*4882a593Smuzhiyun 
5267*4882a593Smuzhiyun 	if (rtStatus == _SUCCESS) {
5268*4882a593Smuzhiyun 		/* RTW_INFO("%s(): read %s successfully\n", __FUNCTION__, pFileName); */
5269*4882a593Smuzhiyun 
5270*4882a593Smuzhiyun 		ptmp = pHalData->para_file_buf;
5271*4882a593Smuzhiyun 		for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
5272*4882a593Smuzhiyun 			if (!IsCommentString(szLine)) {
5273*4882a593Smuzhiyun 				char	band[5] = "", path[5] = "", sign[5]  = "";
5274*4882a593Smuzhiyun 				char	chnl[5] = "", rate[10] = "";
5275*4882a593Smuzhiyun 				char	data[300] = ""; /* 100 is too small */
5276*4882a593Smuzhiyun 
5277*4882a593Smuzhiyun 				if (strlen(szLine) < 10 || szLine[0] != '[')
5278*4882a593Smuzhiyun 					continue;
5279*4882a593Smuzhiyun 
5280*4882a593Smuzhiyun 				strncpy(band, szLine + 1, 2);
5281*4882a593Smuzhiyun 				strncpy(path, szLine + 5, 1);
5282*4882a593Smuzhiyun 				strncpy(sign, szLine + 8, 1);
5283*4882a593Smuzhiyun 
5284*4882a593Smuzhiyun 				i = 10; /* szLine+10 */
5285*4882a593Smuzhiyun 				if (!ParseQualifiedString(szLine, &i, rate, '[', ']')) {
5286*4882a593Smuzhiyun 					/* RTW_INFO("Fail to parse rate!\n"); */
5287*4882a593Smuzhiyun 				}
5288*4882a593Smuzhiyun 				if (!ParseQualifiedString(szLine, &i, chnl, '[', ']')) {
5289*4882a593Smuzhiyun 					/* RTW_INFO("Fail to parse channel group!\n"); */
5290*4882a593Smuzhiyun 				}
5291*4882a593Smuzhiyun 				while (szLine[i] != '{' && i < strlen(szLine))
5292*4882a593Smuzhiyun 					i++;
5293*4882a593Smuzhiyun 				if (!ParseQualifiedString(szLine, &i, data, '{', '}')) {
5294*4882a593Smuzhiyun 					/* RTW_INFO("Fail to parse data!\n"); */
5295*4882a593Smuzhiyun 				}
5296*4882a593Smuzhiyun 
5297*4882a593Smuzhiyun 				initDeltaSwingIndexTables(Adapter, band, path, sign, chnl, rate, data);
5298*4882a593Smuzhiyun 			}
5299*4882a593Smuzhiyun 		}
5300*4882a593Smuzhiyun 	} else
5301*4882a593Smuzhiyun 		RTW_INFO("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
5302*4882a593Smuzhiyun #if 0
5303*4882a593Smuzhiyun 	for (i = 0; i < DELTA_SWINGIDX_SIZE; ++i) {
5304*4882a593Smuzhiyun 		RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_2ga_p[%d] = %d\n", i, pRFCalibrateInfo->delta_swing_table_idx_2ga_p[i]);
5305*4882a593Smuzhiyun 		RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_2ga_n[%d] = %d\n", i, pRFCalibrateInfo->delta_swing_table_idx_2ga_n[i]);
5306*4882a593Smuzhiyun 		RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_2gb_p[%d] = %d\n", i, pRFCalibrateInfo->delta_swing_table_idx_2gb_p[i]);
5307*4882a593Smuzhiyun 		RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_2gb_n[%d] = %d\n", i, pRFCalibrateInfo->delta_swing_table_idx_2gb_n[i]);
5308*4882a593Smuzhiyun 		RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_2g_cck_a_p[%d] = %d\n", i, pRFCalibrateInfo->delta_swing_table_idx_2g_cck_a_p[i]);
5309*4882a593Smuzhiyun 		RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_2g_cck_a_n[%d] = %d\n", i, pRFCalibrateInfo->delta_swing_table_idx_2g_cck_a_n[i]);
5310*4882a593Smuzhiyun 		RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_2g_cck_b_p[%d] = %d\n", i, pRFCalibrateInfo->delta_swing_table_idx_2g_cck_b_p[i]);
5311*4882a593Smuzhiyun 		RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_2g_cck_b_n[%d] = %d\n", i, pRFCalibrateInfo->delta_swing_table_idx_2g_cck_b_n[i]);
5312*4882a593Smuzhiyun 
5313*4882a593Smuzhiyun 		for (j = 0; j < 3; ++j) {
5314*4882a593Smuzhiyun 			RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_5ga_p[%d][%d] = %d\n", j, i, pRFCalibrateInfo->delta_swing_table_idx_5ga_p[j][i]);
5315*4882a593Smuzhiyun 			RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_5ga_n[%d][%d] = %d\n", j, i, pRFCalibrateInfo->delta_swing_table_idx_5ga_n[j][i]);
5316*4882a593Smuzhiyun 			RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_5gb_p[%d][%d] = %d\n", j, i, pRFCalibrateInfo->delta_swing_table_idx_5gb_p[j][i]);
5317*4882a593Smuzhiyun 			RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_5gb_n[%d][%d] = %d\n", j, i, pRFCalibrateInfo->delta_swing_table_idx_5gb_n[j][i]);
5318*4882a593Smuzhiyun 		}
5319*4882a593Smuzhiyun 	}
5320*4882a593Smuzhiyun #endif
5321*4882a593Smuzhiyun 	return rtStatus;
5322*4882a593Smuzhiyun }
5323*4882a593Smuzhiyun 
5324*4882a593Smuzhiyun #if CONFIG_TXPWR_LIMIT
5325*4882a593Smuzhiyun 
5326*4882a593Smuzhiyun #ifndef DBG_TXPWR_LMT_FILE_PARSE
5327*4882a593Smuzhiyun #define DBG_TXPWR_LMT_FILE_PARSE 0
5328*4882a593Smuzhiyun #endif
5329*4882a593Smuzhiyun 
5330*4882a593Smuzhiyun #define PARSE_RET_NO_HDL	0
5331*4882a593Smuzhiyun #define PARSE_RET_SUCCESS	1
5332*4882a593Smuzhiyun #define PARSE_RET_FAIL		2
5333*4882a593Smuzhiyun 
5334*4882a593Smuzhiyun /*
5335*4882a593Smuzhiyun * @@Ver=2.0
5336*4882a593Smuzhiyun * or
5337*4882a593Smuzhiyun * @@DomainCode=0x28, Regulation=C6
5338*4882a593Smuzhiyun * or
5339*4882a593Smuzhiyun * @@CountryCode=GB, Regulation=C7
5340*4882a593Smuzhiyun */
parse_reg_exc_config(_adapter * adapter,char * szLine)5341*4882a593Smuzhiyun static u8 parse_reg_exc_config(_adapter *adapter, char *szLine)
5342*4882a593Smuzhiyun {
5343*4882a593Smuzhiyun #define VER_PREFIX "Ver="
5344*4882a593Smuzhiyun #define DOMAIN_PREFIX "DomainCode=0x"
5345*4882a593Smuzhiyun #define COUNTRY_PREFIX "CountryCode="
5346*4882a593Smuzhiyun #define REG_PREFIX "Regulation="
5347*4882a593Smuzhiyun 
5348*4882a593Smuzhiyun 	const u8 ver_prefix_len = strlen(VER_PREFIX);
5349*4882a593Smuzhiyun 	const u8 domain_prefix_len = strlen(DOMAIN_PREFIX);
5350*4882a593Smuzhiyun 	const u8 country_prefix_len = strlen(COUNTRY_PREFIX);
5351*4882a593Smuzhiyun 	const u8 reg_prefix_len = strlen(REG_PREFIX);
5352*4882a593Smuzhiyun 	u32 i, i_val_s, i_val_e;
5353*4882a593Smuzhiyun 	u32 j;
5354*4882a593Smuzhiyun 	u8 domain = 0xFF;
5355*4882a593Smuzhiyun 	char *country = NULL;
5356*4882a593Smuzhiyun 	u8 parse_reg = 0;
5357*4882a593Smuzhiyun 
5358*4882a593Smuzhiyun 	if (szLine[0] != '@' || szLine[1] != '@')
5359*4882a593Smuzhiyun 		return PARSE_RET_NO_HDL;
5360*4882a593Smuzhiyun 
5361*4882a593Smuzhiyun 	i = 2;
5362*4882a593Smuzhiyun 	if (strncmp(szLine + i, VER_PREFIX, ver_prefix_len) == 0)
5363*4882a593Smuzhiyun 		; /* nothing to do */
5364*4882a593Smuzhiyun 	else if (strncmp(szLine + i, DOMAIN_PREFIX, domain_prefix_len) == 0) {
5365*4882a593Smuzhiyun 		/* get string after domain prefix to ',' */
5366*4882a593Smuzhiyun 		i += domain_prefix_len;
5367*4882a593Smuzhiyun 		i_val_s = i;
5368*4882a593Smuzhiyun 		while (szLine[i] != ',') {
5369*4882a593Smuzhiyun 			if (szLine[i] == '\0')
5370*4882a593Smuzhiyun 				return PARSE_RET_FAIL;
5371*4882a593Smuzhiyun 			i++;
5372*4882a593Smuzhiyun 		}
5373*4882a593Smuzhiyun 		i_val_e = i;
5374*4882a593Smuzhiyun 
5375*4882a593Smuzhiyun 		/* check if all hex */
5376*4882a593Smuzhiyun 		for (j = i_val_s; j < i_val_e; j++)
5377*4882a593Smuzhiyun 			if (IsHexDigit(szLine[j]) == _FALSE)
5378*4882a593Smuzhiyun 				return PARSE_RET_FAIL;
5379*4882a593Smuzhiyun 
5380*4882a593Smuzhiyun 		/* get value from hex string */
5381*4882a593Smuzhiyun 		if (sscanf(szLine + i_val_s, "%hhx", &domain) != 1)
5382*4882a593Smuzhiyun 			return PARSE_RET_FAIL;
5383*4882a593Smuzhiyun 
5384*4882a593Smuzhiyun 		parse_reg = 1;
5385*4882a593Smuzhiyun 	} else if (strncmp(szLine + i, COUNTRY_PREFIX, country_prefix_len) == 0) {
5386*4882a593Smuzhiyun 		/* get string after country prefix to ',' */
5387*4882a593Smuzhiyun 		i += country_prefix_len;
5388*4882a593Smuzhiyun 		i_val_s = i;
5389*4882a593Smuzhiyun 		while (szLine[i] != ',') {
5390*4882a593Smuzhiyun 			if (szLine[i] == '\0')
5391*4882a593Smuzhiyun 				return PARSE_RET_FAIL;
5392*4882a593Smuzhiyun 			i++;
5393*4882a593Smuzhiyun 		}
5394*4882a593Smuzhiyun 		i_val_e = i;
5395*4882a593Smuzhiyun 
5396*4882a593Smuzhiyun 		if (i_val_e - i_val_s != 2)
5397*4882a593Smuzhiyun 			return PARSE_RET_FAIL;
5398*4882a593Smuzhiyun 
5399*4882a593Smuzhiyun 		/* check if all alpha */
5400*4882a593Smuzhiyun 		for (j = i_val_s; j < i_val_e; j++)
5401*4882a593Smuzhiyun 			if (is_alpha(szLine[j]) == _FALSE)
5402*4882a593Smuzhiyun 				return PARSE_RET_FAIL;
5403*4882a593Smuzhiyun 
5404*4882a593Smuzhiyun 		country = szLine + i_val_s;
5405*4882a593Smuzhiyun 
5406*4882a593Smuzhiyun 		parse_reg = 1;
5407*4882a593Smuzhiyun 
5408*4882a593Smuzhiyun 	} else
5409*4882a593Smuzhiyun 		return PARSE_RET_FAIL;
5410*4882a593Smuzhiyun 
5411*4882a593Smuzhiyun 	if (parse_reg) {
5412*4882a593Smuzhiyun 		/* move to 'R' */
5413*4882a593Smuzhiyun 		while (szLine[i] != 'R') {
5414*4882a593Smuzhiyun 			if (szLine[i] == '\0')
5415*4882a593Smuzhiyun 				return PARSE_RET_FAIL;
5416*4882a593Smuzhiyun 			i++;
5417*4882a593Smuzhiyun 		}
5418*4882a593Smuzhiyun 
5419*4882a593Smuzhiyun 		/* check if matching regulation prefix */
5420*4882a593Smuzhiyun 		if (strncmp(szLine + i, REG_PREFIX, reg_prefix_len) != 0)
5421*4882a593Smuzhiyun 			return PARSE_RET_FAIL;
5422*4882a593Smuzhiyun 
5423*4882a593Smuzhiyun 		/* get string after regulation prefix ending with space */
5424*4882a593Smuzhiyun 		i += reg_prefix_len;
5425*4882a593Smuzhiyun 		i_val_s = i;
5426*4882a593Smuzhiyun 		while (szLine[i] != ' ' && szLine[i] != '\t' && szLine[i] != '\0')
5427*4882a593Smuzhiyun 			i++;
5428*4882a593Smuzhiyun 
5429*4882a593Smuzhiyun 		if (i == i_val_s)
5430*4882a593Smuzhiyun 			return PARSE_RET_FAIL;
5431*4882a593Smuzhiyun 
5432*4882a593Smuzhiyun 		rtw_regd_exc_add_with_nlen(adapter_to_rfctl(adapter), country, domain, szLine + i_val_s, i - i_val_s);
5433*4882a593Smuzhiyun 	}
5434*4882a593Smuzhiyun 
5435*4882a593Smuzhiyun 	return PARSE_RET_SUCCESS;
5436*4882a593Smuzhiyun }
5437*4882a593Smuzhiyun 
5438*4882a593Smuzhiyun static int
phy_ParsePowerLimitTableFile(PADAPTER Adapter,char * buffer)5439*4882a593Smuzhiyun phy_ParsePowerLimitTableFile(
5440*4882a593Smuzhiyun 	PADAPTER		Adapter,
5441*4882a593Smuzhiyun 	char			*buffer
5442*4882a593Smuzhiyun )
5443*4882a593Smuzhiyun {
5444*4882a593Smuzhiyun #define LD_STAGE_EXC_MAPPING	0
5445*4882a593Smuzhiyun #define LD_STAGE_TAB_DEFINE		1
5446*4882a593Smuzhiyun #define LD_STAGE_TAB_START		2
5447*4882a593Smuzhiyun #define LD_STAGE_COLUMN_DEFINE	3
5448*4882a593Smuzhiyun #define LD_STAGE_CH_ROW			4
5449*4882a593Smuzhiyun 
5450*4882a593Smuzhiyun 	int	rtStatus = _FAIL;
5451*4882a593Smuzhiyun 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
5452*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(Adapter);
5453*4882a593Smuzhiyun 	struct dm_struct	*pDM_Odm = &(pHalData->odmpriv);
5454*4882a593Smuzhiyun 	u8	loadingStage = LD_STAGE_EXC_MAPPING;
5455*4882a593Smuzhiyun 	u32	i = 0, forCnt = 0;
5456*4882a593Smuzhiyun 	char	*szLine, *ptmp;
5457*4882a593Smuzhiyun 	char band[10], bandwidth[10], rateSection[10], ntx[10], colNumBuf[10];
5458*4882a593Smuzhiyun 	char **regulation = NULL;
5459*4882a593Smuzhiyun 	u8	colNum = 0;
5460*4882a593Smuzhiyun 
5461*4882a593Smuzhiyun 	if (Adapter->registrypriv.RegDecryptCustomFile == 1)
5462*4882a593Smuzhiyun 		phy_DecryptBBPgParaFile(Adapter, buffer);
5463*4882a593Smuzhiyun 
5464*4882a593Smuzhiyun 	ptmp = buffer;
5465*4882a593Smuzhiyun 	for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
5466*4882a593Smuzhiyun 		if (isAllSpaceOrTab(szLine, sizeof(*szLine)))
5467*4882a593Smuzhiyun 			continue;
5468*4882a593Smuzhiyun 		if (IsCommentString(szLine))
5469*4882a593Smuzhiyun 			continue;
5470*4882a593Smuzhiyun 
5471*4882a593Smuzhiyun 		if (loadingStage == LD_STAGE_EXC_MAPPING) {
5472*4882a593Smuzhiyun 			if (szLine[0] == '#' || szLine[1] == '#') {
5473*4882a593Smuzhiyun 				loadingStage = LD_STAGE_TAB_DEFINE;
5474*4882a593Smuzhiyun 				if (DBG_TXPWR_LMT_FILE_PARSE)
5475*4882a593Smuzhiyun 					dump_regd_exc_list(RTW_DBGDUMP, adapter_to_rfctl(Adapter));
5476*4882a593Smuzhiyun 			} else {
5477*4882a593Smuzhiyun 				if (parse_reg_exc_config(Adapter, szLine) == PARSE_RET_FAIL) {
5478*4882a593Smuzhiyun 					RTW_ERR("Fail to parse regulation exception ruls!\n");
5479*4882a593Smuzhiyun 					goto exit;
5480*4882a593Smuzhiyun 				}
5481*4882a593Smuzhiyun 				continue;
5482*4882a593Smuzhiyun 			}
5483*4882a593Smuzhiyun 		}
5484*4882a593Smuzhiyun 
5485*4882a593Smuzhiyun 		if (loadingStage == LD_STAGE_TAB_DEFINE) {
5486*4882a593Smuzhiyun 			/* read "##	2.4G, 20M, 1T, CCK" */
5487*4882a593Smuzhiyun 			if (szLine[0] != '#' || szLine[1] != '#')
5488*4882a593Smuzhiyun 				continue;
5489*4882a593Smuzhiyun 
5490*4882a593Smuzhiyun 			/* skip the space */
5491*4882a593Smuzhiyun 			i = 2;
5492*4882a593Smuzhiyun 			while (szLine[i] == ' ' || szLine[i] == '\t')
5493*4882a593Smuzhiyun 				++i;
5494*4882a593Smuzhiyun 
5495*4882a593Smuzhiyun 			szLine[--i] = ' '; /* return the space in front of the regulation info */
5496*4882a593Smuzhiyun 
5497*4882a593Smuzhiyun 			/* Parse the label of the table */
5498*4882a593Smuzhiyun 			_rtw_memset((void *) band, 0, 10);
5499*4882a593Smuzhiyun 			_rtw_memset((void *) bandwidth, 0, 10);
5500*4882a593Smuzhiyun 			_rtw_memset((void *) ntx, 0, 10);
5501*4882a593Smuzhiyun 			_rtw_memset((void *) rateSection, 0, 10);
5502*4882a593Smuzhiyun 			if (!ParseQualifiedString(szLine, &i, band, ' ', ',')) {
5503*4882a593Smuzhiyun 				RTW_ERR("Fail to parse band!\n");
5504*4882a593Smuzhiyun 				goto exit;
5505*4882a593Smuzhiyun 			}
5506*4882a593Smuzhiyun 			if (!ParseQualifiedString(szLine, &i, bandwidth, ' ', ',')) {
5507*4882a593Smuzhiyun 				RTW_ERR("Fail to parse bandwidth!\n");
5508*4882a593Smuzhiyun 				goto exit;
5509*4882a593Smuzhiyun 			}
5510*4882a593Smuzhiyun 			if (!ParseQualifiedString(szLine, &i, ntx, ' ', ',')) {
5511*4882a593Smuzhiyun 				RTW_ERR("Fail to parse ntx!\n");
5512*4882a593Smuzhiyun 				goto exit;
5513*4882a593Smuzhiyun 			}
5514*4882a593Smuzhiyun 			if (!ParseQualifiedString(szLine, &i, rateSection, ' ', ',')) {
5515*4882a593Smuzhiyun 				RTW_ERR("Fail to parse rate!\n");
5516*4882a593Smuzhiyun 				goto exit;
5517*4882a593Smuzhiyun 			}
5518*4882a593Smuzhiyun 
5519*4882a593Smuzhiyun 			loadingStage = LD_STAGE_TAB_START;
5520*4882a593Smuzhiyun 		} else if (loadingStage == LD_STAGE_TAB_START) {
5521*4882a593Smuzhiyun 			/* read "##	START" */
5522*4882a593Smuzhiyun 			if (szLine[0] != '#' || szLine[1] != '#')
5523*4882a593Smuzhiyun 				continue;
5524*4882a593Smuzhiyun 
5525*4882a593Smuzhiyun 			/* skip the space */
5526*4882a593Smuzhiyun 			i = 2;
5527*4882a593Smuzhiyun 			while (szLine[i] == ' ' || szLine[i] == '\t')
5528*4882a593Smuzhiyun 				++i;
5529*4882a593Smuzhiyun 
5530*4882a593Smuzhiyun 			if (strncmp((u8 *)(szLine + i), "START", 5)) {
5531*4882a593Smuzhiyun 				RTW_ERR("Missing \"##   START\" label\n");
5532*4882a593Smuzhiyun 				goto exit;
5533*4882a593Smuzhiyun 			}
5534*4882a593Smuzhiyun 
5535*4882a593Smuzhiyun 			loadingStage = LD_STAGE_COLUMN_DEFINE;
5536*4882a593Smuzhiyun 		} else if (loadingStage == LD_STAGE_COLUMN_DEFINE) {
5537*4882a593Smuzhiyun 			/* read "##	#5#	FCC	ETSI	MKK	IC	KCC" */
5538*4882a593Smuzhiyun 			if (szLine[0] != '#' || szLine[1] != '#')
5539*4882a593Smuzhiyun 				continue;
5540*4882a593Smuzhiyun 
5541*4882a593Smuzhiyun 			/* skip the space */
5542*4882a593Smuzhiyun 			i = 2;
5543*4882a593Smuzhiyun 			while (szLine[i] == ' ' || szLine[i] == '\t')
5544*4882a593Smuzhiyun 				++i;
5545*4882a593Smuzhiyun 
5546*4882a593Smuzhiyun 			_rtw_memset((void *) colNumBuf, 0, 10);
5547*4882a593Smuzhiyun 			if (!ParseQualifiedString(szLine, &i, colNumBuf, '#', '#')) {
5548*4882a593Smuzhiyun 				RTW_ERR("Fail to parse column number!\n");
5549*4882a593Smuzhiyun 				goto exit;
5550*4882a593Smuzhiyun 			}
5551*4882a593Smuzhiyun 			if (!GetU1ByteIntegerFromStringInDecimal(colNumBuf, &colNum)) {
5552*4882a593Smuzhiyun 				RTW_ERR("Column number \"%s\" is not unsigned decimal\n", colNumBuf);
5553*4882a593Smuzhiyun 				goto exit;
5554*4882a593Smuzhiyun 			}
5555*4882a593Smuzhiyun 			if (colNum == 0) {
5556*4882a593Smuzhiyun 				RTW_ERR("Column number is 0\n");
5557*4882a593Smuzhiyun 				goto exit;
5558*4882a593Smuzhiyun 			}
5559*4882a593Smuzhiyun 
5560*4882a593Smuzhiyun 			if (DBG_TXPWR_LMT_FILE_PARSE)
5561*4882a593Smuzhiyun 				RTW_PRINT("[%s][%s][%s][%s] column num:%d\n", band, bandwidth, rateSection, ntx, colNum);
5562*4882a593Smuzhiyun 
5563*4882a593Smuzhiyun 			regulation = (char **)rtw_zmalloc(sizeof(char *) * colNum);
5564*4882a593Smuzhiyun 			if (!regulation) {
5565*4882a593Smuzhiyun 				RTW_ERR("Regulation alloc fail\n");
5566*4882a593Smuzhiyun 				goto exit;
5567*4882a593Smuzhiyun 			}
5568*4882a593Smuzhiyun 
5569*4882a593Smuzhiyun 			for (forCnt = 0; forCnt < colNum; ++forCnt) {
5570*4882a593Smuzhiyun 				u32 i_ns;
5571*4882a593Smuzhiyun 
5572*4882a593Smuzhiyun 				/* skip the space */
5573*4882a593Smuzhiyun 				while (szLine[i] == ' ' || szLine[i] == '\t')
5574*4882a593Smuzhiyun 					i++;
5575*4882a593Smuzhiyun 				i_ns = i;
5576*4882a593Smuzhiyun 
5577*4882a593Smuzhiyun 				while (szLine[i] != ' ' && szLine[i] != '\t' && szLine[i] != '\0')
5578*4882a593Smuzhiyun 					i++;
5579*4882a593Smuzhiyun 
5580*4882a593Smuzhiyun 				regulation[forCnt] = (char *)rtw_malloc(i - i_ns + 1);
5581*4882a593Smuzhiyun 				if (!regulation[forCnt]) {
5582*4882a593Smuzhiyun 					RTW_ERR("Regulation alloc fail\n");
5583*4882a593Smuzhiyun 					goto exit;
5584*4882a593Smuzhiyun 				}
5585*4882a593Smuzhiyun 
5586*4882a593Smuzhiyun 				_rtw_memcpy(regulation[forCnt], szLine + i_ns, i - i_ns);
5587*4882a593Smuzhiyun 				regulation[forCnt][i - i_ns] = '\0';
5588*4882a593Smuzhiyun 			}
5589*4882a593Smuzhiyun 
5590*4882a593Smuzhiyun 			if (DBG_TXPWR_LMT_FILE_PARSE) {
5591*4882a593Smuzhiyun 				RTW_PRINT("column name:");
5592*4882a593Smuzhiyun 				for (forCnt = 0; forCnt < colNum; ++forCnt)
5593*4882a593Smuzhiyun 					_RTW_PRINT(" %s", regulation[forCnt]);
5594*4882a593Smuzhiyun 				_RTW_PRINT("\n");
5595*4882a593Smuzhiyun 			}
5596*4882a593Smuzhiyun 
5597*4882a593Smuzhiyun 			loadingStage = LD_STAGE_CH_ROW;
5598*4882a593Smuzhiyun 		} else if (loadingStage == LD_STAGE_CH_ROW) {
5599*4882a593Smuzhiyun 			char	channel[10] = {0}, powerLimit[10] = {0};
5600*4882a593Smuzhiyun 			u8	cnt = 0;
5601*4882a593Smuzhiyun 
5602*4882a593Smuzhiyun 			/* the table ends */
5603*4882a593Smuzhiyun 			if (szLine[0] == '#' && szLine[1] == '#') {
5604*4882a593Smuzhiyun 				i = 2;
5605*4882a593Smuzhiyun 				while (szLine[i] == ' ' || szLine[i] == '\t')
5606*4882a593Smuzhiyun 					++i;
5607*4882a593Smuzhiyun 
5608*4882a593Smuzhiyun 				if (strncmp((u8 *)(szLine + i), "END", 3) == 0) {
5609*4882a593Smuzhiyun 					loadingStage = LD_STAGE_TAB_DEFINE;
5610*4882a593Smuzhiyun 					if (regulation) {
5611*4882a593Smuzhiyun 						for (forCnt = 0; forCnt < colNum; ++forCnt) {
5612*4882a593Smuzhiyun 							if (regulation[forCnt]) {
5613*4882a593Smuzhiyun 								rtw_mfree(regulation[forCnt], strlen(regulation[forCnt]) + 1);
5614*4882a593Smuzhiyun 								regulation[forCnt] = NULL;
5615*4882a593Smuzhiyun 							}
5616*4882a593Smuzhiyun 						}
5617*4882a593Smuzhiyun 						rtw_mfree((u8 *)regulation, sizeof(char *) * colNum);
5618*4882a593Smuzhiyun 						regulation = NULL;
5619*4882a593Smuzhiyun 					}
5620*4882a593Smuzhiyun 					colNum = 0;
5621*4882a593Smuzhiyun 					continue;
5622*4882a593Smuzhiyun 				} else {
5623*4882a593Smuzhiyun 					RTW_ERR("Missing \"##   END\" label\n");
5624*4882a593Smuzhiyun 					goto exit;
5625*4882a593Smuzhiyun 				}
5626*4882a593Smuzhiyun 			}
5627*4882a593Smuzhiyun 
5628*4882a593Smuzhiyun 			if ((szLine[0] != 'c' && szLine[0] != 'C') ||
5629*4882a593Smuzhiyun 				(szLine[1] != 'h' && szLine[1] != 'H')
5630*4882a593Smuzhiyun 			) {
5631*4882a593Smuzhiyun 				RTW_WARN("Wrong channel prefix: '%c','%c'(%d,%d)\n", szLine[0], szLine[1], szLine[0], szLine[1]);
5632*4882a593Smuzhiyun 				continue;
5633*4882a593Smuzhiyun 			}
5634*4882a593Smuzhiyun 			i = 2;/* move to the  location behind 'h' */
5635*4882a593Smuzhiyun 
5636*4882a593Smuzhiyun 			/* load the channel number */
5637*4882a593Smuzhiyun 			cnt = 0;
5638*4882a593Smuzhiyun 			while (szLine[i] >= '0' && szLine[i] <= '9') {
5639*4882a593Smuzhiyun 				channel[cnt] = szLine[i];
5640*4882a593Smuzhiyun 				++cnt;
5641*4882a593Smuzhiyun 				++i;
5642*4882a593Smuzhiyun 			}
5643*4882a593Smuzhiyun 			/* RTW_INFO("chnl %s!\n", channel); */
5644*4882a593Smuzhiyun 
5645*4882a593Smuzhiyun 			for (forCnt = 0; forCnt < colNum; ++forCnt) {
5646*4882a593Smuzhiyun 				/* skip the space between channel number and the power limit value */
5647*4882a593Smuzhiyun 				while (szLine[i] == ' ' || szLine[i] == '\t')
5648*4882a593Smuzhiyun 					++i;
5649*4882a593Smuzhiyun 
5650*4882a593Smuzhiyun 				/* load the power limit value */
5651*4882a593Smuzhiyun 				_rtw_memset((void *) powerLimit, 0, 10);
5652*4882a593Smuzhiyun 
5653*4882a593Smuzhiyun 				if (szLine[i] == 'W' && szLine[i + 1] == 'W') {
5654*4882a593Smuzhiyun 					/*
5655*4882a593Smuzhiyun 					* case "WW" assign special ww value
5656*4882a593Smuzhiyun 					* means to get minimal limit in other regulations at same channel
5657*4882a593Smuzhiyun 					*/
5658*4882a593Smuzhiyun 					s8 ww_value = phy_txpwr_ww_lmt_value(Adapter);
5659*4882a593Smuzhiyun 
5660*4882a593Smuzhiyun 					sprintf(powerLimit, "%d", ww_value);
5661*4882a593Smuzhiyun 					i += 2;
5662*4882a593Smuzhiyun 
5663*4882a593Smuzhiyun 				} else if (szLine[i] == 'N' && szLine[i + 1] == 'A') {
5664*4882a593Smuzhiyun 					/*
5665*4882a593Smuzhiyun 					* case "NA" assign max txgi value
5666*4882a593Smuzhiyun 					* means no limitation
5667*4882a593Smuzhiyun 					*/
5668*4882a593Smuzhiyun 					sprintf(powerLimit, "%d", hal_spec->txgi_max);
5669*4882a593Smuzhiyun 					i += 2;
5670*4882a593Smuzhiyun 
5671*4882a593Smuzhiyun 				} else if ((szLine[i] >= '0' && szLine[i] <= '9') || szLine[i] == '.'
5672*4882a593Smuzhiyun 					|| szLine[i] == '+' || szLine[i] == '-'
5673*4882a593Smuzhiyun 				){
5674*4882a593Smuzhiyun 					/* case of dBm value */
5675*4882a593Smuzhiyun 					u8 integer = 0, fraction = 0, negative = 0;
5676*4882a593Smuzhiyun 					u32 u4bMove;
5677*4882a593Smuzhiyun 					s8 lmt = 0;
5678*4882a593Smuzhiyun 
5679*4882a593Smuzhiyun 					if (szLine[i] == '+' || szLine[i] == '-') {
5680*4882a593Smuzhiyun 						if (szLine[i] == '-')
5681*4882a593Smuzhiyun 							negative = 1;
5682*4882a593Smuzhiyun 						i++;
5683*4882a593Smuzhiyun 					}
5684*4882a593Smuzhiyun 
5685*4882a593Smuzhiyun 					if (GetFractionValueFromString(&szLine[i], &integer, &fraction, &u4bMove))
5686*4882a593Smuzhiyun 						i += u4bMove;
5687*4882a593Smuzhiyun 					else {
5688*4882a593Smuzhiyun 						RTW_ERR("Limit \"%s\" is not valid decimal\n", &szLine[i]);
5689*4882a593Smuzhiyun 						goto exit;
5690*4882a593Smuzhiyun 					}
5691*4882a593Smuzhiyun 
5692*4882a593Smuzhiyun 					/* transform to string of value in unit of txgi */
5693*4882a593Smuzhiyun 					lmt = integer * hal_spec->txgi_pdbm + ((u16)fraction * (u16)hal_spec->txgi_pdbm) / 100;
5694*4882a593Smuzhiyun 					if (negative)
5695*4882a593Smuzhiyun 						lmt = -lmt;
5696*4882a593Smuzhiyun 					sprintf(powerLimit, "%d", lmt);
5697*4882a593Smuzhiyun 
5698*4882a593Smuzhiyun 				} else {
5699*4882a593Smuzhiyun 					RTW_ERR("Wrong limit expression \"%c%c\"(%d, %d)\n"
5700*4882a593Smuzhiyun 						, szLine[i], szLine[i + 1], szLine[i], szLine[i + 1]);
5701*4882a593Smuzhiyun 					goto exit;
5702*4882a593Smuzhiyun 				}
5703*4882a593Smuzhiyun 
5704*4882a593Smuzhiyun 				/* store the power limit value */
5705*4882a593Smuzhiyun 				phy_set_tx_power_limit(pDM_Odm, (u8 *)regulation[forCnt], (u8 *)band,
5706*4882a593Smuzhiyun 					(u8 *)bandwidth, (u8 *)rateSection, (u8 *)ntx, (u8 *)channel, (u8 *)powerLimit);
5707*4882a593Smuzhiyun 
5708*4882a593Smuzhiyun 			}
5709*4882a593Smuzhiyun 		}
5710*4882a593Smuzhiyun 	}
5711*4882a593Smuzhiyun 
5712*4882a593Smuzhiyun 	rtStatus = _SUCCESS;
5713*4882a593Smuzhiyun 
5714*4882a593Smuzhiyun exit:
5715*4882a593Smuzhiyun 	if (regulation) {
5716*4882a593Smuzhiyun 		for (forCnt = 0; forCnt < colNum; ++forCnt) {
5717*4882a593Smuzhiyun 			if (regulation[forCnt]) {
5718*4882a593Smuzhiyun 				rtw_mfree(regulation[forCnt], strlen(regulation[forCnt]) + 1);
5719*4882a593Smuzhiyun 				regulation[forCnt] = NULL;
5720*4882a593Smuzhiyun 			}
5721*4882a593Smuzhiyun 		}
5722*4882a593Smuzhiyun 		rtw_mfree((u8 *)regulation, sizeof(char *) * colNum);
5723*4882a593Smuzhiyun 		regulation = NULL;
5724*4882a593Smuzhiyun 	}
5725*4882a593Smuzhiyun 
5726*4882a593Smuzhiyun 	RTW_INFO("%s return %d\n", __func__, rtStatus);
5727*4882a593Smuzhiyun 	return rtStatus;
5728*4882a593Smuzhiyun }
5729*4882a593Smuzhiyun 
5730*4882a593Smuzhiyun int
PHY_ConfigRFWithPowerLimitTableParaFile(PADAPTER Adapter,const char * pFileName)5731*4882a593Smuzhiyun PHY_ConfigRFWithPowerLimitTableParaFile(
5732*4882a593Smuzhiyun 		PADAPTER	Adapter,
5733*4882a593Smuzhiyun 		const char	*pFileName
5734*4882a593Smuzhiyun )
5735*4882a593Smuzhiyun {
5736*4882a593Smuzhiyun 	HAL_DATA_TYPE		*pHalData = GET_HAL_DATA(Adapter);
5737*4882a593Smuzhiyun 	int	rlen = 0, rtStatus = _FAIL;
5738*4882a593Smuzhiyun 
5739*4882a593Smuzhiyun 	if (!(Adapter->registrypriv.load_phy_file & LOAD_RF_TXPWR_LMT_PARA_FILE))
5740*4882a593Smuzhiyun 		return rtStatus;
5741*4882a593Smuzhiyun 
5742*4882a593Smuzhiyun 	_rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
5743*4882a593Smuzhiyun 
5744*4882a593Smuzhiyun 	if (pHalData->rf_tx_pwr_lmt == NULL) {
5745*4882a593Smuzhiyun 		rtw_get_phy_file_path(Adapter, pFileName);
5746*4882a593Smuzhiyun 		if (rtw_readable_file_sz_chk(rtw_phy_para_file_path,
5747*4882a593Smuzhiyun 			MAX_PARA_FILE_BUF_LEN) == _TRUE) {
5748*4882a593Smuzhiyun 			rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
5749*4882a593Smuzhiyun 			if (rlen > 0) {
5750*4882a593Smuzhiyun 				rtStatus = _SUCCESS;
5751*4882a593Smuzhiyun 				pHalData->rf_tx_pwr_lmt = rtw_zvmalloc(rlen);
5752*4882a593Smuzhiyun 				if (pHalData->rf_tx_pwr_lmt) {
5753*4882a593Smuzhiyun 					_rtw_memcpy(pHalData->rf_tx_pwr_lmt, pHalData->para_file_buf, rlen);
5754*4882a593Smuzhiyun 					pHalData->rf_tx_pwr_lmt_len = rlen;
5755*4882a593Smuzhiyun 				} else
5756*4882a593Smuzhiyun 					RTW_INFO("%s rf_tx_pwr_lmt alloc fail !\n", __FUNCTION__);
5757*4882a593Smuzhiyun 			}
5758*4882a593Smuzhiyun 		}
5759*4882a593Smuzhiyun 	} else {
5760*4882a593Smuzhiyun 		if ((pHalData->rf_tx_pwr_lmt_len != 0) && (pHalData->rf_tx_pwr_lmt != NULL)) {
5761*4882a593Smuzhiyun 			_rtw_memcpy(pHalData->para_file_buf, pHalData->rf_tx_pwr_lmt, pHalData->rf_tx_pwr_lmt_len);
5762*4882a593Smuzhiyun 			rtStatus = _SUCCESS;
5763*4882a593Smuzhiyun 		} else
5764*4882a593Smuzhiyun 			RTW_INFO("%s(): Critical Error !!!\n", __FUNCTION__);
5765*4882a593Smuzhiyun 	}
5766*4882a593Smuzhiyun 
5767*4882a593Smuzhiyun 	if (rtStatus == _SUCCESS) {
5768*4882a593Smuzhiyun 		/* RTW_INFO("%s(): read %s ok\n", __FUNCTION__, pFileName); */
5769*4882a593Smuzhiyun 		rtStatus = phy_ParsePowerLimitTableFile(Adapter, pHalData->para_file_buf);
5770*4882a593Smuzhiyun 	} else
5771*4882a593Smuzhiyun 		RTW_INFO("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
5772*4882a593Smuzhiyun 
5773*4882a593Smuzhiyun 	return rtStatus;
5774*4882a593Smuzhiyun }
5775*4882a593Smuzhiyun #endif /* CONFIG_TXPWR_LIMIT */
5776*4882a593Smuzhiyun 
phy_free_filebuf_mask(_adapter * padapter,u8 mask)5777*4882a593Smuzhiyun void phy_free_filebuf_mask(_adapter *padapter, u8 mask)
5778*4882a593Smuzhiyun {
5779*4882a593Smuzhiyun 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
5780*4882a593Smuzhiyun 
5781*4882a593Smuzhiyun 	if (pHalData->mac_reg && (mask & LOAD_MAC_PARA_FILE)) {
5782*4882a593Smuzhiyun 		rtw_vmfree(pHalData->mac_reg, pHalData->mac_reg_len);
5783*4882a593Smuzhiyun 		pHalData->mac_reg = NULL;
5784*4882a593Smuzhiyun 	}
5785*4882a593Smuzhiyun 	if (mask & LOAD_BB_PARA_FILE) {
5786*4882a593Smuzhiyun 		if (pHalData->bb_phy_reg) {
5787*4882a593Smuzhiyun 			rtw_vmfree(pHalData->bb_phy_reg, pHalData->bb_phy_reg_len);
5788*4882a593Smuzhiyun 			pHalData->bb_phy_reg = NULL;
5789*4882a593Smuzhiyun 		}
5790*4882a593Smuzhiyun 		if (pHalData->bb_agc_tab) {
5791*4882a593Smuzhiyun 			rtw_vmfree(pHalData->bb_agc_tab, pHalData->bb_agc_tab_len);
5792*4882a593Smuzhiyun 			pHalData->bb_agc_tab = NULL;
5793*4882a593Smuzhiyun 		}
5794*4882a593Smuzhiyun 	}
5795*4882a593Smuzhiyun 	if (pHalData->bb_phy_reg_pg && (mask & LOAD_BB_PG_PARA_FILE)) {
5796*4882a593Smuzhiyun 		rtw_vmfree(pHalData->bb_phy_reg_pg, pHalData->bb_phy_reg_pg_len);
5797*4882a593Smuzhiyun 		pHalData->bb_phy_reg_pg = NULL;
5798*4882a593Smuzhiyun 	}
5799*4882a593Smuzhiyun 	if (pHalData->bb_phy_reg_mp && (mask & LOAD_BB_MP_PARA_FILE)) {
5800*4882a593Smuzhiyun 		rtw_vmfree(pHalData->bb_phy_reg_mp, pHalData->bb_phy_reg_mp_len);
5801*4882a593Smuzhiyun 		pHalData->bb_phy_reg_mp = NULL;
5802*4882a593Smuzhiyun 	}
5803*4882a593Smuzhiyun 	if (mask & LOAD_RF_PARA_FILE) {
5804*4882a593Smuzhiyun 		if (pHalData->rf_radio_a) {
5805*4882a593Smuzhiyun 			rtw_vmfree(pHalData->rf_radio_a, pHalData->rf_radio_a_len);
5806*4882a593Smuzhiyun 			pHalData->rf_radio_a = NULL;
5807*4882a593Smuzhiyun 		}
5808*4882a593Smuzhiyun 		if (pHalData->rf_radio_b) {
5809*4882a593Smuzhiyun 			rtw_vmfree(pHalData->rf_radio_b, pHalData->rf_radio_b_len);
5810*4882a593Smuzhiyun 			pHalData->rf_radio_b = NULL;
5811*4882a593Smuzhiyun 		}
5812*4882a593Smuzhiyun 	}
5813*4882a593Smuzhiyun 	if (pHalData->rf_tx_pwr_track && (mask & LOAD_RF_TXPWR_TRACK_PARA_FILE)) {
5814*4882a593Smuzhiyun 		rtw_vmfree(pHalData->rf_tx_pwr_track, pHalData->rf_tx_pwr_track_len);
5815*4882a593Smuzhiyun 		pHalData->rf_tx_pwr_track = NULL;
5816*4882a593Smuzhiyun 	}
5817*4882a593Smuzhiyun 	if (pHalData->rf_tx_pwr_lmt && (mask & LOAD_RF_TXPWR_LMT_PARA_FILE)) {
5818*4882a593Smuzhiyun 		rtw_vmfree(pHalData->rf_tx_pwr_lmt, pHalData->rf_tx_pwr_lmt_len);
5819*4882a593Smuzhiyun 		pHalData->rf_tx_pwr_lmt = NULL;
5820*4882a593Smuzhiyun 	}
5821*4882a593Smuzhiyun }
5822*4882a593Smuzhiyun 
phy_free_filebuf(_adapter * padapter)5823*4882a593Smuzhiyun inline void phy_free_filebuf(_adapter *padapter)
5824*4882a593Smuzhiyun {
5825*4882a593Smuzhiyun 	phy_free_filebuf_mask(padapter, 0xFF);
5826*4882a593Smuzhiyun }
5827*4882a593Smuzhiyun 
5828*4882a593Smuzhiyun #endif
5829*4882a593Smuzhiyun 
5830*4882a593Smuzhiyun /*
5831*4882a593Smuzhiyun * check if user specified mbm is valid
5832*4882a593Smuzhiyun */
phy_is_txpwr_user_mbm_valid(_adapter * adapter,s16 mbm)5833*4882a593Smuzhiyun bool phy_is_txpwr_user_mbm_valid(_adapter *adapter, s16 mbm)
5834*4882a593Smuzhiyun {
5835*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
5836*4882a593Smuzhiyun 
5837*4882a593Smuzhiyun 	/* 1T upper bound check */
5838*4882a593Smuzhiyun 	if (hal_spec->txgi_max <= mbm * hal_spec->txgi_pdbm / MBM_PDBM)
5839*4882a593Smuzhiyun 		return 0;
5840*4882a593Smuzhiyun 
5841*4882a593Smuzhiyun 	return 1;
5842*4882a593Smuzhiyun }
5843*4882a593Smuzhiyun 
phy_is_txpwr_user_target_specified(_adapter * adapter)5844*4882a593Smuzhiyun bool phy_is_txpwr_user_target_specified(_adapter *adapter)
5845*4882a593Smuzhiyun {
5846*4882a593Smuzhiyun 	s16 total_mbm = UNSPECIFIED_MBM;
5847*4882a593Smuzhiyun 
5848*4882a593Smuzhiyun #ifdef CONFIG_IOCTL_CFG80211
5849*4882a593Smuzhiyun 	total_mbm = rtw_cfg80211_dev_get_total_txpwr_target_mbm(adapter_to_dvobj(adapter));
5850*4882a593Smuzhiyun #endif
5851*4882a593Smuzhiyun 
5852*4882a593Smuzhiyun 	return total_mbm != UNSPECIFIED_MBM;
5853*4882a593Smuzhiyun }
5854*4882a593Smuzhiyun 
5855*4882a593Smuzhiyun /*
5856*4882a593Smuzhiyun * Return value in unit of TX Gain Index
5857*4882a593Smuzhiyun * hal_spec.txgi_max means unspecified
5858*4882a593Smuzhiyun */
phy_get_txpwr_user_target(_adapter * adapter,struct hal_spec_t * hal_spec,u8 ntx_idx)5859*4882a593Smuzhiyun s8 phy_get_txpwr_user_target(_adapter *adapter, struct hal_spec_t *hal_spec, u8 ntx_idx)
5860*4882a593Smuzhiyun {
5861*4882a593Smuzhiyun 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
5862*4882a593Smuzhiyun 	s16 total_mbm = UNSPECIFIED_MBM;
5863*4882a593Smuzhiyun 	s8 target;
5864*4882a593Smuzhiyun 
5865*4882a593Smuzhiyun #ifdef CONFIG_IOCTL_CFG80211
5866*4882a593Smuzhiyun 	total_mbm = rtw_cfg80211_dev_get_total_txpwr_target_mbm(adapter_to_dvobj(adapter));
5867*4882a593Smuzhiyun #endif
5868*4882a593Smuzhiyun 	if (total_mbm != UNSPECIFIED_MBM)
5869*4882a593Smuzhiyun 		target = (total_mbm - mb_of_ntx(ntx_idx + 1) - rfctl->antenna_gain) * hal_spec->txgi_pdbm / MBM_PDBM;
5870*4882a593Smuzhiyun 	else
5871*4882a593Smuzhiyun 		target = hal_spec->txgi_max;
5872*4882a593Smuzhiyun 
5873*4882a593Smuzhiyun 	return target;
5874*4882a593Smuzhiyun }
5875*4882a593Smuzhiyun 
5876*4882a593Smuzhiyun /*
5877*4882a593Smuzhiyun * Return value in unit of TX Gain Index
5878*4882a593Smuzhiyun * hal_spec.txgi_max means unspecified
5879*4882a593Smuzhiyun */
phy_get_txpwr_user_lmt(_adapter * adapter,struct hal_spec_t * hal_spec,u8 ntx_idx)5880*4882a593Smuzhiyun s8 phy_get_txpwr_user_lmt(_adapter *adapter, struct hal_spec_t *hal_spec, u8 ntx_idx)
5881*4882a593Smuzhiyun {
5882*4882a593Smuzhiyun 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
5883*4882a593Smuzhiyun 	s16 total_mbm = UNSPECIFIED_MBM;
5884*4882a593Smuzhiyun 	s8 lmt;
5885*4882a593Smuzhiyun 
5886*4882a593Smuzhiyun #ifdef CONFIG_IOCTL_CFG80211
5887*4882a593Smuzhiyun 	total_mbm = rtw_cfg80211_dev_get_total_txpwr_lmt_mbm(adapter_to_dvobj(adapter));
5888*4882a593Smuzhiyun #endif
5889*4882a593Smuzhiyun 	if (total_mbm != UNSPECIFIED_MBM)
5890*4882a593Smuzhiyun 		lmt = (total_mbm - mb_of_ntx(ntx_idx + 1) - rfctl->antenna_gain) * hal_spec->txgi_pdbm / MBM_PDBM;
5891*4882a593Smuzhiyun 	else
5892*4882a593Smuzhiyun 		lmt = hal_spec->txgi_max;
5893*4882a593Smuzhiyun 
5894*4882a593Smuzhiyun 	return lmt;
5895*4882a593Smuzhiyun }
5896*4882a593Smuzhiyun 
5897*4882a593Smuzhiyun /*
5898*4882a593Smuzhiyun * Return value in unit of TX Gain Index
5899*4882a593Smuzhiyun * 0 means unspecified
5900*4882a593Smuzhiyun */
phy_get_txpwr_tpc(_adapter * adapter,struct hal_spec_t * hal_spec)5901*4882a593Smuzhiyun s8 phy_get_txpwr_tpc(_adapter *adapter, struct hal_spec_t *hal_spec)
5902*4882a593Smuzhiyun {
5903*4882a593Smuzhiyun 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
5904*4882a593Smuzhiyun 	u16 cnst = 0;
5905*4882a593Smuzhiyun 
5906*4882a593Smuzhiyun 	if (rfctl->tpc_mode == TPC_MODE_MANUAL)
5907*4882a593Smuzhiyun 		cnst = rfctl->tpc_manual_constraint * hal_spec->txgi_pdbm / MBM_PDBM;
5908*4882a593Smuzhiyun 
5909*4882a593Smuzhiyun 	return -cnst;
5910*4882a593Smuzhiyun }
5911*4882a593Smuzhiyun 
dump_txpwr_tpc_settings(void * sel,_adapter * adapter)5912*4882a593Smuzhiyun void dump_txpwr_tpc_settings(void *sel, _adapter *adapter)
5913*4882a593Smuzhiyun {
5914*4882a593Smuzhiyun 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
5915*4882a593Smuzhiyun 
5916*4882a593Smuzhiyun 	if (rfctl->tpc_mode == TPC_MODE_DISABLE)
5917*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "mode:DISABLE(%d)\n", rfctl->tpc_mode);
5918*4882a593Smuzhiyun 	else if (rfctl->tpc_mode == TPC_MODE_MANUAL) {
5919*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "mode:MANUAL(%d)\n", rfctl->tpc_mode);
5920*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "constraint:%d (mB)\n", rfctl->tpc_manual_constraint);
5921*4882a593Smuzhiyun 	}
5922*4882a593Smuzhiyun }
5923*4882a593Smuzhiyun 
dump_txpwr_antenna_gain(void * sel,_adapter * adapter)5924*4882a593Smuzhiyun void dump_txpwr_antenna_gain(void *sel, _adapter *adapter)
5925*4882a593Smuzhiyun {
5926*4882a593Smuzhiyun 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
5927*4882a593Smuzhiyun 
5928*4882a593Smuzhiyun 	RTW_PRINT_SEL(sel, "%d (mBi)\n", rfctl->antenna_gain);
5929*4882a593Smuzhiyun }
5930*4882a593Smuzhiyun 
5931*4882a593Smuzhiyun /*
5932*4882a593Smuzhiyun * Return value in unit of TX Gain Index
5933*4882a593Smuzhiyun */
phy_get_txpwr_target(_adapter * adapter,u8 rfpath,RATE_SECTION rs,u8 rate,u8 ntx_idx,enum channel_width bw,BAND_TYPE band,u8 cch,u8 opch,struct txpwr_idx_comp * tic)5934*4882a593Smuzhiyun s8 phy_get_txpwr_target(_adapter *adapter, u8 rfpath, RATE_SECTION rs, u8 rate, u8 ntx_idx
5935*4882a593Smuzhiyun 	, enum channel_width bw, BAND_TYPE band, u8 cch, u8 opch, struct txpwr_idx_comp *tic)
5936*4882a593Smuzhiyun {
5937*4882a593Smuzhiyun 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
5938*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
5939*4882a593Smuzhiyun 	s8 target, by_rate = 0, btc_diff = 0, extra = 0;
5940*4882a593Smuzhiyun 	s8 lmt, utgt, ulmt;
5941*4882a593Smuzhiyun 	s8 tpc = 0;
5942*4882a593Smuzhiyun 
5943*4882a593Smuzhiyun 	lmt = utgt = ulmt = hal_spec->txgi_max;
5944*4882a593Smuzhiyun 
5945*4882a593Smuzhiyun 	if (band != BAND_ON_2_4G && IS_CCK_RATE(rate))
5946*4882a593Smuzhiyun 		goto exit;
5947*4882a593Smuzhiyun 
5948*4882a593Smuzhiyun 	utgt = phy_get_txpwr_user_target(adapter, hal_spec, ntx_idx);
5949*4882a593Smuzhiyun 	if (utgt != hal_spec->txgi_max)
5950*4882a593Smuzhiyun 		goto get_lmt;
5951*4882a593Smuzhiyun 
5952*4882a593Smuzhiyun #ifdef CONFIG_RTL8812A
5953*4882a593Smuzhiyun 	if (IS_HARDWARE_TYPE_8812(adapter)
5954*4882a593Smuzhiyun 		&& phy_get_txpwr_target_skip_by_rate_8812a(adapter, rate))
5955*4882a593Smuzhiyun 		by_rate = phy_get_target_txpwr(adapter, band, rfpath, rs);
5956*4882a593Smuzhiyun 	else
5957*4882a593Smuzhiyun #endif
5958*4882a593Smuzhiyun 		by_rate = PHY_GetTxPowerByRate(adapter, band, rfpath, rs, rate);
5959*4882a593Smuzhiyun 	if (by_rate == hal_spec->txgi_max)
5960*4882a593Smuzhiyun 		by_rate = 0;
5961*4882a593Smuzhiyun 
5962*4882a593Smuzhiyun #ifdef CONFIG_BT_COEXIST
5963*4882a593Smuzhiyun 	if (hal_data->EEPROMBluetoothCoexist == _TRUE)
5964*4882a593Smuzhiyun 		btc_diff = -(rtw_btcoex_query_reduced_wl_pwr_lvl(adapter) * hal_spec->txgi_pdbm);
5965*4882a593Smuzhiyun #endif
5966*4882a593Smuzhiyun 
5967*4882a593Smuzhiyun 	extra = rtw_hal_get_txpwr_target_extra_bias(adapter, rfpath, rs, rate, bw, band, cch);
5968*4882a593Smuzhiyun 
5969*4882a593Smuzhiyun get_lmt:
5970*4882a593Smuzhiyun 	lmt = phy_get_txpwr_lmt_sub_chs(adapter, NULL, band, bw, rfpath, rate, ntx_idx, cch, opch);
5971*4882a593Smuzhiyun 	ulmt = phy_get_txpwr_user_lmt(adapter, hal_spec, ntx_idx);
5972*4882a593Smuzhiyun 	/* TODO: limit from outer source, ex: 11d */
5973*4882a593Smuzhiyun 
5974*4882a593Smuzhiyun 	tpc = phy_get_txpwr_tpc(adapter, hal_spec);
5975*4882a593Smuzhiyun 
5976*4882a593Smuzhiyun exit:
5977*4882a593Smuzhiyun 	if (utgt != hal_spec->txgi_max)
5978*4882a593Smuzhiyun 		target = utgt;
5979*4882a593Smuzhiyun 	else
5980*4882a593Smuzhiyun 		target = by_rate + btc_diff + extra;
5981*4882a593Smuzhiyun 
5982*4882a593Smuzhiyun 	if (target > lmt)
5983*4882a593Smuzhiyun 		target = lmt;
5984*4882a593Smuzhiyun 	if (target > ulmt)
5985*4882a593Smuzhiyun 		target = ulmt;
5986*4882a593Smuzhiyun 
5987*4882a593Smuzhiyun 	target += tpc;
5988*4882a593Smuzhiyun 
5989*4882a593Smuzhiyun 	if (tic) {
5990*4882a593Smuzhiyun 		tic->target = target;
5991*4882a593Smuzhiyun 		if (utgt == hal_spec->txgi_max) {
5992*4882a593Smuzhiyun 			tic->by_rate = by_rate;
5993*4882a593Smuzhiyun 			tic->btc = btc_diff;
5994*4882a593Smuzhiyun 			tic->extra = extra;
5995*4882a593Smuzhiyun 		}
5996*4882a593Smuzhiyun 		tic->utarget = utgt;
5997*4882a593Smuzhiyun 		tic->limit = lmt;
5998*4882a593Smuzhiyun 		tic->ulimit = ulmt;
5999*4882a593Smuzhiyun 		tic->tpc = tpc;
6000*4882a593Smuzhiyun 	}
6001*4882a593Smuzhiyun 
6002*4882a593Smuzhiyun 	return target;
6003*4882a593Smuzhiyun }
6004*4882a593Smuzhiyun 
6005*4882a593Smuzhiyun /* TODO: common dpd_diff getting API from phydm */
6006*4882a593Smuzhiyun #ifdef CONFIG_RTL8822C
6007*4882a593Smuzhiyun #include "./rtl8822c/rtl8822c.h"
6008*4882a593Smuzhiyun #endif
6009*4882a593Smuzhiyun 
6010*4882a593Smuzhiyun /*
6011*4882a593Smuzhiyun * Return in unit of TX Gain Index
6012*4882a593Smuzhiyun */
phy_get_txpwr_amends(_adapter * adapter,u8 rfpath,RATE_SECTION rs,u8 rate,u8 ntx_idx,enum channel_width bw,BAND_TYPE band,u8 cch,struct txpwr_idx_comp * tic)6013*4882a593Smuzhiyun s8 phy_get_txpwr_amends(_adapter *adapter, u8 rfpath, RATE_SECTION rs, u8 rate, u8 ntx_idx
6014*4882a593Smuzhiyun 	, enum channel_width bw, BAND_TYPE band, u8 cch, struct txpwr_idx_comp *tic)
6015*4882a593Smuzhiyun {
6016*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
6017*4882a593Smuzhiyun 	s8 tpt_diff = 0, dpd_diff = 0, val = 0;
6018*4882a593Smuzhiyun 
6019*4882a593Smuzhiyun 	if (band != BAND_ON_2_4G && IS_CCK_RATE(rate))
6020*4882a593Smuzhiyun 		goto exit;
6021*4882a593Smuzhiyun 
6022*4882a593Smuzhiyun 	if (IS_HARDWARE_TYPE_8188E(adapter) || IS_HARDWARE_TYPE_8188F(adapter) || IS_HARDWARE_TYPE_8188GTV(adapter)
6023*4882a593Smuzhiyun 		|| IS_HARDWARE_TYPE_8192E(adapter) || IS_HARDWARE_TYPE_8192F(adapter)
6024*4882a593Smuzhiyun 		|| IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter) || IS_HARDWARE_TYPE_8723D(adapter)
6025*4882a593Smuzhiyun 		|| IS_HARDWARE_TYPE_8710B(adapter)
6026*4882a593Smuzhiyun 		|| IS_HARDWARE_TYPE_8821(adapter) || IS_HARDWARE_TYPE_8812(adapter)
6027*4882a593Smuzhiyun 	)
6028*4882a593Smuzhiyun 		tpt_diff = PHY_GetTxPowerTrackingOffset(adapter, rfpath, rate);
6029*4882a593Smuzhiyun 
6030*4882a593Smuzhiyun #ifdef CONFIG_RTL8822C
6031*4882a593Smuzhiyun 	if (IS_HARDWARE_TYPE_8822C(adapter))
6032*4882a593Smuzhiyun 		dpd_diff = -(rtl8822c_get_dis_dpd_by_rate_diff(adapter, rate) * hal_spec->txgi_pdbm);
6033*4882a593Smuzhiyun #endif
6034*4882a593Smuzhiyun 
6035*4882a593Smuzhiyun exit:
6036*4882a593Smuzhiyun 	if (tic) {
6037*4882a593Smuzhiyun 		tic->tpt = tpt_diff;
6038*4882a593Smuzhiyun 		tic->dpd = dpd_diff;
6039*4882a593Smuzhiyun 	}
6040*4882a593Smuzhiyun 
6041*4882a593Smuzhiyun 	return tpt_diff + dpd_diff;
6042*4882a593Smuzhiyun }
6043*4882a593Smuzhiyun 
6044*4882a593Smuzhiyun #ifdef CONFIG_TXPWR_PG_WITH_TSSI_OFFSET
phy_get_tssi_txpwr_by_rate_ref(_adapter * adapter,enum rf_path path,enum channel_width bw,u8 cch,u8 opch)6045*4882a593Smuzhiyun s8 phy_get_tssi_txpwr_by_rate_ref(_adapter *adapter, enum rf_path path
6046*4882a593Smuzhiyun 	, enum channel_width bw, u8 cch, u8 opch)
6047*4882a593Smuzhiyun {
6048*4882a593Smuzhiyun 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
6049*4882a593Smuzhiyun 	u8 ntx_idx = phy_get_current_tx_num(adapter, MGN_MCS7);
6050*4882a593Smuzhiyun 	BAND_TYPE band = cch > 14 ? BAND_ON_5G : BAND_ON_2_4G;
6051*4882a593Smuzhiyun 	s8 pwr_idx;
6052*4882a593Smuzhiyun 
6053*4882a593Smuzhiyun 	pwr_idx = phy_get_txpwr_target(adapter, path, HT_1SS, MGN_MCS7
6054*4882a593Smuzhiyun 		, ntx_idx, bw, band, cch, opch, NULL);
6055*4882a593Smuzhiyun 	pwr_idx += phy_get_txpwr_amends(adapter, path, HT_1SS, MGN_MCS7
6056*4882a593Smuzhiyun 		, ntx_idx, bw, band, cch, NULL);
6057*4882a593Smuzhiyun 
6058*4882a593Smuzhiyun 	return pwr_idx;
6059*4882a593Smuzhiyun }
6060*4882a593Smuzhiyun #endif
6061*4882a593Smuzhiyun 
6062*4882a593Smuzhiyun /*
6063*4882a593Smuzhiyun  * Rteurn tx power index for rate
6064*4882a593Smuzhiyun  */
hal_com_get_txpwr_idx(_adapter * adapter,enum rf_path rfpath,RATE_SECTION rs,enum MGN_RATE rate,enum channel_width bw,BAND_TYPE band,u8 cch,u8 opch,struct txpwr_idx_comp * tic)6065*4882a593Smuzhiyun u8 hal_com_get_txpwr_idx(_adapter *adapter, enum rf_path rfpath
6066*4882a593Smuzhiyun 	, RATE_SECTION rs, enum MGN_RATE rate, enum channel_width bw, BAND_TYPE band, u8 cch, u8 opch
6067*4882a593Smuzhiyun 	, struct txpwr_idx_comp *tic)
6068*4882a593Smuzhiyun {
6069*4882a593Smuzhiyun 	PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
6070*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
6071*4882a593Smuzhiyun 	s16 power_idx = 0;
6072*4882a593Smuzhiyun 	s8 base = 0;
6073*4882a593Smuzhiyun 	s8 rate_target, rate_amends;
6074*4882a593Smuzhiyun 	u8 ntx_idx = phy_get_current_tx_num(adapter, rate);
6075*4882a593Smuzhiyun 
6076*4882a593Smuzhiyun 	/* target */
6077*4882a593Smuzhiyun 	rate_target = phy_get_txpwr_target(adapter, rfpath, rs, rate, ntx_idx, bw, band, cch, opch, tic);
6078*4882a593Smuzhiyun 
6079*4882a593Smuzhiyun 	/* amends */
6080*4882a593Smuzhiyun 	rate_amends = phy_get_txpwr_amends(adapter, rfpath, rs, rate, ntx_idx, bw, band, cch, tic);
6081*4882a593Smuzhiyun 
6082*4882a593Smuzhiyun 	switch (hal->txpwr_pg_mode) {
6083*4882a593Smuzhiyun #ifdef CONFIG_TXPWR_PG_WITH_PWR_IDX
6084*4882a593Smuzhiyun 	case TXPWR_PG_WITH_PWR_IDX: {
6085*4882a593Smuzhiyun 		/*
6086*4882a593Smuzhiyun 		* power index =
6087*4882a593Smuzhiyun 		* 1. pg base (per rate section) +
6088*4882a593Smuzhiyun 		* 2. target diff (per rate) to target of its rate section +
6089*4882a593Smuzhiyun 		* 3. amends diff (per rate)
6090*4882a593Smuzhiyun 		*/
6091*4882a593Smuzhiyun 		u8 rs_target;
6092*4882a593Smuzhiyun 
6093*4882a593Smuzhiyun 		base = phy_get_pg_txpwr_idx(adapter, rfpath, rs, ntx_idx, bw, band, cch);
6094*4882a593Smuzhiyun 		rs_target = phy_get_target_txpwr(adapter, band, rfpath, rs);
6095*4882a593Smuzhiyun 		power_idx = base + (rate_target - rs_target) + (rate_amends);
6096*4882a593Smuzhiyun 
6097*4882a593Smuzhiyun 		if (tic) {
6098*4882a593Smuzhiyun 			if (tic->utarget == hal_spec->txgi_max)
6099*4882a593Smuzhiyun 				tic->by_rate -= rs_target;
6100*4882a593Smuzhiyun 			else
6101*4882a593Smuzhiyun 				tic->utarget -= rs_target;
6102*4882a593Smuzhiyun 			if (tic->limit != hal_spec->txgi_max)
6103*4882a593Smuzhiyun 				tic->limit -= rs_target;
6104*4882a593Smuzhiyun 			if (tic->ulimit != hal_spec->txgi_max)
6105*4882a593Smuzhiyun 				tic->ulimit -= rs_target;
6106*4882a593Smuzhiyun 		}
6107*4882a593Smuzhiyun 	}
6108*4882a593Smuzhiyun 		break;
6109*4882a593Smuzhiyun #endif
6110*4882a593Smuzhiyun #ifdef CONFIG_TXPWR_PG_WITH_TSSI_OFFSET
6111*4882a593Smuzhiyun 	case TXPWR_PG_WITH_TSSI_OFFSET: {
6112*4882a593Smuzhiyun 		/*
6113*4882a593Smuzhiyun 		* power index =
6114*4882a593Smuzhiyun 		* 1. base (fixed) +
6115*4882a593Smuzhiyun 		* 2. target (per rate) +
6116*4882a593Smuzhiyun 		* 3. amends diff (per rate)
6117*4882a593Smuzhiyun 		* base is selected that power index of MCS7 ==  halrf_get_tssi_codeword_for_txindex()
6118*4882a593Smuzhiyun 		*/
6119*4882a593Smuzhiyun 		s8 mcs7_idx;
6120*4882a593Smuzhiyun 
6121*4882a593Smuzhiyun 		mcs7_idx = phy_get_tssi_txpwr_by_rate_ref(adapter, rfpath, bw, cch, opch);
6122*4882a593Smuzhiyun 		base = halrf_get_tssi_codeword_for_txindex(adapter_to_phydm(adapter)) - mcs7_idx;
6123*4882a593Smuzhiyun 		power_idx = base + rate_target + rate_amends;
6124*4882a593Smuzhiyun 	}
6125*4882a593Smuzhiyun 		break;
6126*4882a593Smuzhiyun #endif
6127*4882a593Smuzhiyun 	}
6128*4882a593Smuzhiyun 
6129*4882a593Smuzhiyun 	if (tic) {
6130*4882a593Smuzhiyun 		tic->ntx_idx = ntx_idx;
6131*4882a593Smuzhiyun 		tic->base = base;
6132*4882a593Smuzhiyun 	}
6133*4882a593Smuzhiyun 
6134*4882a593Smuzhiyun 	if (power_idx < 0)
6135*4882a593Smuzhiyun 		power_idx = 0;
6136*4882a593Smuzhiyun 	else if (power_idx > hal_spec->txgi_max)
6137*4882a593Smuzhiyun 		power_idx = hal_spec->txgi_max;
6138*4882a593Smuzhiyun 
6139*4882a593Smuzhiyun #if defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8812A)
6140*4882a593Smuzhiyun 	if ((IS_HARDWARE_TYPE_8821(adapter) || IS_HARDWARE_TYPE_8812(adapter))
6141*4882a593Smuzhiyun 		&& power_idx % 2 == 1 && !IS_NORMAL_CHIP(hal->version_id))
6142*4882a593Smuzhiyun 		--power_idx;
6143*4882a593Smuzhiyun #endif
6144*4882a593Smuzhiyun 
6145*4882a593Smuzhiyun 	return power_idx;
6146*4882a593Smuzhiyun }
6147*4882a593Smuzhiyun 
6148*4882a593Smuzhiyun /* get txpowr in mBm for single path */
phy_get_txpwr_single_mbm(_adapter * adapter,u8 rfpath,RATE_SECTION rs,u8 rate,enum channel_width bw,u8 cch,u8 opch,bool eirp,struct txpwr_idx_comp * tic)6149*4882a593Smuzhiyun s16 phy_get_txpwr_single_mbm(_adapter *adapter, u8 rfpath, RATE_SECTION rs, u8 rate
6150*4882a593Smuzhiyun 	, enum channel_width bw, u8 cch, u8 opch, bool eirp, struct txpwr_idx_comp *tic)
6151*4882a593Smuzhiyun {
6152*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
6153*4882a593Smuzhiyun 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
6154*4882a593Smuzhiyun 	BAND_TYPE band = cch <= 14 ? BAND_ON_2_4G : BAND_ON_5G;
6155*4882a593Smuzhiyun 	u8 ntx_idx = phy_get_current_tx_num(adapter, rate);
6156*4882a593Smuzhiyun 	s16 val;
6157*4882a593Smuzhiyun 
6158*4882a593Smuzhiyun 	val = phy_get_txpwr_target(adapter, rfpath, rs, rate, ntx_idx, bw, band, cch, opch, tic);
6159*4882a593Smuzhiyun 	val = (val * MBM_PDBM) / hal_spec->txgi_pdbm;
6160*4882a593Smuzhiyun 	if (eirp)
6161*4882a593Smuzhiyun 		val += rfctl->antenna_gain;
6162*4882a593Smuzhiyun 	if (tic)
6163*4882a593Smuzhiyun 		tic->ntx_idx = ntx_idx;
6164*4882a593Smuzhiyun 
6165*4882a593Smuzhiyun 	return val;
6166*4882a593Smuzhiyun }
6167*4882a593Smuzhiyun 
6168*4882a593Smuzhiyun /* get txpowr in mBm with effect of N-TX */
phy_get_txpwr_total_mbm(_adapter * adapter,RATE_SECTION rs,u8 rate,enum channel_width bw,u8 cch,u8 opch,bool eirp,struct txpwr_idx_comp * tic)6169*4882a593Smuzhiyun s16 phy_get_txpwr_total_mbm(_adapter *adapter, RATE_SECTION rs, u8 rate
6170*4882a593Smuzhiyun 	, enum channel_width bw, u8 cch, u8 opch, bool eirp, struct txpwr_idx_comp *tic)
6171*4882a593Smuzhiyun {
6172*4882a593Smuzhiyun 	s16 val;
6173*4882a593Smuzhiyun 	u8 tx_num = phy_get_current_tx_num(adapter, rate) + 1;
6174*4882a593Smuzhiyun 
6175*4882a593Smuzhiyun 	/* assume all path have same txpower target */
6176*4882a593Smuzhiyun 	val = phy_get_txpwr_single_mbm(adapter, RF_PATH_A, rs, rate, bw, cch, opch, eirp, tic);
6177*4882a593Smuzhiyun 	val += mb_of_ntx(tx_num);
6178*4882a593Smuzhiyun 
6179*4882a593Smuzhiyun 	return val;
6180*4882a593Smuzhiyun }
6181*4882a593Smuzhiyun 
_phy_get_txpwr_max_mbm(_adapter * adapter,s8 rfpath,enum channel_width bw,u8 cch,u8 opch,u16 bmp_cck_ofdm,u32 bmp_ht,u64 bmp_vht,bool eirp)6182*4882a593Smuzhiyun static s16 _phy_get_txpwr_max_mbm(_adapter *adapter, s8 rfpath
6183*4882a593Smuzhiyun 	, enum channel_width bw, u8 cch, u8 opch, u16 bmp_cck_ofdm, u32 bmp_ht, u64 bmp_vht, bool eirp)
6184*4882a593Smuzhiyun {
6185*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
6186*4882a593Smuzhiyun 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
6187*4882a593Smuzhiyun 	BAND_TYPE band = cch <= 14 ? BAND_ON_2_4G : BAND_ON_5G;
6188*4882a593Smuzhiyun 	u8 tx_num;
6189*4882a593Smuzhiyun 	RATE_SECTION rs;
6190*4882a593Smuzhiyun 	u8 hw_rate;
6191*4882a593Smuzhiyun 	int i;
6192*4882a593Smuzhiyun 	s16 max = UNSPECIFIED_MBM, mbm;
6193*4882a593Smuzhiyun 
6194*4882a593Smuzhiyun 	if (0)
6195*4882a593Smuzhiyun 		RTW_INFO("cck_ofdm:0x%04x, ht:0x%08x, vht:0x%016llx\n", bmp_cck_ofdm, bmp_ht, bmp_vht);
6196*4882a593Smuzhiyun 
6197*4882a593Smuzhiyun 	for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
6198*4882a593Smuzhiyun 		tx_num = rate_section_to_tx_num(rs);
6199*4882a593Smuzhiyun 		if (tx_num + 1 > hal_data->tx_nss)
6200*4882a593Smuzhiyun 			continue;
6201*4882a593Smuzhiyun 
6202*4882a593Smuzhiyun 		if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
6203*4882a593Smuzhiyun 			continue;
6204*4882a593Smuzhiyun 
6205*4882a593Smuzhiyun 		if (IS_VHT_RATE_SECTION(rs) && !IS_HARDWARE_TYPE_JAGUAR_ALL(adapter))
6206*4882a593Smuzhiyun 			continue;
6207*4882a593Smuzhiyun 
6208*4882a593Smuzhiyun 		for (i = 0; i < rates_by_sections[rs].rate_num; i++) {
6209*4882a593Smuzhiyun 			hw_rate = MRateToHwRate(rates_by_sections[rs].rates[i]);
6210*4882a593Smuzhiyun 			if (IS_LEGACY_HRATE(hw_rate)) {
6211*4882a593Smuzhiyun 				if (!(bmp_cck_ofdm & BIT(hw_rate)))
6212*4882a593Smuzhiyun 					continue;
6213*4882a593Smuzhiyun 			} else if (IS_HT_HRATE(hw_rate)) {
6214*4882a593Smuzhiyun 				if (!(bmp_ht & BIT(hw_rate - DESC_RATEMCS0)))
6215*4882a593Smuzhiyun 					continue;
6216*4882a593Smuzhiyun 			} else if (IS_VHT_HRATE(hw_rate)) {
6217*4882a593Smuzhiyun 				if (!(bmp_vht & BIT(hw_rate - DESC_RATEVHTSS1MCS0)))
6218*4882a593Smuzhiyun 					continue;
6219*4882a593Smuzhiyun 			}
6220*4882a593Smuzhiyun 
6221*4882a593Smuzhiyun 			if (rfpath < 0) /* total */
6222*4882a593Smuzhiyun 				mbm = phy_get_txpwr_total_mbm(adapter, rs, rates_by_sections[rs].rates[i], bw, cch, opch, eirp, NULL);
6223*4882a593Smuzhiyun 			else
6224*4882a593Smuzhiyun 				mbm = phy_get_txpwr_single_mbm(adapter, rfpath, rs, rates_by_sections[rs].rates[i], bw, cch, opch, eirp, NULL);
6225*4882a593Smuzhiyun 
6226*4882a593Smuzhiyun 			if (max == UNSPECIFIED_MBM || mbm > max)
6227*4882a593Smuzhiyun 				max = mbm;
6228*4882a593Smuzhiyun 		}
6229*4882a593Smuzhiyun 	}
6230*4882a593Smuzhiyun 
6231*4882a593Smuzhiyun 	return max;
6232*4882a593Smuzhiyun }
6233*4882a593Smuzhiyun 
phy_get_txpwr_single_max_mbm(_adapter * adapter,u8 rfpath,enum channel_width bw,u8 cch,u8 opch,u16 bmp_cck_ofdm,u32 bmp_ht,u64 bmp_vht,bool eirp)6234*4882a593Smuzhiyun s16 phy_get_txpwr_single_max_mbm(_adapter *adapter, u8 rfpath
6235*4882a593Smuzhiyun 	, enum channel_width bw, u8 cch, u8 opch, u16 bmp_cck_ofdm, u32 bmp_ht, u64 bmp_vht, bool eirp)
6236*4882a593Smuzhiyun {
6237*4882a593Smuzhiyun 	return _phy_get_txpwr_max_mbm(adapter, rfpath, bw, cch, opch, bmp_cck_ofdm, bmp_ht, bmp_vht, eirp);
6238*4882a593Smuzhiyun }
6239*4882a593Smuzhiyun 
phy_get_txpwr_total_max_mbm(_adapter * adapter,enum channel_width bw,u8 cch,u8 opch,u16 bmp_cck_ofdm,u32 bmp_ht,u64 bmp_vht,bool eirp)6240*4882a593Smuzhiyun s16 phy_get_txpwr_total_max_mbm(_adapter *adapter
6241*4882a593Smuzhiyun 	, enum channel_width bw, u8 cch, u8 opch, u16 bmp_cck_ofdm, u32 bmp_ht, u64 bmp_vht, bool eirp)
6242*4882a593Smuzhiyun {
6243*4882a593Smuzhiyun 	return _phy_get_txpwr_max_mbm(adapter, -1, bw, cch, opch, bmp_cck_ofdm, bmp_ht, bmp_vht, eirp);
6244*4882a593Smuzhiyun }
6245*4882a593Smuzhiyun 
6246*4882a593Smuzhiyun s8
phy_get_tx_power_final_absolute_value(_adapter * adapter,u8 rfpath,u8 rate,enum channel_width bw,u8 cch)6247*4882a593Smuzhiyun phy_get_tx_power_final_absolute_value(_adapter *adapter, u8 rfpath, u8 rate,
6248*4882a593Smuzhiyun 				      enum channel_width bw, u8 cch)
6249*4882a593Smuzhiyun {
6250*4882a593Smuzhiyun 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
6251*4882a593Smuzhiyun 	RATE_SECTION rs = mgn_rate_to_rs(rate);
6252*4882a593Smuzhiyun 	BAND_TYPE band = cch <= 14 ? BAND_ON_2_4G : BAND_ON_5G;
6253*4882a593Smuzhiyun 	s8 val;
6254*4882a593Smuzhiyun 
6255*4882a593Smuzhiyun 	val = phy_get_txpwr_target(adapter, rfpath
6256*4882a593Smuzhiyun 		, rs, rate, phy_get_current_tx_num(adapter, rate), bw, band, cch, 0, NULL);
6257*4882a593Smuzhiyun 
6258*4882a593Smuzhiyun 	val /= hal_spec->txgi_pdbm;
6259*4882a593Smuzhiyun 
6260*4882a593Smuzhiyun 	return val;
6261*4882a593Smuzhiyun }
6262