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