Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions drivers/wifi/siwx91x/Kconfig.siwx91x
Original file line number Diff line number Diff line change
Expand Up @@ -178,4 +178,30 @@ config WIFI_SILABS_SIWX91X_ENABLE_INSTANT_SCAN
# This device supports filtering scan results for only one SSID.
config WIFI_MGMT_SCAN_SSID_FILT_MAX
default 1

config WIFI_SILABS_SIWX91X_MFP
bool "802.11w Management Frame Protection (MFP) support"
default y
help
Enable IEEE 802.11w Management Frame Protection (MFP) for secure
handling of management frames.

Note:
- Required for WPA3-Personal and WPA3-Transition modes.
- Disabling this frees memory used by MFP, improving TCP throughput
by about 10–12% (≈1–2 Mbps).

config WIFI_SILABS_SIWX91X_FEAT_SECURITY_PSK
bool "WPA/WPA2 (PSK) Security Support"
default y
help
Enable WPA/WPA2 (PSK-based) security in client mode.
Recommended for configurations requiring WPA, WPA2, or mixed security modes.
Disabling this feature can reduce data buffer usage, potentially improving throughput.

config WIFI_SILABS_SIWX91X_FEAT_HIDE_PSK_CREDENTIALS
bool "Hide PSK and Sensitive Credentials in Logs"
help
When enabled, prevents printing sensitive credentials such as
PSK, PMK, and EAP keys in debug or log messages.
endif
4 changes: 4 additions & 0 deletions dts/arm/silabs/siwg917.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@
interrupt-parent = <&nvic>;
interrupts = <30 0>, <74 0>;
interrupt-names = "nwp_stack", "nwp_irq";
antenna-selection = "ext-gpios";
support-1p8v;
enable-xtal-correction;
qspi-80mhz-clk;
status = "okay";

bt_hci0: bt_hci {
Expand Down
46 changes: 46 additions & 0 deletions dts/bindings/net/wireless/silabs,siwx91x-nwp.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,49 @@ properties:
- deep-sleep-without-ram-retention
- deep-sleep-with-ram-retention
required: true

support-1p8v:
type: boolean
description: |
Enables 1.8 V operation support.

enable-xtal-correction:
type: boolean
description: |
Enables automatic 40 MHz XTAL frequency correction.
Disable this when using a custom or uncalibrated XTAL and manual tuning is required.

qspi-80mhz-clk:
type: boolean
description: |
Enables 80 MHz QSPI clock mode for the NWP flash interface to improve
throughput. Enable this if the external flash device supports 80 MHz
operation; otherwise, keep it disabled.
# Note:
# Zephyr typically manages clocks via a clock-controller driver.
# However, the NWP is not yet fully compatible with that model.
# This property is kept as a temporary solution for NWP-specific configuration.

antenna-selection:
type: string
description: |
Selects the front-end (antenna) switch configuration for the NWP.

This property determines how the RF path is controlled:
- "none": Reserved or unused configuration.
- "ext-gpios": Use external ULP GPIOs (4, 5, and 0) as ANT_SEL control lines
for the external RF switch network.
- "internal": Use the internal on-chip RF switch logic. No external GPIO
control is required. Recommended for boards without an external RF
switch circuit.

The value maps directly to bits [30:29] of the SL_SI91X_EXT_FEAT register:
- 00b: Reserved
- 01b: External GPIOs (ULP_GPIO4/5/0)
- 10b: Internal front-end switch
- 11b: Reserved
enum:
- "none"
- "ext-gpios"
- "internal"
required: true
76 changes: 57 additions & 19 deletions soc/silabs/silabs_siwx91x/siwg917/siwx91x_nwp.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "sl_si91x_power_manager.h"

#define AP_MAX_NUM_STA 4
#define SL_SI91X_EXT_FEAT_FRONT_END_MSK (BIT(30) | BIT(29))

LOG_MODULE_REGISTER(siwx91x_nwp);

Expand All @@ -43,6 +44,10 @@ struct siwx91x_nwp_config {
void (*config_irq)(const struct device *dev);
uint32_t stack_size;
uint8_t power_profile;
uint8_t antenna_selection;
bool support_1p8v;
bool enable_xtal_correction;
bool qspi_80mhz_clk;
};

typedef struct {
Expand Down Expand Up @@ -147,16 +152,50 @@ static void siwx91x_apply_sram_config(sl_si91x_boot_configuration_t *boot_config
}
}

static void siwx91x_apply_boot_config(const struct device *dev,
sl_si91x_boot_configuration_t *boot_config)
{
const struct siwx91x_nwp_config *cfg = dev->config;
struct {
bool enabled;
uint32_t *target;
uint32_t bit;
} features[] = {
{ cfg->support_1p8v, &boot_config->ext_custom_feature_bit_map,
SL_SI91X_EXT_FEAT_1P8V_SUPPORT },
{ !cfg->enable_xtal_correction, &boot_config->ext_custom_feature_bit_map,
SL_SI91X_EXT_FEAT_DISABLE_XTAL_CORRECTION },
{ cfg->qspi_80mhz_clk, &boot_config->ext_custom_feature_bit_map,
SL_SI91X_EXT_FEAT_NWP_QSPI_80MHZ_CLK_ENABLE },
};

for (int i = 0; i < ARRAY_SIZE(features); i++) {
if (features[i].enabled) {
*features[i].target |= features[i].bit;
}
}

boot_config->ext_custom_feature_bit_map &= ~SL_SI91X_EXT_FEAT_FRONT_END_MSK;
boot_config->ext_custom_feature_bit_map |=
FIELD_PREP(SL_SI91X_EXT_FEAT_FRONT_END_MSK, cfg->antenna_selection);
}

static void siwx91x_configure_sta_mode(sl_si91x_boot_configuration_t *boot_config)
{
const bool wifi_enabled = IS_ENABLED(CONFIG_WIFI_SILABS_SIWX91X);
const bool bt_enabled = IS_ENABLED(CONFIG_BT_SILABS_SIWX91X);

boot_config->oper_mode = SL_SI91X_CLIENT_MODE;

if (IS_ENABLED(CONFIG_WIFI_SILABS_SIWX91X_ROAMING_USE_DEAUTH)) {
boot_config->custom_feature_bit_map |=
SL_SI91X_CUSTOM_FEAT_ROAM_WITH_DEAUTH_OR_NULL_DATA;
if (wifi_enabled) {
boot_config->feature_bit_map |= SL_SI91X_FEAT_SECURITY_OPEN;
if (IS_ENABLED(CONFIG_WIFI_SILABS_SIWX91X_FEAT_SECURITY_PSK)) {
boot_config->feature_bit_map |= SL_SI91X_FEAT_SECURITY_PSK;
}
if (IS_ENABLED(CONFIG_WIFI_SILABS_SIWX91X_ROAMING_USE_DEAUTH)) {
boot_config->custom_feature_bit_map |=
SL_SI91X_CUSTOM_FEAT_ROAM_WITH_DEAUTH_OR_NULL_DATA;
}
}

if (wifi_enabled && bt_enabled) {
Expand All @@ -174,9 +213,9 @@ static void siwx91x_configure_sta_mode(sl_si91x_boot_configuration_t *boot_confi

#ifdef CONFIG_WIFI_SILABS_SIWX91X
boot_config->ext_tcp_ip_feature_bit_map = SL_SI91X_CONFIG_FEAT_EXTENSION_VALID;
boot_config->ext_custom_feature_bit_map |=
SL_SI91X_EXT_FEAT_IEEE_80211W |
SL_SI91X_EXT_FEAT_FRONT_END_SWITCH_PINS_ULP_GPIO_4_5_0;
if (IS_ENABLED(CONFIG_WIFI_SILABS_SIWX91X_MFP)) {
boot_config->ext_custom_feature_bit_map |= SL_SI91X_EXT_FEAT_IEEE_80211W;
}
if (IS_ENABLED(CONFIG_WIFI_SILABS_SIWX91X_ENHANCED_MAX_PSP)) {
boot_config->config_feature_bit_map = SL_SI91X_ENABLE_ENHANCED_MAX_PSP;
}
Expand Down Expand Up @@ -316,20 +355,11 @@ static int siwx91x_get_nwp_config(const struct device *dev,
.band = SL_SI91X_WIFI_BAND_2_4GHZ,
.boot_option = LOAD_NWP_FW,
.boot_config = {
.feature_bit_map = SL_SI91X_FEAT_SECURITY_OPEN | SL_SI91X_FEAT_WPS_DISABLE |
SL_SI91X_FEAT_SECURITY_PSK | SL_SI91X_FEAT_AGGREGATION |
SL_SI91X_FEAT_HIDE_PSK_CREDENTIALS,
.feature_bit_map = SL_SI91X_FEAT_WPS_DISABLE | SL_SI91X_FEAT_AGGREGATION,
.tcp_ip_feature_bit_map = SL_SI91X_TCP_IP_FEAT_EXTENSION_VALID,
.custom_feature_bit_map = SL_SI91X_CUSTOM_FEAT_EXTENSION_VALID |
SL_SI91X_CUSTOM_FEAT_ASYNC_CONNECTION_STATUS |
SL_SI91X_CUSTOM_FEAT_RTC_FROM_HOST,
.ext_custom_feature_bit_map =
SL_SI91X_EXT_FEAT_XTAL_CLK | SL_SI91X_EXT_FEAT_1P8V_SUPPORT |
SL_SI91X_EXT_FEAT_DISABLE_XTAL_CORRECTION |
SL_SI91X_EXT_FEAT_NWP_QSPI_80MHZ_CLK_ENABLE |
SL_SI91X_EXT_FEAT_FRONT_END_SWITCH_PINS_ULP_GPIO_4_5_0 |
SL_SI91X_EXT_FEAT_FRONT_END_INTERNAL_SWITCH |
SL_SI91X_EXT_FEAT_XTAL_CLK,
SL_SI91X_CUSTOM_FEAT_ASYNC_CONNECTION_STATUS,
.ext_custom_feature_bit_map = SL_SI91X_EXT_FEAT_XTAL_CLK,
}
};

Expand All @@ -344,8 +374,12 @@ static int siwx91x_get_nwp_config(const struct device *dev,
return -EINVAL;
}

if (IS_ENABLED(CONFIG_WIFI_SILABS_SIWX91X_FEAT_HIDE_PSK_CREDENTIALS)) {
boot_config->feature_bit_map |= SL_SI91X_FEAT_HIDE_PSK_CREDENTIALS;
}
siwx91x_store_country_code(dev, DEFAULT_COUNTRY_CODE);
siwx91x_apply_sram_config(boot_config);
siwx91x_apply_boot_config(dev, boot_config);

switch (wifi_oper_mode) {
case WIFI_STA_MODE:
Expand Down Expand Up @@ -467,7 +501,11 @@ BUILD_ASSERT(CONFIG_SIWX91X_NWP_INIT_PRIORITY < CONFIG_KERNEL_INIT_PRIORITY_DEFA
static const struct siwx91x_nwp_config siwx91x_nwp_config_##inst = { \
.config_irq = silabs_siwx91x_nwp_irq_configure_##inst, \
.power_profile = DT_ENUM_IDX(DT_DRV_INST(inst), power_profile), \
.stack_size = DT_INST_PROP(inst, stack_size) \
.stack_size = DT_INST_PROP(inst, stack_size), \
.support_1p8v = DT_INST_PROP(inst, support_1p8v), \
.enable_xtal_correction = DT_INST_PROP(inst, enable_xtal_correction), \
.qspi_80mhz_clk = DT_INST_PROP(inst, qspi_80mhz_clk), \
.antenna_selection = DT_INST_ENUM_IDX(inst, antenna_selection), \
}; \
\
/* Coprocessor uses value stored in IVT to store its stack. We can't use Z_ISR_DECLARE() */\
Expand Down