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 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
4084 char antenna_gain_str[8];
4085 u8 cch_20, cch_40, cch_80;
4086
4087 txpwr_mbm_get_dbm_str(rfctl->antenna_gain, 0, antenna_gain_str, 8);
4088 RTW_PRINT_SEL(sel, "antenna_gain:%s\n", antenna_gain_str);
4089
4090 cch_80 = bw == CHANNEL_WIDTH_80 ? cch : 0;
4091 cch_40 = bw == CHANNEL_WIDTH_40 ? cch : 0;
4092 cch_20 = bw == CHANNEL_WIDTH_20 ? cch : 0;
4093 if (cch_80 != 0)
4094 cch_40 = rtw_get_scch_by_cch_opch(cch_80, CHANNEL_WIDTH_80, opch);
4095 if (cch_40 != 0)
4096 cch_20 = rtw_get_scch_by_cch_opch(cch_40, CHANNEL_WIDTH_40, opch);
4097
4098 RTW_PRINT_SEL(sel, "%s", ch_width_str(bw));
4099 if (bw >= CHANNEL_WIDTH_80)
4100 _RTW_PRINT_SEL(sel, ", cch80:%u", cch_80);
4101 if (bw >= CHANNEL_WIDTH_40)
4102 _RTW_PRINT_SEL(sel, ", cch40:%u", cch_40);
4103 _RTW_PRINT_SEL(sel, ", cch20:%u\n", cch_20);
4104
4105 if (!phy_is_txpwr_user_target_specified(adapter)) {
4106 RTW_PRINT_SEL(sel, "%-9s %2s %-6s = min((%-6s + %-6s + %-6s), %-6s, %-6s) + %-6s\n"
4107 , "rate", "", "target", "byr", "btc", "extra", "lmt", "ulmt", "tpc");
4108 } else {
4109 RTW_PRINT_SEL(sel, "%-9s %2s %-6s = min(%-6s, %-6s, %-6s) + %-6s\n"
4110 , "rate", "", "target", "utgt", "lmt", "ulmt", "tpc");
4111 }
4112 }
4113
dump_txpwr_total_dbm_by_rs(void * sel,_adapter * adapter,u8 rs,enum channel_width bw,u8 cch,u8 opch)4114 void dump_txpwr_total_dbm_by_rs(void *sel, _adapter *adapter, u8 rs, enum channel_width bw, u8 cch, u8 opch)
4115 {
4116 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
4117 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
4118 u8 i;
4119 u8 band = cch > 14 ? BAND_ON_5G : BAND_ON_2_4G;
4120
4121 if (rs >= RATE_SECTION_NUM)
4122 return;
4123
4124 if (rate_section_to_tx_num(rs) + 1 > hal_data->tx_nss)
4125 return;
4126
4127 if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
4128 return;
4129
4130 if (IS_VHT_RATE_SECTION(rs) && !IS_HARDWARE_TYPE_JAGUAR_ALL(adapter))
4131 return;
4132
4133 for (i = 0; i < rates_by_sections[rs].rate_num; i++) {
4134 struct txpwr_idx_comp tic;
4135 s16 target, byr, tpc, btc, extra, utgt, lmt, ulmt;
4136 u8 tx_num;
4137
4138 target = phy_get_txpwr_total_mbm(adapter, rs, rates_by_sections[rs].rates[i], bw, cch, opch, 0, &tic);
4139 tx_num = tic.ntx_idx + 1;
4140 if (tic.limit == hal_spec->txgi_max)
4141 lmt = UNSPECIFIED_MBM;
4142 else
4143 lmt = ((tic.limit * MBM_PDBM) / hal_spec->txgi_pdbm) + mb_of_ntx(tx_num);
4144 if (tic.ulimit == hal_spec->txgi_max)
4145 ulmt = UNSPECIFIED_MBM;
4146 else
4147 ulmt = ((tic.ulimit * MBM_PDBM) / hal_spec->txgi_pdbm) + mb_of_ntx(tx_num);
4148 tpc = (tic.tpc * MBM_PDBM) / hal_spec->txgi_pdbm;
4149
4150 if (tic.utarget == hal_spec->txgi_max) {
4151 byr = ((tic.by_rate * MBM_PDBM) / hal_spec->txgi_pdbm) + mb_of_ntx(tx_num);
4152 btc = (tic.btc * MBM_PDBM) / hal_spec->txgi_pdbm;
4153 extra = (tic.extra * MBM_PDBM) / hal_spec->txgi_pdbm;
4154 dump_txpwr_total_dbm_value(sel, adapter, rates_by_sections[rs].rates[i], tic.ntx_idx
4155 , target, byr, btc, extra, lmt, ulmt, tpc);
4156 } else {
4157 utgt = ((tic.utarget * MBM_PDBM) / hal_spec->txgi_pdbm) + mb_of_ntx(tx_num);
4158 dump_txpwr_total_dbm_value_utgt(sel, adapter, rates_by_sections[rs].rates[i], tic.ntx_idx
4159 , target, utgt, lmt, ulmt, tpc);
4160 }
4161 }
4162 }
4163
4164 /* 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)4165 void dump_txpwr_total_dbm(void *sel, _adapter *adapter, enum channel_width bw, u8 cch, u8 opch)
4166 {
4167 u8 rs;
4168
4169 dump_txpwr_total_dbm_title(sel, adapter, bw, cch, opch);
4170 for (rs = CCK; rs < RATE_SECTION_NUM; rs++)
4171 dump_txpwr_total_dbm_by_rs(sel, adapter, rs, bw, cch, opch);
4172 }
4173 #endif
4174
phy_is_tx_power_limit_needed(_adapter * adapter)4175 bool phy_is_tx_power_limit_needed(_adapter *adapter)
4176 {
4177 #if CONFIG_TXPWR_LIMIT
4178 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
4179 struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
4180
4181 if (regsty->RegEnableTxPowerLimit == 1
4182 || (regsty->RegEnableTxPowerLimit == 2 && hal_data->EEPROMRegulatory == 1))
4183 return _TRUE;
4184 #endif
4185
4186 return _FALSE;
4187 }
4188
phy_is_tx_power_by_rate_needed(_adapter * adapter)4189 bool phy_is_tx_power_by_rate_needed(_adapter *adapter)
4190 {
4191 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
4192 struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
4193
4194 if (regsty->RegEnableTxPowerByRate == 1
4195 || (regsty->RegEnableTxPowerByRate == 2 && hal_data->EEPROMRegulatory != 2))
4196 return _TRUE;
4197
4198 return _FALSE;
4199 }
4200
phy_load_tx_power_by_rate(_adapter * adapter,u8 chk_file)4201 int phy_load_tx_power_by_rate(_adapter *adapter, u8 chk_file)
4202 {
4203 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
4204 int ret = _FAIL;
4205
4206 hal_data->txpwr_by_rate_loaded = 0;
4207 PHY_InitTxPowerByRate(adapter);
4208
4209 /* tx power limit is based on tx power by rate */
4210 hal_data->txpwr_limit_loaded = 0;
4211
4212 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
4213 if (chk_file
4214 && phy_ConfigBBWithPgParaFile(adapter, PHY_FILE_PHY_REG_PG) == _SUCCESS
4215 ) {
4216 hal_data->txpwr_by_rate_from_file = 1;
4217 goto post_hdl;
4218 }
4219 #endif
4220
4221 #ifdef CONFIG_EMBEDDED_FWIMG
4222 if (HAL_STATUS_SUCCESS == odm_config_bb_with_header_file(&hal_data->odmpriv, CONFIG_BB_PHY_REG_PG)) {
4223 RTW_INFO("default power by rate loaded\n");
4224 hal_data->txpwr_by_rate_from_file = 0;
4225 goto post_hdl;
4226 }
4227 #endif
4228
4229 RTW_ERR("%s():Read Tx power by rate fail\n", __func__);
4230 goto exit;
4231
4232 post_hdl:
4233 if (hal_data->odmpriv.phy_reg_pg_value_type != PHY_REG_PG_EXACT_VALUE) {
4234 rtw_warn_on(1);
4235 goto exit;
4236 }
4237
4238 PHY_TxPowerByRateConfiguration(adapter);
4239 hal_data->txpwr_by_rate_loaded = 1;
4240
4241 ret = _SUCCESS;
4242
4243 exit:
4244 return ret;
4245 }
4246
4247 #if CONFIG_TXPWR_LIMIT
phy_load_tx_power_limit(_adapter * adapter,u8 chk_file)4248 int phy_load_tx_power_limit(_adapter *adapter, u8 chk_file)
4249 {
4250 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
4251 struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
4252 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
4253 int ret = _FAIL;
4254
4255 hal_data->txpwr_limit_loaded = 0;
4256 rtw_regd_exc_list_free(rfctl);
4257 rtw_txpwr_lmt_list_free(rfctl);
4258
4259 if (!hal_data->txpwr_by_rate_loaded && regsty->target_tx_pwr_valid != _TRUE) {
4260 RTW_ERR("%s():Read Tx power limit before target tx power is specify\n", __func__);
4261 goto exit;
4262 }
4263
4264 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
4265 if (chk_file
4266 && PHY_ConfigRFWithPowerLimitTableParaFile(adapter, PHY_FILE_TXPWR_LMT) == _SUCCESS
4267 ) {
4268 hal_data->txpwr_limit_from_file = 1;
4269 goto post_hdl;
4270 }
4271 #endif
4272
4273 #ifdef CONFIG_EMBEDDED_FWIMG
4274 if (odm_config_rf_with_header_file(&hal_data->odmpriv, CONFIG_RF_TXPWR_LMT, RF_PATH_A) == HAL_STATUS_SUCCESS) {
4275 RTW_INFO("default power limit loaded\n");
4276 hal_data->txpwr_limit_from_file = 0;
4277 goto post_hdl;
4278 }
4279 #endif
4280
4281 RTW_ERR("%s():Read Tx power limit fail\n", __func__);
4282 goto exit;
4283
4284 post_hdl:
4285 phy_txpwr_lmt_post_hdl(adapter);
4286 rtw_txpwr_init_regd(rfctl);
4287 hal_data->txpwr_limit_loaded = 1;
4288 ret = _SUCCESS;
4289
4290 exit:
4291 return ret;
4292 }
4293 #endif /* CONFIG_TXPWR_LIMIT */
4294
phy_load_tx_power_ext_info(_adapter * adapter,u8 chk_file)4295 void phy_load_tx_power_ext_info(_adapter *adapter, u8 chk_file)
4296 {
4297 struct registry_priv *regsty = adapter_to_regsty(adapter);
4298
4299 /* check registy target tx power */
4300 regsty->target_tx_pwr_valid = rtw_regsty_chk_target_tx_power_valid(adapter);
4301
4302 /* power by rate */
4303 if (phy_is_tx_power_by_rate_needed(adapter)
4304 || regsty->target_tx_pwr_valid != _TRUE /* need target tx power from by rate table */
4305 )
4306 phy_load_tx_power_by_rate(adapter, chk_file);
4307
4308 /* power limit */
4309 #if CONFIG_TXPWR_LIMIT
4310 if (phy_is_tx_power_limit_needed(adapter))
4311 phy_load_tx_power_limit(adapter, chk_file);
4312 #endif
4313 }
4314
phy_reload_tx_power_ext_info(_adapter * adapter)4315 inline void phy_reload_tx_power_ext_info(_adapter *adapter)
4316 {
4317 phy_load_tx_power_ext_info(adapter, 1);
4318 }
4319
phy_reload_default_tx_power_ext_info(_adapter * adapter)4320 inline void phy_reload_default_tx_power_ext_info(_adapter *adapter)
4321 {
4322 phy_load_tx_power_ext_info(adapter, 0);
4323 }
4324
4325 #ifdef CONFIG_PROC_DEBUG
dump_tx_power_ext_info(void * sel,_adapter * adapter)4326 void dump_tx_power_ext_info(void *sel, _adapter *adapter)
4327 {
4328 struct registry_priv *regsty = adapter_to_regsty(adapter);
4329 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
4330
4331 RTW_PRINT_SEL(sel, "txpwr_pg_mode: %s\n", txpwr_pg_mode_str(hal_data->txpwr_pg_mode));
4332
4333 if (regsty->target_tx_pwr_valid == _TRUE)
4334 RTW_PRINT_SEL(sel, "target_tx_power: from registry\n");
4335 else if (hal_data->txpwr_by_rate_loaded)
4336 RTW_PRINT_SEL(sel, "target_tx_power: from power by rate\n");
4337 else
4338 RTW_PRINT_SEL(sel, "target_tx_power: unavailable\n");
4339
4340 RTW_PRINT_SEL(sel, "tx_power_by_rate: %s, %s, %s\n"
4341 , phy_is_tx_power_by_rate_needed(adapter) ? "enabled" : "disabled"
4342 , hal_data->txpwr_by_rate_loaded ? "loaded" : "unloaded"
4343 , hal_data->txpwr_by_rate_from_file ? "file" : "default"
4344 );
4345
4346 RTW_PRINT_SEL(sel, "tx_power_limit: %s, %s, %s\n"
4347 , phy_is_tx_power_limit_needed(adapter) ? "enabled" : "disabled"
4348 , hal_data->txpwr_limit_loaded ? "loaded" : "unloaded"
4349 , hal_data->txpwr_limit_from_file ? "file" : "default"
4350 );
4351 }
4352
dump_target_tx_power(void * sel,_adapter * adapter)4353 void dump_target_tx_power(void *sel, _adapter *adapter)
4354 {
4355 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
4356 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
4357 struct registry_priv *regsty = adapter_to_regsty(adapter);
4358 int path, tx_num, band, rs;
4359 u8 target;
4360
4361 for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
4362 if (!hal_is_band_support(adapter, band))
4363 continue;
4364
4365 for (path = 0; path < RF_PATH_MAX; path++) {
4366 if (!HAL_SPEC_CHK_RF_PATH(hal_spec, band, path))
4367 break;
4368
4369 RTW_PRINT_SEL(sel, "[%s][%c]%s\n", band_str(band), rf_path_char(path)
4370 , (regsty->target_tx_pwr_valid == _FALSE && hal_data->txpwr_by_rate_undefined_band_path[band][path]) ? "(dup)" : "");
4371
4372 for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
4373 tx_num = rate_section_to_tx_num(rs);
4374 if (tx_num + 1 > hal_data->tx_nss)
4375 continue;
4376
4377 if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
4378 continue;
4379
4380 if (IS_VHT_RATE_SECTION(rs) && !IS_HARDWARE_TYPE_JAGUAR_ALL(adapter))
4381 continue;
4382
4383 target = phy_get_target_txpwr(adapter, band, path, rs);
4384
4385 if (target % hal_spec->txgi_pdbm) {
4386 _RTW_PRINT_SEL(sel, "%7s: %2d.%d\n", rate_section_str(rs)
4387 , target / hal_spec->txgi_pdbm, (target % hal_spec->txgi_pdbm) * 100 / hal_spec->txgi_pdbm);
4388 } else {
4389 _RTW_PRINT_SEL(sel, "%7s: %5d\n", rate_section_str(rs)
4390 , target / hal_spec->txgi_pdbm);
4391 }
4392 }
4393 }
4394 }
4395
4396 return;
4397 }
4398
dump_tx_power_by_rate(void * sel,_adapter * adapter)4399 void dump_tx_power_by_rate(void *sel, _adapter *adapter)
4400 {
4401 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
4402 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
4403 int path, tx_num, band, n, rs;
4404 u8 rate_num, max_rate_num, base;
4405 s8 by_rate;
4406
4407 for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
4408 if (!hal_is_band_support(adapter, band))
4409 continue;
4410
4411 for (path = 0; path < RF_PATH_MAX; path++) {
4412 if (!HAL_SPEC_CHK_RF_PATH(hal_spec, band, path))
4413 break;
4414
4415 RTW_PRINT_SEL(sel, "[%s][%c]%s\n", band_str(band), rf_path_char(path)
4416 , hal_data->txpwr_by_rate_undefined_band_path[band][path] ? "(dup)" : "");
4417
4418 for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
4419 tx_num = rate_section_to_tx_num(rs);
4420 if (tx_num + 1 > hal_data->tx_nss)
4421 continue;
4422
4423 if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
4424 continue;
4425
4426 if (IS_VHT_RATE_SECTION(rs) && !IS_HARDWARE_TYPE_JAGUAR_ALL(adapter))
4427 continue;
4428
4429 if (IS_HARDWARE_TYPE_JAGUAR_ALL(adapter))
4430 max_rate_num = 10;
4431 else
4432 max_rate_num = 8;
4433 rate_num = rate_section_rate_num(rs);
4434
4435 RTW_PRINT_SEL(sel, "%7s: ", rate_section_str(rs));
4436
4437 /* dump power by rate in db */
4438 for (n = rate_num - 1; n >= 0; n--) {
4439 by_rate = PHY_GetTxPowerByRate(adapter, band, path, rs, rates_by_sections[rs].rates[n]);
4440 if (by_rate % hal_spec->txgi_pdbm) {
4441 _RTW_PRINT_SEL(sel, "%2d.%d ", by_rate / hal_spec->txgi_pdbm
4442 , (by_rate % hal_spec->txgi_pdbm) * 100 / hal_spec->txgi_pdbm);
4443 } else
4444 _RTW_PRINT_SEL(sel, "%5d ", by_rate / hal_spec->txgi_pdbm);
4445 }
4446 for (n = 0; n < max_rate_num - rate_num; n++)
4447 _RTW_PRINT_SEL(sel, "%5s ", "");
4448
4449 _RTW_PRINT_SEL(sel, "|");
4450
4451 /* dump power by rate in offset */
4452 for (n = rate_num - 1; n >= 0; n--) {
4453 by_rate = PHY_GetTxPowerByRate(adapter, band, path, rs, rates_by_sections[rs].rates[n]);
4454 base = phy_get_target_txpwr(adapter, band, path, rs);
4455 _RTW_PRINT_SEL(sel, "%3d ", by_rate - base);
4456 }
4457 RTW_PRINT_SEL(sel, "\n");
4458
4459 }
4460 }
4461 }
4462 }
4463 #endif
4464 /*
4465 * phy file path is stored in global char array rtw_phy_para_file_path
4466 * need to care about racing
4467 */
rtw_get_phy_file_path(_adapter * adapter,const char * file_name)4468 int rtw_get_phy_file_path(_adapter *adapter, const char *file_name)
4469 {
4470 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
4471 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
4472 int len = 0;
4473
4474 if (file_name) {
4475 len += snprintf(rtw_phy_para_file_path, PATH_LENGTH_MAX, "%s", rtw_phy_file_path);
4476 #if defined(CONFIG_MULTIDRV) || defined(REALTEK_CONFIG_PATH_WITH_IC_NAME_FOLDER)
4477 len += snprintf(rtw_phy_para_file_path + len, PATH_LENGTH_MAX - len, "%s/", hal_spec->ic_name);
4478 #endif
4479 len += snprintf(rtw_phy_para_file_path + len, PATH_LENGTH_MAX - len, "%s", file_name);
4480
4481 return _TRUE;
4482 }
4483 #endif
4484 return _FALSE;
4485 }
4486
4487 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
4488 int
phy_ConfigMACWithParaFile(PADAPTER Adapter,char * pFileName)4489 phy_ConfigMACWithParaFile(
4490 PADAPTER Adapter,
4491 char *pFileName
4492 )
4493 {
4494 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
4495 int rlen = 0, rtStatus = _FAIL;
4496 char *szLine, *ptmp;
4497 u32 u4bRegOffset, u4bRegValue, u4bMove;
4498
4499 if (!(Adapter->registrypriv.load_phy_file & LOAD_MAC_PARA_FILE))
4500 return rtStatus;
4501
4502 _rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
4503
4504 if ((pHalData->mac_reg_len == 0) && (pHalData->mac_reg == NULL)) {
4505 rtw_get_phy_file_path(Adapter, pFileName);
4506 if (rtw_readable_file_sz_chk(rtw_phy_para_file_path,
4507 MAX_PARA_FILE_BUF_LEN) == _TRUE) {
4508 rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
4509 if (rlen > 0) {
4510 rtStatus = _SUCCESS;
4511 pHalData->mac_reg = rtw_zvmalloc(rlen);
4512 if (pHalData->mac_reg) {
4513 _rtw_memcpy(pHalData->mac_reg, pHalData->para_file_buf, rlen);
4514 pHalData->mac_reg_len = rlen;
4515 } else
4516 RTW_INFO("%s mac_reg alloc fail !\n", __FUNCTION__);
4517 }
4518 }
4519 } else {
4520 if ((pHalData->mac_reg_len != 0) && (pHalData->mac_reg != NULL)) {
4521 _rtw_memcpy(pHalData->para_file_buf, pHalData->mac_reg, pHalData->mac_reg_len);
4522 rtStatus = _SUCCESS;
4523 } else
4524 RTW_INFO("%s(): Critical Error !!!\n", __FUNCTION__);
4525 }
4526
4527 if (rtStatus == _SUCCESS) {
4528 ptmp = pHalData->para_file_buf;
4529 for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
4530 if (!IsCommentString(szLine)) {
4531 /* Get 1st hex value as register offset */
4532 if (GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove)) {
4533 if (u4bRegOffset == 0xffff) {
4534 /* Ending. */
4535 break;
4536 }
4537
4538 /* Get 2nd hex value as register value. */
4539 szLine += u4bMove;
4540 if (GetHexValueFromString(szLine, &u4bRegValue, &u4bMove))
4541 rtw_write8(Adapter, u4bRegOffset, (u8)u4bRegValue);
4542 }
4543 }
4544 }
4545 } else
4546 RTW_INFO("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
4547
4548 return rtStatus;
4549 }
4550
4551 int
phy_ConfigBBWithParaFile(PADAPTER Adapter,char * pFileName,u32 ConfigType)4552 phy_ConfigBBWithParaFile(
4553 PADAPTER Adapter,
4554 char *pFileName,
4555 u32 ConfigType
4556 )
4557 {
4558 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
4559 int rlen = 0, rtStatus = _FAIL;
4560 char *szLine, *ptmp;
4561 u32 u4bRegOffset, u4bRegValue, u4bMove;
4562 char *pBuf = NULL;
4563 u32 *pBufLen = NULL;
4564
4565 if (!(Adapter->registrypriv.load_phy_file & LOAD_BB_PARA_FILE))
4566 return rtStatus;
4567
4568 switch (ConfigType) {
4569 case CONFIG_BB_PHY_REG:
4570 pBuf = pHalData->bb_phy_reg;
4571 pBufLen = &pHalData->bb_phy_reg_len;
4572 break;
4573 case CONFIG_BB_AGC_TAB:
4574 pBuf = pHalData->bb_agc_tab;
4575 pBufLen = &pHalData->bb_agc_tab_len;
4576 break;
4577 default:
4578 RTW_INFO("Unknown ConfigType!! %d\r\n", ConfigType);
4579 break;
4580 }
4581
4582 _rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
4583
4584 if ((pBufLen != NULL) && (*pBufLen == 0) && (pBuf == NULL)) {
4585 rtw_get_phy_file_path(Adapter, pFileName);
4586 if (rtw_readable_file_sz_chk(rtw_phy_para_file_path,
4587 MAX_PARA_FILE_BUF_LEN) == _TRUE) {
4588 rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
4589 if (rlen > 0) {
4590 rtStatus = _SUCCESS;
4591 pBuf = rtw_zvmalloc(rlen);
4592 if (pBuf) {
4593 _rtw_memcpy(pBuf, pHalData->para_file_buf, rlen);
4594 *pBufLen = rlen;
4595
4596 switch (ConfigType) {
4597 case CONFIG_BB_PHY_REG:
4598 pHalData->bb_phy_reg = pBuf;
4599 break;
4600 case CONFIG_BB_AGC_TAB:
4601 pHalData->bb_agc_tab = pBuf;
4602 break;
4603 }
4604 } else
4605 RTW_INFO("%s(): ConfigType %d alloc fail !\n", __FUNCTION__, ConfigType);
4606 }
4607 }
4608 } else {
4609 if ((pBufLen != NULL) && (*pBufLen != 0) && (pBuf != NULL)) {
4610 _rtw_memcpy(pHalData->para_file_buf, pBuf, *pBufLen);
4611 rtStatus = _SUCCESS;
4612 } else
4613 RTW_INFO("%s(): Critical Error !!!\n", __FUNCTION__);
4614 }
4615
4616 if (rtStatus == _SUCCESS) {
4617 ptmp = pHalData->para_file_buf;
4618 for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
4619 if (!IsCommentString(szLine)) {
4620 /* Get 1st hex value as register offset. */
4621 if (GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove)) {
4622 if (u4bRegOffset == 0xffff) {
4623 /* Ending. */
4624 break;
4625 } else if (u4bRegOffset == 0xfe || u4bRegOffset == 0xffe) {
4626 #ifdef CONFIG_LONG_DELAY_ISSUE
4627 rtw_msleep_os(50);
4628 #else
4629 rtw_mdelay_os(50);
4630 #endif
4631 } else if (u4bRegOffset == 0xfd)
4632 rtw_mdelay_os(5);
4633 else if (u4bRegOffset == 0xfc)
4634 rtw_mdelay_os(1);
4635 else if (u4bRegOffset == 0xfb)
4636 rtw_udelay_os(50);
4637 else if (u4bRegOffset == 0xfa)
4638 rtw_udelay_os(5);
4639 else if (u4bRegOffset == 0xf9)
4640 rtw_udelay_os(1);
4641
4642 /* Get 2nd hex value as register value. */
4643 szLine += u4bMove;
4644 if (GetHexValueFromString(szLine, &u4bRegValue, &u4bMove)) {
4645 /* RTW_INFO("[BB-ADDR]%03lX=%08lX\n", u4bRegOffset, u4bRegValue); */
4646 phy_set_bb_reg(Adapter, u4bRegOffset, bMaskDWord, u4bRegValue);
4647
4648 if (u4bRegOffset == 0xa24)
4649 pHalData->odmpriv.rf_calibrate_info.rega24 = u4bRegValue;
4650
4651 /* Add 1us delay between BB/RF register setting. */
4652 rtw_udelay_os(1);
4653 }
4654 }
4655 }
4656 }
4657 } else
4658 RTW_INFO("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
4659
4660 return rtStatus;
4661 }
4662
4663 void
phy_DecryptBBPgParaFile(PADAPTER Adapter,char * buffer)4664 phy_DecryptBBPgParaFile(
4665 PADAPTER Adapter,
4666 char *buffer
4667 )
4668 {
4669 u32 i = 0, j = 0;
4670 u8 map[95] = {0};
4671 u8 currentChar;
4672 char *BufOfLines, *ptmp;
4673
4674 /* RTW_INFO("=====>phy_DecryptBBPgParaFile()\n"); */
4675 /* 32 the ascii code of the first visable char, 126 the last one */
4676 for (i = 0; i < 95; ++i)
4677 map[i] = (u8)(94 - i);
4678
4679 ptmp = buffer;
4680 i = 0;
4681 for (BufOfLines = GetLineFromBuffer(ptmp); BufOfLines != NULL; BufOfLines = GetLineFromBuffer(ptmp)) {
4682 /* RTW_INFO("Encrypted Line: %s\n", BufOfLines); */
4683
4684 for (j = 0; j < strlen(BufOfLines); ++j) {
4685 currentChar = BufOfLines[j];
4686
4687 if (currentChar == '\0')
4688 break;
4689
4690 currentChar -= (u8)((((i + j) * 3) % 128));
4691
4692 BufOfLines[j] = map[currentChar - 32] + 32;
4693 }
4694 /* RTW_INFO("Decrypted Line: %s\n", BufOfLines ); */
4695 if (strlen(BufOfLines) != 0)
4696 i++;
4697 BufOfLines[strlen(BufOfLines)] = '\n';
4698 }
4699 }
4700
4701 #ifndef DBG_TXPWR_BY_RATE_FILE_PARSE
4702 #define DBG_TXPWR_BY_RATE_FILE_PARSE 0
4703 #endif
4704
4705 int
phy_ParseBBPgParaFile(PADAPTER Adapter,char * buffer)4706 phy_ParseBBPgParaFile(
4707 PADAPTER Adapter,
4708 char *buffer
4709 )
4710 {
4711 int rtStatus = _FAIL;
4712 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
4713 struct hal_spec_t *hal_spec = GET_HAL_SPEC(Adapter);
4714 char *szLine, *ptmp;
4715 u32 u4bRegOffset, u4bRegMask;
4716 u32 u4bMove;
4717 BOOLEAN firstLine = _TRUE;
4718 u8 tx_num = 0;
4719 u8 band = 0, rf_path = 0;
4720
4721 if (Adapter->registrypriv.RegDecryptCustomFile == 1)
4722 phy_DecryptBBPgParaFile(Adapter, buffer);
4723
4724 ptmp = buffer;
4725 for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
4726 if (isAllSpaceOrTab(szLine, sizeof(*szLine)))
4727 continue;
4728
4729 if (!IsCommentString(szLine)) {
4730 /* Get header info (relative value or exact value) */
4731 if (firstLine) {
4732 if (strncmp(szLine, "#[v1]", 5) == 0
4733 || strncmp(szLine, "#[v2]", 5) == 0)
4734 pHalData->odmpriv.phy_reg_pg_version = szLine[3] - '0';
4735 else {
4736 RTW_ERR("The format in PHY_REG_PG are invalid %s\n", szLine);
4737 goto exit;
4738 }
4739
4740 if (strncmp(szLine + 5, "[Exact]#", 8) == 0) {
4741 pHalData->odmpriv.phy_reg_pg_value_type = PHY_REG_PG_EXACT_VALUE;
4742 firstLine = _FALSE;
4743 continue;
4744 } else {
4745 RTW_ERR("The values in PHY_REG_PG are invalid %s\n", szLine);
4746 goto exit;
4747 }
4748 }
4749
4750 if (pHalData->odmpriv.phy_reg_pg_version > 0) {
4751 u32 index = 0;
4752
4753 if (strncmp(szLine, "0xffff", 6) == 0)
4754 break;
4755
4756 if (strncmp(szLine, "#[END]#", 7)) {
4757 /* load the table label info */
4758 if (szLine[0] == '#') {
4759 index = 0;
4760 if (strncmp(szLine, "#[2.4G]", 7) == 0) {
4761 band = BAND_ON_2_4G;
4762 index += 8;
4763 } else if (strncmp(szLine, "#[5G]", 5) == 0) {
4764 band = BAND_ON_5G;
4765 index += 6;
4766 } else {
4767 RTW_ERR("Invalid band %s in PHY_REG_PG.txt\n", szLine);
4768 goto exit;
4769 }
4770
4771 rf_path = szLine[index] - 'A';
4772 if (DBG_TXPWR_BY_RATE_FILE_PARSE)
4773 RTW_INFO(" Table label Band %d, RfPath %d\n", band, rf_path );
4774 } else { /* load rows of tables */
4775 if (szLine[1] == '1')
4776 tx_num = RF_1TX;
4777 else if (szLine[1] == '2')
4778 tx_num = RF_2TX;
4779 else if (szLine[1] == '3')
4780 tx_num = RF_3TX;
4781 else if (szLine[1] == '4')
4782 tx_num = RF_4TX;
4783 else {
4784 RTW_ERR("Invalid row in PHY_REG_PG.txt '%c'(%d)\n", szLine[1], szLine[1]);
4785 goto exit;
4786 }
4787
4788 while (szLine[index] != ']')
4789 ++index;
4790 ++index;/* skip ] */
4791
4792 /* Get 2nd hex value as register offset. */
4793 szLine += index;
4794 if (GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove))
4795 szLine += u4bMove;
4796 else
4797 goto exit;
4798
4799 /* Get 2nd hex value as register mask. */
4800 if (GetHexValueFromString(szLine, &u4bRegMask, &u4bMove))
4801 szLine += u4bMove;
4802 else
4803 goto exit;
4804
4805 if (pHalData->odmpriv.phy_reg_pg_value_type == PHY_REG_PG_EXACT_VALUE) {
4806 u32 combineValue = 0;
4807 u8 integer = 0, fraction = 0;
4808
4809 if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
4810 szLine += u4bMove;
4811 else
4812 goto exit;
4813
4814 integer *= hal_spec->txgi_pdbm;
4815 integer += ((u16)fraction * (u16)hal_spec->txgi_pdbm) / 100;
4816 if (pHalData->odmpriv.phy_reg_pg_version == 1)
4817 combineValue |= (((integer / 10) << 4) + (integer % 10));
4818 else
4819 combineValue |= integer;
4820
4821 if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
4822 szLine += u4bMove;
4823 else
4824 goto exit;
4825
4826 integer *= hal_spec->txgi_pdbm;
4827 integer += ((u16)fraction * (u16)hal_spec->txgi_pdbm) / 100;
4828 combineValue <<= 8;
4829 if (pHalData->odmpriv.phy_reg_pg_version == 1)
4830 combineValue |= (((integer / 10) << 4) + (integer % 10));
4831 else
4832 combineValue |= integer;
4833
4834 if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
4835 szLine += u4bMove;
4836 else
4837 goto exit;
4838
4839 integer *= hal_spec->txgi_pdbm;
4840 integer += ((u16)fraction * (u16)hal_spec->txgi_pdbm) / 100;
4841 combineValue <<= 8;
4842 if (pHalData->odmpriv.phy_reg_pg_version == 1)
4843 combineValue |= (((integer / 10) << 4) + (integer % 10));
4844 else
4845 combineValue |= integer;
4846
4847 if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
4848 szLine += u4bMove;
4849 else
4850 goto exit;
4851
4852 integer *= hal_spec->txgi_pdbm;
4853 integer += ((u16)fraction * (u16)hal_spec->txgi_pdbm) / 100;
4854 combineValue <<= 8;
4855 if (pHalData->odmpriv.phy_reg_pg_version == 1)
4856 combineValue |= (((integer / 10) << 4) + (integer % 10));
4857 else
4858 combineValue |= integer;
4859
4860 phy_store_tx_power_by_rate(Adapter, band, rf_path, tx_num, u4bRegOffset, u4bRegMask, combineValue);
4861
4862 if (DBG_TXPWR_BY_RATE_FILE_PARSE)
4863 RTW_INFO("addr:0x%3x mask:0x%08x %dTx = 0x%08x\n", u4bRegOffset, u4bRegMask, tx_num + 1, combineValue);
4864 }
4865 }
4866 }
4867 }
4868 }
4869 }
4870
4871 rtStatus = _SUCCESS;
4872
4873 exit:
4874 RTW_INFO("%s return %d\n", __func__, rtStatus);
4875 return rtStatus;
4876 }
4877
4878 int
phy_ConfigBBWithPgParaFile(PADAPTER Adapter,const char * pFileName)4879 phy_ConfigBBWithPgParaFile(
4880 PADAPTER Adapter,
4881 const char *pFileName)
4882 {
4883 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
4884 int rlen = 0, rtStatus = _FAIL;
4885
4886 if (!(Adapter->registrypriv.load_phy_file & LOAD_BB_PG_PARA_FILE))
4887 return rtStatus;
4888
4889 _rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
4890
4891 if (pHalData->bb_phy_reg_pg == NULL) {
4892 rtw_get_phy_file_path(Adapter, pFileName);
4893 if (rtw_readable_file_sz_chk(rtw_phy_para_file_path,
4894 MAX_PARA_FILE_BUF_LEN) == _TRUE) {
4895 rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
4896 if (rlen > 0) {
4897 rtStatus = _SUCCESS;
4898 pHalData->bb_phy_reg_pg = rtw_zvmalloc(rlen);
4899 if (pHalData->bb_phy_reg_pg) {
4900 _rtw_memcpy(pHalData->bb_phy_reg_pg, pHalData->para_file_buf, rlen);
4901 pHalData->bb_phy_reg_pg_len = rlen;
4902 } else
4903 RTW_INFO("%s bb_phy_reg_pg alloc fail !\n", __FUNCTION__);
4904 }
4905 }
4906 } else {
4907 if ((pHalData->bb_phy_reg_pg_len != 0) && (pHalData->bb_phy_reg_pg != NULL)) {
4908 _rtw_memcpy(pHalData->para_file_buf, pHalData->bb_phy_reg_pg, pHalData->bb_phy_reg_pg_len);
4909 rtStatus = _SUCCESS;
4910 } else
4911 RTW_INFO("%s(): Critical Error !!!\n", __FUNCTION__);
4912 }
4913
4914 if (rtStatus == _SUCCESS) {
4915 /* RTW_INFO("phy_ConfigBBWithPgParaFile(): read %s ok\n", pFileName); */
4916 rtStatus = phy_ParseBBPgParaFile(Adapter, pHalData->para_file_buf);
4917 } else
4918 RTW_INFO("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
4919
4920 return rtStatus;
4921 }
4922
4923 #if (MP_DRIVER == 1)
4924
4925 int
phy_ConfigBBWithMpParaFile(PADAPTER Adapter,char * pFileName)4926 phy_ConfigBBWithMpParaFile(
4927 PADAPTER Adapter,
4928 char *pFileName
4929 )
4930 {
4931 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
4932 int rlen = 0, rtStatus = _FAIL;
4933 char *szLine, *ptmp;
4934 u32 u4bRegOffset, u4bRegValue, u4bMove;
4935
4936 if (!(Adapter->registrypriv.load_phy_file & LOAD_BB_MP_PARA_FILE))
4937 return rtStatus;
4938
4939 _rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
4940
4941 if ((pHalData->bb_phy_reg_mp_len == 0) && (pHalData->bb_phy_reg_mp == NULL)) {
4942 rtw_get_phy_file_path(Adapter, pFileName);
4943 if (rtw_readable_file_sz_chk(rtw_phy_para_file_path,
4944 MAX_PARA_FILE_BUF_LEN) == _TRUE) {
4945 rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
4946 if (rlen > 0) {
4947 rtStatus = _SUCCESS;
4948 pHalData->bb_phy_reg_mp = rtw_zvmalloc(rlen);
4949 if (pHalData->bb_phy_reg_mp) {
4950 _rtw_memcpy(pHalData->bb_phy_reg_mp, pHalData->para_file_buf, rlen);
4951 pHalData->bb_phy_reg_mp_len = rlen;
4952 } else
4953 RTW_INFO("%s bb_phy_reg_mp alloc fail !\n", __FUNCTION__);
4954 }
4955 }
4956 } else {
4957 if ((pHalData->bb_phy_reg_mp_len != 0) && (pHalData->bb_phy_reg_mp != NULL)) {
4958 _rtw_memcpy(pHalData->para_file_buf, pHalData->bb_phy_reg_mp, pHalData->bb_phy_reg_mp_len);
4959 rtStatus = _SUCCESS;
4960 } else
4961 RTW_INFO("%s(): Critical Error !!!\n", __FUNCTION__);
4962 }
4963
4964 if (rtStatus == _SUCCESS) {
4965 /* RTW_INFO("phy_ConfigBBWithMpParaFile(): read %s ok\n", pFileName); */
4966
4967 ptmp = pHalData->para_file_buf;
4968 for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
4969 if (!IsCommentString(szLine)) {
4970 /* Get 1st hex value as register offset. */
4971 if (GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove)) {
4972 if (u4bRegOffset == 0xffff) {
4973 /* Ending. */
4974 break;
4975 } else if (u4bRegOffset == 0xfe || u4bRegOffset == 0xffe) {
4976 #ifdef CONFIG_LONG_DELAY_ISSUE
4977 rtw_msleep_os(50);
4978 #else
4979 rtw_mdelay_os(50);
4980 #endif
4981 } else if (u4bRegOffset == 0xfd)
4982 rtw_mdelay_os(5);
4983 else if (u4bRegOffset == 0xfc)
4984 rtw_mdelay_os(1);
4985 else if (u4bRegOffset == 0xfb)
4986 rtw_udelay_os(50);
4987 else if (u4bRegOffset == 0xfa)
4988 rtw_udelay_os(5);
4989 else if (u4bRegOffset == 0xf9)
4990 rtw_udelay_os(1);
4991
4992 /* Get 2nd hex value as register value. */
4993 szLine += u4bMove;
4994 if (GetHexValueFromString(szLine, &u4bRegValue, &u4bMove)) {
4995 /* RTW_INFO("[ADDR]%03lX=%08lX\n", u4bRegOffset, u4bRegValue); */
4996 phy_set_bb_reg(Adapter, u4bRegOffset, bMaskDWord, u4bRegValue);
4997
4998 /* Add 1us delay between BB/RF register setting. */
4999 rtw_udelay_os(1);
5000 }
5001 }
5002 }
5003 }
5004 } else
5005 RTW_INFO("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
5006
5007 return rtStatus;
5008 }
5009
5010 #endif
5011
5012 int
PHY_ConfigRFWithParaFile(PADAPTER Adapter,char * pFileName,enum rf_path eRFPath)5013 PHY_ConfigRFWithParaFile(
5014 PADAPTER Adapter,
5015 char *pFileName,
5016 enum rf_path eRFPath
5017 )
5018 {
5019 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
5020 int rlen = 0, rtStatus = _FAIL;
5021 char *szLine, *ptmp;
5022 u32 u4bRegOffset, u4bRegValue, u4bMove;
5023 u16 i;
5024 char *pBuf = NULL;
5025 u32 *pBufLen = NULL;
5026
5027 if (!(Adapter->registrypriv.load_phy_file & LOAD_RF_PARA_FILE))
5028 return rtStatus;
5029
5030 switch (eRFPath) {
5031 case RF_PATH_A:
5032 pBuf = pHalData->rf_radio_a;
5033 pBufLen = &pHalData->rf_radio_a_len;
5034 break;
5035 case RF_PATH_B:
5036 pBuf = pHalData->rf_radio_b;
5037 pBufLen = &pHalData->rf_radio_b_len;
5038 break;
5039 default:
5040 RTW_INFO("Unknown RF path!! %d\r\n", eRFPath);
5041 break;
5042 }
5043
5044 _rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
5045
5046 if ((pBufLen != NULL) && (*pBufLen == 0) && (pBuf == NULL)) {
5047 rtw_get_phy_file_path(Adapter, pFileName);
5048 if (rtw_readable_file_sz_chk(rtw_phy_para_file_path,
5049 MAX_PARA_FILE_BUF_LEN) == _TRUE) {
5050 rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
5051 if (rlen > 0) {
5052 rtStatus = _SUCCESS;
5053 pBuf = rtw_zvmalloc(rlen);
5054 if (pBuf) {
5055 _rtw_memcpy(pBuf, pHalData->para_file_buf, rlen);
5056 *pBufLen = rlen;
5057
5058 switch (eRFPath) {
5059 case RF_PATH_A:
5060 pHalData->rf_radio_a = pBuf;
5061 break;
5062 case RF_PATH_B:
5063 pHalData->rf_radio_b = pBuf;
5064 break;
5065 default:
5066 RTW_INFO("Unknown RF path!! %d\r\n", eRFPath);
5067 break;
5068 }
5069 } else
5070 RTW_INFO("%s(): eRFPath=%d alloc fail !\n", __FUNCTION__, eRFPath);
5071 }
5072 }
5073 } else {
5074 if ((pBufLen != NULL) && (*pBufLen != 0) && (pBuf != NULL)) {
5075 _rtw_memcpy(pHalData->para_file_buf, pBuf, *pBufLen);
5076 rtStatus = _SUCCESS;
5077 } else
5078 RTW_INFO("%s(): Critical Error !!!\n", __FUNCTION__);
5079 }
5080
5081 if (rtStatus == _SUCCESS) {
5082 /* RTW_INFO("%s(): read %s successfully\n", __FUNCTION__, pFileName); */
5083
5084 ptmp = pHalData->para_file_buf;
5085 for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
5086 if (!IsCommentString(szLine)) {
5087 /* Get 1st hex value as register offset. */
5088 if (GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove)) {
5089 if (u4bRegOffset == 0xfe || u4bRegOffset == 0xffe) {
5090 /* Deay specific ms. Only RF configuration require delay. */
5091 #ifdef CONFIG_LONG_DELAY_ISSUE
5092 rtw_msleep_os(50);
5093 #else
5094 rtw_mdelay_os(50);
5095 #endif
5096 } else if (u4bRegOffset == 0xfd) {
5097 /* delay_ms(5); */
5098 for (i = 0; i < 100; i++)
5099 rtw_udelay_os(MAX_STALL_TIME);
5100 } else if (u4bRegOffset == 0xfc) {
5101 /* delay_ms(1); */
5102 for (i = 0; i < 20; i++)
5103 rtw_udelay_os(MAX_STALL_TIME);
5104 } else if (u4bRegOffset == 0xfb)
5105 rtw_udelay_os(50);
5106 else if (u4bRegOffset == 0xfa)
5107 rtw_udelay_os(5);
5108 else if (u4bRegOffset == 0xf9)
5109 rtw_udelay_os(1);
5110 else if (u4bRegOffset == 0xffff)
5111 break;
5112
5113 /* Get 2nd hex value as register value. */
5114 szLine += u4bMove;
5115 if (GetHexValueFromString(szLine, &u4bRegValue, &u4bMove)) {
5116 phy_set_rf_reg(Adapter, eRFPath, u4bRegOffset, bRFRegOffsetMask, u4bRegValue);
5117
5118 /* Temp add, for frequency lock, if no delay, that may cause */
5119 /* frequency shift, ex: 2412MHz => 2417MHz */
5120 /* If frequency shift, the following action may works. */
5121 /* Fractional-N table in radio_a.txt */
5122 /* 0x2a 0x00001 */ /* channel 1 */
5123 /* 0x2b 0x00808 frequency divider. */
5124 /* 0x2b 0x53333 */
5125 /* 0x2c 0x0000c */
5126 rtw_udelay_os(1);
5127 }
5128 }
5129 }
5130 }
5131 } else
5132 RTW_INFO("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
5133
5134 return rtStatus;
5135 }
5136
5137 void
initDeltaSwingIndexTables(PADAPTER Adapter,char * Band,char * Path,char * Sign,char * Channel,char * Rate,char * Data)5138 initDeltaSwingIndexTables(
5139 PADAPTER Adapter,
5140 char *Band,
5141 char *Path,
5142 char *Sign,
5143 char *Channel,
5144 char *Rate,
5145 char *Data
5146 )
5147 {
5148 #define STR_EQUAL_5G(_band, _path, _sign, _rate, _chnl) \
5149 ((strcmp(Band, _band) == 0) && (strcmp(Path, _path) == 0) && (strcmp(Sign, _sign) == 0) &&\
5150 (strcmp(Rate, _rate) == 0) && (strcmp(Channel, _chnl) == 0)\
5151 )
5152 #define STR_EQUAL_2G(_band, _path, _sign, _rate) \
5153 ((strcmp(Band, _band) == 0) && (strcmp(Path, _path) == 0) && (strcmp(Sign, _sign) == 0) &&\
5154 (strcmp(Rate, _rate) == 0)\
5155 )
5156
5157 #define STORE_SWING_TABLE(_array, _iteratedIdx) \
5158 do { \
5159 for (token = strsep(&Data, delim); token != NULL; token = strsep(&Data, delim)) {\
5160 sscanf(token, "%d", &idx);\
5161 _array[_iteratedIdx++] = (u8)idx;\
5162 } } while (0)\
5163
5164 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
5165 struct dm_struct *pDM_Odm = &pHalData->odmpriv;
5166 struct dm_rf_calibration_struct *pRFCalibrateInfo = &(pDM_Odm->rf_calibrate_info);
5167 u32 j = 0;
5168 char *token;
5169 char delim[] = ",";
5170 u32 idx = 0;
5171
5172 /* RTW_INFO("===>initDeltaSwingIndexTables(): Band: %s;\nPath: %s;\nSign: %s;\nChannel: %s;\nRate: %s;\n, Data: %s;\n", */
5173 /* Band, Path, Sign, Channel, Rate, Data); */
5174
5175 if (STR_EQUAL_2G("2G", "A", "+", "CCK"))
5176 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2g_cck_a_p, j);
5177 else if (STR_EQUAL_2G("2G", "A", "-", "CCK"))
5178 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2g_cck_a_n, j);
5179 else if (STR_EQUAL_2G("2G", "B", "+", "CCK"))
5180 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2g_cck_b_p, j);
5181 else if (STR_EQUAL_2G("2G", "B", "-", "CCK"))
5182 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2g_cck_b_n, j);
5183 else if (STR_EQUAL_2G("2G", "A", "+", "ALL"))
5184 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2ga_p, j);
5185 else if (STR_EQUAL_2G("2G", "A", "-", "ALL"))
5186 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2ga_n, j);
5187 else if (STR_EQUAL_2G("2G", "B", "+", "ALL"))
5188 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2gb_p, j);
5189 else if (STR_EQUAL_2G("2G", "B", "-", "ALL"))
5190 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2gb_n, j);
5191 else if (STR_EQUAL_5G("5G", "A", "+", "ALL", "0"))
5192 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_p[0], j);
5193 else if (STR_EQUAL_5G("5G", "A", "-", "ALL", "0"))
5194 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_n[0], j);
5195 else if (STR_EQUAL_5G("5G", "B", "+", "ALL", "0"))
5196 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_p[0], j);
5197 else if (STR_EQUAL_5G("5G", "B", "-", "ALL", "0"))
5198 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_n[0], j);
5199 else if (STR_EQUAL_5G("5G", "A", "+", "ALL", "1"))
5200 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_p[1], j);
5201 else if (STR_EQUAL_5G("5G", "A", "-", "ALL", "1"))
5202 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_n[1], j);
5203 else if (STR_EQUAL_5G("5G", "B", "+", "ALL", "1"))
5204 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_p[1], j);
5205 else if (STR_EQUAL_5G("5G", "B", "-", "ALL", "1"))
5206 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_n[1], j);
5207 else if (STR_EQUAL_5G("5G", "A", "+", "ALL", "2"))
5208 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_p[2], j);
5209 else if (STR_EQUAL_5G("5G", "A", "-", "ALL", "2"))
5210 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_n[2], j);
5211 else if (STR_EQUAL_5G("5G", "B", "+", "ALL", "2"))
5212 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_p[2], j);
5213 else if (STR_EQUAL_5G("5G", "B", "-", "ALL", "2"))
5214 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_n[2], j);
5215 else if (STR_EQUAL_5G("5G", "A", "+", "ALL", "3"))
5216 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_p[3], j);
5217 else if (STR_EQUAL_5G("5G", "A", "-", "ALL", "3"))
5218 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_n[3], j);
5219 else if (STR_EQUAL_5G("5G", "B", "+", "ALL", "3"))
5220 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_p[3], j);
5221 else if (STR_EQUAL_5G("5G", "B", "-", "ALL", "3"))
5222 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_n[3], j);
5223 else
5224 RTW_INFO("===>initDeltaSwingIndexTables(): The input is invalid!!\n");
5225 }
5226
5227 int
PHY_ConfigRFWithTxPwrTrackParaFile(PADAPTER Adapter,char * pFileName)5228 PHY_ConfigRFWithTxPwrTrackParaFile(
5229 PADAPTER Adapter,
5230 char *pFileName
5231 )
5232 {
5233 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
5234 struct dm_struct *pDM_Odm = &pHalData->odmpriv;
5235 int rlen = 0, rtStatus = _FAIL;
5236 char *szLine, *ptmp;
5237 u32 i = 0;
5238
5239 if (!(Adapter->registrypriv.load_phy_file & LOAD_RF_TXPWR_TRACK_PARA_FILE))
5240 return rtStatus;
5241
5242 _rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
5243
5244 if ((pHalData->rf_tx_pwr_track_len == 0) && (pHalData->rf_tx_pwr_track == NULL)) {
5245 rtw_get_phy_file_path(Adapter, pFileName);
5246 if (rtw_readable_file_sz_chk(rtw_phy_para_file_path,
5247 MAX_PARA_FILE_BUF_LEN) == _TRUE) {
5248 rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
5249 if (rlen > 0) {
5250 rtStatus = _SUCCESS;
5251 pHalData->rf_tx_pwr_track = rtw_zvmalloc(rlen);
5252 if (pHalData->rf_tx_pwr_track) {
5253 _rtw_memcpy(pHalData->rf_tx_pwr_track, pHalData->para_file_buf, rlen);
5254 pHalData->rf_tx_pwr_track_len = rlen;
5255 } else
5256 RTW_INFO("%s rf_tx_pwr_track alloc fail !\n", __FUNCTION__);
5257 }
5258 }
5259 } else {
5260 if ((pHalData->rf_tx_pwr_track_len != 0) && (pHalData->rf_tx_pwr_track != NULL)) {
5261 _rtw_memcpy(pHalData->para_file_buf, pHalData->rf_tx_pwr_track, pHalData->rf_tx_pwr_track_len);
5262 rtStatus = _SUCCESS;
5263 } else
5264 RTW_INFO("%s(): Critical Error !!!\n", __FUNCTION__);
5265 }
5266
5267 if (rtStatus == _SUCCESS) {
5268 /* RTW_INFO("%s(): read %s successfully\n", __FUNCTION__, pFileName); */
5269
5270 ptmp = pHalData->para_file_buf;
5271 for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
5272 if (!IsCommentString(szLine)) {
5273 char band[5] = "", path[5] = "", sign[5] = "";
5274 char chnl[5] = "", rate[10] = "";
5275 char data[300] = ""; /* 100 is too small */
5276
5277 if (strlen(szLine) < 10 || szLine[0] != '[')
5278 continue;
5279
5280 strncpy(band, szLine + 1, 2);
5281 strncpy(path, szLine + 5, 1);
5282 strncpy(sign, szLine + 8, 1);
5283
5284 i = 10; /* szLine+10 */
5285 if (!ParseQualifiedString(szLine, &i, rate, '[', ']')) {
5286 /* RTW_INFO("Fail to parse rate!\n"); */
5287 }
5288 if (!ParseQualifiedString(szLine, &i, chnl, '[', ']')) {
5289 /* RTW_INFO("Fail to parse channel group!\n"); */
5290 }
5291 while (szLine[i] != '{' && i < strlen(szLine))
5292 i++;
5293 if (!ParseQualifiedString(szLine, &i, data, '{', '}')) {
5294 /* RTW_INFO("Fail to parse data!\n"); */
5295 }
5296
5297 initDeltaSwingIndexTables(Adapter, band, path, sign, chnl, rate, data);
5298 }
5299 }
5300 } else
5301 RTW_INFO("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
5302 #if 0
5303 for (i = 0; i < DELTA_SWINGIDX_SIZE; ++i) {
5304 RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_2ga_p[%d] = %d\n", i, pRFCalibrateInfo->delta_swing_table_idx_2ga_p[i]);
5305 RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_2ga_n[%d] = %d\n", i, pRFCalibrateInfo->delta_swing_table_idx_2ga_n[i]);
5306 RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_2gb_p[%d] = %d\n", i, pRFCalibrateInfo->delta_swing_table_idx_2gb_p[i]);
5307 RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_2gb_n[%d] = %d\n", i, pRFCalibrateInfo->delta_swing_table_idx_2gb_n[i]);
5308 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]);
5309 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]);
5310 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]);
5311 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]);
5312
5313 for (j = 0; j < 3; ++j) {
5314 RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_5ga_p[%d][%d] = %d\n", j, i, pRFCalibrateInfo->delta_swing_table_idx_5ga_p[j][i]);
5315 RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_5ga_n[%d][%d] = %d\n", j, i, pRFCalibrateInfo->delta_swing_table_idx_5ga_n[j][i]);
5316 RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_5gb_p[%d][%d] = %d\n", j, i, pRFCalibrateInfo->delta_swing_table_idx_5gb_p[j][i]);
5317 RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_5gb_n[%d][%d] = %d\n", j, i, pRFCalibrateInfo->delta_swing_table_idx_5gb_n[j][i]);
5318 }
5319 }
5320 #endif
5321 return rtStatus;
5322 }
5323
5324 #if CONFIG_TXPWR_LIMIT
5325
5326 #ifndef DBG_TXPWR_LMT_FILE_PARSE
5327 #define DBG_TXPWR_LMT_FILE_PARSE 0
5328 #endif
5329
5330 #define PARSE_RET_NO_HDL 0
5331 #define PARSE_RET_SUCCESS 1
5332 #define PARSE_RET_FAIL 2
5333
5334 /*
5335 * @@Ver=2.0
5336 * or
5337 * @@DomainCode=0x28, Regulation=C6
5338 * or
5339 * @@CountryCode=GB, Regulation=C7
5340 */
parse_reg_exc_config(_adapter * adapter,char * szLine)5341 static u8 parse_reg_exc_config(_adapter *adapter, char *szLine)
5342 {
5343 #define VER_PREFIX "Ver="
5344 #define DOMAIN_PREFIX "DomainCode=0x"
5345 #define COUNTRY_PREFIX "CountryCode="
5346 #define REG_PREFIX "Regulation="
5347
5348 const u8 ver_prefix_len = strlen(VER_PREFIX);
5349 const u8 domain_prefix_len = strlen(DOMAIN_PREFIX);
5350 const u8 country_prefix_len = strlen(COUNTRY_PREFIX);
5351 const u8 reg_prefix_len = strlen(REG_PREFIX);
5352 u32 i, i_val_s, i_val_e;
5353 u32 j;
5354 u8 domain = 0xFF;
5355 char *country = NULL;
5356 u8 parse_reg = 0;
5357
5358 if (szLine[0] != '@' || szLine[1] != '@')
5359 return PARSE_RET_NO_HDL;
5360
5361 i = 2;
5362 if (strncmp(szLine + i, VER_PREFIX, ver_prefix_len) == 0)
5363 ; /* nothing to do */
5364 else if (strncmp(szLine + i, DOMAIN_PREFIX, domain_prefix_len) == 0) {
5365 /* get string after domain prefix to ',' */
5366 i += domain_prefix_len;
5367 i_val_s = i;
5368 while (szLine[i] != ',') {
5369 if (szLine[i] == '\0')
5370 return PARSE_RET_FAIL;
5371 i++;
5372 }
5373 i_val_e = i;
5374
5375 /* check if all hex */
5376 for (j = i_val_s; j < i_val_e; j++)
5377 if (IsHexDigit(szLine[j]) == _FALSE)
5378 return PARSE_RET_FAIL;
5379
5380 /* get value from hex string */
5381 if (sscanf(szLine + i_val_s, "%hhx", &domain) != 1)
5382 return PARSE_RET_FAIL;
5383
5384 parse_reg = 1;
5385 } else if (strncmp(szLine + i, COUNTRY_PREFIX, country_prefix_len) == 0) {
5386 /* get string after country prefix to ',' */
5387 i += country_prefix_len;
5388 i_val_s = i;
5389 while (szLine[i] != ',') {
5390 if (szLine[i] == '\0')
5391 return PARSE_RET_FAIL;
5392 i++;
5393 }
5394 i_val_e = i;
5395
5396 if (i_val_e - i_val_s != 2)
5397 return PARSE_RET_FAIL;
5398
5399 /* check if all alpha */
5400 for (j = i_val_s; j < i_val_e; j++)
5401 if (is_alpha(szLine[j]) == _FALSE)
5402 return PARSE_RET_FAIL;
5403
5404 country = szLine + i_val_s;
5405
5406 parse_reg = 1;
5407
5408 } else
5409 return PARSE_RET_FAIL;
5410
5411 if (parse_reg) {
5412 /* move to 'R' */
5413 while (szLine[i] != 'R') {
5414 if (szLine[i] == '\0')
5415 return PARSE_RET_FAIL;
5416 i++;
5417 }
5418
5419 /* check if matching regulation prefix */
5420 if (strncmp(szLine + i, REG_PREFIX, reg_prefix_len) != 0)
5421 return PARSE_RET_FAIL;
5422
5423 /* get string after regulation prefix ending with space */
5424 i += reg_prefix_len;
5425 i_val_s = i;
5426 while (szLine[i] != ' ' && szLine[i] != '\t' && szLine[i] != '\0')
5427 i++;
5428
5429 if (i == i_val_s)
5430 return PARSE_RET_FAIL;
5431
5432 rtw_regd_exc_add_with_nlen(adapter_to_rfctl(adapter), country, domain, szLine + i_val_s, i - i_val_s);
5433 }
5434
5435 return PARSE_RET_SUCCESS;
5436 }
5437
5438 static int
phy_ParsePowerLimitTableFile(PADAPTER Adapter,char * buffer)5439 phy_ParsePowerLimitTableFile(
5440 PADAPTER Adapter,
5441 char *buffer
5442 )
5443 {
5444 #define LD_STAGE_EXC_MAPPING 0
5445 #define LD_STAGE_TAB_DEFINE 1
5446 #define LD_STAGE_TAB_START 2
5447 #define LD_STAGE_COLUMN_DEFINE 3
5448 #define LD_STAGE_CH_ROW 4
5449
5450 int rtStatus = _FAIL;
5451 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
5452 struct hal_spec_t *hal_spec = GET_HAL_SPEC(Adapter);
5453 struct dm_struct *pDM_Odm = &(pHalData->odmpriv);
5454 u8 loadingStage = LD_STAGE_EXC_MAPPING;
5455 u32 i = 0, forCnt = 0;
5456 char *szLine, *ptmp;
5457 char band[10], bandwidth[10], rateSection[10], ntx[10], colNumBuf[10];
5458 char **regulation = NULL;
5459 u8 colNum = 0;
5460
5461 if (Adapter->registrypriv.RegDecryptCustomFile == 1)
5462 phy_DecryptBBPgParaFile(Adapter, buffer);
5463
5464 ptmp = buffer;
5465 for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
5466 if (isAllSpaceOrTab(szLine, sizeof(*szLine)))
5467 continue;
5468 if (IsCommentString(szLine))
5469 continue;
5470
5471 if (loadingStage == LD_STAGE_EXC_MAPPING) {
5472 if (szLine[0] == '#' || szLine[1] == '#') {
5473 loadingStage = LD_STAGE_TAB_DEFINE;
5474 if (DBG_TXPWR_LMT_FILE_PARSE)
5475 dump_regd_exc_list(RTW_DBGDUMP, adapter_to_rfctl(Adapter));
5476 } else {
5477 if (parse_reg_exc_config(Adapter, szLine) == PARSE_RET_FAIL) {
5478 RTW_ERR("Fail to parse regulation exception ruls!\n");
5479 goto exit;
5480 }
5481 continue;
5482 }
5483 }
5484
5485 if (loadingStage == LD_STAGE_TAB_DEFINE) {
5486 /* read "## 2.4G, 20M, 1T, CCK" */
5487 if (szLine[0] != '#' || szLine[1] != '#')
5488 continue;
5489
5490 /* skip the space */
5491 i = 2;
5492 while (szLine[i] == ' ' || szLine[i] == '\t')
5493 ++i;
5494
5495 szLine[--i] = ' '; /* return the space in front of the regulation info */
5496
5497 /* Parse the label of the table */
5498 _rtw_memset((void *) band, 0, 10);
5499 _rtw_memset((void *) bandwidth, 0, 10);
5500 _rtw_memset((void *) ntx, 0, 10);
5501 _rtw_memset((void *) rateSection, 0, 10);
5502 if (!ParseQualifiedString(szLine, &i, band, ' ', ',')) {
5503 RTW_ERR("Fail to parse band!\n");
5504 goto exit;
5505 }
5506 if (!ParseQualifiedString(szLine, &i, bandwidth, ' ', ',')) {
5507 RTW_ERR("Fail to parse bandwidth!\n");
5508 goto exit;
5509 }
5510 if (!ParseQualifiedString(szLine, &i, ntx, ' ', ',')) {
5511 RTW_ERR("Fail to parse ntx!\n");
5512 goto exit;
5513 }
5514 if (!ParseQualifiedString(szLine, &i, rateSection, ' ', ',')) {
5515 RTW_ERR("Fail to parse rate!\n");
5516 goto exit;
5517 }
5518
5519 loadingStage = LD_STAGE_TAB_START;
5520 } else if (loadingStage == LD_STAGE_TAB_START) {
5521 /* read "## START" */
5522 if (szLine[0] != '#' || szLine[1] != '#')
5523 continue;
5524
5525 /* skip the space */
5526 i = 2;
5527 while (szLine[i] == ' ' || szLine[i] == '\t')
5528 ++i;
5529
5530 if (strncmp((u8 *)(szLine + i), "START", 5)) {
5531 RTW_ERR("Missing \"## START\" label\n");
5532 goto exit;
5533 }
5534
5535 loadingStage = LD_STAGE_COLUMN_DEFINE;
5536 } else if (loadingStage == LD_STAGE_COLUMN_DEFINE) {
5537 /* read "## #5# FCC ETSI MKK IC KCC" */
5538 if (szLine[0] != '#' || szLine[1] != '#')
5539 continue;
5540
5541 /* skip the space */
5542 i = 2;
5543 while (szLine[i] == ' ' || szLine[i] == '\t')
5544 ++i;
5545
5546 _rtw_memset((void *) colNumBuf, 0, 10);
5547 if (!ParseQualifiedString(szLine, &i, colNumBuf, '#', '#')) {
5548 RTW_ERR("Fail to parse column number!\n");
5549 goto exit;
5550 }
5551 if (!GetU1ByteIntegerFromStringInDecimal(colNumBuf, &colNum)) {
5552 RTW_ERR("Column number \"%s\" is not unsigned decimal\n", colNumBuf);
5553 goto exit;
5554 }
5555 if (colNum == 0) {
5556 RTW_ERR("Column number is 0\n");
5557 goto exit;
5558 }
5559
5560 if (DBG_TXPWR_LMT_FILE_PARSE)
5561 RTW_PRINT("[%s][%s][%s][%s] column num:%d\n", band, bandwidth, rateSection, ntx, colNum);
5562
5563 regulation = (char **)rtw_zmalloc(sizeof(char *) * colNum);
5564 if (!regulation) {
5565 RTW_ERR("Regulation alloc fail\n");
5566 goto exit;
5567 }
5568
5569 for (forCnt = 0; forCnt < colNum; ++forCnt) {
5570 u32 i_ns;
5571
5572 /* skip the space */
5573 while (szLine[i] == ' ' || szLine[i] == '\t')
5574 i++;
5575 i_ns = i;
5576
5577 while (szLine[i] != ' ' && szLine[i] != '\t' && szLine[i] != '\0')
5578 i++;
5579
5580 regulation[forCnt] = (char *)rtw_malloc(i - i_ns + 1);
5581 if (!regulation[forCnt]) {
5582 RTW_ERR("Regulation alloc fail\n");
5583 goto exit;
5584 }
5585
5586 _rtw_memcpy(regulation[forCnt], szLine + i_ns, i - i_ns);
5587 regulation[forCnt][i - i_ns] = '\0';
5588 }
5589
5590 if (DBG_TXPWR_LMT_FILE_PARSE) {
5591 RTW_PRINT("column name:");
5592 for (forCnt = 0; forCnt < colNum; ++forCnt)
5593 _RTW_PRINT(" %s", regulation[forCnt]);
5594 _RTW_PRINT("\n");
5595 }
5596
5597 loadingStage = LD_STAGE_CH_ROW;
5598 } else if (loadingStage == LD_STAGE_CH_ROW) {
5599 char channel[10] = {0}, powerLimit[10] = {0};
5600 u8 cnt = 0;
5601
5602 /* the table ends */
5603 if (szLine[0] == '#' && szLine[1] == '#') {
5604 i = 2;
5605 while (szLine[i] == ' ' || szLine[i] == '\t')
5606 ++i;
5607
5608 if (strncmp((u8 *)(szLine + i), "END", 3) == 0) {
5609 loadingStage = LD_STAGE_TAB_DEFINE;
5610 if (regulation) {
5611 for (forCnt = 0; forCnt < colNum; ++forCnt) {
5612 if (regulation[forCnt]) {
5613 rtw_mfree(regulation[forCnt], strlen(regulation[forCnt]) + 1);
5614 regulation[forCnt] = NULL;
5615 }
5616 }
5617 rtw_mfree((u8 *)regulation, sizeof(char *) * colNum);
5618 regulation = NULL;
5619 }
5620 colNum = 0;
5621 continue;
5622 } else {
5623 RTW_ERR("Missing \"## END\" label\n");
5624 goto exit;
5625 }
5626 }
5627
5628 if ((szLine[0] != 'c' && szLine[0] != 'C') ||
5629 (szLine[1] != 'h' && szLine[1] != 'H')
5630 ) {
5631 RTW_WARN("Wrong channel prefix: '%c','%c'(%d,%d)\n", szLine[0], szLine[1], szLine[0], szLine[1]);
5632 continue;
5633 }
5634 i = 2;/* move to the location behind 'h' */
5635
5636 /* load the channel number */
5637 cnt = 0;
5638 while (szLine[i] >= '0' && szLine[i] <= '9') {
5639 channel[cnt] = szLine[i];
5640 ++cnt;
5641 ++i;
5642 }
5643 /* RTW_INFO("chnl %s!\n", channel); */
5644
5645 for (forCnt = 0; forCnt < colNum; ++forCnt) {
5646 /* skip the space between channel number and the power limit value */
5647 while (szLine[i] == ' ' || szLine[i] == '\t')
5648 ++i;
5649
5650 /* load the power limit value */
5651 _rtw_memset((void *) powerLimit, 0, 10);
5652
5653 if (szLine[i] == 'W' && szLine[i + 1] == 'W') {
5654 /*
5655 * case "WW" assign special ww value
5656 * means to get minimal limit in other regulations at same channel
5657 */
5658 s8 ww_value = phy_txpwr_ww_lmt_value(Adapter);
5659
5660 sprintf(powerLimit, "%d", ww_value);
5661 i += 2;
5662
5663 } else if (szLine[i] == 'N' && szLine[i + 1] == 'A') {
5664 /*
5665 * case "NA" assign max txgi value
5666 * means no limitation
5667 */
5668 sprintf(powerLimit, "%d", hal_spec->txgi_max);
5669 i += 2;
5670
5671 } else if ((szLine[i] >= '0' && szLine[i] <= '9') || szLine[i] == '.'
5672 || szLine[i] == '+' || szLine[i] == '-'
5673 ){
5674 /* case of dBm value */
5675 u8 integer = 0, fraction = 0, negative = 0;
5676 u32 u4bMove;
5677 s8 lmt = 0;
5678
5679 if (szLine[i] == '+' || szLine[i] == '-') {
5680 if (szLine[i] == '-')
5681 negative = 1;
5682 i++;
5683 }
5684
5685 if (GetFractionValueFromString(&szLine[i], &integer, &fraction, &u4bMove))
5686 i += u4bMove;
5687 else {
5688 RTW_ERR("Limit \"%s\" is not valid decimal\n", &szLine[i]);
5689 goto exit;
5690 }
5691
5692 /* transform to string of value in unit of txgi */
5693 lmt = integer * hal_spec->txgi_pdbm + ((u16)fraction * (u16)hal_spec->txgi_pdbm) / 100;
5694 if (negative)
5695 lmt = -lmt;
5696 sprintf(powerLimit, "%d", lmt);
5697
5698 } else {
5699 RTW_ERR("Wrong limit expression \"%c%c\"(%d, %d)\n"
5700 , szLine[i], szLine[i + 1], szLine[i], szLine[i + 1]);
5701 goto exit;
5702 }
5703
5704 /* store the power limit value */
5705 phy_set_tx_power_limit(pDM_Odm, (u8 *)regulation[forCnt], (u8 *)band,
5706 (u8 *)bandwidth, (u8 *)rateSection, (u8 *)ntx, (u8 *)channel, (u8 *)powerLimit);
5707
5708 }
5709 }
5710 }
5711
5712 rtStatus = _SUCCESS;
5713
5714 exit:
5715 if (regulation) {
5716 for (forCnt = 0; forCnt < colNum; ++forCnt) {
5717 if (regulation[forCnt]) {
5718 rtw_mfree(regulation[forCnt], strlen(regulation[forCnt]) + 1);
5719 regulation[forCnt] = NULL;
5720 }
5721 }
5722 rtw_mfree((u8 *)regulation, sizeof(char *) * colNum);
5723 regulation = NULL;
5724 }
5725
5726 RTW_INFO("%s return %d\n", __func__, rtStatus);
5727 return rtStatus;
5728 }
5729
5730 int
PHY_ConfigRFWithPowerLimitTableParaFile(PADAPTER Adapter,const char * pFileName)5731 PHY_ConfigRFWithPowerLimitTableParaFile(
5732 PADAPTER Adapter,
5733 const char *pFileName
5734 )
5735 {
5736 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
5737 int rlen = 0, rtStatus = _FAIL;
5738
5739 if (!(Adapter->registrypriv.load_phy_file & LOAD_RF_TXPWR_LMT_PARA_FILE))
5740 return rtStatus;
5741
5742 _rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
5743
5744 if (pHalData->rf_tx_pwr_lmt == NULL) {
5745 rtw_get_phy_file_path(Adapter, pFileName);
5746 if (rtw_readable_file_sz_chk(rtw_phy_para_file_path,
5747 MAX_PARA_FILE_BUF_LEN) == _TRUE) {
5748 rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
5749 if (rlen > 0) {
5750 rtStatus = _SUCCESS;
5751 pHalData->rf_tx_pwr_lmt = rtw_zvmalloc(rlen);
5752 if (pHalData->rf_tx_pwr_lmt) {
5753 _rtw_memcpy(pHalData->rf_tx_pwr_lmt, pHalData->para_file_buf, rlen);
5754 pHalData->rf_tx_pwr_lmt_len = rlen;
5755 } else
5756 RTW_INFO("%s rf_tx_pwr_lmt alloc fail !\n", __FUNCTION__);
5757 }
5758 }
5759 } else {
5760 if ((pHalData->rf_tx_pwr_lmt_len != 0) && (pHalData->rf_tx_pwr_lmt != NULL)) {
5761 _rtw_memcpy(pHalData->para_file_buf, pHalData->rf_tx_pwr_lmt, pHalData->rf_tx_pwr_lmt_len);
5762 rtStatus = _SUCCESS;
5763 } else
5764 RTW_INFO("%s(): Critical Error !!!\n", __FUNCTION__);
5765 }
5766
5767 if (rtStatus == _SUCCESS) {
5768 /* RTW_INFO("%s(): read %s ok\n", __FUNCTION__, pFileName); */
5769 rtStatus = phy_ParsePowerLimitTableFile(Adapter, pHalData->para_file_buf);
5770 } else
5771 RTW_INFO("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
5772
5773 return rtStatus;
5774 }
5775 #endif /* CONFIG_TXPWR_LIMIT */
5776
phy_free_filebuf_mask(_adapter * padapter,u8 mask)5777 void phy_free_filebuf_mask(_adapter *padapter, u8 mask)
5778 {
5779 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
5780
5781 if (pHalData->mac_reg && (mask & LOAD_MAC_PARA_FILE)) {
5782 rtw_vmfree(pHalData->mac_reg, pHalData->mac_reg_len);
5783 pHalData->mac_reg = NULL;
5784 }
5785 if (mask & LOAD_BB_PARA_FILE) {
5786 if (pHalData->bb_phy_reg) {
5787 rtw_vmfree(pHalData->bb_phy_reg, pHalData->bb_phy_reg_len);
5788 pHalData->bb_phy_reg = NULL;
5789 }
5790 if (pHalData->bb_agc_tab) {
5791 rtw_vmfree(pHalData->bb_agc_tab, pHalData->bb_agc_tab_len);
5792 pHalData->bb_agc_tab = NULL;
5793 }
5794 }
5795 if (pHalData->bb_phy_reg_pg && (mask & LOAD_BB_PG_PARA_FILE)) {
5796 rtw_vmfree(pHalData->bb_phy_reg_pg, pHalData->bb_phy_reg_pg_len);
5797 pHalData->bb_phy_reg_pg = NULL;
5798 }
5799 if (pHalData->bb_phy_reg_mp && (mask & LOAD_BB_MP_PARA_FILE)) {
5800 rtw_vmfree(pHalData->bb_phy_reg_mp, pHalData->bb_phy_reg_mp_len);
5801 pHalData->bb_phy_reg_mp = NULL;
5802 }
5803 if (mask & LOAD_RF_PARA_FILE) {
5804 if (pHalData->rf_radio_a) {
5805 rtw_vmfree(pHalData->rf_radio_a, pHalData->rf_radio_a_len);
5806 pHalData->rf_radio_a = NULL;
5807 }
5808 if (pHalData->rf_radio_b) {
5809 rtw_vmfree(pHalData->rf_radio_b, pHalData->rf_radio_b_len);
5810 pHalData->rf_radio_b = NULL;
5811 }
5812 }
5813 if (pHalData->rf_tx_pwr_track && (mask & LOAD_RF_TXPWR_TRACK_PARA_FILE)) {
5814 rtw_vmfree(pHalData->rf_tx_pwr_track, pHalData->rf_tx_pwr_track_len);
5815 pHalData->rf_tx_pwr_track = NULL;
5816 }
5817 if (pHalData->rf_tx_pwr_lmt && (mask & LOAD_RF_TXPWR_LMT_PARA_FILE)) {
5818 rtw_vmfree(pHalData->rf_tx_pwr_lmt, pHalData->rf_tx_pwr_lmt_len);
5819 pHalData->rf_tx_pwr_lmt = NULL;
5820 }
5821 }
5822
phy_free_filebuf(_adapter * padapter)5823 inline void phy_free_filebuf(_adapter *padapter)
5824 {
5825 phy_free_filebuf_mask(padapter, 0xFF);
5826 }
5827
5828 #endif
5829
5830 /*
5831 * check if user specified mbm is valid
5832 */
phy_is_txpwr_user_mbm_valid(_adapter * adapter,s16 mbm)5833 bool phy_is_txpwr_user_mbm_valid(_adapter *adapter, s16 mbm)
5834 {
5835 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
5836
5837 /* 1T upper bound check */
5838 if (hal_spec->txgi_max <= mbm * hal_spec->txgi_pdbm / MBM_PDBM)
5839 return 0;
5840
5841 return 1;
5842 }
5843
phy_is_txpwr_user_target_specified(_adapter * adapter)5844 bool phy_is_txpwr_user_target_specified(_adapter *adapter)
5845 {
5846 s16 total_mbm = UNSPECIFIED_MBM;
5847
5848 #ifdef CONFIG_IOCTL_CFG80211
5849 total_mbm = rtw_cfg80211_dev_get_total_txpwr_target_mbm(adapter_to_dvobj(adapter));
5850 #endif
5851
5852 return total_mbm != UNSPECIFIED_MBM;
5853 }
5854
5855 /*
5856 * Return value in unit of TX Gain Index
5857 * hal_spec.txgi_max means unspecified
5858 */
phy_get_txpwr_user_target(_adapter * adapter,struct hal_spec_t * hal_spec,u8 ntx_idx)5859 s8 phy_get_txpwr_user_target(_adapter *adapter, struct hal_spec_t *hal_spec, u8 ntx_idx)
5860 {
5861 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
5862 s16 total_mbm = UNSPECIFIED_MBM;
5863 s8 target;
5864
5865 #ifdef CONFIG_IOCTL_CFG80211
5866 total_mbm = rtw_cfg80211_dev_get_total_txpwr_target_mbm(adapter_to_dvobj(adapter));
5867 #endif
5868 if (total_mbm != UNSPECIFIED_MBM)
5869 target = (total_mbm - mb_of_ntx(ntx_idx + 1) - rfctl->antenna_gain) * hal_spec->txgi_pdbm / MBM_PDBM;
5870 else
5871 target = hal_spec->txgi_max;
5872
5873 return target;
5874 }
5875
5876 /*
5877 * Return value in unit of TX Gain Index
5878 * hal_spec.txgi_max means unspecified
5879 */
phy_get_txpwr_user_lmt(_adapter * adapter,struct hal_spec_t * hal_spec,u8 ntx_idx)5880 s8 phy_get_txpwr_user_lmt(_adapter *adapter, struct hal_spec_t *hal_spec, u8 ntx_idx)
5881 {
5882 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
5883 s16 total_mbm = UNSPECIFIED_MBM;
5884 s8 lmt;
5885
5886 #ifdef CONFIG_IOCTL_CFG80211
5887 total_mbm = rtw_cfg80211_dev_get_total_txpwr_lmt_mbm(adapter_to_dvobj(adapter));
5888 #endif
5889 if (total_mbm != UNSPECIFIED_MBM)
5890 lmt = (total_mbm - mb_of_ntx(ntx_idx + 1) - rfctl->antenna_gain) * hal_spec->txgi_pdbm / MBM_PDBM;
5891 else
5892 lmt = hal_spec->txgi_max;
5893
5894 return lmt;
5895 }
5896
5897 /*
5898 * Return value in unit of TX Gain Index
5899 * 0 means unspecified
5900 */
phy_get_txpwr_tpc(_adapter * adapter,struct hal_spec_t * hal_spec)5901 s8 phy_get_txpwr_tpc(_adapter *adapter, struct hal_spec_t *hal_spec)
5902 {
5903 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
5904 u16 cnst = 0;
5905
5906 if (rfctl->tpc_mode == TPC_MODE_MANUAL)
5907 cnst = rfctl->tpc_manual_constraint * hal_spec->txgi_pdbm / MBM_PDBM;
5908
5909 return -cnst;
5910 }
5911
dump_txpwr_tpc_settings(void * sel,_adapter * adapter)5912 void dump_txpwr_tpc_settings(void *sel, _adapter *adapter)
5913 {
5914 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
5915
5916 if (rfctl->tpc_mode == TPC_MODE_DISABLE)
5917 RTW_PRINT_SEL(sel, "mode:DISABLE(%d)\n", rfctl->tpc_mode);
5918 else if (rfctl->tpc_mode == TPC_MODE_MANUAL) {
5919 RTW_PRINT_SEL(sel, "mode:MANUAL(%d)\n", rfctl->tpc_mode);
5920 RTW_PRINT_SEL(sel, "constraint:%d (mB)\n", rfctl->tpc_manual_constraint);
5921 }
5922 }
5923
dump_txpwr_antenna_gain(void * sel,_adapter * adapter)5924 void dump_txpwr_antenna_gain(void *sel, _adapter *adapter)
5925 {
5926 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
5927
5928 RTW_PRINT_SEL(sel, "%d (mBi)\n", rfctl->antenna_gain);
5929 }
5930
5931 /*
5932 * Return value in unit of TX Gain Index
5933 */
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)5934 s8 phy_get_txpwr_target(_adapter *adapter, u8 rfpath, RATE_SECTION rs, u8 rate, u8 ntx_idx
5935 , enum channel_width bw, BAND_TYPE band, u8 cch, u8 opch, struct txpwr_idx_comp *tic)
5936 {
5937 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
5938 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
5939 s8 target, by_rate = 0, btc_diff = 0, extra = 0;
5940 s8 lmt, utgt, ulmt;
5941 s8 tpc = 0;
5942
5943 lmt = utgt = ulmt = hal_spec->txgi_max;
5944
5945 if (band != BAND_ON_2_4G && IS_CCK_RATE(rate))
5946 goto exit;
5947
5948 utgt = phy_get_txpwr_user_target(adapter, hal_spec, ntx_idx);
5949 if (utgt != hal_spec->txgi_max)
5950 goto get_lmt;
5951
5952 #ifdef CONFIG_RTL8812A
5953 if (IS_HARDWARE_TYPE_8812(adapter)
5954 && phy_get_txpwr_target_skip_by_rate_8812a(adapter, rate))
5955 by_rate = phy_get_target_txpwr(adapter, band, rfpath, rs);
5956 else
5957 #endif
5958 by_rate = PHY_GetTxPowerByRate(adapter, band, rfpath, rs, rate);
5959 if (by_rate == hal_spec->txgi_max)
5960 by_rate = 0;
5961
5962 #ifdef CONFIG_BT_COEXIST
5963 if (hal_data->EEPROMBluetoothCoexist == _TRUE)
5964 btc_diff = -(rtw_btcoex_query_reduced_wl_pwr_lvl(adapter) * hal_spec->txgi_pdbm);
5965 #endif
5966
5967 extra = rtw_hal_get_txpwr_target_extra_bias(adapter, rfpath, rs, rate, bw, band, cch);
5968
5969 get_lmt:
5970 lmt = phy_get_txpwr_lmt_sub_chs(adapter, NULL, band, bw, rfpath, rate, ntx_idx, cch, opch);
5971 ulmt = phy_get_txpwr_user_lmt(adapter, hal_spec, ntx_idx);
5972 /* TODO: limit from outer source, ex: 11d */
5973
5974 tpc = phy_get_txpwr_tpc(adapter, hal_spec);
5975
5976 exit:
5977 if (utgt != hal_spec->txgi_max)
5978 target = utgt;
5979 else
5980 target = by_rate + btc_diff + extra;
5981
5982 if (target > lmt)
5983 target = lmt;
5984 if (target > ulmt)
5985 target = ulmt;
5986
5987 target += tpc;
5988
5989 if (tic) {
5990 tic->target = target;
5991 if (utgt == hal_spec->txgi_max) {
5992 tic->by_rate = by_rate;
5993 tic->btc = btc_diff;
5994 tic->extra = extra;
5995 }
5996 tic->utarget = utgt;
5997 tic->limit = lmt;
5998 tic->ulimit = ulmt;
5999 tic->tpc = tpc;
6000 }
6001
6002 return target;
6003 }
6004
6005 /* TODO: common dpd_diff getting API from phydm */
6006 #ifdef CONFIG_RTL8822C
6007 #include "./rtl8822c/rtl8822c.h"
6008 #endif
6009
6010 /*
6011 * Return in unit of TX Gain Index
6012 */
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)6013 s8 phy_get_txpwr_amends(_adapter *adapter, u8 rfpath, RATE_SECTION rs, u8 rate, u8 ntx_idx
6014 , enum channel_width bw, BAND_TYPE band, u8 cch, struct txpwr_idx_comp *tic)
6015 {
6016 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
6017 s8 tpt_diff = 0, dpd_diff = 0, val = 0;
6018
6019 if (band != BAND_ON_2_4G && IS_CCK_RATE(rate))
6020 goto exit;
6021
6022 if (IS_HARDWARE_TYPE_8188E(adapter) || IS_HARDWARE_TYPE_8188F(adapter) || IS_HARDWARE_TYPE_8188GTV(adapter)
6023 || IS_HARDWARE_TYPE_8192E(adapter) || IS_HARDWARE_TYPE_8192F(adapter)
6024 || IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter) || IS_HARDWARE_TYPE_8723D(adapter)
6025 || IS_HARDWARE_TYPE_8710B(adapter)
6026 || IS_HARDWARE_TYPE_8821(adapter) || IS_HARDWARE_TYPE_8812(adapter)
6027 )
6028 tpt_diff = PHY_GetTxPowerTrackingOffset(adapter, rfpath, rate);
6029
6030 #ifdef CONFIG_RTL8822C
6031 if (IS_HARDWARE_TYPE_8822C(adapter))
6032 dpd_diff = -(rtl8822c_get_dis_dpd_by_rate_diff(adapter, rate) * hal_spec->txgi_pdbm);
6033 #endif
6034
6035 exit:
6036 if (tic) {
6037 tic->tpt = tpt_diff;
6038 tic->dpd = dpd_diff;
6039 }
6040
6041 return tpt_diff + dpd_diff;
6042 }
6043
6044 #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)6045 s8 phy_get_tssi_txpwr_by_rate_ref(_adapter *adapter, enum rf_path path
6046 , enum channel_width bw, u8 cch, u8 opch)
6047 {
6048 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
6049 u8 ntx_idx = phy_get_current_tx_num(adapter, MGN_MCS7);
6050 BAND_TYPE band = cch > 14 ? BAND_ON_5G : BAND_ON_2_4G;
6051 s8 pwr_idx;
6052
6053 pwr_idx = phy_get_txpwr_target(adapter, path, HT_1SS, MGN_MCS7
6054 , ntx_idx, bw, band, cch, opch, NULL);
6055 pwr_idx += phy_get_txpwr_amends(adapter, path, HT_1SS, MGN_MCS7
6056 , ntx_idx, bw, band, cch, NULL);
6057
6058 return pwr_idx;
6059 }
6060 #endif
6061
6062 /*
6063 * Rteurn tx power index for rate
6064 */
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)6065 u8 hal_com_get_txpwr_idx(_adapter *adapter, enum rf_path rfpath
6066 , RATE_SECTION rs, enum MGN_RATE rate, enum channel_width bw, BAND_TYPE band, u8 cch, u8 opch
6067 , struct txpwr_idx_comp *tic)
6068 {
6069 PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
6070 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
6071 s16 power_idx = 0;
6072 s8 base = 0;
6073 s8 rate_target, rate_amends;
6074 u8 ntx_idx = phy_get_current_tx_num(adapter, rate);
6075
6076 /* target */
6077 rate_target = phy_get_txpwr_target(adapter, rfpath, rs, rate, ntx_idx, bw, band, cch, opch, tic);
6078
6079 /* amends */
6080 rate_amends = phy_get_txpwr_amends(adapter, rfpath, rs, rate, ntx_idx, bw, band, cch, tic);
6081
6082 switch (hal->txpwr_pg_mode) {
6083 #ifdef CONFIG_TXPWR_PG_WITH_PWR_IDX
6084 case TXPWR_PG_WITH_PWR_IDX: {
6085 /*
6086 * power index =
6087 * 1. pg base (per rate section) +
6088 * 2. target diff (per rate) to target of its rate section +
6089 * 3. amends diff (per rate)
6090 */
6091 u8 rs_target;
6092
6093 base = phy_get_pg_txpwr_idx(adapter, rfpath, rs, ntx_idx, bw, band, cch);
6094 rs_target = phy_get_target_txpwr(adapter, band, rfpath, rs);
6095 power_idx = base + (rate_target - rs_target) + (rate_amends);
6096
6097 if (tic) {
6098 if (tic->utarget == hal_spec->txgi_max)
6099 tic->by_rate -= rs_target;
6100 else
6101 tic->utarget -= rs_target;
6102 if (tic->limit != hal_spec->txgi_max)
6103 tic->limit -= rs_target;
6104 if (tic->ulimit != hal_spec->txgi_max)
6105 tic->ulimit -= rs_target;
6106 }
6107 }
6108 break;
6109 #endif
6110 #ifdef CONFIG_TXPWR_PG_WITH_TSSI_OFFSET
6111 case TXPWR_PG_WITH_TSSI_OFFSET: {
6112 /*
6113 * power index =
6114 * 1. base (fixed) +
6115 * 2. target (per rate) +
6116 * 3. amends diff (per rate)
6117 * base is selected that power index of MCS7 == halrf_get_tssi_codeword_for_txindex()
6118 */
6119 s8 mcs7_idx;
6120
6121 mcs7_idx = phy_get_tssi_txpwr_by_rate_ref(adapter, rfpath, bw, cch, opch);
6122 base = halrf_get_tssi_codeword_for_txindex(adapter_to_phydm(adapter)) - mcs7_idx;
6123 power_idx = base + rate_target + rate_amends;
6124 }
6125 break;
6126 #endif
6127 }
6128
6129 if (tic) {
6130 tic->ntx_idx = ntx_idx;
6131 tic->base = base;
6132 }
6133
6134 if (power_idx < 0)
6135 power_idx = 0;
6136 else if (power_idx > hal_spec->txgi_max)
6137 power_idx = hal_spec->txgi_max;
6138
6139 #if defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8812A)
6140 if ((IS_HARDWARE_TYPE_8821(adapter) || IS_HARDWARE_TYPE_8812(adapter))
6141 && power_idx % 2 == 1 && !IS_NORMAL_CHIP(hal->version_id))
6142 --power_idx;
6143 #endif
6144
6145 return power_idx;
6146 }
6147
6148 /* get txpowr in mBm for single path */
phy_get_txpwr_single_mbm(_adapter * adapter,u8 rfpath,RATE_SECTION rs,u8 rate,enum channel_width bw,u8 cch,u8 opch,bool eirp,struct txpwr_idx_comp * tic)6149 s16 phy_get_txpwr_single_mbm(_adapter *adapter, u8 rfpath, RATE_SECTION rs, u8 rate
6150 , enum channel_width bw, u8 cch, u8 opch, bool eirp, struct txpwr_idx_comp *tic)
6151 {
6152 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
6153 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
6154 BAND_TYPE band = cch <= 14 ? BAND_ON_2_4G : BAND_ON_5G;
6155 u8 ntx_idx = phy_get_current_tx_num(adapter, rate);
6156 s16 val;
6157
6158 val = phy_get_txpwr_target(adapter, rfpath, rs, rate, ntx_idx, bw, band, cch, opch, tic);
6159 val = (val * MBM_PDBM) / hal_spec->txgi_pdbm;
6160 if (eirp)
6161 val += rfctl->antenna_gain;
6162 if (tic)
6163 tic->ntx_idx = ntx_idx;
6164
6165 return val;
6166 }
6167
6168 /* get txpowr in mBm with effect of N-TX */
phy_get_txpwr_total_mbm(_adapter * adapter,RATE_SECTION rs,u8 rate,enum channel_width bw,u8 cch,u8 opch,bool eirp,struct txpwr_idx_comp * tic)6169 s16 phy_get_txpwr_total_mbm(_adapter *adapter, RATE_SECTION rs, u8 rate
6170 , enum channel_width bw, u8 cch, u8 opch, bool eirp, struct txpwr_idx_comp *tic)
6171 {
6172 s16 val;
6173 u8 tx_num = phy_get_current_tx_num(adapter, rate) + 1;
6174
6175 /* assume all path have same txpower target */
6176 val = phy_get_txpwr_single_mbm(adapter, RF_PATH_A, rs, rate, bw, cch, opch, eirp, tic);
6177 val += mb_of_ntx(tx_num);
6178
6179 return val;
6180 }
6181
_phy_get_txpwr_max_mbm(_adapter * adapter,s8 rfpath,enum channel_width bw,u8 cch,u8 opch,u16 bmp_cck_ofdm,u32 bmp_ht,u64 bmp_vht,bool eirp)6182 static s16 _phy_get_txpwr_max_mbm(_adapter *adapter, s8 rfpath
6183 , enum channel_width bw, u8 cch, u8 opch, u16 bmp_cck_ofdm, u32 bmp_ht, u64 bmp_vht, bool eirp)
6184 {
6185 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
6186 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
6187 BAND_TYPE band = cch <= 14 ? BAND_ON_2_4G : BAND_ON_5G;
6188 u8 tx_num;
6189 RATE_SECTION rs;
6190 u8 hw_rate;
6191 int i;
6192 s16 max = UNSPECIFIED_MBM, mbm;
6193
6194 if (0)
6195 RTW_INFO("cck_ofdm:0x%04x, ht:0x%08x, vht:0x%016llx\n", bmp_cck_ofdm, bmp_ht, bmp_vht);
6196
6197 for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
6198 tx_num = rate_section_to_tx_num(rs);
6199 if (tx_num + 1 > hal_data->tx_nss)
6200 continue;
6201
6202 if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
6203 continue;
6204
6205 if (IS_VHT_RATE_SECTION(rs) && !IS_HARDWARE_TYPE_JAGUAR_ALL(adapter))
6206 continue;
6207
6208 for (i = 0; i < rates_by_sections[rs].rate_num; i++) {
6209 hw_rate = MRateToHwRate(rates_by_sections[rs].rates[i]);
6210 if (IS_LEGACY_HRATE(hw_rate)) {
6211 if (!(bmp_cck_ofdm & BIT(hw_rate)))
6212 continue;
6213 } else if (IS_HT_HRATE(hw_rate)) {
6214 if (!(bmp_ht & BIT(hw_rate - DESC_RATEMCS0)))
6215 continue;
6216 } else if (IS_VHT_HRATE(hw_rate)) {
6217 if (!(bmp_vht & BIT(hw_rate - DESC_RATEVHTSS1MCS0)))
6218 continue;
6219 }
6220
6221 if (rfpath < 0) /* total */
6222 mbm = phy_get_txpwr_total_mbm(adapter, rs, rates_by_sections[rs].rates[i], bw, cch, opch, eirp, NULL);
6223 else
6224 mbm = phy_get_txpwr_single_mbm(adapter, rfpath, rs, rates_by_sections[rs].rates[i], bw, cch, opch, eirp, NULL);
6225
6226 if (max == UNSPECIFIED_MBM || mbm > max)
6227 max = mbm;
6228 }
6229 }
6230
6231 return max;
6232 }
6233
phy_get_txpwr_single_max_mbm(_adapter * adapter,u8 rfpath,enum channel_width bw,u8 cch,u8 opch,u16 bmp_cck_ofdm,u32 bmp_ht,u64 bmp_vht,bool eirp)6234 s16 phy_get_txpwr_single_max_mbm(_adapter *adapter, u8 rfpath
6235 , enum channel_width bw, u8 cch, u8 opch, u16 bmp_cck_ofdm, u32 bmp_ht, u64 bmp_vht, bool eirp)
6236 {
6237 return _phy_get_txpwr_max_mbm(adapter, rfpath, bw, cch, opch, bmp_cck_ofdm, bmp_ht, bmp_vht, eirp);
6238 }
6239
phy_get_txpwr_total_max_mbm(_adapter * adapter,enum channel_width bw,u8 cch,u8 opch,u16 bmp_cck_ofdm,u32 bmp_ht,u64 bmp_vht,bool eirp)6240 s16 phy_get_txpwr_total_max_mbm(_adapter *adapter
6241 , enum channel_width bw, u8 cch, u8 opch, u16 bmp_cck_ofdm, u32 bmp_ht, u64 bmp_vht, bool eirp)
6242 {
6243 return _phy_get_txpwr_max_mbm(adapter, -1, bw, cch, opch, bmp_cck_ofdm, bmp_ht, bmp_vht, eirp);
6244 }
6245
6246 s8
phy_get_tx_power_final_absolute_value(_adapter * adapter,u8 rfpath,u8 rate,enum channel_width bw,u8 cch)6247 phy_get_tx_power_final_absolute_value(_adapter *adapter, u8 rfpath, u8 rate,
6248 enum channel_width bw, u8 cch)
6249 {
6250 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
6251 RATE_SECTION rs = mgn_rate_to_rs(rate);
6252 BAND_TYPE band = cch <= 14 ? BAND_ON_2_4G : BAND_ON_5G;
6253 s8 val;
6254
6255 val = phy_get_txpwr_target(adapter, rfpath
6256 , rs, rate, phy_get_current_tx_num(adapter, rate), bw, band, cch, 0, NULL);
6257
6258 val /= hal_spec->txgi_pdbm;
6259
6260 return val;
6261 }
6262