diff --git a/drivers/bluetooth/hci/Kconfig b/drivers/bluetooth/hci/Kconfig index d62c3bb0b18e1..f5ca0be28ce04 100644 --- a/drivers/bluetooth/hci/Kconfig +++ b/drivers/bluetooth/hci/Kconfig @@ -184,7 +184,7 @@ config BT_SILABS_SIWX91X bool "Silabs SiWx91x Bluetooth interface" default y depends on DT_HAS_SILABS_SIWX91X_BT_HCI_ENABLED - select WISECONNECT_NETWORK_STACK + select SILABS_SIWX91X_NWP select ENTROPY_GENERATOR help Use Silicon Labs Wiseconnect 3.x Bluetooth library to connect to the controller. diff --git a/drivers/bluetooth/hci/hci_silabs_siwx91x.c b/drivers/bluetooth/hci/hci_silabs_siwx91x.c index f56141948a776..2932cba87664f 100644 --- a/drivers/bluetooth/hci/hci_silabs_siwx91x.c +++ b/drivers/bluetooth/hci/hci_silabs_siwx91x.c @@ -15,6 +15,10 @@ LOG_MODULE_REGISTER(bt_hci_driver_siwg917); static void siwx91x_bt_resp_rcvd(uint16_t status, rsi_ble_event_rcp_rcvd_info_t *resp_buf); +struct hci_config { + const struct device *nwp_dev; +}; + struct hci_data { bt_hci_recv_t recv; rsi_data_packet_t rsi_data_packet; @@ -95,15 +99,30 @@ static void siwx91x_bt_resp_rcvd(uint16_t status, rsi_ble_event_rcp_rcvd_info_t } } +static int siwx91x_bt_init(const struct device *dev) +{ + const struct hci_config *hci_config = dev->config; + + if (!device_is_ready(hci_config->nwp_dev)) { + LOG_ERR("NWP device not ready"); + return -ENODEV; + } + + return 0; +} + static DEVICE_API(bt_hci, siwx91x_api) = { .open = siwx91x_bt_open, .send = siwx91x_bt_send, }; #define HCI_DEVICE_INIT(inst) \ + static struct hci_config hci_config_##inst = { \ + .nwp_dev = DEVICE_DT_GET(DT_INST_PARENT(inst)) \ + }; \ static struct hci_data hci_data_##inst; \ - DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &hci_data_##inst, NULL, POST_KERNEL, \ - CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &siwx91x_api) + DEVICE_DT_INST_DEFINE(inst, siwx91x_bt_init, NULL, &hci_data_##inst, &hci_config_##inst, \ + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &siwx91x_api) /* Only one instance supported right now */ HCI_DEVICE_INIT(0) diff --git a/drivers/flash/Kconfig.siwx91x b/drivers/flash/Kconfig.siwx91x index ec7e7af209b5f..5bb8aee766cb5 100644 --- a/drivers/flash/Kconfig.siwx91x +++ b/drivers/flash/Kconfig.siwx91x @@ -9,7 +9,7 @@ config SOC_FLASH_SILABS_SIWX91X select FLASH_HAS_EXPLICIT_ERASE select FLASH_HAS_PAGE_LAYOUT # Flash controller is handled by the network coprocessor - select WISECONNECT_NETWORK_STACK + select SILABS_SIWX91X_NWP help Enable flash controller for flash embedded on Silicon Labs SiWx91x chips. diff --git a/drivers/wifi/siwx91x/Kconfig.siwx91x b/drivers/wifi/siwx91x/Kconfig.siwx91x index b7bf8a6d9faae..e71d7c2bf1e7b 100644 --- a/drivers/wifi/siwx91x/Kconfig.siwx91x +++ b/drivers/wifi/siwx91x/Kconfig.siwx91x @@ -6,7 +6,7 @@ config WIFI_SILABS_SIWX91X default y depends on DT_HAS_SILABS_SIWX91X_WIFI_ENABLED depends on NETWORKING - select WISECONNECT_NETWORK_STACK + select SILABS_SIWX91X_NWP select EVENTS select NET_L2_WIFI_MGMT help diff --git a/drivers/wifi/siwx91x/siwx91x_wifi.c b/drivers/wifi/siwx91x/siwx91x_wifi.c index f7f9873b526cb..b6d9c4bbc4865 100644 --- a/drivers/wifi/siwx91x/siwx91x_wifi.c +++ b/drivers/wifi/siwx91x/siwx91x_wifi.c @@ -7,7 +7,7 @@ #include -#include +#include #include "siwx91x_wifi.h" #include "siwx91x_wifi_ap.h" #include "siwx91x_wifi_ps.h" @@ -207,7 +207,7 @@ static int siwx91x_mode(const struct device *dev, struct wifi_mode_info *mode) mode->mode = cur_mode; } else if (mode->oper == WIFI_MGMT_SET) { if (cur_mode != mode->mode) { - ret = siwx91x_nwp_mode_switch(mode->mode, false, 0); + ret = siwx91x_nwp_mode_switch(siwx91x_cfg->nwp_dev, mode->mode, false, 0); if (ret < 0) { return ret; } @@ -394,6 +394,7 @@ static int map_sdk_region_to_zephyr_channel_info(const sli_si91x_set_region_ap_r static int siwx91x_wifi_reg_domain(const struct device *dev, struct wifi_reg_domain *reg_domain) { + const struct siwx91x_config *siwx91x_cfg = dev->config; const sli_si91x_set_region_ap_request_t *sdk_reg = NULL; sl_wifi_operation_mode_t oper_mode = sli_get_opermode(); sl_wifi_region_code_t region_code; @@ -411,13 +412,13 @@ static int siwx91x_wifi_reg_domain(const struct device *dev, struct wifi_reg_dom } if (region_code == SL_WIFI_DEFAULT_REGION) { - siwx91x_store_country_code(DEFAULT_COUNTRY_CODE); + siwx91x_store_country_code(siwx91x_cfg->nwp_dev, DEFAULT_COUNTRY_CODE); LOG_INF("Country code not supported, using default region"); } else { - siwx91x_store_country_code(reg_domain->country_code); + siwx91x_store_country_code(siwx91x_cfg->nwp_dev, reg_domain->country_code); } } else if (reg_domain->oper == WIFI_MGMT_GET) { - country_code = siwx91x_get_country_code(); + country_code = siwx91x_get_country_code(siwx91x_cfg->nwp_dev); memcpy(reg_domain->country_code, country_code, WIFI_COUNTRY_CODE_LEN); region_code = siwx91x_map_country_code_to_region(country_code); @@ -532,6 +533,13 @@ int siwx91x_set_rts_threshold(const struct device *dev, unsigned int rts_thresho static int siwx91x_dev_init(const struct device *dev) { + const struct siwx91x_config *siwx91x_cfg = dev->config; + + if (!device_is_ready(siwx91x_cfg->nwp_dev)) { + LOG_ERR("NWP device not ready"); + return -ENODEV; + } + return 0; } @@ -568,6 +576,7 @@ static const struct net_wifi_mgmt_offload siwx91x_api = { }; static const struct siwx91x_config siwx91x_cfg = { + .nwp_dev = DEVICE_DT_GET(DT_INST_PARENT(0)), .scan_tx_power = DT_INST_PROP(0, wifi_max_tx_pwr_scan), .join_tx_power = DT_INST_PROP(0, wifi_max_tx_pwr_join), }; diff --git a/drivers/wifi/siwx91x/siwx91x_wifi.h b/drivers/wifi/siwx91x/siwx91x_wifi.h index 374e0f2cf69b4..8819f0518f2c7 100644 --- a/drivers/wifi/siwx91x/siwx91x_wifi.h +++ b/drivers/wifi/siwx91x/siwx91x_wifi.h @@ -10,6 +10,7 @@ #include "sl_si91x_types.h" struct siwx91x_config { + const struct device *nwp_dev; uint8_t scan_tx_power; uint8_t join_tx_power; }; diff --git a/drivers/wifi/siwx91x/siwx91x_wifi_ap.c b/drivers/wifi/siwx91x/siwx91x_wifi_ap.c index a43bf6c2ae83b..283a69fb0ea03 100644 --- a/drivers/wifi/siwx91x/siwx91x_wifi_ap.c +++ b/drivers/wifi/siwx91x/siwx91x_wifi_ap.c @@ -3,7 +3,7 @@ * Copyright (c) 2024-2025 Silicon Laboratories Inc. * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include "siwx91x_wifi.h" #include "sl_rsi_utility.h" @@ -13,11 +13,13 @@ LOG_MODULE_DECLARE(siwx91x_wifi); static int siwx91x_nwp_reboot_if_required(const struct device *dev, uint8_t oper_mode) { + const struct siwx91x_config *siwx91x_cfg = dev->config; struct siwx91x_dev *sidev = dev->data; int ret; if (sidev->reboot_needed) { - ret = siwx91x_nwp_mode_switch(oper_mode, sidev->hidden_ssid, sidev->max_num_sta); + ret = siwx91x_nwp_mode_switch(siwx91x_cfg->nwp_dev, oper_mode, sidev->hidden_ssid, + sidev->max_num_sta); if (ret < 0) { LOG_ERR("Failed to reboot the device: %d", ret); return ret; diff --git a/drivers/wifi/siwx91x/siwx91x_wifi_ps.c b/drivers/wifi/siwx91x/siwx91x_wifi_ps.c index 703674a542b51..fd5c422f91f6c 100644 --- a/drivers/wifi/siwx91x/siwx91x_wifi_ps.c +++ b/drivers/wifi/siwx91x/siwx91x_wifi_ps.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ #include -#include +#include #include "siwx91x_wifi.h" #include "siwx91x_wifi_ps.h" diff --git a/drivers/wifi/siwx91x/siwx91x_wifi_scan.c b/drivers/wifi/siwx91x/siwx91x_wifi_scan.c index 263d65142a922..30849e5031341 100644 --- a/drivers/wifi/siwx91x/siwx91x_wifi_scan.c +++ b/drivers/wifi/siwx91x/siwx91x_wifi_scan.c @@ -5,7 +5,7 @@ */ #include -#include +#include #include "siwx91x_wifi.h" #include "siwx91x_wifi_scan.h" diff --git a/drivers/wifi/siwx91x/siwx91x_wifi_sta.c b/drivers/wifi/siwx91x/siwx91x_wifi_sta.c index 1ba53d6cb2563..40cbc0932b5e1 100644 --- a/drivers/wifi/siwx91x/siwx91x_wifi_sta.c +++ b/drivers/wifi/siwx91x/siwx91x_wifi_sta.c @@ -5,7 +5,7 @@ */ #include -#include +#include #include "siwx91x_wifi.h" #include "siwx91x_wifi_socket.h" #include "siwx91x_wifi_ps.h" diff --git a/dts/arm/silabs/siwg917.dtsi b/dts/arm/silabs/siwg917.dtsi index 1ccb7ee235094..1db4c3f8d1619 100644 --- a/dts/arm/silabs/siwg917.dtsi +++ b/dts/arm/silabs/siwg917.dtsi @@ -76,6 +76,11 @@ nwp: nwp { compatible = "silabs,siwx91x-nwp"; power-profile = "high-performance"; + stack-size = <10240>; + interrupt-parent = <&nvic>; + interrupts = <30 0>, <74 0>; + interrupt-names = "nwp_stack", "nwp_irq"; + status = "okay"; bt_hci0: bt_hci { compatible = "silabs,siwx91x-bt-hci"; diff --git a/dts/bindings/net/wireless/silabs,siwx91x-nwp.yaml b/dts/bindings/net/wireless/silabs,siwx91x-nwp.yaml index 381712460e6ce..94cabaf269ef7 100644 --- a/dts/bindings/net/wireless/silabs,siwx91x-nwp.yaml +++ b/dts/bindings/net/wireless/silabs,siwx91x-nwp.yaml @@ -1,7 +1,7 @@ # Copyright (c) 2025 Silicon Laboratories Inc. # SPDX-License-Identifier: Apache-2.0 -title: Silicon Labs SiWx91x NWP (Network Wireless Processor) +title: Silicon Labs SiWx91x NWP (Network Wireless Coprocessor) description: | The Network Wireless Processor (NWP) manages Wi-Fi and Bluetooth connectivity on SiWx91x devices, @@ -10,7 +10,17 @@ description: | compatible: "silabs,siwx91x-nwp" +include: base.yaml + properties: + interrupts: + required: true + + stack-size: + type: int + description: Stack size for the NWP in bytes + required: true + power-profile: type: string description: Power/performance profile diff --git a/modules/hal_silabs/wiseconnect/CMakeLists.txt b/modules/hal_silabs/wiseconnect/CMakeLists.txt index 7849da66df00b..1edfb7e76d410 100644 --- a/modules/hal_silabs/wiseconnect/CMakeLists.txt +++ b/modules/hal_silabs/wiseconnect/CMakeLists.txt @@ -154,7 +154,7 @@ if(CONFIG_BT_SILABS_SIWX91X) ) endif() # CONFIG_BT_SILABS_SIWX91X -if(CONFIG_WISECONNECT_NETWORK_STACK) +if(CONFIG_SILABS_SIWX91X_NWP) zephyr_compile_definitions( SLI_SI91X_ENABLE_OS SL_SI91X_SI917_RAM_MEM_CONFIG=2 @@ -198,7 +198,7 @@ if(CONFIG_WISECONNECT_NETWORK_STACK) ${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/firmware_upgrade/firmware_upgradation.c ) zephyr_include_directories(.) -endif() # CONFIG_WISECONNECT_NETWORK_STACK +endif() # CONFIG_SILABS_SIWX91X_NWP if(CONFIG_SOC_SILABS_SLEEPTIMER) zephyr_include_directories( diff --git a/soc/silabs/silabs_siwx91x/Kconfig b/soc/silabs/silabs_siwx91x/Kconfig index 22c68e45a3d57..7deef76782dc8 100644 --- a/soc/silabs/silabs_siwx91x/Kconfig +++ b/soc/silabs/silabs_siwx91x/Kconfig @@ -20,9 +20,22 @@ config SOC_SILABS_SLEEPTIMER help The Sleeptimer HAL module is used for SIWX91X. +config SILABS_SIWX91X_NWP + bool "Silabs Network Coprocessor" + depends on DT_HAS_SILABS_SIWX91X_NWP_ENABLED + select CMSIS_RTOS_V2 + select POLL + select DYNAMIC_THREAD + select THREAD_NAME + select THREAD_STACK_INFO + select THREAD_MONITOR + select INIT_STACKS + help + Add support for Network Coprocessor (also named NWP) presents on SiWx91x parts. + config SOC_SIWX91X_PM_BACKEND_PMGR bool - select WISECONNECT_NETWORK_STACK + select SILABS_SIWX91X_NWP select SILABS_SLEEPTIMER_TIMER select SRAM_VECTOR_TABLE select CODE_DATA_RELOCATION_SRAM @@ -64,7 +77,7 @@ config SIWX91X_ENCRYPT config SIWX91X_FIRMWARE_UPGRADE bool "Support for firmware upgrade" - select WISECONNECT_NETWORK_STACK + select SILABS_SIWX91X_NWP help The firmware upgrade process for SiWx91x devices involves coordinated communication with both the Network Co-Processor (NCP) and the ROM diff --git a/soc/silabs/silabs_siwx91x/Kconfig.defconfig b/soc/silabs/silabs_siwx91x/Kconfig.defconfig index 5f9e8640dd5ab..b03130795de12 100644 --- a/soc/silabs/silabs_siwx91x/Kconfig.defconfig +++ b/soc/silabs/silabs_siwx91x/Kconfig.defconfig @@ -13,17 +13,7 @@ configdefault SYS_CLOCK_TICKS_PER_SEC configdefault UART_NS16550_DW8250_DW_APB default y -config WISECONNECT_NETWORK_STACK - bool - select CMSIS_RTOS_V2 - select POLL - select DYNAMIC_THREAD - select THREAD_NAME - select THREAD_STACK_INFO - select THREAD_MONITOR - select INIT_STACKS - -if WISECONNECT_NETWORK_STACK +if SILABS_SIWX91X_NWP # WiseConnect create threads with realtime priority. Default (10kHz) clock tick # prevent proper use of the system with these threads. @@ -42,7 +32,7 @@ config CMSIS_V2_THREAD_DYNAMIC_STACK_SIZE config CMSIS_V2_THREAD_MAX_STACK_SIZE default 2048 -endif # WISECONNECT_NETWORK_STACK +endif rsource "*/Kconfig.defconfig" diff --git a/soc/silabs/silabs_siwx91x/siwg917/CMakeLists.txt b/soc/silabs/silabs_siwx91x/siwg917/CMakeLists.txt index cbe06c37ac0ca..fbbb430f05cf6 100644 --- a/soc/silabs/silabs_siwx91x/siwg917/CMakeLists.txt +++ b/soc/silabs/silabs_siwx91x/siwg917/CMakeLists.txt @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_sources_ifdef(CONFIG_SOC_SERIES_SIWG917 soc.c) -zephyr_sources_ifdef(CONFIG_WISECONNECT_NETWORK_STACK nwp.c) +zephyr_sources_ifdef(CONFIG_SILABS_SIWX91X_NWP siwx91x_nwp.c) zephyr_sources_ifdef(CONFIG_SOC_SIWX91X_PM_BACKEND_PMGR soc_siwx91x_power_pmgr.c) set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/silabs/silabs_siwx91x/siwg917/nwp.c b/soc/silabs/silabs_siwx91x/siwg917/siwx91x_nwp.c similarity index 66% rename from soc/silabs/silabs_siwx91x/siwg917/nwp.c rename to soc/silabs/silabs_siwx91x/siwg917/siwx91x_nwp.c index 988c3521bdd78..49ebc89fca0a6 100644 --- a/soc/silabs/silabs_siwx91x/siwg917/nwp.c +++ b/soc/silabs/silabs_siwx91x/siwg917/siwx91x_nwp.c @@ -10,12 +10,14 @@ * SPDX-License-Identifier: Apache-2.0 */ +#define DT_DRV_COMPAT silabs_siwx91x_nwp + #include #include #include #include -#include "nwp.h" +#include "siwx91x_nwp.h" #include "nwp_fw_version.h" #include "sl_wifi_callback_framework.h" @@ -25,8 +27,6 @@ #endif #include "sl_si91x_power_manager.h" -#define NWP_NODE DT_NODELABEL(nwp) -#define SI91X_POWER_PROFILE DT_ENUM_IDX(NWP_NODE, power_profile) #define AP_MAX_NUM_STA 4 LOG_MODULE_REGISTER(siwx91x_nwp); @@ -35,14 +35,16 @@ BUILD_ASSERT(DT_REG_SIZE(DT_CHOSEN(zephyr_sram)) == KB(195) || DT_REG_SIZE(DT_CHOSEN(zephyr_sram)) == KB(255) || DT_REG_SIZE(DT_CHOSEN(zephyr_sram)) == KB(319)); -extern const sli_si91x_set_region_ap_request_t default_US_region_2_4GHZ_configurations; -extern const sli_si91x_set_region_ap_request_t default_EU_region_2_4GHZ_configurations; -extern const sli_si91x_set_region_ap_request_t default_JP_region_2_4GHZ_configurations; -extern const sli_si91x_set_region_ap_request_t default_KR_region_2_4GHZ_configurations; -extern const sli_si91x_set_region_ap_request_t default_SG_region_2_4GHZ_configurations; -extern const sli_si91x_set_region_ap_request_t default_CN_region_2_4GHZ_configurations; +struct siwx91x_nwp_data { + char current_country_code[WIFI_COUNTRY_CODE_LEN]; +}; + +struct siwx91x_nwp_config { + void (*config_irq)(const struct device *dev); + uint32_t stack_size; + uint8_t power_profile; +}; -static char current_country_code[WIFI_COUNTRY_CODE_LEN]; typedef struct { const char *const *codes; size_t num_codes; @@ -50,30 +52,31 @@ typedef struct { const sli_si91x_set_region_ap_request_t *sdk_reg; } region_map_t; +extern const sli_si91x_set_region_ap_request_t default_US_region_2_4GHZ_configurations; +extern const sli_si91x_set_region_ap_request_t default_EU_region_2_4GHZ_configurations; +extern const sli_si91x_set_region_ap_request_t default_JP_region_2_4GHZ_configurations; +extern const sli_si91x_set_region_ap_request_t default_KR_region_2_4GHZ_configurations; +extern const sli_si91x_set_region_ap_request_t default_SG_region_2_4GHZ_configurations; +extern const sli_si91x_set_region_ap_request_t default_CN_region_2_4GHZ_configurations; + static const char *const us_codes[] = { - "AE", "AR", "AS", "BB", "BM", "BR", "BS", "CA", "CO", "CR", "CU", "CX", - "DM", "DO", "EC", "FM", "GD", "GY", "GU", "HN", "HT", "JM", "KY", "LB", - "LK", "MH", "MN", "MP", "MO", "MY", "NI", "PA", "PE", "PG", "PH", "PK", - "PR", "PW", "PY", "SG", "MX", "SV", "TC", "TH", "TT", "US", "UY", "VE", - "VI", "VN", "VU", "00" - /* Map "00" (world domain) to US region, - * as using the world domain is not recommended - */ + "AE", "AR", "AS", "BB", "BM", "BR", "BS", "CA", "CO", "CR", "CU", "CX", "DM", "DO", + "EC", "FM", "GD", "GY", "GU", "HN", "HT", "JM", "KY", "LB", "LK", "MH", "MN", "MP", + "MO", "MY", "NI", "PA", "PE", "PG", "PH", "PK", "PR", "PW", "PY", "SG", "MX", "SV", + "TC", "TH", "TT", "US", "UY", "VE", "VI", "VN", "VU", "00" + /* Map "00" (world domain) to US region as using the world domain is not recommended */ }; static const char *const eu_codes[] = { - "AD", "AF", "AI", "AL", "AM", "AN", "AT", "AW", "AU", "AZ", "BA", "BE", - "BG", "BH", "BL", "BT", "BY", "CH", "CY", "CZ", "DE", "DK", "EE", "ES", - "FR", "GB", "GE", "GF", "GL", "GP", "GR", "GT", "HK", "HR", "HU", "ID", - "IE", "IL", "IN", "IR", "IS", "IT", "JO", "KH", "FI", "KN", "KW", "KZ", - "LC", "LI", "LT", "LU", "LV", "MD", "ME", "MK", "MF", "MT", "MV", "MQ", - "NL", "NO", "NZ", "OM", "PF", "PL", "PM", "PT", "QA", "RO", "RS", "RU", - "SA", "SE", "SI", "SK", "SR", "SY", "TR", "TW", "UA", "UZ", "VC", "WF", - "WS", "YE", "RE", "YT" + "AD", "AF", "AI", "AL", "AM", "AN", "AT", "AW", "AU", "AZ", "BA", "BE", "BG", "BH", "BL", + "BT", "BY", "CH", "CY", "CZ", "DE", "DK", "EE", "ES", "FR", "GB", "GE", "GF", "GL", "GP", + "GR", "GT", "HK", "HR", "HU", "ID", "IE", "IL", "IN", "IR", "IS", "IT", "JO", "KH", "FI", + "KN", "KW", "KZ", "LC", "LI", "LT", "LU", "LV", "MD", "ME", "MK", "MF", "MT", "MV", "MQ", + "NL", "NO", "NZ", "OM", "PF", "PL", "PM", "PT", "QA", "RO", "RS", "RU", "SA", "SE", "SI", + "SK", "SR", "SY", "TR", "TW", "UA", "UZ", "VC", "WF", "WS", "YE", "RE", "YT" }; static const char *const jp_codes[] = {"BD", "BN", "BO", "CL", "BZ", "JP", "NP"}; static const char *const kr_codes[] = {"KR", "KP"}; static const char *const cn_codes[] = {"CN"}; - static const region_map_t region_maps[] = { {us_codes, ARRAY_SIZE(us_codes), SL_WIFI_REGION_US, &default_US_region_2_4GHZ_configurations}, @@ -87,17 +90,20 @@ static const region_map_t region_maps[] = { &default_CN_region_2_4GHZ_configurations}, }; -int siwx91x_store_country_code(const char *country_code) +int siwx91x_store_country_code(const struct device *dev, const char *country_code) { __ASSERT(country_code, "country_code cannot be NULL"); + struct siwx91x_nwp_data *data = dev->data; - memcpy(current_country_code, country_code, WIFI_COUNTRY_CODE_LEN); + memcpy(data->current_country_code, country_code, WIFI_COUNTRY_CODE_LEN); return 0; } -const char *siwx91x_get_country_code(void) +const char *siwx91x_get_country_code(const struct device *dev) { - return current_country_code; + const struct siwx91x_nwp_data *data = dev->data; + + return data->current_country_code; } sl_wifi_region_code_t siwx91x_map_country_code_to_region(const char *country_code) @@ -107,7 +113,7 @@ sl_wifi_region_code_t siwx91x_map_country_code_to_region(const char *country_cod ARRAY_FOR_EACH(region_maps, i) { for (size_t j = 0; j < region_maps[i].num_codes; j++) { if (memcmp(country_code, region_maps[i].codes[j], - WIFI_COUNTRY_CODE_LEN) == 0) { + WIFI_COUNTRY_CODE_LEN) == 0) { return region_maps[i].region_code; } } @@ -166,8 +172,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; + 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_ENHANCED_MAX_PSP)) { boot_config->config_feature_bit_map = SL_SI91X_ENABLE_ENHANCED_MAX_PSP; } @@ -177,26 +184,25 @@ static void siwx91x_configure_sta_mode(sl_si91x_boot_configuration_t *boot_confi boot_config->ext_custom_feature_bit_map |= SL_SI91X_EXT_FEAT_BT_CUSTOM_FEAT_ENABLE; boot_config->bt_feature_bit_map |= SL_SI91X_BT_RF_TYPE | SL_SI91X_ENABLE_BLE_PROTOCOL; boot_config->ble_feature_bit_map |= - SL_SI91X_BLE_MAX_NBR_PERIPHERALS(RSI_BLE_MAX_NBR_PERIPHERALS) | - SL_SI91X_BLE_MAX_NBR_CENTRALS(RSI_BLE_MAX_NBR_CENTRALS) | - SL_SI91X_BLE_MAX_NBR_ATT_SERV(RSI_BLE_MAX_NBR_ATT_SERV) | - SL_SI91X_BLE_MAX_NBR_ATT_REC(RSI_BLE_MAX_NBR_ATT_REC) | - SL_SI91X_BLE_PWR_INX(RSI_BLE_PWR_INX) | - SL_SI91X_BLE_PWR_SAVE_OPTIONS(RSI_BLE_PWR_SAVE_OPTIONS) | - SL_SI91X_916_BLE_COMPATIBLE_FEAT_ENABLE | - SL_SI91X_FEAT_BLE_CUSTOM_FEAT_EXTENSION_VALID; + SL_SI91X_BLE_MAX_NBR_PERIPHERALS(RSI_BLE_MAX_NBR_PERIPHERALS) | + SL_SI91X_BLE_MAX_NBR_CENTRALS(RSI_BLE_MAX_NBR_CENTRALS) | + SL_SI91X_BLE_MAX_NBR_ATT_SERV(RSI_BLE_MAX_NBR_ATT_SERV) | + SL_SI91X_BLE_MAX_NBR_ATT_REC(RSI_BLE_MAX_NBR_ATT_REC) | + SL_SI91X_BLE_PWR_INX(RSI_BLE_PWR_INX) | + SL_SI91X_BLE_PWR_SAVE_OPTIONS(RSI_BLE_PWR_SAVE_OPTIONS) | + SL_SI91X_916_BLE_COMPATIBLE_FEAT_ENABLE | + SL_SI91X_FEAT_BLE_CUSTOM_FEAT_EXTENSION_VALID; boot_config->ble_ext_feature_bit_map |= - SL_SI91X_BLE_NUM_CONN_EVENTS(RSI_BLE_NUM_CONN_EVENTS) | - SL_SI91X_BLE_NUM_REC_BYTES(RSI_BLE_NUM_REC_BYTES) | - SL_SI91X_BLE_ENABLE_ADV_EXTN | - SL_SI91X_BLE_AE_MAX_ADV_SETS(RSI_BLE_AE_MAX_ADV_SETS) | - SL_SI91X_BT_BLE_STACK_BYPASS_ENABLE; + SL_SI91X_BLE_NUM_CONN_EVENTS(RSI_BLE_NUM_CONN_EVENTS) | + SL_SI91X_BLE_NUM_REC_BYTES(RSI_BLE_NUM_REC_BYTES) | SL_SI91X_BLE_ENABLE_ADV_EXTN | + SL_SI91X_BLE_AE_MAX_ADV_SETS(RSI_BLE_AE_MAX_ADV_SETS) | + SL_SI91X_BT_BLE_STACK_BYPASS_ENABLE; #endif } -static void siwx91x_configure_ap_mode(sl_si91x_boot_configuration_t *boot_config, - bool hidden_ssid, uint8_t max_num_sta) +static void siwx91x_configure_ap_mode(sl_si91x_boot_configuration_t *boot_config, bool hidden_ssid, + uint8_t max_num_sta) { boot_config->oper_mode = SL_SI91X_ACCESS_POINT_MODE; boot_config->coex_mode = SL_SI91X_WLAN_ONLY_MODE; @@ -299,8 +305,9 @@ static int siwx91x_check_nwp_version(void) return 0; } -int siwx91x_get_nwp_config(sl_wifi_device_configuration_t *get_config, uint8_t wifi_oper_mode, - bool hidden_ssid, uint8_t max_num_sta) +static int siwx91x_get_nwp_config(const struct device *dev, + sl_wifi_device_configuration_t *get_config, + uint8_t wifi_oper_mode, bool hidden_ssid, uint8_t max_num_sta) { sl_wifi_device_configuration_t default_config = { .region_code = siwx91x_map_country_code_to_region(DEFAULT_COUNTRY_CODE), @@ -335,7 +342,7 @@ int siwx91x_get_nwp_config(sl_wifi_device_configuration_t *get_config, uint8_t w return -EINVAL; } - siwx91x_store_country_code(DEFAULT_COUNTRY_CODE); + siwx91x_store_country_code(dev, DEFAULT_COUNTRY_CODE); siwx91x_apply_sram_config(boot_config); switch (wifi_oper_mode) { @@ -357,12 +364,13 @@ int siwx91x_get_nwp_config(sl_wifi_device_configuration_t *get_config, uint8_t w return 0; } -int siwx91x_nwp_mode_switch(uint8_t oper_mode, bool hidden_ssid, uint8_t max_num_sta) +int siwx91x_nwp_mode_switch(const struct device *dev, uint8_t oper_mode, bool hidden_ssid, + uint8_t max_num_sta) { sl_wifi_device_configuration_t nwp_config; int status; - status = siwx91x_get_nwp_config(&nwp_config, oper_mode, hidden_ssid, max_num_sta); + status = siwx91x_get_nwp_config(dev, &nwp_config, oper_mode, hidden_ssid, max_num_sta); if (status < 0) { return status; } @@ -381,74 +389,96 @@ int siwx91x_nwp_mode_switch(uint8_t oper_mode, bool hidden_ssid, uint8_t max_num return 0; } -static int siwg917_nwp_init(void) +static int siwx91x_nwp_init(const struct device *dev) { - sl_wifi_device_configuration_t network_config; - int status; + const struct siwx91x_nwp_config *config = dev->config; __maybe_unused sl_wifi_performance_profile_t performance_profile = { - .profile = SI91X_POWER_PROFILE}; + .profile = config->power_profile}; __maybe_unused sl_bt_performance_profile_t bt_performance_profile = { - .profile = SI91X_POWER_PROFILE}; + .profile = config->power_profile}; + sl_wifi_device_configuration_t network_config; + int ret; - siwx91x_get_nwp_config(&network_config, WIFI_STA_MODE, false, 0); + siwx91x_get_nwp_config(dev, &network_config, WIFI_STA_MODE, false, 0); /* TODO: If sl_net_*_profile() functions will be needed for WiFi then call * sl_net_set_profile() here. Currently these are unused. + * Despite its name, this function need to be called even if wifi is not used. */ - status = sl_wifi_init(&network_config, NULL, sl_wifi_default_event_handler); - if (status != SL_STATUS_OK) { + ret = sl_wifi_init(&network_config, NULL, sl_wifi_default_event_handler); + if (ret) { return -EINVAL; } /* Check if the NWP firmware version is correct */ - status = siwx91x_check_nwp_version(); - if (status < 0) { + ret = siwx91x_check_nwp_version(); + if (ret < 0) { LOG_ERR("Unexpected NWP firmware version (expected: %s)", - SIWX91X_NWP_FW_EXPECTED_VERSION); + SIWX91X_NWP_FW_EXPECTED_VERSION); } if (IS_ENABLED(CONFIG_SOC_SIWX91X_PM_BACKEND_PMGR)) { if (IS_ENABLED(CONFIG_BT_SILABS_SIWX91X)) { - status = sl_si91x_bt_set_performance_profile(&bt_performance_profile); - if (status != SL_STATUS_OK) { + ret = sl_si91x_bt_set_performance_profile(&bt_performance_profile); + if (ret) { LOG_ERR("Failed to initiate power save in BLE mode"); return -EINVAL; } } /* * Note: the WiFi related sources are always imported (because of - * CONFIG_WISECONNECT_NETWORK_STACK) whatever the value of CONFIG_WIFI. However, + * CONFIG_SILABS_SIWX91X_NWP) whatever the value of CONFIG_WIFI. However, * because of boot_config->coex_mode, sl_wifi_set_performance_profile() is a no-op * if CONFIG_WIFI=n and CONFIG_BT=y. We could probably remove the dependency to the * WiFi sources in this case. However, outside of the code size, this dependency * does not hurt. */ - status = sl_wifi_set_performance_profile(&performance_profile); - if (status != SL_STATUS_OK) { + ret = sl_wifi_set_performance_profile(&performance_profile); + if (ret) { return -EINVAL; } /* Remove the previously added PS4 power state requirement */ sl_si91x_power_manager_remove_ps_requirement(SL_SI91X_POWER_MANAGER_PS4); } + + config->config_irq(dev); + return 0; } + #if defined(CONFIG_MBEDTLS_INIT) BUILD_ASSERT(CONFIG_SIWX91X_NWP_INIT_PRIORITY < CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, "mbed TLS must be initialized after the NWP."); #endif -SYS_INIT(siwg917_nwp_init, POST_KERNEL, CONFIG_SIWX91X_NWP_INIT_PRIORITY); -/* IRQn 74 is used for communication with co-processor */ -Z_ISR_DECLARE(74, 0, IRQ074_Handler, 0); - -/* Co-processor will use value stored in IVT to store its stack. - * - * FIXME: We can't use Z_ISR_DECLARE() to declare this entry - * FIXME: Allow to configure size of buffer - */ -static uint8_t __aligned(8) siwg917_nwp_stack[10 * 1024]; -static Z_DECL_ALIGN(struct _isr_list) Z_GENERIC_SECTION(.intList) - __used __isr_siwg917_coprocessor_stack_irq = { - .irq = 30, - .flags = ISR_FLAG_DIRECT, - .func = &siwg917_nwp_stack[sizeof(siwg917_nwp_stack) - 1], - }; +#define SIWX91X_NWP_DEFINE(inst) \ + \ + static void silabs_siwx91x_nwp_irq_configure_##inst(const struct device *dev) \ + { \ + ARG_UNUSED(dev); \ + IRQ_CONNECT(DT_INST_IRQ_BY_NAME(inst, nwp_irq, irq), \ + DT_INST_IRQ_BY_NAME(inst, nwp_irq, priority), IRQ074_Handler, NULL, 0);\ + irq_enable(DT_INST_IRQ_BY_NAME(inst, nwp_irq, irq)); \ + }; \ + \ + static struct siwx91x_nwp_data siwx91x_nwp_data_##inst = {}; \ + \ + 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) \ + }; \ + \ + /* Coprocessor uses value stored in IVT to store its stack. We can't use Z_ISR_DECLARE() */\ + static uint8_t __aligned(8) siwx91x_nwp_stack_##inst[DT_INST_PROP(inst, stack_size)]; \ + static Z_DECL_ALIGN(struct _isr_list) Z_GENERIC_SECTION(.intList) \ + __used __isr_siwg917_coprocessor_stack_irq_##inst = { \ + .irq = DT_IRQ_BY_NAME(DT_DRV_INST(inst), nwp_stack, irq), \ + .flags = ISR_FLAG_DIRECT, \ + .func = &siwx91x_nwp_stack_##inst[sizeof(siwx91x_nwp_stack_##inst) - 1], \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, &siwx91x_nwp_init, NULL, &siwx91x_nwp_data_##inst, \ + &siwx91x_nwp_config_##inst, POST_KERNEL, \ + CONFIG_SIWX91X_NWP_INIT_PRIORITY, NULL); + +DT_INST_FOREACH_STATUS_OKAY(SIWX91X_NWP_DEFINE) diff --git a/soc/silabs/silabs_siwx91x/siwg917/nwp.h b/soc/silabs/silabs_siwx91x/siwg917/siwx91x_nwp.h similarity index 81% rename from soc/silabs/silabs_siwx91x/siwg917/nwp.h rename to soc/silabs/silabs_siwx91x/siwg917/siwx91x_nwp.h index f67b5f83f5889..f18bd8531185e 100644 --- a/soc/silabs/silabs_siwx91x/siwg917/nwp.h +++ b/soc/silabs/silabs_siwx91x/siwg917/siwx91x_nwp.h @@ -2,13 +2,14 @@ * Copyright (c) 2025 Silicon Laboratories Inc. * SPDX-License-Identifier: Apache-2.0 */ -#ifndef SIWG917_NWP_H -#define SIWG917_NWP_H +#ifndef SIWX91X_NWP_H +#define SIWX91X_NWP_H +#include #include "sl_wifi.h" #define SIWX91X_INTERFACE_MASK (0x03) -#define DEFAULT_COUNTRY_CODE "00" +#define DEFAULT_COUNTRY_CODE "00" /** * @brief Switch the Wi-Fi operating mode. @@ -17,13 +18,15 @@ * operating mode based on the provided features. It performs a soft reboot * of the NWP to apply the new mode along with the updated features. * + * @param[in] dev NWP device. * @param[in] oper_mode Wi-Fi operating mode to switch to. * @param[in] hidden_ssid SSID and its length (used only in WIFI_AP_MODE). * @param[in] max_num_sta Maximum number of supported stations (only for WIFI_AP_MODE). * * @return 0 on success, negative error code on failure. */ -int siwx91x_nwp_mode_switch(uint8_t oper_mode, bool hidden_ssid, uint8_t max_num_sta); +int siwx91x_nwp_mode_switch(const struct device *dev, uint8_t oper_mode, bool hidden_ssid, + uint8_t max_num_sta); /** * @brief Map an ISO/IEC 3166-1 alpha-2 country code to a Wi-Fi region code. @@ -55,9 +58,10 @@ const sli_si91x_set_region_ap_request_t *siwx91x_find_sdk_region_table(uint8_t r * * This function saves the provided country code to a static internal buffer. * + * @param[in] dev NWP device. * @param[in] country_code Pointer to a 2-character ISO country code. */ -int siwx91x_store_country_code(const char *country_code); +int siwx91x_store_country_code(const struct device *dev, const char *country_code); /** * @brief Retrieve the currently stored country code. @@ -65,8 +69,10 @@ int siwx91x_store_country_code(const char *country_code); * This function returns a pointer to the internally stored 2-character * country code set by store_country_code(). * + * @param[in] dev NWP device. + * * @return Pointer to the stored country code string. */ -const char *siwx91x_get_country_code(void); +const char *siwx91x_get_country_code(const struct device *dev); #endif diff --git a/soc/silabs/silabs_siwx91x/siwg917/soc_siwx91x_power_pmgr.c b/soc/silabs/silabs_siwx91x/siwg917/soc_siwx91x_power_pmgr.c index b2cf131067356..c7c10e9026470 100644 --- a/soc/silabs/silabs_siwx91x/siwg917/soc_siwx91x_power_pmgr.c +++ b/soc/silabs/silabs_siwx91x/siwg917/soc_siwx91x_power_pmgr.c @@ -42,7 +42,7 @@ void pm_state_set(enum pm_state state, uint8_t substate_id) LOG_ERR("Failed to configure clocks for sleep mode"); goto out; } - if (IS_ENABLED(CONFIG_WISECONNECT_NETWORK_STACK)) { + if (IS_ENABLED(CONFIG_SILABS_SIWX91X_NWP)) { if (!(M4_ULP_SLP_STATUS_REG & ULP_MODE_SWITCHED_NPSS)) { if (!sl_si91x_is_device_initialized()) { LOG_ERR("Device is not initialized");