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