diff --git a/drivers/wifi/CMakeLists.txt b/drivers/wifi/CMakeLists.txt index b12ecf88a3e..df1e7c39465 100644 --- a/drivers/wifi/CMakeLists.txt +++ b/drivers/wifi/CMakeLists.txt @@ -8,3 +8,4 @@ add_subdirectory_ifdef(CONFIG_WIFI_ESP32 esp32) add_subdirectory_ifdef(CONFIG_WIFI_ESWIFI eswifi) add_subdirectory_ifdef(CONFIG_WIFI_SIMPLELINK simplelink) add_subdirectory_ifdef(CONFIG_WIFI_WINC1500 winc1500) +add_subdirectory_ifdef(CONFIG_WIFI_AIROC infineon) diff --git a/drivers/wifi/Kconfig b/drivers/wifi/Kconfig index 4bb4197bede..d7133f5be04 100644 --- a/drivers/wifi/Kconfig +++ b/drivers/wifi/Kconfig @@ -40,5 +40,6 @@ source "drivers/wifi/simplelink/Kconfig.simplelink" source "drivers/wifi/eswifi/Kconfig.eswifi" source "drivers/wifi/esp_at/Kconfig.esp_at" source "drivers/wifi/esp32/Kconfig.esp32" +source "drivers/wifi/infineon/Kconfig.airoc" endif # WIFI diff --git a/drivers/wifi/infineon/CMakeLists.txt b/drivers/wifi/infineon/CMakeLists.txt new file mode 100644 index 00000000000..20f69f18111 --- /dev/null +++ b/drivers/wifi/infineon/CMakeLists.txt @@ -0,0 +1,13 @@ +# Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or +# an affiliate of Cypress Semiconductor Corporation +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(./) + +zephyr_library_sources_ifdef(CONFIG_WIFI_AIROC airoc_wifi.c) +zephyr_library_sources_ifdef(CONFIG_WIFI_AIROC airoc_whd_hal.c) + +zephyr_compile_definitions(CYBSP_WIFI_CAPABLE) +zephyr_compile_definitions(CY_RTOS_AWARE) +zephyr_compile_definitions(WHD_USE_CUSTOM_MALLOC_IMPL) +zephyr_compile_definitions(WHD_USE_CUSTOM_HAL_IMPL) diff --git a/drivers/wifi/infineon/Kconfig.airoc b/drivers/wifi/infineon/Kconfig.airoc new file mode 100644 index 00000000000..993fbdad212 --- /dev/null +++ b/drivers/wifi/infineon/Kconfig.airoc @@ -0,0 +1,150 @@ +# Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or +# an affiliate of Cypress Semiconductor Corporation +# SPDX-License-Identifier: Apache-2.0 + +menuconfig WIFI_AIROC + bool "Infineon AIROC SoC Wi-Fi support" + select THREAD_CUSTOM_DATA + select WIFI_OFFLOAD + select NET_L2_WIFI_MGMT + select SDIO_STACK + select SDHC + select WIFI_USE_NATIVE_NETWORKING + select USE_INFINEON_ABSTRACTION_RTOS + depends on DT_HAS_INFINEON_AIROC_WIFI_ENABLED + help + Enable Infineon AIROC SoC Wi-Fi support. + +if WIFI_AIROC + +if SHELL +config SHELL_STACK_SIZE + default 4096 +endif # SHELL + +config SYSTEM_WORKQUEUE_STACK_SIZE + default 4096 + +config AIROC_WIFI_EVENT_TASK_STACK_SIZE + int "Event Task Stack Size" + default 4096 + +config AIROC_WIFI_EVENT_TASK_PRIO + int "Event Task Priority" + default 4 + +config AIROC_WLAN_MFG_FIRMWARE + bool "WLAN Manufacturing Firmware" + help + Enable WLAN Manufacturing Firmware. + +config AIROC_WIFI_CUSTOM + bool "Custom CYW43xx device/module" + help + Select Custom CYW43xx device/module. For this option, + user must to provide path to FW, CLM and NVRAM for + custom or vendor CYW43xx modules. + +choice AIROC_PART + prompt "Select AIROC part" + depends on !AIROC_WIFI_CUSTOM + +config CYW4343W + bool "CYW4343W" + help + Enable Infineon AIROC CYW4343W Wi-Fi connectivity, + More information about CYW4343W device you can find on + https://www.infineon.com/cms/en/product/wireless-connectivity/airoc-wi-fi-plus-bluetooth-combos/cyw4343w/ + +config CYW4373 + bool "CYW4373" + help + Enable Infineon AIROC CYW4373 Wi-Fi connectivity, + More information about CYW4373 device you can find on + https://www.infineon.com/cms/en/product/wireless-connectivity/airoc-wi-fi-plus-bluetooth-combos/cyw4373/ + +config CYW43012 + bool "CYW43012" + help + Enable Infineon AIROC CYW43012 Wi-Fi connectivity, + More information about CYW43012 device you can find on + https://www.infineon.com/cms/en/product/wireless-connectivity/airoc-wi-fi-plus-bluetooth-combos/cyw43012/ + +config CYW43438 + bool "CYW43438" + help + Enable Infineon AIROC CYW43438 Wi-Fi connectivity, + More information about CYW43438 device you can find on + https://www.infineon.com/cms/en/product/wireless-connectivity/airoc-wi-fi-plus-bluetooth-combos/cyw43438/ + +config CYW43439 + bool "CYW43439" + help + Enable Infineon AIROC CYW43439 Wi-Fi connectivity, + More information about CYW43439 device you can find on + https://www.infineon.com/cms/en/product/wireless-connectivity/airoc-wi-fi-plus-bluetooth-combos/cyw43439/ +endchoice + +choice CYW43012_MODULE + prompt "Select CYW43012 module" + depends on CYW43012 && !AIROC_WIFI_CUSTOM + +config CYW43012_MURATA_1LV + bool "MURATA-1LV" + help + Murata Type 1LV module based on Infineon CYW43012 combo chipset + which supports Wi-Fi® 802.11a/b/g/n + Bluetooth® 5.0 BR/EDR/LE + up to 72.2Mbps PHY data rate on Wi-fi® and 3Mbps PHY data rate + on Bluetooth®. 2Mbps LE PHY is also supported. + + Detailed information about Murata Type 1LV module you can find on + https://www.murata.com/en-us/products/connectivitymodule/wi-fi-bluetooth/overview/lineup/type1lv +endchoice + +choice CYW4343W_MODULE + prompt "Select CYW4343W module" + depends on CYW4343W && !AIROC_WIFI_CUSTOM + +config CYW4343W_MURATA_1DX + bool "MURATA-1DX" + help + Murata Type 1DX modules based on Infineon CYW4343W combo chipset + which supports Wi-Fi® 802.11b/g/n + Bluetooth® 5.1 BR/EDR/LE + up to 65Mbps PHY data rate on Wi-fi® and 3Mbps PHY data rate + on Bluetooth®. + + Detailed information about Type 1DX module you can find on + https://www.murata.com/en-us/products/connectivitymodule/wi-fi-bluetooth/overview/lineup/type1dx +endchoice + +choice CYW4373_MODULE + prompt "Select CYW4373 module" + depends on CYW4373 && !AIROC_WIFI_CUSTOM + +config CYW4373_STERLING_LWB5PLUS + bool "STERLING-LWB5plus" + help + Laird Sterling LWB5+ 802.11ac / Bluetooth 5.0 M.2 Carrier Board + (E-Type Key w/ SDIO/UART) + + Detailed information about Type Sterling LWB5+ module you can find on + https://www.lairdconnect.com/wireless-modules/wifi-modules-bluetooth/sterling-lwb5-plus-wifi-5-bluetooth-5-module +endchoice + +choice CYW43439_MODULE + prompt "Select CYW43439 module" + depends on CYW43439 && !AIROC_WIFI_CUSTOM + +config CYW43439_MURATA_1YN + bool "MURATA_1YN" + help + Murata Type 1YN module based on Infineon CYW43439 combo chipset + which supports Wi-Fi® 802.11b/g/n + Bluetooth® 5.2 BR/EDR/LE + up to 65Mbps PHY data rate on Wi-fi® and 3Mbps PHY data rate on + Bluetooth®. + + Detailed information about Murata Type 1YN module you can find on + https://www.murata.com/en-us/products/connectivitymodule/wi-fi-bluetooth/overview/lineup/type1yn +endchoice + +endif # AIROC_WIFI diff --git a/drivers/wifi/infineon/airoc_whd_hal.c b/drivers/wifi/infineon/airoc_whd_hal.c new file mode 100644 index 00000000000..5b02d0bba49 --- /dev/null +++ b/drivers/wifi/infineon/airoc_whd_hal.c @@ -0,0 +1,438 @@ +/* + * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include +#include +#include + +#define DT_DRV_COMPAT infineon_airoc_wifi + +LOG_MODULE_REGISTER(infineon_airoc, CONFIG_WIFI_LOG_LEVEL); + +#ifdef __cplusplus +extern "C" { +#endif + +/** Defines the amount of stack memory available for the wifi thread. */ +#if !defined(CY_WIFI_THREAD_STACK_SIZE) +#define CY_WIFI_THREAD_STACK_SIZE (5120) +#endif + +/** Defines the priority of the thread that services wifi packets. Legal values are defined by the + * RTOS being used. + */ +#if !defined(CY_WIFI_THREAD_PRIORITY) +#define CY_WIFI_THREAD_PRIORITY (CY_RTOS_PRIORITY_HIGH) +#endif + +/** Defines the country this will operate in for wifi initialization parameters. See the + * wifi-host-driver's whd_country_code_t for legal options. + */ +#if !defined(CY_WIFI_COUNTRY) +#define CY_WIFI_COUNTRY (WHD_COUNTRY_AUSTRALIA) +#endif + +/** Defines the priority of the interrupt that handles out-of-band notifications from the wifi + * chip. Legal values are defined by the MCU running this code. + */ +#if !defined(CY_WIFI_OOB_INTR_PRIORITY) +#define CY_WIFI_OOB_INTR_PRIORITY (2) +#endif + +/** Defines whether to use the out-of-band pin to allow the WIFI chip to wake up the MCU. */ +#if defined(CY_WIFI_HOST_WAKE_SW_FORCE) +#define CY_USE_OOB_INTR (CY_WIFI_HOST_WAKE_SW_FORCE) +#else +#define CY_USE_OOB_INTR (1u) +#endif /* defined(CY_WIFI_HOST_WAKE_SW_FORCE) */ + +#define CY_WIFI_HOST_WAKE_IRQ_EVENT GPIO_INT_TRIG_LOW +#define DEFAULT_OOB_PIN (0) +#define WLAN_POWER_UP_DELAY_MS (250) +#define WLAN_CBUCK_DISCHARGE_MS (10) + +extern whd_resource_source_t resource_ops; + +struct whd_bus_priv { + whd_sdio_config_t sdio_config; + whd_bus_stats_t whd_bus_stats; + whd_sdio_t sdio_obj; +}; + +static whd_init_config_t init_config_default = { + .thread_stack_size = CY_WIFI_THREAD_STACK_SIZE, + .thread_stack_start = NULL, + .thread_priority = (uint32_t)CY_WIFI_THREAD_PRIORITY, + .country = CY_WIFI_COUNTRY +}; + +/****************************************************** + * Function + ******************************************************/ + +int airoc_wifi_power_on(const struct device *dev) +{ +#if DT_INST_NODE_HAS_PROP(0, wifi_reg_on_gpios) + int ret; + const struct airoc_wifi_config *config = dev->config; + + /* Check WIFI REG_ON gpio instance */ + if (!device_is_ready(config->wifi_reg_on_gpio.port)) { + LOG_ERR("Error: failed to configure wifi_reg_on %s pin %d", + config->wifi_reg_on_gpio.port->name, config->wifi_reg_on_gpio.pin); + return -EIO; + } + + /* Configure wifi_reg_on as output */ + ret = gpio_pin_configure_dt(&config->wifi_reg_on_gpio, GPIO_OUTPUT); + if (ret) { + LOG_ERR("Error %d: failed to configure wifi_reg_on %s pin %d", ret, + config->wifi_reg_on_gpio.port->name, config->wifi_reg_on_gpio.pin); + return ret; + } + ret = gpio_pin_set_dt(&config->wifi_reg_on_gpio, 0); + if (ret) { + return ret; + } + + /* Allow CBUCK regulator to discharge */ + (void)cyhal_system_delay_ms(WLAN_CBUCK_DISCHARGE_MS); + + /* WIFI power on */ + ret = gpio_pin_set_dt(&config->wifi_reg_on_gpio, 1); + if (ret) { + return ret; + } + (void)cyhal_system_delay_ms(WLAN_POWER_UP_DELAY_MS); +#endif /* DT_INST_NODE_HAS_PROP(0, reg_on_gpios) */ + + return 0; +} + +int airoc_wifi_init_primary(const struct device *dev, whd_interface_t *interface, + whd_netif_funcs_t *netif_funcs, whd_buffer_funcs_t *buffer_if) +{ + int ret; + struct airoc_wifi_data *data = dev->data; + const struct airoc_wifi_config *config = dev->config; + + whd_sdio_config_t whd_sdio_config = { + .sdio_1bit_mode = WHD_FALSE, + .high_speed_sdio_clock = WHD_FALSE, + }; + +#if DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) + whd_oob_config_t oob_config = { + .host_oob_pin = (void *)&config->wifi_host_wake_gpio, + .dev_gpio_sel = DEFAULT_OOB_PIN, + .is_falling_edge = + (CY_WIFI_HOST_WAKE_IRQ_EVENT == GPIO_INT_TRIG_LOW) ? WHD_TRUE : WHD_FALSE, + .intr_priority = CY_WIFI_OOB_INTR_PRIORITY}; + whd_sdio_config.oob_config = oob_config; +#endif + + if (airoc_wifi_power_on(dev)) { + LOG_ERR("airoc_wifi_power_on retuens fail"); + return -ENODEV; + } + + if (!device_is_ready(config->sdhc_dev)) { + LOG_ERR("SDHC device is not ready"); + return -ENODEV; + } + + ret = sd_init(config->sdhc_dev, &data->card); + if (ret) { + return ret; + } + + /* Init SDIO functions */ + ret = sdio_init_func(&data->card, &data->sdio_func1, BACKPLANE_FUNCTION); + if (ret) { + LOG_ERR("sdio_enable_func BACKPLANE_FUNCTION, error: %x", ret); + return ret; + } + ret = sdio_init_func(&data->card, &data->sdio_func2, WLAN_FUNCTION); + if (ret) { + LOG_ERR("sdio_enable_func WLAN_FUNCTION, error: %x", ret); + return ret; + } + ret = sdio_set_block_size(&data->sdio_func1, SDIO_64B_BLOCK); + if (ret) { + LOG_ERR("Can't set block size for BACKPLANE_FUNCTION, error: %x", ret); + return ret; + } + ret = sdio_set_block_size(&data->sdio_func2, SDIO_64B_BLOCK); + if (ret) { + LOG_ERR("Can't set block size for WLAN_FUNCTION, error: %x", ret); + return ret; + } + + /* Init wifi host driver (whd) */ + cy_rslt_t whd_ret = whd_init(&data->whd_drv, &init_config_default, &resource_ops, buffer_if, + netif_funcs); + if (whd_ret == CY_RSLT_SUCCESS) { + whd_ret = whd_bus_sdio_attach(data->whd_drv, &whd_sdio_config, + (whd_sdio_t)&data->card); + + if (whd_ret == CY_RSLT_SUCCESS) { + whd_ret = whd_wifi_on(data->whd_drv, interface); + } + + if (whd_ret != CY_RSLT_SUCCESS) { + whd_deinit(*interface); + return -ENODEV; + } + } + return 0; +} + +/* + * Implement SDIO CMD52/53 wrappers + */ + +static struct sdio_func *airoc_wifi_get_sdio_func(struct sd_card *sd, whd_bus_function_t function) +{ + struct airoc_wifi_data *data = CONTAINER_OF(sd, struct airoc_wifi_data, card); + struct sdio_func *func[] = {&sd->func0, &data->sdio_func1, &data->sdio_func2}; + + if (function > WLAN_FUNCTION) { + return NULL; + } + + return func[function]; +} + +whd_result_t whd_bus_sdio_cmd52(whd_driver_t whd_driver, whd_bus_transfer_direction_t direction, + whd_bus_function_t function, uint32_t address, uint8_t value, + sdio_response_needed_t response_expected, uint8_t *response) +{ + int ret; + struct sd_card *sd = whd_driver->bus_priv->sdio_obj; + struct sdio_func *func = airoc_wifi_get_sdio_func(sd, function); + + WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, cmd52); + + if (direction == BUS_WRITE) { + ret = sdio_rw_byte(func, address, value, response); + } else { + ret = sdio_read_byte(func, address, response); + } + WHD_BUS_STATS_CONDITIONAL_INCREMENT_VARIABLE(whd_driver->bus_priv, (ret != WHD_SUCCESS), + cmd52_fail); + + /* Possibly device might not respond to this cmd. So, don't check return value here */ + if ((ret != WHD_SUCCESS) && (address == SDIO_SLEEP_CSR)) { + return ret; + } + + CHECK_RETURN(ret); + return WHD_SUCCESS; +} + +whd_result_t whd_bus_sdio_cmd53(whd_driver_t whd_driver, whd_bus_transfer_direction_t direction, + whd_bus_function_t function, sdio_transfer_mode_t mode, + uint32_t address, uint16_t data_size, uint8_t *data, + sdio_response_needed_t response_expected, uint32_t *response) +{ + whd_result_t ret; + struct sd_card *sd = whd_driver->bus_priv->sdio_obj; + struct sdio_func *func = airoc_wifi_get_sdio_func(sd, function); + + if (direction == BUS_WRITE) { + WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, cmd53_write); + ret = sdio_write_addr(func, address, data, data_size); + } else { + WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, cmd53_read); + ret = sdio_read_addr(func, address, data, data_size); + } + + WHD_BUS_STATS_CONDITIONAL_INCREMENT_VARIABLE( + whd_driver->bus_priv, ((ret != WHD_SUCCESS) && (direction == BUS_READ)), + cmd53_read_fail); + WHD_BUS_STATS_CONDITIONAL_INCREMENT_VARIABLE( + whd_driver->bus_priv, ((ret != WHD_SUCCESS) && (direction == BUS_WRITE)), + cmd53_write_fail); + + CHECK_RETURN(ret); + return WHD_SUCCESS; +} + +/* + * Implement SDIO Card interrupt + */ + +void whd_bus_sdio_irq_handler(const struct device *dev, int reason, const void *user_data) +{ + if (reason == SDHC_INT_SDIO) { + whd_driver_t whd_driver = (whd_driver_t)user_data; + + WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, sdio_intrs); + + /* call thread notify to wake up WHD thread */ + whd_thread_notify_irq(whd_driver); + } +} + +whd_result_t whd_bus_sdio_irq_register(whd_driver_t whd_driver) +{ + /* Nothing to do here, all handles by whd_bus_sdio_irq_enable function */ + return WHD_SUCCESS; +} + +whd_result_t whd_bus_sdio_irq_enable(whd_driver_t whd_driver, whd_bool_t enable) +{ + int ret; + struct sd_card *sd = whd_driver->bus_priv->sdio_obj; + + /* Enable/disable SDIO Card interrupts */ + if (enable) { + ret = sdhc_enable_interrupt(sd->sdhc, whd_bus_sdio_irq_handler, SDHC_INT_SDIO, + whd_driver); + } else { + ret = sdhc_disable_interrupt(sd->sdhc, SDHC_INT_SDIO); + } + return ret; +} + +/* + * Implement OOB functionality + */ + +void whd_bus_sdio_oob_irq_handler(const struct device *port, struct gpio_callback *cb, + gpio_port_pins_t pins) +{ +#if DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) + struct airoc_wifi_data *data = CONTAINER_OF(cb, struct airoc_wifi_data, host_oob_pin_cb); + + /* Get OOB pin info */ + const whd_oob_config_t *oob_config = &data->whd_drv->bus_priv->sdio_config.oob_config; + const struct gpio_dt_spec *host_oob_pin = oob_config->host_oob_pin; + + /* Check OOB state is correct */ + int expected_event = (oob_config->is_falling_edge == WHD_TRUE) ? 0 : 1; + + if (!(pins & BIT(host_oob_pin->pin)) || (gpio_pin_get_dt(host_oob_pin) != expected_event)) { + WPRINT_WHD_ERROR(("Unexpected interrupt event %d\n", expected_event)); + WHD_BUS_STATS_INCREMENT_VARIABLE(data->whd_drv->bus_priv, error_intrs); + return; + } + + WHD_BUS_STATS_INCREMENT_VARIABLE(data->whd_drv->bus_priv, oob_intrs); + + /* Call thread notify to wake up WHD thread */ + whd_thread_notify_irq(data->whd_drv); + +#endif /* DT_INST_NODE_HAS_PROP(0, wifi-host-wake-gpios) */ +} + +whd_result_t whd_bus_sdio_register_oob_intr(whd_driver_t whd_driver) +{ +#if DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) + int ret; + const struct device *dev = DEVICE_DT_GET(DT_DRV_INST(0)); + struct airoc_wifi_data *data = dev->data; + + /* Get OOB pin info */ + const whd_oob_config_t *oob_config = &whd_driver->bus_priv->sdio_config.oob_config; + const struct gpio_dt_spec *host_oob_pin = oob_config->host_oob_pin; + + /* Check if OOB pin is ready */ + if (!gpio_is_ready_dt(host_oob_pin)) { + WPRINT_WHD_ERROR(("%s: Failed at gpio_is_ready_dt for host_oob_pin\n", __func__)); + return WHD_HAL_ERROR; + } + + /* Configure OOB pin as output */ + ret = gpio_pin_configure_dt(host_oob_pin, GPIO_INPUT); + if (ret != 0) { + WPRINT_WHD_ERROR(( + " %s: Failed at gpio_pin_configure_dt for host_oob_pin, result code = %d\n", + __func__, ret)); + return WHD_HAL_ERROR; + } + + /* Initialize/add OOB pin callback */ + gpio_init_callback(&data->host_oob_pin_cb, whd_bus_sdio_oob_irq_handler, + BIT(host_oob_pin->pin)); + + ret = gpio_add_callback_dt(host_oob_pin, &data->host_oob_pin_cb); + if (ret != 0) { + WPRINT_WHD_ERROR( + ("%s: Failed at gpio_add_callback_dt for host_oob_pin, result code = %d\n", + __func__, ret)); + return WHD_HAL_ERROR; + } +#endif /* DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) */ + + return WHD_SUCCESS; +} + +whd_result_t whd_bus_sdio_unregister_oob_intr(whd_driver_t whd_driver) +{ +#if DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) + int ret; + const whd_oob_config_t *oob_config = &whd_driver->bus_priv->sdio_config.oob_config; + + /* Disable OOB pin interrupts */ + ret = gpio_pin_interrupt_configure_dt(oob_config->host_oob_pin, GPIO_INT_DISABLE); + if (ret != 0) { + WPRINT_WHD_ERROR(("%s: Failed at gpio_pin_interrupt_configure_dt for host_oob_pin, " + "result code = %d\n", + __func__, ret)); + return WHD_HAL_ERROR; + } +#endif /* DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) */ + return WHD_SUCCESS; +} + +whd_result_t whd_bus_sdio_enable_oob_intr(whd_driver_t whd_driver, whd_bool_t enable) +{ +#if DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) + int ret; + const whd_oob_config_t *oob_config = &whd_driver->bus_priv->sdio_config.oob_config; + uint32_t trig_conf = + (oob_config->is_falling_edge == WHD_TRUE) ? GPIO_INT_TRIG_LOW : GPIO_INT_TRIG_HIGH; + + /* Enable OOB pin interrupts */ + ret = gpio_pin_interrupt_configure_dt(oob_config->host_oob_pin, + GPIO_INT_ENABLE | GPIO_INT_EDGE | trig_conf); + if (ret != 0) { + WPRINT_WHD_ERROR(("%s: Failed at gpio_pin_interrupt_configure_dt for host_oob_pin, " + "result code = %d\n", + __func__, ret)); + return WHD_HAL_ERROR; + } +#endif /* DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) */ + return WHD_SUCCESS; +} + +/* + * Implement WHD memory wrappers + */ + +void *whd_mem_malloc(size_t size) +{ + return k_malloc(size); +} + +void *whd_mem_calloc(size_t nitems, size_t size) +{ + return k_calloc(nitems, size); +} + +void whd_mem_free(void *ptr) +{ + k_free(ptr); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif diff --git a/drivers/wifi/infineon/airoc_wifi.c b/drivers/wifi/infineon/airoc_wifi.c new file mode 100644 index 00000000000..c0c780822d8 --- /dev/null +++ b/drivers/wifi/infineon/airoc_wifi.c @@ -0,0 +1,772 @@ +/* + * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @brief AIROC Wi-Fi driver. + */ + +#define DT_DRV_COMPAT infineon_airoc_wifi + +#include +#include + +LOG_MODULE_REGISTER(infineon_airoc_wifi, CONFIG_WIFI_LOG_LEVEL); + +#ifndef AIROC_WIFI_TX_PACKET_POOL_COUNT +#define AIROC_WIFI_TX_PACKET_POOL_COUNT (10) +#endif + +#ifndef AIROC_WIFI_RX_PACKET_POOL_COUNT +#define AIROC_WIFI_RX_PACKET_POOL_COUNT (10) +#endif + +#ifndef AIROC_WIFI_PACKET_POOL_SIZE +#define AIROC_WIFI_PACKET_POOL_SIZE (1600) +#endif + +#define AIROC_WIFI_PACKET_POOL_COUNT \ + (AIROC_WIFI_TX_PACKET_POOL_COUNT + AIROC_WIFI_RX_PACKET_POOL_COUNT) + +#define AIROC_WIFI_WAIT_SEMA_MS (30 * 1000) +#define AIROC_WIFI_SCAN_TIMEOUT_MS (12 * 1000) + +/* AIROC private functions */ +static whd_result_t airoc_wifi_host_buffer_get(whd_buffer_t *buffer, whd_buffer_dir_t direction, + uint16_t size, uint32_t timeout_ms); +static void airoc_wifi_buffer_release(whd_buffer_t buffer, whd_buffer_dir_t direction); +static uint8_t *airoc_wifi_buffer_get_current_piece_data_pointer(whd_buffer_t buffer); +static uint16_t airoc_wifi_buffer_get_current_piece_size(whd_buffer_t buffer); +static whd_result_t airoc_wifi_buffer_set_size(whd_buffer_t buffer, unsigned short size); +static whd_result_t airoc_wifi_buffer_add_remove_at_front(whd_buffer_t *buffer, + int32_t add_remove_amount); +static void airoc_wifi_network_process_ethernet_data(whd_interface_t interface, + whd_buffer_t buffer); +int airoc_wifi_init_primary(const struct device *dev, whd_interface_t *interface, + whd_netif_funcs_t *netif_funcs, whd_buffer_funcs_t *buffer_if); + +/* Allocate network pool */ +NET_BUF_POOL_FIXED_DEFINE(airoc_pool, AIROC_WIFI_PACKET_POOL_COUNT, + AIROC_WIFI_PACKET_POOL_SIZE, 0, NULL); + +/* AIROC globals */ +static uint16_t ap_event_handler_index = 0xFF; + +/* Use global iface pointer to support any Ethernet driver */ +/* necessary for wifi callback functions */ +static struct net_if *airoc_wifi_iface; + +static whd_interface_t airoc_if; +static whd_interface_t airoc_sta_if; +static whd_interface_t airoc_ap_if; + +static const whd_event_num_t sta_link_events[] = { + WLC_E_LINK, WLC_E_DEAUTH_IND, WLC_E_DISASSOC_IND, + WLC_E_PSK_SUP, WLC_E_CSA_COMPLETE_IND, WLC_E_NONE}; + +static const whd_event_num_t ap_link_events[] = {WLC_E_DISASSOC_IND, WLC_E_DEAUTH_IND, + WLC_E_ASSOC_IND, WLC_E_REASSOC_IND, + WLC_E_AUTHORIZED, WLC_E_NONE}; + +static uint16_t sta_event_handler_index = 0xFF; +static void airoc_event_task(void); +static struct airoc_wifi_data airoc_wifi_data = {0}; + +static struct airoc_wifi_config airoc_wifi_config = { + .sdhc_dev = DEVICE_DT_GET(DT_INST_PARENT(0)), + .wifi_reg_on_gpio = GPIO_DT_SPEC_GET_OR(DT_DRV_INST(0), wifi_reg_on_gpios, {0}), + .wifi_host_wake_gpio = GPIO_DT_SPEC_GET_OR(DT_DRV_INST(0), wifi_host_wake_gpios, {0}), + .wifi_dev_wake_gpio = GPIO_DT_SPEC_GET_OR(DT_DRV_INST(0), wifi_dev_wake_gpios, {0}), +}; + +static whd_buffer_funcs_t airoc_wifi_buffer_if_default = { + .whd_host_buffer_get = airoc_wifi_host_buffer_get, + .whd_buffer_release = airoc_wifi_buffer_release, + .whd_buffer_get_current_piece_data_pointer = + airoc_wifi_buffer_get_current_piece_data_pointer, + .whd_buffer_get_current_piece_size = airoc_wifi_buffer_get_current_piece_size, + .whd_buffer_set_size = airoc_wifi_buffer_set_size, + .whd_buffer_add_remove_at_front = airoc_wifi_buffer_add_remove_at_front, +}; + +static whd_netif_funcs_t airoc_wifi_netif_if_default = { + .whd_network_process_ethernet_data = airoc_wifi_network_process_ethernet_data, +}; + +K_MSGQ_DEFINE(airoc_wifi_msgq, sizeof(whd_event_header_t), 10, 4); +K_THREAD_STACK_DEFINE(airoc_wifi_event_stack, CONFIG_AIROC_WIFI_EVENT_TASK_STACK_SIZE); +static struct k_thread airoc_wifi_event_thread; + +struct airoc_wifi_event_t { + uint8_t is_ap_event; + uint32_t event_type; +}; + +/* + * AIROC Wi-Fi helper functions + */ +whd_interface_t airoc_wifi_get_whd_interface(void) +{ + return airoc_if; +} + +static void airoc_wifi_scan_cb_search(whd_scan_result_t **result_ptr, void *user_data, + whd_scan_status_t status) +{ + if (status == WHD_SCAN_ABORTED) { + k_sem_give(&airoc_wifi_data.sema_scan); + return; + } + + if (status == WHD_SCAN_COMPLETED_SUCCESSFULLY) { + k_sem_give(&airoc_wifi_data.sema_scan); + } else if ((status == WHD_SCAN_INCOMPLETE) && (user_data != NULL) && + ((**result_ptr).SSID.length > 0)) { + + if (strncmp(((whd_scan_result_t *)user_data)->SSID.value, (**result_ptr).SSID.value, + (**result_ptr).SSID.length) == 0) { + memcpy(user_data, *result_ptr, sizeof(whd_scan_result_t)); + } + } +} + +static int convert_whd_security_to_zephyr(whd_security_t security) +{ + int zephyr_security = WIFI_SECURITY_TYPE_UNKNOWN; + + switch (security) { + case WHD_SECURITY_OPEN: + zephyr_security = WIFI_SECURITY_TYPE_NONE; + break; + case WHD_SECURITY_WEP_PSK: + zephyr_security = WIFI_SECURITY_TYPE_WEP; + break; + + case WHD_SECURITY_WPA3_WPA2_PSK: + case WHD_SECURITY_WPA2_AES_PSK: + zephyr_security = WIFI_SECURITY_TYPE_PSK; + break; + + case WHD_SECURITY_WPA2_AES_PSK_SHA256: + zephyr_security = WIFI_SECURITY_TYPE_PSK_SHA256; + break; + + case WHD_SECURITY_WPA3_SAE: + zephyr_security = WIFI_SECURITY_TYPE_SAE; + break; + + case WHD_SECURITY_WPA_AES_PSK: + zephyr_security = WIFI_SECURITY_TYPE_WPA_PSK; + break; + + default: + if ((security & ENTERPRISE_ENABLED) != 0) { + zephyr_security = WIFI_SECURITY_TYPE_EAP; + } + break; + } + return zephyr_security; +} + +static void parse_scan_result(whd_scan_result_t *p_whd_result, struct wifi_scan_result *p_zy_result) +{ + if (p_whd_result->SSID.length != 0) { + p_zy_result->ssid_length = p_whd_result->SSID.length; + strncpy(p_zy_result->ssid, p_whd_result->SSID.value, p_whd_result->SSID.length); + p_zy_result->channel = p_whd_result->channel; + p_zy_result->security = convert_whd_security_to_zephyr(p_whd_result->security); + p_zy_result->rssi = (int8_t)p_whd_result->signal_strength; + p_zy_result->mac_length = 6; + memcpy(p_zy_result->mac, &p_whd_result->BSSID, 6); + } +} + +static void scan_callback(whd_scan_result_t **result_ptr, void *user_data, whd_scan_status_t status) +{ + struct airoc_wifi_data *data = user_data; + whd_scan_result_t whd_scan_result; + struct wifi_scan_result zephyr_scan_result; + + if (status == WHD_SCAN_COMPLETED_SUCCESSFULLY || status == WHD_SCAN_ABORTED) { + data->scan_rslt_cb(data->iface, 0, NULL); + data->scan_rslt_cb = NULL; + /* NOTE: It is complete of scan packet, do not need to clean result_ptr, + * WHD will release result_ptr buffer + */ + return; + } + + /* We recived scan data so process it */ + if ((result_ptr != NULL) && (*result_ptr != NULL)) { + memcpy(&whd_scan_result, *result_ptr, sizeof(whd_scan_result_t)); + parse_scan_result(&whd_scan_result, &zephyr_scan_result); + data->scan_rslt_cb(data->iface, 0, &zephyr_scan_result); + } + memset(*result_ptr, 0, sizeof(whd_scan_result_t)); +} + +/* + * Implement WHD network buffers functions + */ +static whd_result_t airoc_wifi_host_buffer_get(whd_buffer_t *buffer, whd_buffer_dir_t direction, + uint16_t size, uint32_t timeout_ms) +{ + ARG_UNUSED(direction); + ARG_UNUSED(timeout_ms); + struct net_buf *buf; + + buf = net_buf_alloc_len(&airoc_pool, size, K_NO_WAIT); + if (buf == NULL) { + return WHD_BUFFER_ALLOC_FAIL; + } + *buffer = buf; + return WHD_SUCCESS; +} + +static void airoc_wifi_buffer_release(whd_buffer_t buffer, whd_buffer_dir_t direction) +{ + CY_UNUSED_PARAMETER(direction); + (void)net_buf_destroy((struct net_buf *)buffer); +} + +static uint8_t *airoc_wifi_buffer_get_current_piece_data_pointer(whd_buffer_t buffer) +{ + CY_ASSERT(buffer != NULL); + struct net_buf *buf = (struct net_buf *)buffer; + + return (uint8_t *)buf->data; +} + +static uint16_t airoc_wifi_buffer_get_current_piece_size(whd_buffer_t buffer) +{ + CY_ASSERT(buffer != NULL); + struct net_buf *buf = (struct net_buf *)buffer; + + return (uint16_t)buf->size; +} + +static whd_result_t airoc_wifi_buffer_set_size(whd_buffer_t buffer, unsigned short size) +{ + CY_ASSERT(buffer != NULL); + struct net_buf *buf = (struct net_buf *)buffer; + + buf->size = size; + return CY_RSLT_SUCCESS; +} + +static whd_result_t airoc_wifi_buffer_add_remove_at_front(whd_buffer_t *buffer, + int32_t add_remove_amount) +{ + CY_ASSERT(buffer != NULL); + struct net_buf **buf = (struct net_buf **)buffer; + + if (add_remove_amount > 0) { + (*buf)->len = (*buf)->size; + (*buf)->data = net_buf_pull(*buf, add_remove_amount); + } else { + (*buf)->data = net_buf_push(*buf, -add_remove_amount); + (*buf)->len = (*buf)->size; + } + return WHD_SUCCESS; +} + +static int airoc_mgmt_send(const struct device *dev, struct net_pkt *pkt) +{ + struct airoc_wifi_data *data = dev->data; + cy_rslt_t ret; + size_t pkt_len = net_pkt_get_len(pkt); + struct net_buf *buf = NULL; + + /* Read the packet payload */ + if (net_pkt_read(pkt, data->frame_buf, pkt_len) < 0) { + LOG_ERR("net_pkt_read failed"); + return -EIO; + } + + /* Allocate Network Buffer from pool with Packet Length + Data Header */ + buf = net_buf_alloc_len(&airoc_pool, pkt_len + sizeof(data_header_t), K_NO_WAIT); + if (buf == NULL) { + return -EIO; + } + + /* Reserve the buffer Headroom for WHD Data header */ + net_buf_reserve(buf, sizeof(data_header_t)); + + /* Copy the buffer to network Buffer pointer */ + (void)memcpy(buf->data, data->frame_buf, pkt_len); + + /* Call WHD API to send out the Packet */ + ret = whd_network_send_ethernet_data(airoc_if, (void *)buf); + if (ret != CY_RSLT_SUCCESS) { + LOG_ERR("whd_network_send_ethernet_data failed"); +#if defined(CONFIG_NET_STATISTICS_WIFI) + data->stats.errors.tx++; +#endif + return -EIO; + } + +#if defined(CONFIG_NET_STATISTICS_WIFI) + data->stats.bytes.sent += pkt_len; + data->stats.pkts.tx++; +#endif + + return 0; +} + +static void airoc_wifi_network_process_ethernet_data(whd_interface_t interface, whd_buffer_t buffer) +{ + struct net_pkt *pkt; + uint8_t *data = whd_buffer_get_current_piece_data_pointer(interface->whd_driver, buffer); + uint32_t len = whd_buffer_get_current_piece_size(interface->whd_driver, buffer); + bool net_pkt_unref_flag = false; + + if ((airoc_wifi_iface != NULL) && net_if_flag_is_set(airoc_wifi_iface, NET_IF_UP)) { + + pkt = net_pkt_rx_alloc_with_buffer(airoc_wifi_iface, len, AF_UNSPEC, 0, K_NO_WAIT); + + if (pkt != NULL) { + if (net_pkt_write(pkt, data, len) < 0) { + LOG_ERR("Failed to write pkt"); + net_pkt_unref_flag = true; + } + + if ((net_pkt_unref_flag) || (net_recv_data(airoc_wifi_iface, pkt) < 0)) { + LOG_ERR("Failed to push received data"); + net_pkt_unref_flag = true; + } + } else { + LOG_ERR("Failed to get net buffer"); + } + } + + /* Release a packet buffer */ + airoc_wifi_buffer_release(buffer, WHD_NETWORK_RX); + +#if defined(CONFIG_NET_STATISTICS_WIFI) + airoc_wifi_data.stats.bytes.received += len; + airoc_wifi_data.stats.pkts.rx++; +#endif + + if (net_pkt_unref_flag) { + net_pkt_unref(pkt); +#if defined(CONFIG_NET_STATISTICS_WIFI) + airoc_wifi_data.stats.errors.rx++; +#endif + } +} + +static void *link_events_handler(whd_interface_t ifp, const whd_event_header_t *event_header, + const uint8_t *event_data, void *handler_user_data) +{ + ARG_UNUSED(ifp); + ARG_UNUSED(event_data); + ARG_UNUSED(handler_user_data); + + k_msgq_put(&airoc_wifi_msgq, event_header, K_FOREVER); + return NULL; +} + +static void airoc_event_task(void) +{ + whd_event_header_t event_header; + + while (1) { + k_msgq_get(&airoc_wifi_msgq, &event_header, K_FOREVER); + + switch ((whd_event_num_t)event_header.event_type) { + case WLC_E_LINK: + break; + + case WLC_E_DEAUTH_IND: + case WLC_E_DISASSOC_IND: + net_if_dormant_on(airoc_wifi_iface); + break; + + default: + break; + } + } +} + +static void airoc_mgmt_init(struct net_if *iface) +{ + const struct device *dev = net_if_get_device(iface); + struct airoc_wifi_data *data = dev->data; + struct ethernet_context *eth_ctx = net_if_l2_data(iface); + + eth_ctx->eth_if_type = L2_ETH_IF_TYPE_WIFI; + data->iface = iface; + airoc_wifi_iface = iface; + + /* Read WLAN MAC Address */ + if (whd_wifi_get_mac_address(airoc_sta_if, &airoc_sta_if->mac_addr) != WHD_SUCCESS) { + LOG_ERR("Failed to get mac address"); + } else { + (void)memcpy(&data->mac_addr, &airoc_sta_if->mac_addr, + sizeof(airoc_sta_if->mac_addr)); + } + + /* Assign link local address. */ + if (net_if_set_link_addr(iface, data->mac_addr, 6, NET_LINK_ETHERNET)) { + LOG_ERR("Failed to set link addr"); + } + + /* Initialize Ethernet L2 stack */ + ethernet_init(iface); + + /* Not currently connected to a network */ + net_if_dormant_on(iface); + + /* L1 network layer (physical layer) is up */ + net_if_carrier_on(data->iface); +} + +static int airoc_mgmt_scan(const struct device *dev, struct wifi_scan_params *params, + scan_result_cb_t cb) +{ + struct airoc_wifi_data *data = dev->data; + + if (data->scan_rslt_cb != NULL) { + LOG_INF("Scan callback in progress"); + return -EINPROGRESS; + } + + if (k_sem_take(&data->sema_common, K_MSEC(AIROC_WIFI_WAIT_SEMA_MS)) != 0) { + return -EAGAIN; + } + + data->scan_rslt_cb = cb; + + /* Connect to the network */ + if (whd_wifi_scan(airoc_sta_if, params->scan_type, WHD_BSS_TYPE_ANY, &(data->ssid), NULL, + NULL, NULL, scan_callback, &(data->scan_result), data) != WHD_SUCCESS) { + LOG_ERR("Failed to start scan"); + k_sem_give(&data->sema_common); + return -EAGAIN; + } + + k_sem_give(&data->sema_common); + return 0; +} + +static int airoc_mgmt_connect(const struct device *dev, struct wifi_connect_req_params *params) +{ + struct airoc_wifi_data *data = (struct airoc_wifi_data *)dev->data; + whd_ssid_t ssid = {0}; + int ret = 0; + + if (k_sem_take(&data->sema_common, K_MSEC(AIROC_WIFI_WAIT_SEMA_MS)) != 0) { + return -EAGAIN; + } + + if (data->is_sta_connected) { + LOG_ERR("Already connected"); + ret = -EALREADY; + goto error; + } + + if (data->is_ap_up) { + LOG_ERR("Network interface is busy AP. Please first disable AP."); + ret = -EBUSY; + goto error; + } + + ssid.length = params->ssid_length; + memcpy(ssid.value, params->ssid, params->ssid_length); + + whd_scan_result_t scan_result; + whd_scan_result_t usr_result = {0}; + + usr_result.SSID.length = ssid.length; + memcpy(usr_result.SSID.value, ssid.value, ssid.length); + + if (whd_wifi_scan(airoc_sta_if, WHD_SCAN_TYPE_ACTIVE, WHD_BSS_TYPE_ANY, NULL, NULL, NULL, + NULL, airoc_wifi_scan_cb_search, &scan_result, + &(usr_result)) != WHD_SUCCESS) { + LOG_ERR("Failed start scan"); + ret = -EAGAIN; + goto error; + } + + if (k_sem_take(&airoc_wifi_data.sema_scan, K_MSEC(AIROC_WIFI_SCAN_TIMEOUT_MS)) != 0) { + whd_wifi_stop_scan(airoc_sta_if); + ret = -EAGAIN; + goto error; + } + + if (usr_result.security == 0) { + ret = -EAGAIN; + LOG_ERR("Could not scan device"); + goto error; + } + + /* Connect to the network */ + if (whd_wifi_join(airoc_sta_if, &usr_result.SSID, usr_result.security, params->psk, + params->psk_length) != WHD_SUCCESS) { + LOG_ERR("Failed to connect with network"); + + ret = -EAGAIN; + goto error; + } + +error: + if (ret < 0) { + net_if_dormant_on(data->iface); + } else { + net_if_dormant_off(data->iface); + data->is_sta_connected = true; +#if defined(CONFIG_NET_DHCPV4) + net_dhcpv4_restart(data->iface); +#endif /* defined(CONFIG_NET_DHCPV4) */ + } + + wifi_mgmt_raise_connect_result_event(data->iface, ret); + k_sem_give(&data->sema_common); + return ret; +} + +static int airoc_mgmt_disconnect(const struct device *dev) +{ + int ret = 0; + struct airoc_wifi_data *data = (struct airoc_wifi_data *)dev->data; + + if (k_sem_take(&data->sema_common, K_MSEC(AIROC_WIFI_WAIT_SEMA_MS)) != 0) { + return -EAGAIN; + } + + if (whd_wifi_leave(airoc_sta_if) != WHD_SUCCESS) { + k_sem_give(&data->sema_common); + ret = -EAGAIN; + } else { + data->is_sta_connected = false; + net_if_dormant_on(data->iface); + } + + wifi_mgmt_raise_disconnect_result_event(data->iface, ret); + k_sem_give(&data->sema_common); + + return ret; +} + +static void *airoc_wifi_ap_link_events_handler(whd_interface_t ifp, + const whd_event_header_t *event_header, + const uint8_t *event_data, void *handler_user_data) +{ + struct airoc_wifi_event_t airoc_event = { + .is_ap_event = 1, + .event_type = event_header->event_type + }; + + k_msgq_put(&airoc_wifi_msgq, &airoc_event, K_FOREVER); + + return NULL; +} + +static int airoc_mgmt_ap_enable(const struct device *dev, struct wifi_connect_req_params *params) +{ + struct airoc_wifi_data *data = dev->data; + whd_security_t security; + whd_ssid_t ssid; + uint8_t channel; + int ret = 0; + + if (k_sem_take(&data->sema_common, K_MSEC(AIROC_WIFI_WAIT_SEMA_MS)) != 0) { + return -EAGAIN; + } + + if (data->is_sta_connected) { + LOG_ERR("Network interface is busy in STA mode. Please first disconnect STA."); + ret = -EBUSY; + goto error; + } + + if (data->is_ap_up) { + LOG_ERR("Already AP is on - first disable"); + ret = -EAGAIN; + goto error; + } + + if (!data->second_interface_init) { + if (whd_add_secondary_interface(data->whd_drv, NULL, &airoc_ap_if) != + CY_RSLT_SUCCESS) { + LOG_ERR("Error Unable to bring up the whd secondary interface"); + ret = -EAGAIN; + goto error; + } + data->second_interface_init = true; + } + + ssid.length = params->ssid_length; + memcpy(ssid.value, params->ssid, ssid.length); + + /* make sure to set valid channels for 2G and 5G: + * - 2G channels from 1 to 11, + * - 5G channels from 36 to 165 + */ + if (((params->channel > 0) && (params->channel < 12)) || + ((params->channel > 35) && (params->channel < 166))) { + channel = params->channel; + } else { + channel = 1; + LOG_WRN("Discard of setting unsupported channel: %u (will set 1)", + params->channel); + } + + if (params->psk_length == 0) { + security = WHD_SECURITY_OPEN; + } else { + security = WHD_SECURITY_WPA2_AES_PSK; + } + + if (whd_wifi_init_ap(airoc_ap_if, &ssid, security, (const uint8_t *)params->psk, + params->psk_length, channel) != 0) { + LOG_ERR("Failed to init whd ap interface"); + ret = -EAGAIN; + goto error; + } + + if (whd_wifi_start_ap(airoc_ap_if) != 0) { + LOG_ERR("Failed to start whd ap interface"); + ret = -EAGAIN; + goto error; + } + + /* set event handler */ + if (whd_management_set_event_handler(airoc_ap_if, ap_link_events, + airoc_wifi_ap_link_events_handler, NULL, + &ap_event_handler_index) != 0) { + whd_wifi_stop_ap(airoc_ap_if); + ret = -EAGAIN; + goto error; + } + + data->is_ap_up = true; + airoc_if = airoc_ap_if; +error: + + k_sem_give(&data->sema_common); + return ret; +} + +#if defined(CONFIG_NET_STATISTICS_WIFI) +static int airoc_mgmt_wifi_stats(const struct device *dev, struct net_stats_wifi *stats) +{ + struct airoc_wifi_data *data = dev->data; + + stats->bytes.received = data->stats.bytes.received; + stats->bytes.sent = data->stats.bytes.sent; + stats->pkts.rx = data->stats.pkts.rx; + stats->pkts.tx = data->stats.pkts.tx; + stats->errors.rx = data->stats.errors.rx; + stats->errors.tx = data->stats.errors.tx; + stats->broadcast.rx = data->stats.broadcast.rx; + stats->broadcast.tx = data->stats.broadcast.tx; + stats->multicast.rx = data->stats.multicast.rx; + stats->multicast.tx = data->stats.multicast.tx; + stats->sta_mgmt.beacons_rx = data->stats.sta_mgmt.beacons_rx; + stats->sta_mgmt.beacons_miss = data->stats.sta_mgmt.beacons_miss; + + return 0; +} +#endif + +static int airoc_mgmt_ap_disable(const struct device *dev) +{ + cy_rslt_t whd_ret; + struct airoc_wifi_data *data = dev->data; + + if (k_sem_take(&data->sema_common, K_MSEC(AIROC_WIFI_WAIT_SEMA_MS)) != 0) { + return -EAGAIN; + } + + if (whd_wifi_deregister_event_handler(airoc_ap_if, ap_event_handler_index)) { + LOG_ERR("Can't whd_wifi_deregister_event_handler"); + } + + whd_ret = whd_wifi_stop_ap(airoc_ap_if); + if (whd_ret == CY_RSLT_SUCCESS) { + data->is_ap_up = false; + airoc_if = airoc_sta_if; + } else { + LOG_ERR("Can't stop wifi ap: %u", whd_ret); + } + + k_sem_give(&data->sema_common); + + if (whd_ret != CY_RSLT_SUCCESS) { + return -ENODEV; + } + + return 0; +} + +static int airoc_init(const struct device *dev) +{ + int ret; + cy_rslt_t whd_ret; + struct airoc_wifi_data *data = dev->data; + + k_tid_t tid = k_thread_create( + &airoc_wifi_event_thread, airoc_wifi_event_stack, + CONFIG_AIROC_WIFI_EVENT_TASK_STACK_SIZE, (k_thread_entry_t)airoc_event_task, NULL, + NULL, NULL, CONFIG_AIROC_WIFI_EVENT_TASK_PRIO, K_INHERIT_PERMS, K_NO_WAIT); + + if (!tid) { + LOG_ERR("ERROR spawning tx thread"); + return -EAGAIN; + } + k_thread_name_set(tid, "airoc_event"); + + whd_ret = airoc_wifi_init_primary(dev, &airoc_sta_if, &airoc_wifi_netif_if_default, + &airoc_wifi_buffer_if_default); + if (whd_ret != CY_RSLT_SUCCESS) { + LOG_ERR("airoc_wifi_init_primary failed ret = %d \r\n", whd_ret); + return -EAGAIN; + } + airoc_if = airoc_sta_if; + + whd_ret = whd_management_set_event_handler(airoc_sta_if, sta_link_events, + link_events_handler, NULL, &sta_event_handler_index); + if (whd_ret != CY_RSLT_SUCCESS) { + LOG_ERR("whd_management_set_event_handler failed ret = %d \r\n", whd_ret); + return -EAGAIN; + } + + ret = k_sem_init(&data->sema_common, 1, 1); + if (ret != 0) { + LOG_ERR("k_sem_init(sema_common) failure"); + return ret; + } + + ret = k_sem_init(&data->sema_scan, 0, 1); + if (ret != 0) { + LOG_ERR("k_sem_init(sema_scan) failure"); + return ret; + } + + return 0; +} + +static const struct wifi_mgmt_ops airoc_wifi_mgmt = { + .scan = airoc_mgmt_scan, + .connect = airoc_mgmt_connect, + .disconnect = airoc_mgmt_disconnect, + .ap_enable = airoc_mgmt_ap_enable, + .ap_disable = airoc_mgmt_ap_disable, +#if defined(CONFIG_NET_STATISTICS_ETHERNET) + .get_stats = airoc_mgmt_wifi_stats, +#endif +}; + +static const struct net_wifi_mgmt_offload airoc_api = { + .wifi_iface.iface_api.init = airoc_mgmt_init, + .wifi_iface.send = airoc_mgmt_send, + .wifi_mgmt_api = &airoc_wifi_mgmt, +}; + +NET_DEVICE_DT_INST_DEFINE(0, airoc_init, NULL, &airoc_wifi_data, &airoc_wifi_config, + CONFIG_WIFI_INIT_PRIORITY, &airoc_api, ETHERNET_L2, + NET_L2_GET_CTX_TYPE(ETHERNET_L2), WHD_LINK_MTU); diff --git a/drivers/wifi/infineon/airoc_wifi.h b/drivers/wifi/infineon/airoc_wifi.h new file mode 100644 index 00000000000..648423ab109 --- /dev/null +++ b/drivers/wifi/infineon/airoc_wifi.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +struct airoc_wifi_data { + struct sd_card card; + struct sdio_func sdio_func1; + struct sdio_func sdio_func2; + struct net_if *iface; + bool second_interface_init; + bool is_ap_up; + bool is_sta_connected; + uint8_t mac_addr[6]; + scan_result_cb_t scan_rslt_cb; + whd_ssid_t ssid; + whd_scan_result_t scan_result; + struct k_sem sema_common; + struct k_sem sema_scan; +#if defined(CONFIG_NET_STATISTICS_WIFI) + struct net_stats_wifi stats; +#endif + whd_driver_t whd_drv; + struct gpio_callback host_oob_pin_cb; + uint8_t frame_buf[NET_ETH_MAX_FRAME_SIZE]; +}; + +struct airoc_wifi_config { + const struct device *sdhc_dev; + struct gpio_dt_spec wifi_reg_on_gpio; + struct gpio_dt_spec wifi_host_wake_gpio; + struct gpio_dt_spec wifi_dev_wake_gpio; +}; + +/** + * \brief This function returns pointer type to handle instance + * of whd interface (whd_interface_t) which allocated in + * Zephyr AIROC driver (drivers/wifi/infineon/airoc_wifi.c) + */ + +whd_interface_t airoc_wifi_get_whd_interface(void); diff --git a/drivers/wifi/infineon/cybsp.h b/drivers/wifi/infineon/cybsp.h new file mode 100644 index 00000000000..dfa23ffbae5 --- /dev/null +++ b/drivers/wifi/infineon/cybsp.h @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* This is enpty/stub file used in WHD */ diff --git a/dts/bindings/wifi/infineon,airoc-wifi.yaml b/dts/bindings/wifi/infineon,airoc-wifi.yaml new file mode 100644 index 00000000000..9c93b238a4e --- /dev/null +++ b/dts/bindings/wifi/infineon,airoc-wifi.yaml @@ -0,0 +1,50 @@ +# Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or +# an affiliate of Cypress Semiconductor Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +description: | + AIROC Wi-Fi Connectivity. + + Example of enabling AIROC Wi-Fi device (for SDIO): + &sdhc0 { + status = "okay"; + + /* SDIO pins */ + pinctrl-0 = <&p2_4_sdio_cmd &p2_5_sdio_clk &p2_0_sdio_data0 + &p2_1_sdio_data1 &p2_2_sdio_data2 &p2_3_sdio_data3>; + pinctrl-names = "default"; + + /* Wifi configuration */ + airoc-wifi { + status = "okay"; + compatible = "infineon,airoc-wifi-sdio"; + + /* Wi-Fi control gpios */ + wifi-reg-on-gpios = <&gpio_prt2 6 GPIO_ACTIVE_HIGH>; + wifi-host-wake-gpios = <&gpio_prt0 4 GPIO_ACTIVE_HIGH>; + }; + }; + +compatible: "infineon,airoc-wifi" + +include: [base.yaml, pinctrl-device.yaml] + +properties: + wifi-reg-on-gpios: + description: | + Power-up/down gpio to control the internal regulators used + by the WiFi section of AIROC Wi-Fi device. + type: phandle-array + + wifi-host-wake-gpios: + description: | + Host wake-up gpio. Signal from the AIROC Wi-Fi device + to the host indicating that the device requires attention. + type: phandle-array + + wifi-dev-wake-gpios: + description: | + WiFi device wake-up gpio. Signal from the host to the + AIROC Wi-Fi device indicating that the host requires attention. + type: phandle-array diff --git a/modules/hal_infineon/CMakeLists.txt b/modules/hal_infineon/CMakeLists.txt index 1db3cf57a6a..27dbd71897f 100644 --- a/modules/hal_infineon/CMakeLists.txt +++ b/modules/hal_infineon/CMakeLists.txt @@ -36,6 +36,11 @@ if (CONFIG_SOC_FAMILY_INFINEON_CAT1A) add_subdirectory(abstraction-rtos) endif() +## Add Wi-Fi assets for AIROC devices +if (CONFIG_WIFI_AIROC) + add_subdirectory(wifi-host-driver) +endif() + ## Add BT assets for AIROC devices if (CONFIG_BT_AIROC) add_subdirectory(btstack-integration) diff --git a/modules/hal_infineon/Kconfig b/modules/hal_infineon/Kconfig index 83d24bfacd5..af92b98b3dc 100644 --- a/modules/hal_infineon/Kconfig +++ b/modules/hal_infineon/Kconfig @@ -72,7 +72,7 @@ config USE_INFINEON_WDT Enable WATCHDOG TIMER (WDT) HAL module driver for Infineon devices -config ABSTRACTION_RTOS_COMPONENT_ZEPHYR +config USE_INFINEON_ABSTRACTION_RTOS bool "Abstraction RTOS component (Zephyr support)" help Enable Abstraction RTOS component with Zephyr support diff --git a/modules/hal_infineon/abstraction-rtos/CMakeLists.txt b/modules/hal_infineon/abstraction-rtos/CMakeLists.txt index cd61908659f..6b2b0e6449f 100644 --- a/modules/hal_infineon/abstraction-rtos/CMakeLists.txt +++ b/modules/hal_infineon/abstraction-rtos/CMakeLists.txt @@ -5,7 +5,7 @@ zephyr_include_directories(${ZEPHYR_HAL_INFINEON_MODULE_DIR}/abstraction-rtos/include) # Enable Zephyr support -zephyr_include_directories_ifdef(CONFIG_ABSTRACTION_RTOS_COMPONENT_ZEPHYR +zephyr_include_directories_ifdef(CONFIG_USE_INFINEON_ABSTRACTION_RTOS include/COMPONENT_ZEPHYR) -zephyr_library_sources_ifdef(CONFIG_ABSTRACTION_RTOS_COMPONENT_ZEPHYR +zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_ABSTRACTION_RTOS source/COMPONENT_ZEPHYR/cyabs_rtos_zephyr.c) diff --git a/modules/hal_infineon/wifi-host-driver/CMakeLists.txt b/modules/hal_infineon/wifi-host-driver/CMakeLists.txt new file mode 100644 index 00000000000..afdb147676d --- /dev/null +++ b/modules/hal_infineon/wifi-host-driver/CMakeLists.txt @@ -0,0 +1,216 @@ +# Copyright (c) 2023 Cypress Semiconductor Corporation. +# +# SPDX-License-Identifier: Apache-2.0 + +set(hal_dir ${ZEPHYR_HAL_INFINEON_MODULE_DIR}) +set(hal_wifi_dir ${hal_dir}/wifi-host-driver) +set(hal_wifi_dir_resources ${hal_dir}/wifi-host-driver/WiFi_Host_Driver/resources) + +set(hal_blobs_dir ${hal_dir}/zephyr/blobs/img/whd/resources) +set(blob_gen_dir ${ZEPHYR_BINARY_DIR}/include/generated) + +set(cyw43xx_fw_bin_gen_inc ${blob_gen_dir}/cyw43xx_fw_blob.inc) +set(cyw43xx_clm_bin_gen_inc ${blob_gen_dir}/cyw43xx_clm_blob.inc) + +######################################################################################### +# Wi-Fi Host driver +######################################################################################### +if(CONFIG_AIROC_WLAN_MFG_FIRMWARE) + zephyr_compile_definitions(WLAN_MFG_FIRMWARE) +endif() + +# Add WHD includes +zephyr_include_directories(${hal_wifi_dir}) +zephyr_include_directories(${hal_wifi_dir}/WiFi_Host_Driver/inc) +zephyr_include_directories(${hal_wifi_dir}/WiFi_Host_Driver/src) +zephyr_include_directories(${hal_wifi_dir}/WiFi_Host_Driver/src/include) +zephyr_include_directories(${hal_wifi_dir}/WiFi_Host_Driver/resources/resource_imp) + +# src +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_ap.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_buffer_api.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_cdc_bdc.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_chip.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_chip_constants.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_clm.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_debug.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_events.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_logging.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_management.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_network_if.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_resource_if.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_sdpcm.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_thread.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_utils.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_wifi.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_wifi_api.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_wifi_p2p.c) + +# src/bus_protocols +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/bus_protocols/whd_bus.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/bus_protocols/whd_bus_common.c) +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/bus_protocols/whd_bus_sdio_protocol.c) + +# resources/resource_imp +zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/resources/resource_imp/whd_resources.c) + +# CYW43012 firmware +if(CONFIG_CYW43012 AND NOT CONFIG_AIROC_WIFI_CUSTOM) + zephyr_include_directories(${hal_wifi_dir}/WiFi_Host_Driver/resources/firmware/COMPONENT_43012) + + # firmware + if(CONFIG_AIROC_WLAN_MFG_FIRMWARE) + set(cyw43xx_fw_bin ${hal_blobs_dir}/firmware/COMPONENT_43012/43012C0-mfgtest.bin) + zephyr_library_sources(${hal_wifi_dir_resources}/firmware/COMPONENT_43012/43012C0-mfgtest_bin.c) + else() + set(cyw43xx_fw_bin ${hal_blobs_dir}/firmware/COMPONENT_43012/43012C0.bin) + zephyr_library_sources(${hal_wifi_dir_resources}/firmware/COMPONENT_43012/43012C0_bin.c) + endif() +endif() + +# CYW4343W firmware +if(CONFIG_CYW4343W AND NOT CONFIG_AIROC_WIFI_CUSTOM) + zephyr_include_directories(${hal_wifi_dir_resources}/firmware/COMPONENT_4343W) + + # firmware + if(CONFIG_AIROC_WLAN_MFG_FIRMWARE) + set(cyw43xx_fw_bin ${hal_blobs_dir}/firmware/COMPONENT_4343W/4343WA1-mfgtest.bin) + zephyr_library_sources(${hal_wifi_dir_resources}/firmware/COMPONENT_4343W/4343WA1-mfgtest_bin.c) + else() + set(cyw43xx_fw_bin ${hal_blobs_dir}/firmware/COMPONENT_4343W/4343WA1.bin) + zephyr_library_sources(${hal_wifi_dir_resources}/firmware/COMPONENT_4343W/4343WA1_bin.c) + endif() +endif() + +# CYW43438 firmware/clm +if(CONFIG_CYW43438 AND NOT CONFIG_AIROC_WIFI_CUSTOM) + zephyr_include_directories(${hal_wifi_dir_resources}/firmware/COMPONENT_43438) + zephyr_include_directories(${hal_wifi_dir_resources}/clm/COMPONENT_43438) + + # firmware/clm + if(CONFIG_AIROC_WLAN_MFG_FIRMWARE) + set(cyw43xx_fw_bin ${hal_blobs_dir}/firmware/COMPONENT_43438/43438A1-mfgtest.bin) + set(cyw43xx_clm_bin ${hal_blobs_dir}/clm/COMPONENT_43438/43438A1-mfgtest.clm_blob) + + zephyr_library_sources(${hal_wifi_dir_resources}/firmware/COMPONENT_43438/43438A1-mfgtest_bin.c) + zephyr_library_sources(${hal_wifi_dir_resources}/clm/COMPONENT_43438/43438A1-mfgtest_clm_blob.c) + else() + set(cyw43xx_fw_bin ${hal_blobs_dir}/firmware/COMPONENT_43438/43438A1.bin) + set(cyw43xx_clm_bin ${hal_blobs_dir}/clm/COMPONENT_43438/43438A1.clm_blob) + + zephyr_library_sources(${hal_wifi_dir_resources}/firmware/COMPONENT_43438/43438A1_bin.c) + zephyr_library_sources(${hal_wifi_dir_resources}/clm/COMPONENT_43438/43438A1_clm_blob.c) + endif() + +endif() + +# CYW43439 firmware +if(CONFIG_CYW43439 AND NOT CONFIG_AIROC_WIFI_CUSTOM) + zephyr_include_directories(${hal_wifi_dir_resources}/firmware/COMPONENT_43439) + + # firmware + if(CONFIG_AIROC_WLAN_MFG_FIRMWARE) + set(cyw43xx_fw_bin ${hal_blobs_dir}/firmware/COMPONENT_43439/43439A0-mfgtest.bin) + zephyr_library_sources(${hal_wifi_dir_resources}/firmware/COMPONENT_43439/43439A0-mfgtest_bin.c) + else() + set(cyw43xx_fw_bin ${hal_blobs_dir}/firmware/COMPONENT_43439/43439A0.bin) + zephyr_library_sources(${hal_wifi_dir_resources}/firmware/COMPONENT_43439/43439A0_bin.c) + endif() +endif() + +# CYW4373 firmware +if(CONFIG_CYW4373 AND NOT CONFIG_AIROC_WIFI_CUSTOM) + zephyr_include_directories(${hal_wifi_dir_resources}/firmware/COMPONENT_4373) + + # firmware + if(CONFIG_AIROC_WLAN_MFG_FIRMWARE) + set(cyw43xx_fw_bin ${hal_blobs_dir}/firmware/COMPONENT_4373/4373A0-mfgtest.bin) + zephyr_library_sources(${hal_wifi_dir_resources}/firmware/COMPONENT_4373/4373A0-mfgtest_bin.c) + else() + set(cyw43xx_fw_bin ${hal_blobs_dir}/firmware/COMPONENT_4373/4373A0.bin) + zephyr_library_sources(${hal_wifi_dir_resources}/firmware/COMPONENT_4373/4373A0_bin.c) + endif() +endif() + + +# CYW43012_MURATA_1LV clm/nvram +if(CONFIG_CYW43012_MURATA_1LV AND NOT CONFIG_AIROC_WIFI_CUSTOM) + zephyr_include_directories(${hal_wifi_dir}/WiFi_Host_Driver/resources/clm/COMPONENT_43012) + + # clm + if(CONFIG_AIROC_WLAN_MFG_FIRMWARE) + set(cyw43xx_clm_bin ${hal_blobs_dir}/clm/COMPONENT_43012/43012C0-mfgtest.clm_blob) + + zephyr_library_sources(${hal_wifi_dir_resources}/clm/COMPONENT_43012/43012C0-mfgtest_clm_blob.c) + else() + set(cyw43xx_clm_bin ${hal_blobs_dir}/clm/COMPONENT_43012/43012C0.clm_blob) + + zephyr_library_sources(${hal_wifi_dir_resources}/clm/COMPONENT_43012/43012C0_clm_blob.c) + endif() + + # nvram + zephyr_include_directories(${hal_wifi_dir_resources}/nvram/COMPONENT_43012/COMPONENT_MURATA-1LV) +endif() + +# CYW4343W_MURATA_1DX clm/nvram +if(CONFIG_CYW4343W_MURATA_1DX AND NOT CONFIG_AIROC_WIFI_CUSTOM) + zephyr_include_directories(${hal_wifi_dir_resources}/clm/COMPONENT_4343W) + + # clm + if(CONFIG_AIROC_WLAN_MFG_FIRMWARE) + set(cyw43xx_clm_bin ${hal_blobs_dir}/clm/COMPONENT_4343W/4343WA1-mfgtest.clm_blob) + zephyr_library_sources(${hal_wifi_dir_resources}/clm/COMPONENT_4343W/4343WA1-mfgtest_clm_blob.c) + else() + set(cyw43xx_clm_bin ${hal_blobs_dir}/clm/COMPONENT_4343W/4343WA1.clm_blob) + zephyr_library_sources(${hal_wifi_dir_resources}/clm/COMPONENT_4343W/4343WA1_clm_blob.c) + endif() + + # nvram + zephyr_include_directories(${hal_wifi_dir_resources}/nvram/COMPONENT_4343W/COMPONENT_MURATA-1DX) +endif() + +# CYW43439_MURATA_1YN +if(CONFIG_CYW43439_MURATA_1YN AND NOT CONFIG_AIROC_WIFI_CUSTOM) + zephyr_include_directories(${hal_wifi_dir_resources}/clm/COMPONENT_43439) + + # clm + if(CONFIG_AIROC_WLAN_MFG_FIRMWARE) + set(cyw43xx_clm_bin ${hal_blobs_dir}/clm/COMPONENT_43439/43439A0-mfgtest.clm_blob) + zephyr_library_sources(${hal_wifi_dir_resources}/clm/COMPONENT_43439/43439A0-mfgtest_clm_blob.c) + else() + set(cyw43xx_clm_bin ${hal_blobs_dir}/clm/COMPONENT_43439/43439A0.clm_blob) + zephyr_library_sources(${hal_wifi_dir_resources}/clm/COMPONENT_43439/43439A0_clm_blob.c) + endif() + + # nvram + zephyr_include_directories(${hal_wifi_dir_resources}/nvram/COMPONENT_43439/COMPONENT_MURATA-1YN) +endif() + +# CYW4373_STERLING_LWB5PLUS +if(CONFIG_CYW4373_STERLING_LWB5PLUS AND NOT CONFIG_AIROC_WIFI_CUSTOM) + zephyr_include_directories(${hal_wifi_dir_resources}/clm/COMPONENT_4373/COMPONENT_STERLING-LWB5plus) + + # clm + if(CONFIG_AIROC_WLAN_MFG_FIRMWARE) + set(cyw43xx_clm_bin ${hal_blobs_dir}/clm/COMPONENT_4373/COMPONENT_STERLING-LWB5plus/4373A0-mfgtest.clm_blob) + zephyr_library_sources(${hal_wifi_dir_resources}/clm/COMPONENT_4373/COMPONENT_STERLING-LWB5plus/4373A0-mfgtest_clm_blob.c) + else() + set(cyw43xx_clm_bin ${hal_blobs_dir}/clm/COMPONENT_4373/COMPONENT_STERLING-LWB5plus/4373A0.clm_blob) + zephyr_library_sources(${hal_wifi_dir_resources}/clm/COMPONENT_4373/COMPONENT_STERLING-LWB5plus/4373A0_clm_blob.c) + endif() + + # nvram + zephyr_include_directories_ifdef(${hal_wifi_dir_resources}/nvram/COMPONENT_4373/COMPONENT_STERLING-LWB5plus) +endif() + +# generate FW inc_blob from fw_bin +if(EXISTS ${cyw43xx_fw_bin}) + message(INFO " generate include of blob FW file: ${cyw43xx_fw_bin}") + generate_inc_file_for_target(app ${cyw43xx_fw_bin} ${cyw43xx_fw_bin_gen_inc}) +endif() + +# generate CLM inc_blob from clm_bin +if(EXISTS ${cyw43xx_clm_bin}) + message(INFO " generate include of blob CLM file: ${cyw43xx_clm_bin}") + generate_inc_file_for_target(app ${cyw43xx_clm_bin} ${cyw43xx_clm_bin_gen_inc}) +endif() diff --git a/samples/net/wifi/boards/cy8cproto_062_4343w.conf b/samples/net/wifi/boards/cy8cproto_062_4343w.conf new file mode 100644 index 00000000000..943db317fad --- /dev/null +++ b/samples/net/wifi/boards/cy8cproto_062_4343w.conf @@ -0,0 +1,3 @@ +CONFIG_NET_IF_MAX_IPV4_COUNT=2 +CONFIG_NET_MGMT_EVENT_QUEUE_TIMEOUT=20 +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 diff --git a/tests/drivers/build_all/modem/testcase.yaml b/tests/drivers/build_all/modem/testcase.yaml index 8b42363b4ff..89abfbd79df 100644 --- a/tests/drivers/build_all/modem/testcase.yaml +++ b/tests/drivers/build_all/modem/testcase.yaml @@ -63,7 +63,9 @@ tests: - CONFIG_UART_MUX=y drivers.modem.esp_at.build: extra_args: CONF_FILE=modem_esp_at.conf - platform_exclude: ip_k66f + platform_exclude: + - ip_k66f + - cy8cproto_062_4343w filter: CONFIG_SERIAL min_ram: 36 drivers.modem.esp_at.async.build: diff --git a/west.yml b/west.yml index 9326bd85722..6b4391cb380 100644 --- a/west.yml +++ b/west.yml @@ -168,7 +168,7 @@ manifest: groups: - hal - name: hal_infineon - revision: 815e84a5150f95627201f192779a0180d5052de7 + revision: 69c883d3bd9fac8a18dd8384624b8c472a68d06f path: modules/hal/infineon groups: - hal