Skip to content

Commit 0615885

Browse files
ArunmaniAlagarsamy2710kartben
authored andcommitted
drivers: wifi: siwx91x: Add support for regulatory domain GET
Added support for retrieving the regulatory domain information from the siwx91x driver. Since the SDK does not provide a GET API for region details, the driver now stores the country code and reuse the configuration `sli_si91x_set_region_ap_request_t` to get the channel information. This stored data is returned when a GET operation is requested. Signed-off-by: Arunmani Alagarsamy <[email protected]>
1 parent eac7784 commit 0615885

File tree

3 files changed

+130
-6
lines changed

3 files changed

+130
-6
lines changed

drivers/wifi/siwx91x/siwx91x_wifi.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "sl_wifi_callback_framework.h"
2020

2121
#define SIWX91X_DRIVER_VERSION KERNEL_VERSION_STRING
22+
#define MAX_24GHZ_CHANNELS 14
2223

2324
LOG_MODULE_REGISTER(siwx91x_wifi);
2425

@@ -369,10 +370,43 @@ static int siwx91x_get_version(const struct device *dev, struct wifi_version *pa
369370
return 0;
370371
}
371372

373+
static int map_sdk_region_to_zephyr_channel_info(const sli_si91x_set_region_ap_request_t *sdk_reg,
374+
struct wifi_reg_chan_info *z_chan_info,
375+
size_t *num_channels)
376+
{
377+
uint8_t first_channel = sdk_reg->channel_info[0].first_channel;
378+
uint8_t channel;
379+
uint16_t freq;
380+
381+
*num_channels = sdk_reg->channel_info[0].no_of_channels;
382+
if (*num_channels > MAX_24GHZ_CHANNELS) {
383+
return -EOVERFLOW;
384+
}
385+
386+
for (int idx = 0; idx < *num_channels; idx++) {
387+
channel = first_channel + idx;
388+
freq = 2407 + channel * 5;
389+
390+
if (freq > 2472) {
391+
freq = 2484; /* channel 14 */
392+
}
393+
394+
z_chan_info[idx].center_frequency = freq;
395+
z_chan_info[idx].max_power = sdk_reg->channel_info[0].max_tx_power;
396+
z_chan_info[idx].supported = 1;
397+
z_chan_info[idx].passive_only = 0;
398+
z_chan_info[idx].dfs = 0;
399+
}
400+
401+
return 0;
402+
}
403+
372404
static int siwx91x_wifi_reg_domain(const struct device *dev, struct wifi_reg_domain *reg_domain)
373405
{
406+
const sli_si91x_set_region_ap_request_t *sdk_reg = NULL;
374407
sl_wifi_operation_mode_t oper_mode = sli_get_opermode();
375408
sl_wifi_region_code_t region_code;
409+
const char *country_code;
376410
int ret;
377411

378412
__ASSERT(reg_domain, "reg_domain cannot be NULL");
@@ -386,8 +420,28 @@ static int siwx91x_wifi_reg_domain(const struct device *dev, struct wifi_reg_dom
386420
}
387421

388422
if (region_code == SL_WIFI_DEFAULT_REGION) {
423+
siwx91x_store_country_code(DEFAULT_COUNTRY_CODE);
389424
LOG_INF("Country code not supported, using default region");
425+
} else {
426+
siwx91x_store_country_code(reg_domain->country_code);
390427
}
428+
} else if (reg_domain->oper == WIFI_MGMT_GET) {
429+
country_code = siwx91x_get_country_code();
430+
memcpy(reg_domain->country_code, country_code, WIFI_COUNTRY_CODE_LEN);
431+
region_code = siwx91x_map_country_code_to_region(country_code);
432+
433+
sdk_reg = siwx91x_find_sdk_region_table(region_code);
434+
if (!sdk_reg) {
435+
return -ENOENT;
436+
}
437+
438+
ret = map_sdk_region_to_zephyr_channel_info(sdk_reg, reg_domain->chan_info,
439+
&reg_domain->num_channels);
440+
if (ret) {
441+
return ret;
442+
}
443+
} else {
444+
return -EINVAL;
391445
}
392446

393447
return 0;

soc/silabs/silabs_siwx91x/siwg917/nwp.c

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,19 @@ BUILD_ASSERT(DT_REG_SIZE(DT_CHOSEN(zephyr_sram)) == KB(195) ||
3232
DT_REG_SIZE(DT_CHOSEN(zephyr_sram)) == KB(255) ||
3333
DT_REG_SIZE(DT_CHOSEN(zephyr_sram)) == KB(319));
3434

35+
extern const sli_si91x_set_region_ap_request_t default_US_region_2_4GHZ_configurations;
36+
extern const sli_si91x_set_region_ap_request_t default_EU_region_2_4GHZ_configurations;
37+
extern const sli_si91x_set_region_ap_request_t default_JP_region_2_4GHZ_configurations;
38+
extern const sli_si91x_set_region_ap_request_t default_KR_region_2_4GHZ_configurations;
39+
extern const sli_si91x_set_region_ap_request_t default_SG_region_2_4GHZ_configurations;
40+
extern const sli_si91x_set_region_ap_request_t default_CN_region_2_4GHZ_configurations;
41+
42+
static char current_country_code[WIFI_COUNTRY_CODE_LEN];
3543
typedef struct {
3644
const char *const *codes;
3745
size_t num_codes;
3846
sl_wifi_region_code_t region_code;
47+
const sli_si91x_set_region_ap_request_t *sdk_reg;
3948
} region_map_t;
4049

4150
static const char *const us_codes[] = {
@@ -63,13 +72,31 @@ static const char *const kr_codes[] = {"KR", "KP"};
6372
static const char *const cn_codes[] = {"CN"};
6473

6574
static const region_map_t region_maps[] = {
66-
{us_codes, ARRAY_SIZE(us_codes), SL_WIFI_REGION_US},
67-
{eu_codes, ARRAY_SIZE(eu_codes), SL_WIFI_REGION_EU},
68-
{jp_codes, ARRAY_SIZE(jp_codes), SL_WIFI_REGION_JP},
69-
{kr_codes, ARRAY_SIZE(kr_codes), SL_WIFI_REGION_KR},
70-
{cn_codes, ARRAY_SIZE(cn_codes), SL_WIFI_REGION_CN},
75+
{us_codes, ARRAY_SIZE(us_codes), SL_WIFI_REGION_US,
76+
&default_US_region_2_4GHZ_configurations},
77+
{eu_codes, ARRAY_SIZE(eu_codes), SL_WIFI_REGION_EU,
78+
&default_EU_region_2_4GHZ_configurations},
79+
{jp_codes, ARRAY_SIZE(jp_codes), SL_WIFI_REGION_JP,
80+
&default_JP_region_2_4GHZ_configurations},
81+
{kr_codes, ARRAY_SIZE(kr_codes), SL_WIFI_REGION_KR,
82+
&default_KR_region_2_4GHZ_configurations},
83+
{cn_codes, ARRAY_SIZE(cn_codes), SL_WIFI_REGION_CN,
84+
&default_CN_region_2_4GHZ_configurations},
7185
};
7286

87+
int siwx91x_store_country_code(const char *country_code)
88+
{
89+
__ASSERT(country_code, "country_code cannot be NULL");
90+
91+
memcpy(current_country_code, country_code, WIFI_COUNTRY_CODE_LEN);
92+
return 0;
93+
}
94+
95+
const char *siwx91x_get_country_code(void)
96+
{
97+
return current_country_code;
98+
}
99+
73100
sl_wifi_region_code_t siwx91x_map_country_code_to_region(const char *country_code)
74101
{
75102
__ASSERT(country_code, "country_code cannot be NULL");
@@ -85,6 +112,16 @@ sl_wifi_region_code_t siwx91x_map_country_code_to_region(const char *country_cod
85112
return SL_WIFI_DEFAULT_REGION;
86113
}
87114

115+
const sli_si91x_set_region_ap_request_t *siwx91x_find_sdk_region_table(uint8_t region_code)
116+
{
117+
ARRAY_FOR_EACH(region_maps, i) {
118+
if (region_maps[i].region_code == region_code) {
119+
return region_maps[i].sdk_reg;
120+
}
121+
}
122+
return NULL;
123+
}
124+
88125
static void siwx91x_apply_sram_config(sl_si91x_boot_configuration_t *boot_config)
89126
{
90127
/* The size does not match exactly because 1 KB is reserved at the start of the RAM */
@@ -214,8 +251,8 @@ int siwx91x_get_nwp_config(sl_wifi_device_configuration_t *get_config, uint8_t w
214251
bool hidden_ssid, uint8_t max_num_sta)
215252
{
216253
sl_wifi_device_configuration_t default_config = {
254+
.region_code = siwx91x_map_country_code_to_region(DEFAULT_COUNTRY_CODE),
217255
.band = SL_SI91X_WIFI_BAND_2_4GHZ,
218-
.region_code = DEFAULT_REGION,
219256
.boot_option = LOAD_NWP_FW,
220257
.boot_config = {
221258
.feature_bit_map = SL_SI91X_FEAT_SECURITY_OPEN | SL_SI91X_FEAT_WPS_DISABLE |
@@ -246,6 +283,7 @@ int siwx91x_get_nwp_config(sl_wifi_device_configuration_t *get_config, uint8_t w
246283
return -EINVAL;
247284
}
248285

286+
siwx91x_store_country_code(DEFAULT_COUNTRY_CODE);
249287
siwx91x_apply_sram_config(boot_config);
250288

251289
switch (wifi_oper_mode) {

soc/silabs/silabs_siwx91x/siwg917/nwp.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "sl_wifi.h"
99

1010
#define SIWX91X_INTERFACE_MASK (0x03)
11+
#define DEFAULT_COUNTRY_CODE "00"
1112

1213
/**
1314
* @brief Switch the Wi-Fi operating mode.
@@ -37,4 +38,35 @@ int siwx91x_nwp_mode_switch(uint8_t oper_mode, bool hidden_ssid, uint8_t max_num
3738
*/
3839
sl_wifi_region_code_t siwx91x_map_country_code_to_region(const char *country_code);
3940

41+
/**
42+
* @brief Get the default SDK region configuration for a region code.
43+
*
44+
* Looks up the given sl_wifi_region_code_t and returns the corresponding
45+
* SDK region configuration, or NULL if not found.
46+
*
47+
* @param[in] region_code Wi-Fi region code (SL_WIFI_REGION_*).
48+
*
49+
* @return Pointer to SDK region configuration, or NULL if unsupported.
50+
*/
51+
const sli_si91x_set_region_ap_request_t *siwx91x_find_sdk_region_table(uint8_t region_code);
52+
53+
/**
54+
* @brief Store the country code internally for GET operation.
55+
*
56+
* This function saves the provided country code to a static internal buffer.
57+
*
58+
* @param[in] country_code Pointer to a 2-character ISO country code.
59+
*/
60+
int siwx91x_store_country_code(const char *country_code);
61+
62+
/**
63+
* @brief Retrieve the currently stored country code.
64+
*
65+
* This function returns a pointer to the internally stored 2-character
66+
* country code set by store_country_code().
67+
*
68+
* @return Pointer to the stored country code string.
69+
*/
70+
const char *siwx91x_get_country_code(void);
71+
4072
#endif

0 commit comments

Comments
 (0)