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