1 /** @file wlan_txpwrlimit_cfg.c
2 *
3 * @brief This file provides WLAN World Wide Safe Mode Tx Power Limit APIs.
4 *
5 * Copyright 2008-2024 NXP
6 *
7 * SPDX-License-Identifier: BSD-3-Clause
8 *
9 */
10
11 #include <wlan.h>
12 #include <wifi.h>
13 #ifdef RW610
14 #include "fsl_ocotp.h"
15 #endif
16
17 #ifdef WIFI_BT_TX_PWR_LIMITS
18 #include WIFI_BT_TX_PWR_LIMITS
19 #else
20 #error "Region tx power config not defined"
21 #endif
22
23 #if defined(RW610) && (CONFIG_COMPRESS_TX_PWTBL || ((CONFIG_COMPRESS_RU_TX_PWTBL) && (CONFIG_11AX)))
24 typedef struct _rg_power_info
25 {
26 t_u8 *rg_power_table;
27 t_u16 rg_len;
28 } rg_power_info;
29 #endif
30
31 #if defined(RW610) && ((CONFIG_COMPRESS_RU_TX_PWTBL) && (CONFIG_11AX))
32
33 typedef struct _ru_power_cfg
34 {
35 t_u16 region_code;
36 rg_power_info power_info;
37 } ru_power_cfg;
38
39 /* All type boards ru txpwr data is same, */
40 ru_power_cfg ru_power_cfg_rw610[] = {
41 {0x00, .power_info = {(t_u8 *)rutxpowerlimit_cfg_set_WW, sizeof(rutxpowerlimit_cfg_set_WW)}},
42 {0x10, .power_info = {(t_u8 *)rutxpowerlimit_cfg_set_FCC, sizeof(rutxpowerlimit_cfg_set_FCC)}},
43 {0x30, .power_info = {(t_u8 *)rutxpowerlimit_cfg_set_EU, sizeof(rutxpowerlimit_cfg_set_EU)}},
44 {0x50, .power_info = {(t_u8 *)rutxpowerlimit_cfg_set_CN, sizeof(rutxpowerlimit_cfg_set_CN)}},
45 {0xFF, .power_info = {(t_u8 *)rutxpowerlimit_cfg_set_JP, sizeof(rutxpowerlimit_cfg_set_JP)}},
46 };
47
wlan_set_ru_power_cfg(t_u16 region_code)48 int wlan_set_ru_power_cfg(t_u16 region_code)
49 {
50 int i = 0;
51 int rv = -WM_FAIL;
52
53 for (i = 0; i < sizeof(ru_power_cfg_rw610) / sizeof(ru_power_cfg); i++)
54 {
55 if (region_code == ru_power_cfg_rw610[i].region_code)
56 {
57 rv = wlan_set_11ax_rutxpowerlimit(ru_power_cfg_rw610[i].power_info.rg_power_table,
58 ru_power_cfg_rw610[i].power_info.rg_len);
59
60 return rv;
61 }
62 }
63
64 /* Set default world wide ru txpwr if ru_power_cfg_rw610 does not have a corresponding region_code temporarily */
65 wlcm_d("power_info of region_code %d not available, use default world wide ru txpwr by default.", region_code);
66
67 rv = wlan_set_11ax_rutxpowerlimit(ru_power_cfg_rw610[0].power_info.rg_power_table,
68 ru_power_cfg_rw610[0].power_info.rg_len);
69
70 return rv;
71 }
72 #endif
73
74 #if defined(RW610) && (CONFIG_COMPRESS_TX_PWTBL)
75 #define MAX_SOC_OTP_LINE 64
76 #define OTP_PKG_TAG 0x15D
77 #define PKG_TYPE_MAX 3
78
79 typedef struct _rg_power_cfg
80 {
81 t_u16 region_code;
82 rg_power_info power_info[PKG_TYPE_MAX];
83 } rg_power_cfg;
84
85 /* For CSP board, we didn't get tx_power_table data, so use bga data temporary
86 * And maybe no BGA or QFN data for avaliable region, use other type data
87 */
88 rg_power_cfg rg_power_cfg_rw610[] = {
89 {0x10, .power_info[RW610_PACKAGE_TYPE_QFN] = {(t_u8 *)rg_rw610_qfn, sizeof(rg_rw610_qfn)},
90 .power_info[RW610_PACKAGE_TYPE_CSP] = {(t_u8 *)rg_rw610_csp, sizeof(rg_rw610_csp)},
91 .power_info[RW610_PACKAGE_TYPE_BGA] = {(t_u8 *)rg_rw610_bga, sizeof(rg_rw610_bga)}},
92 {0x30, .power_info[RW610_PACKAGE_TYPE_QFN] = {(t_u8 *)rg_rw610_EU, sizeof(rg_rw610_EU)},
93 .power_info[RW610_PACKAGE_TYPE_CSP] = {(t_u8 *)rg_rw610_EU, sizeof(rg_rw610_EU)},
94 .power_info[RW610_PACKAGE_TYPE_BGA] = {(t_u8 *)rg_rw610_EU, sizeof(rg_rw610_EU)}},
95 {0x40, .power_info[RW610_PACKAGE_TYPE_QFN] = {(t_u8 *)rg_rw610_JP, sizeof(rg_rw610_JP)},
96 .power_info[RW610_PACKAGE_TYPE_CSP] = {(t_u8 *)rg_rw610_JP, sizeof(rg_rw610_JP)},
97 .power_info[RW610_PACKAGE_TYPE_BGA] = {(t_u8 *)rg_rw610_JP, sizeof(rg_rw610_JP)}},
98 {0x50, .power_info[RW610_PACKAGE_TYPE_QFN] = {(t_u8 *)rg_rw610_CA, sizeof(rg_rw610_CA)},
99 .power_info[RW610_PACKAGE_TYPE_CSP] = {(t_u8 *)rg_rw610_CA, sizeof(rg_rw610_CA)},
100 .power_info[RW610_PACKAGE_TYPE_BGA] = {(t_u8 *)rg_rw610_CA, sizeof(rg_rw610_CA)}},
101 {0xFF, .power_info[RW610_PACKAGE_TYPE_QFN] = {(t_u8 *)rg_rw610_JP, sizeof(rg_rw610_JP)},
102 .power_info[RW610_PACKAGE_TYPE_CSP] = {(t_u8 *)rg_rw610_JP, sizeof(rg_rw610_JP)},
103 .power_info[RW610_PACKAGE_TYPE_BGA] = {(t_u8 *)rg_rw610_JP, sizeof(rg_rw610_JP)}},
104 };
105
wlan_set_rg_power_cfg(t_u16 region_code)106 int wlan_set_rg_power_cfg(t_u16 region_code)
107 {
108 int i = 0;
109 uint32_t board_type = 0;
110 int rv = WM_SUCCESS;
111
112 board_type = wifi_get_board_type();
113 if (RW610_PACKAGE_TYPE_QFN == board_type)
114 {
115 (void)PRINTF("PKG_TYPE: QFN\r\n");
116 (void)PRINTF("Set QFN tx power table data \r\n");
117 }
118 else if (RW610_PACKAGE_TYPE_BGA == board_type)
119 {
120 (void)PRINTF("PKG_TYPE: BGA\r\n");
121 (void)PRINTF("Set BGA tx power table data \r\n");
122 }
123 else if (RW610_PACKAGE_TYPE_CSP == board_type)
124 {
125 (void)PRINTF("PKG_TYPE: CSP\r\n");
126 (void)PRINTF("Set CSP tx power table data \r\n");
127 }
128 else
129 {
130 board_type = RW610_PACKAGE_TYPE_BGA;
131 (void)PRINTF("PKG_TYPE: UNKNOWN\r\n");
132 (void)PRINTF("Set BGA tx power table data \r\n");
133 (void)PRINTF("Can't get board type, we use bga data default \r\n");
134 }
135
136 for (i = 0; i < sizeof(rg_power_cfg_rw610) / sizeof(rg_power_cfg); i++)
137 {
138 if (region_code == rg_power_cfg_rw610[i].region_code)
139 {
140 rv = wlan_set_region_power_cfg(rg_power_cfg_rw610[i].power_info[board_type].rg_power_table,
141 rg_power_cfg_rw610[i].power_info[board_type].rg_len);
142
143 return rv;
144 }
145 }
146
147 /* Set FCC power table if rg_power_cfg_rw610 does not have a corresponding region_code temporarily */
148 wlcm_d("power_info of region_code %d not available, use US power table by default.", region_code);
149
150 rv = wlan_set_region_power_cfg(rg_power_cfg_rw610[0].power_info[board_type].rg_power_table,
151 rg_power_cfg_rw610[0].power_info[board_type].rg_len);
152
153 return rv;
154 }
155 #elif (CONFIG_COMPRESS_TX_PWTBL)
156 typedef struct _rg_power_cfg
157 {
158 t_u16 region_code;
159 t_u8 *rg_power_table;
160 t_u16 rg_len;
161 } rg_power_cfg;
162
163 rg_power_cfg rg_power_cfg_FC[] = {
164 {
165 0x00,
166 (t_u8 *)rg_table_fc,
167 sizeof(rg_table_fc),
168 },
169 };
170
wlan_set_rg_power_cfg(t_u16 region_code)171 int wlan_set_rg_power_cfg(t_u16 region_code)
172 {
173 int i = 0;
174 int rv = WM_SUCCESS;
175
176 for (i = 0; i < sizeof(rg_power_cfg_FC) / sizeof(rg_power_cfg); i++)
177 {
178 if (region_code == rg_power_cfg_FC[i].region_code)
179 {
180 rv = wlan_set_region_power_cfg(rg_power_cfg_FC[i].rg_power_table, rg_power_cfg_FC[i].rg_len);
181 if (rv != WM_SUCCESS)
182 (void)PRINTF("Unable to set compressed TX power table configuration\r\n");
183 return rv;
184 }
185 }
186
187 return -WM_FAIL;
188 }
189
190 #endif
191
192 #if CONFIG_COMPRESS_TX_PWTBL
wlan_set_wwsm_txpwrlimit()193 int wlan_set_wwsm_txpwrlimit()
194 {
195 int rv = WM_SUCCESS;
196 #ifdef WLAN_REGION_CODE
197 rv = wlan_set_country_code(WLAN_REGION_CODE);
198 if (rv != WM_SUCCESS)
199 {
200 (void)PRINTF("Unable to set country code\r\n");
201 return -WM_FAIL;
202 }
203 #endif
204 #ifdef RW610
205 unsigned int region_code = 0;
206 #endif
207 #ifdef WLAN_REGION_CODE
208 rv = wlan_set_country_code(WLAN_REGION_CODE);
209 if (rv != WM_SUCCESS)
210 {
211 (void)PRINTF("Unable to set country code\r\n");
212 return -WM_FAIL;
213 }
214 #endif
215 #ifdef RW610
216 ARG_UNUSED(tx_pwrlimit_2g_cfg);
217 ARG_UNUSED(chanlist_2g_cfg);
218 #if CONFIG_5GHz_SUPPORT
219 ARG_UNUSED(tx_pwrlimit_5g_cfg);
220 ARG_UNUSED(chanlist_5g_cfg);
221 #endif
222 #endif
223 #ifndef RW610
224 rv = wlan_set_chanlist(&chanlist_2g_cfg);
225 if (rv != WM_SUCCESS)
226 {
227 (void)PRINTF("Unable to set 2G chanlist configuration\r\n");
228 return -WM_FAIL;
229 }
230 #if CONFIG_5GHz_SUPPORT
231 rv = wlan_set_chanlist(&chanlist_5g_cfg);
232 if (rv != WM_SUCCESS)
233 {
234 (void)PRINTF("Unable to set 5G chanlist configuration\r\n");
235 return -WM_FAIL;
236 }
237 #endif
238 #endif
239 #ifdef RW610
240 wlan_get_region_code(®ion_code);
241 rv = wlan_set_rg_power_cfg(region_code);
242 #if (CONFIG_COMPRESS_RU_TX_PWTBL) && (CONFIG_11AX)
243 rv = wlan_set_ru_power_cfg(region_code);
244 if (rv != WM_SUCCESS)
245 {
246 return -WM_FAIL;
247 }
248 #endif
249 #else
250 rv = wlan_set_region_power_cfg(rg_table_fc, rg_table_fc_len);
251 #endif
252 if (rv != WM_SUCCESS)
253 {
254 (void)PRINTF("Unable to set compressed TX power table configuration\r\n");
255 return -WM_FAIL;
256 }
257 #ifndef RW610
258 #if CONFIG_11AX
259 #if CONFIG_COMPRESS_RU_TX_PWTBL
260 rv = wlan_set_11ax_rutxpowerlimit(rutxpowerlimit_cfg_set, sizeof(rutxpowerlimit_cfg_set));
261 if (rv != WM_SUCCESS)
262 {
263 (void)PRINTF("Unable to set RU TX PWR Limit configuration\r\n");
264 return -WM_FAIL;
265 }
266 #else
267 rv = wlan_set_11ax_rutxpowerlimit_legacy(&rutxpowerlimit_2g_cfg_set);
268 if (rv != WM_SUCCESS)
269 {
270 (void)PRINTF("Unable to set 2G RU TX PWR Limit configuration\r\n");
271 return -WM_FAIL;
272 }
273 #if CONFIG_5GHz_SUPPORT
274 else
275 {
276 rv = wlan_set_11ax_rutxpowerlimit_legacy(&rutxpowerlimit_5g_cfg_set);
277 if (rv != WM_SUCCESS)
278 {
279 (void)PRINTF("Unable to set 5G RU TX PWR Limit configuration\r\n");
280 return -WM_FAIL;
281 }
282 }
283 #endif
284 #endif /* CONFIG_COMPRESS_RU_TX_PWTBL */
285 #endif /* CONFIG_11AX */
286 #endif /* RW610 */
287
288 return rv;
289 }
290 #else
wlan_set_wwsm_txpwrlimit(void)291 int wlan_set_wwsm_txpwrlimit(void)
292 {
293 int rv = WM_SUCCESS;
294 #ifdef WLAN_REGION_CODE
295 rv = wlan_set_country_code(WLAN_REGION_CODE);
296 if (rv != WM_SUCCESS)
297 {
298 (void)PRINTF("Unable to set country code\r\n");
299 return -WM_FAIL;
300 }
301 #endif
302 rv = wlan_set_chanlist_and_txpwrlimit(&chanlist_2g_cfg, &tx_pwrlimit_2g_cfg);
303 if (rv != WM_SUCCESS)
304 {
305 (void)PRINTF("Unable to set 2G TX PWR Limit configuration\r\n");
306 return -WM_FAIL;
307 }
308 #if CONFIG_5GHz_SUPPORT
309 rv = wlan_set_chanlist_and_txpwrlimit(&chanlist_5g_cfg, &tx_pwrlimit_5g_cfg);
310 if (rv != WM_SUCCESS)
311 {
312 (void)PRINTF("Unable to set 5G TX PWR Limit configuration\r\n");
313 return -WM_FAIL;
314 }
315 #endif
316
317 #ifndef RW610
318 #if CONFIG_11AX
319 #if CONFIG_COMPRESS_RU_TX_PWTBL
320 rv = wlan_set_11ax_rutxpowerlimit(rutxpowerlimit_cfg_set, sizeof(rutxpowerlimit_cfg_set));
321 if (rv != WM_SUCCESS)
322 {
323 (void)PRINTF("Unable to set RU TX PWR Limit configuration\r\n");
324 return -WM_FAIL;
325 }
326 #else
327 rv = wlan_set_11ax_rutxpowerlimit_legacy(&rutxpowerlimit_2g_cfg_set);
328 if (rv != WM_SUCCESS)
329 {
330 (void)PRINTF("Unable to set 2G RU TX PWR Limit configuration\r\n");
331 return -WM_FAIL;
332 }
333 #if CONFIG_5GHz_SUPPORT
334 else
335 {
336 rv = wlan_set_11ax_rutxpowerlimit_legacy(&rutxpowerlimit_5g_cfg_set);
337 if (rv != WM_SUCCESS)
338 {
339 (void)PRINTF("Unable to set 5G RU TX PWR Limit configuration\r\n");
340 return -WM_FAIL;
341 }
342 }
343 #endif
344 #endif /* CONFIG_COMPRESS_RU_TX_PWTBL */
345 #endif /* CONFIG_11AX */
346 #endif /* RW610 */
347
348 return rv;
349 }
350 #endif /* CONFIG_COMPRESS_TX_PWTBL */
351
352 #ifndef RW610
wlan_get_wlan_region_code(void)353 const char *wlan_get_wlan_region_code(void)
354 {
355 #ifdef WLAN_REGION_CODE
356 return WLAN_REGION_CODE;
357 #else
358 #error "Please define WLAN_REGION_CODE in Region tx power config file"
359 #endif
360 }
361 #endif
362