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