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