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