From c412dadcb98f8a7767a3e6cee6592ea30c9f5651 Mon Sep 17 00:00:00 2001 From: Tiago Medicci Serrano Date: Thu, 25 Apr 2024 13:41:36 -0300 Subject: [PATCH] esp32c3/wifi: Add support for the Wi-Fi in ESP32-C3 This commit introduces support for both station and softAP modes. --- .../esp32c3/boards/esp32c3-generic/index.rst | 41 + .../platforms/risc-v/esp32c3/index.rst | 8 +- arch/risc-v/src/common/espressif/Kconfig | 2 +- arch/risc-v/src/common/espressif/Wireless.mk | 5 +- arch/risc-v/src/common/espressif/esp_start.c | 1 + arch/risc-v/src/esp32c3/Make.defs | 7 + arch/risc-v/src/esp32c3/esp_coex_adapter.c | 587 ++ arch/risc-v/src/esp32c3/esp_wifi_adapter.c | 5615 +++++++++++++++++ arch/risc-v/src/esp32c3/esp_wifi_adapter.h | 672 ++ arch/risc-v/src/esp32c3/hal_esp32c3.mk | 15 + .../esp32c3/common/include/esp_board_wlan.h | 73 + .../esp32c3/common/scripts/esp32c3_aliases.ld | 1 + .../scripts/esp32c3_mcuboot_sections.ld | 25 + .../scripts/esp32c3_simple_boot_sections.ld | 43 + boards/risc-v/esp32c3/common/src/Make.defs | 4 + .../esp32c3/common/src/esp_board_wlan.c | 81 + .../configs/sta_softap/defconfig | 82 + .../esp32c3-generic/configs/wifi/defconfig | 78 + .../esp32c3-generic/src/esp32c3_bringup.c | 22 + 19 files changed, 7353 insertions(+), 9 deletions(-) create mode 100644 arch/risc-v/src/esp32c3/esp_coex_adapter.c create mode 100644 arch/risc-v/src/esp32c3/esp_wifi_adapter.c create mode 100644 arch/risc-v/src/esp32c3/esp_wifi_adapter.h create mode 100644 boards/risc-v/esp32c3/common/include/esp_board_wlan.h create mode 100644 boards/risc-v/esp32c3/common/src/esp_board_wlan.c create mode 100644 boards/risc-v/esp32c3/esp32c3-generic/configs/sta_softap/defconfig create mode 100644 boards/risc-v/esp32c3/esp32c3-generic/configs/wifi/defconfig diff --git a/Documentation/platforms/risc-v/esp32c3/boards/esp32c3-generic/index.rst b/Documentation/platforms/risc-v/esp32c3/boards/esp32c3-generic/index.rst index bb9fa5e2eb..eaf89cac04 100644 --- a/Documentation/platforms/risc-v/esp32c3/boards/esp32c3-generic/index.rst +++ b/Documentation/platforms/risc-v/esp32c3/boards/esp32c3-generic/index.rst @@ -162,6 +162,26 @@ Once booted you can use the following commands to mount the file system:: nsh> mksmartfs /dev/smart0 nsh> mount -t smartfs /dev/smart0 /mnt +sta_softap +---------- + +With this configuration you can run these commands to be able +to connect your smartphone or laptop to your board:: + + nsh> ifup wlan1 + nsh> dhcpd_start wlan1 + nsh> wapi psk wlan1 mypasswd 3 + nsh> wapi essid wlan1 nuttxap 1 + +In this case, you are creating the access point ``nuttxapp`` in your board and to +connect to it on your smartphone you will be required to type the password ``mypasswd`` +using WPA2. + +.. tip:: Please refer to :ref:`ESP32 Wi-Fi SoftAP Mode ` + for more information. + +The ``dhcpd_start`` is necessary to let your board to associate an IP to your smartphone. + timer ----- @@ -220,3 +240,24 @@ To test it, just run the following command:: nsh> wdog -i /dev/watchdogX Where X is the watchdog instance. + +wifi +---- + +Enables Wi-Fi support. You can define your credentials this way:: + + $ make menuconfig + -> Application Configuration + -> Network Utilities + -> Network initialization (NETUTILS_NETINIT [=y]) + -> WAPI Configuration + +Or if you don't want to keep it saved in the firmware you can do it +at runtime:: + + nsh> wapi psk wlan0 mypasswd 3 + nsh> wapi essid wlan0 myssid 1 + nsh> renew wlan0 + +.. tip:: Please refer to :ref:`ESP32 Wi-Fi Station Mode ` + for more information. diff --git a/Documentation/platforms/risc-v/esp32c3/index.rst b/Documentation/platforms/risc-v/esp32c3/index.rst index d970bbf8fa..c6c870d12d 100644 --- a/Documentation/platforms/risc-v/esp32c3/index.rst +++ b/Documentation/platforms/risc-v/esp32c3/index.rst @@ -142,9 +142,9 @@ Peripheral Support The following list indicates the state of peripherals' support in NuttX: -=========== ======= ===== +=========== ======= ==================== Peripheral Support NOTES -=========== ======= ===== +=========== ======= ==================== ADC No AES No Bluetooth No @@ -165,8 +165,8 @@ Timers Yes Touch No UART Yes Watchdog Yes -Wifi No -=========== ======= ===== +Wifi Yes WPA3-SAE supported +=========== ======= ==================== Secure Boot and Flash Encryption ================================ diff --git a/arch/risc-v/src/common/espressif/Kconfig b/arch/risc-v/src/common/espressif/Kconfig index f247b485c5..52c5eb5f2e 100644 --- a/arch/risc-v/src/common/espressif/Kconfig +++ b/arch/risc-v/src/common/espressif/Kconfig @@ -350,7 +350,7 @@ config ESP_WIRELESS config ESPRESSIF_WIFI bool "Wi-Fi" - depends on ESPRESSIF_ESP32C6 + depends on ESPRESSIF_ESP32C3 || ESPRESSIF_ESP32C6 default n select ESP_WIRELESS ---help--- diff --git a/arch/risc-v/src/common/espressif/Wireless.mk b/arch/risc-v/src/common/espressif/Wireless.mk index a27de857bd..e2e627ca9f 100644 --- a/arch/risc-v/src/common/espressif/Wireless.mk +++ b/arch/risc-v/src/common/espressif/Wireless.mk @@ -28,10 +28,7 @@ EXTRA_LIBPATHS += -L $(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$ EXTRA_LIBPATHS += -L $(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_phy$(DELIM)lib$(DELIM)$(CHIP_SERIES) EXTRA_LIBPATHS += -L $(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_wifi$(DELIM)lib$(DELIM)$(CHIP_SERIES) -EXTRA_LIBS += -lphy -lcoexist -ifeq ($(CHIP_SERIES),esp32c6) -EXTRA_LIBS += -lmesh -endif +EXTRA_LIBS += -lphy -lcoexist -lmesh ifeq ($(CONFIG_ESPRESSIF_WIFI),y) diff --git a/arch/risc-v/src/common/espressif/esp_start.c b/arch/risc-v/src/common/espressif/esp_start.c index 96dbc3e37b..25685998bf 100644 --- a/arch/risc-v/src/common/espressif/esp_start.c +++ b/arch/risc-v/src/common/espressif/esp_start.c @@ -50,6 +50,7 @@ #include "soc/extmem_reg.h" #include "soc/mmu.h" #include "soc/reg_base.h" +#include "spi_flash_mmap.h" #include "rom/cache.h" #ifdef CONFIG_ESPRESSIF_SIMPLE_BOOT diff --git a/arch/risc-v/src/esp32c3/Make.defs b/arch/risc-v/src/esp32c3/Make.defs index a8bdc3b46a..97e5963f4b 100644 --- a/arch/risc-v/src/esp32c3/Make.defs +++ b/arch/risc-v/src/esp32c3/Make.defs @@ -21,4 +21,11 @@ include common/Make.defs include common/espressif/Make.defs +# Wireless interfaces. + +ifeq ($(CONFIG_ESPRESSIF_WIFI),y) +CHIP_CSRCS += esp_coex_adapter.c esp_wifi_adapter.c +EXTRA_LIBS += -lcore -lnet80211 -lpp +endif + CFLAGS += ${DEFINE_PREFIX}_RETARGETABLE_LOCKING diff --git a/arch/risc-v/src/esp32c3/esp_coex_adapter.c b/arch/risc-v/src/esp32c3/esp_coex_adapter.c new file mode 100644 index 0000000000..d994285bd0 --- /dev/null +++ b/arch/risc-v/src/esp32c3/esp_coex_adapter.c @@ -0,0 +1,587 @@ +/**************************************************************************** + * arch/risc-v/src/esp32c3/esp_coex_adapter.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "esp_hr_timer.h" +#include "esp_wlan.h" + +#include "esp_attr.h" +#include "esp_timer.h" +#include "soc/rtc.h" +#include "esp_private/esp_clk.h" +#include "esp_coexist_adapter.h" +#include "rom/ets_sys.h" +#include "soc/soc_caps.h" +#include "soc/system_reg.h" +#include "esp_modem_wrapper.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define OSI_FUNCS_TIME_BLOCKING 0xffffffff + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int64_t esp_coex_esp_timer_get_time_wrapper(void); +static int32_t esp_coex_semphr_take_from_isr_wrapper(void *semphr, + void *hptw); +static int32_t esp_coex_semphr_give_from_isr_wrapper(void *semphr, + void *hptw); +static int esp_coex_is_in_isr_wrapper(void); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +coex_adapter_funcs_t g_coex_adapter_funcs = +{ + ._version = COEX_ADAPTER_VERSION, + ._task_yield_from_isr = esp_coex_common_task_yield_from_isr_wrapper, + ._semphr_create = esp_coex_common_semphr_create_wrapper, + ._semphr_delete = esp_coex_common_semphr_delete_wrapper, + ._semphr_take_from_isr = esp_coex_semphr_take_from_isr_wrapper, + ._semphr_give_from_isr = esp_coex_semphr_give_from_isr_wrapper, + ._semphr_take = esp_coex_common_semphr_take_wrapper, + ._semphr_give = esp_coex_common_semphr_give_wrapper, + ._is_in_isr = esp_coex_is_in_isr_wrapper, + ._malloc_internal = esp_coex_common_malloc_internal_wrapper, + ._free = free, + ._esp_timer_get_time = esp_coex_esp_timer_get_time_wrapper, + ._timer_disarm = esp_coex_common_timer_disarm_wrapper, + ._timer_done = esp_coex_common_timer_done_wrapper, + ._timer_setfn = esp_coex_common_timer_setfn_wrapper, + ._timer_arm_us = esp_coex_common_timer_arm_us_wrapper, + ._magic = COEX_ADAPTER_MAGIC, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_coex_esp_timer_get_time_wrapper + * + * Description: + * This function retrieves the current time of the High Resolution Timer + * in microseconds. It is a wrapper around the esp_hr_timer_time_us + * function, providing a consistent interface for the coexistence module. + * + * Input Parameters: + * None. + * + * Returned Value: + * The current time of the High Resolution Timer in microseconds, as a + * 64-bit integer. + * + ****************************************************************************/ + +static IRAM_ATTR int64_t esp_coex_esp_timer_get_time_wrapper(void) +{ + return (int64_t)esp_hr_timer_time_us(); +} + +/**************************************************************************** + * Name: esp_coex_semphr_take_from_isr_wrapper + * + * Description: + * Take a semaphore from an ISR + * + * Input Parameters: + * semphr - Semaphore data pointer. + * hptw - Unused. + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +static int32_t IRAM_ATTR esp_coex_semphr_take_from_isr_wrapper(void *semphr, + void *hptw) +{ + *(int *)hptw = 0; + + return nuttx_err_to_freertos(nxsem_trywait(semphr)); +} + +/**************************************************************************** + * Name: esp_coex_semphr_give_from_isr_wrapper + * + * Description: + * Post semaphore + * + * Input Parameters: + * semphr - Semaphore data pointer + * hptw - Unused. + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +static int32_t IRAM_ATTR esp_coex_semphr_give_from_isr_wrapper(void *semphr, + void *hptw) +{ + *(int *)hptw = 0; + + return esp_coex_common_semphr_give_wrapper(semphr); +} + +/**************************************************************************** + * Name: esp_coex_is_in_isr_wrapper + * + * Description: + * This function checks if the current context is an interrupt service + * routine (ISR). It is a wrapper around the NuttX up_interrupt_context + * function. + * + * Input Parameters: + * None + * + * Returned Value: + * Returns 1 if the current context is an ISR, 0 otherwise. + * + ****************************************************************************/ + +static int IRAM_ATTR esp_coex_is_in_isr_wrapper(void) +{ + return (int)up_interrupt_context(); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_coex_common_env_is_chip_wrapper + * + * Description: + * This function checks if the environment is a chip or FPGA. + * + * Input Parameters: + * None + * + * Returned Value: + * Returns true if the environment is a chip, false if it's an FPGA. + * + ****************************************************************************/ + +bool IRAM_ATTR esp_coex_common_env_is_chip_wrapper(void) +{ +#ifdef CONFIG_IDF_ENV_FPGA + return false; +#else + return true; +#endif +} + +/**************************************************************************** + * Name: esp_coex_common_spin_lock_create_wrapper + * + * Description: + * Create spin lock in SMP mode + * + * Input Parameters: + * None + * + * Returned Value: + * Spin lock data pointer + * + ****************************************************************************/ + +void *esp_coex_common_spin_lock_create_wrapper(void) +{ + spinlock_t *lock; + int tmp; + + tmp = sizeof(*lock); + lock = kmm_malloc(tmp); + if (!lock) + { + wlerr("Failed to alloc %d memory\n", tmp); + DEBUGPANIC(); + } + + spin_initialize(lock, SP_UNLOCKED); + + return lock; +} + +/**************************************************************************** + * Name: esp_coex_common_int_disable_wrapper + * + * Description: + * Enter critical section by disabling interrupts and taking the spin lock + * if in SMP mode. + * + * Input Parameters: + * wifi_int_mux - Spin lock data pointer + * + * Returned Value: + * CPU PS value. + * + ****************************************************************************/ + +uint32_t IRAM_ATTR esp_coex_common_int_disable_wrapper(void *wifi_int_mux) +{ + irqstate_t flags; + + flags = spin_lock_irqsave((spinlock_t *)wifi_int_mux); + + return (uint32_t)flags; +} + +/**************************************************************************** + * Name: esp_coex_common_int_restore_wrapper + * + * Description: + * Exit from critical section by enabling interrupts and releasing the spin + * lock if in SMP mode. + * + * Input Parameters: + * wifi_int_mux - Spin lock data pointer + * tmp - CPU PS value. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void IRAM_ATTR esp_coex_common_int_restore_wrapper(void *wifi_int_mux, + uint32_t tmp) +{ + irqstate_t flags = (irqstate_t)tmp; + + spin_unlock_irqrestore((spinlock_t *)wifi_int_mux, flags); +} + +/**************************************************************************** + * Name: esp_task_yield_from_isr + * + * Description: + * Perform a solicited context switch on FreeRTOS. Do nothing in NuttX. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void IRAM_ATTR esp_coex_common_task_yield_from_isr_wrapper(void) +{ +} + +/**************************************************************************** + * Name: esp_coex_common_semphr_create_wrapper + * + * Description: + * Create and initialize semaphore + * + * Input Parameters: + * max - No meanining for NuttX + * init - semaphore initialization value + * + * Returned Value: + * Semaphore data pointer + * + ****************************************************************************/ + +void *esp_coex_common_semphr_create_wrapper(uint32_t max, uint32_t init) +{ + int ret; + sem_t *sem; + int tmp; + + tmp = sizeof(sem_t); + sem = kmm_malloc(tmp); + if (!sem) + { + wlerr("Failed to alloc %d memory\n", tmp); + return NULL; + } + + ret = nxsem_init(sem, 0, init); + if (ret) + { + wlerr("Failed to initialize sem error=%d\n", ret); + kmm_free(sem); + return NULL; + } + + return sem; +} + +/**************************************************************************** + * Name: esp_coex_common_semphr_delete_wrapper + * + * Description: + * Delete semaphore + * + * Input Parameters: + * semphr - Semaphore data pointer + * + * Returned Value: + * None + * + ****************************************************************************/ + +void esp_coex_common_semphr_delete_wrapper(void *semphr) +{ + sem_t *sem = (sem_t *)semphr; + + nxsem_destroy(sem); + kmm_free(sem); +} + +/**************************************************************************** + * Name: esp_coex_common_semphr_take_wrapper + * + * Description: + * This function attempts to take (wait for) a semaphore within a certain + * period of time. It is a wrapper around the NuttX nxsem_wait and + * nxsem_tickwait functions, providing error handling and translation + * between NuttX and ESP-IDF error codes. + * + * Input Parameters: + * semphr - Pointer to the semaphore data structure. + * block_time_tick - The maximum number of system ticks to wait. + * + * Returned Value: + * Returns 0 if the semaphore was successfully taken, or a negative error + * code if the operation failed or the timeout expired. + * + ****************************************************************************/ + +int32_t esp_coex_common_semphr_take_wrapper(void *semphr, + uint32_t block_time_tick) +{ + int ret; + sem_t *sem = (sem_t *)semphr; + + if (block_time_tick == OSI_FUNCS_TIME_BLOCKING) + { + ret = nxsem_wait(sem); + } + else + { + if (block_time_tick > 0) + { + ret = nxsem_tickwait(sem, block_time_tick); + } + else + { + ret = nxsem_trywait(sem); + } + } + + if (ret) + { + wlerr("ERROR: Failed to wait sem in %lu ticks. Error=%d\n", + block_time_tick, ret); + } + + return nuttx_err_to_freertos(ret); +} + +/**************************************************************************** + * Name: esp_coex_common_semphr_give_wrapper + * + * Description: + * This function posts (releases) a semaphore. It is a wrapper around the + * NuttX nxsem_post function, providing error handling and translation + * between NuttX and ESP-IDF error codes. + * + * Input Parameters: + * semphr - Pointer to the semaphore data structure. + * + * Returned Value: + * Returns 0 if the semaphore was successfully posted, or a negative error + * code if the operation failed. + * + ****************************************************************************/ + +int32_t esp_coex_common_semphr_give_wrapper(void *semphr) +{ + int ret; + sem_t *sem = (sem_t *)semphr; + + ret = nxsem_post(sem); + if (ret) + { + wlerr("Failed to post sem error=%d\n", ret); + } + + return nuttx_err_to_freertos(ret); +} + +/**************************************************************************** + * Name: esp_coex_common_timer_disarm_wrapper + * + * Description: + * Disable timer + * + * Input Parameters: + * timer - timer data pointer + * + * Returned Value: + * None + * + ****************************************************************************/ + +void IRAM_ATTR esp_coex_common_timer_disarm_wrapper(void *timer) +{ + ets_timer_disarm(timer); +} + +/**************************************************************************** + * Name: esp_coex_common_timer_done_wrapper + * + * Description: + * Disable and free timer + * + * Input Parameters: + * ptimer - timer data pointer + * + * Returned Value: + * None + * + ****************************************************************************/ + +void esp_coex_common_timer_done_wrapper(void *ptimer) +{ + ets_timer_done(ptimer); +} + +/**************************************************************************** + * Name: esp_coex_common_timer_setfn_wrapper + * + * Description: + * Set timer callback function and private data + * + * Input Parameters: + * ptimer - Timer data pointer + * pfunction - Callback function + * parg - Callback function private data + * + * Returned Value: + * None + * + ****************************************************************************/ + +void esp_coex_common_timer_setfn_wrapper(void *ptimer, + void *pfunction, + void *parg) +{ + ets_timer_setfn(ptimer, pfunction, parg); +} + +/**************************************************************************** + * Name: esp_coex_common_timer_arm_us_wrapper + * + * Description: + * Set timer timeout period and repeat flag + * + * Input Parameters: + * ptimer - timer data pointer + * us - micro seconds + * repeat - true: run cycle, false: run once + * + * Returned Value: + * None + * + ****************************************************************************/ + +void IRAM_ATTR esp_coex_common_timer_arm_us_wrapper(void *ptimer, + uint32_t us, + bool repeat) +{ + ets_timer_arm_us(ptimer, us, repeat); +} + +/**************************************************************************** + * Name: esp_coex_common_malloc_internal_wrapper + * + * Description: + * Drivers allocate a block of memory + * + * Input Parameters: + * size - memory size + * + * Returned Value: + * Memory pointer + * + ****************************************************************************/ + +IRAM_ATTR void *esp_coex_common_malloc_internal_wrapper(size_t size) +{ + return kmm_malloc(size); +} + +/**************************************************************************** + * Name: esp_coex_common_clk_slowclk_cal_get_wrapper + * + * Description: + * Get the calibration value of RTC slow clock + * + * Input Parameters: + * None + * + * Returned Value: + * The calibration value obtained using rtc_clk_cal + * + ****************************************************************************/ + +uint32_t esp_coex_common_clk_slowclk_cal_get_wrapper(void) +{ + /* The bit width of WiFi light sleep clock calibration is 12 while the one + * of system is 19. It should shift 19 - 12 = 7. + */ + + if (GET_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_XTAL)) + { + uint64_t time_per_us = 1000000ULL; + return (((time_per_us << RTC_CLK_CAL_FRACT) / (MHZ)) >> + (RTC_CLK_CAL_FRACT - SOC_WIFI_LIGHT_SLEEP_CLK_WIDTH)); + } + else + { + return (esp_clk_slowclk_cal_get() >> + (RTC_CLK_CAL_FRACT - SOC_WIFI_LIGHT_SLEEP_CLK_WIDTH)); + } +} diff --git a/arch/risc-v/src/esp32c3/esp_wifi_adapter.c b/arch/risc-v/src/esp32c3/esp_wifi_adapter.c new file mode 100644 index 0000000000..0ac761bd47 --- /dev/null +++ b/arch/risc-v/src/esp32c3/esp_wifi_adapter.c @@ -0,0 +1,5615 @@ +/**************************************************************************** + * arch/risc-v/src/esp32c3/esp_wifi_adapter.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "esp_irq.h" +#include "esp_hr_timer.h" + +#include "esp_types.h" +#include "esp_random.h" +#include "esp_mac.h" +#include "esp_intr_alloc.h" +#include "esp_attr.h" +#include "esp_log.h" +#include "esp_event.h" +#include "esp_timer.h" +#include "esp_private/wifi_os_adapter.h" +#include "esp_private/wifi.h" +#include "esp_phy_init.h" +#include "soc/rtc_cntl_reg.h" +#include "soc/syscon_reg.h" +#include "soc/system_reg.h" +#include "esp_private/periph_ctrl.h" +#include "esp_private/esp_clk.h" +#include "os.h" +#include "esp_smartconfig.h" +#include "esp_coexist_internal.h" +#include "rom/ets_sys.h" +#include "esp_modem_wrapper.h" + +#include "esp_wlan.h" +#include "esp_wifi_adapter.h" +#include "esp_wifi_utils.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define MHZ (1000000) + +#define PHY_RF_MASK ((1 << PHY_BT_MODULE) | (1 << PHY_WIFI_MODULE)) + +#define WIFI_CONNECT_TIMEOUT CONFIG_ESPRESSIF_WIFI_CONNECT_TIMEOUT + +#define ESP_WIFI_11B_MAX_BITRATE 11 +#define ESP_WIFI_11G_MAX_BITRATE 54 +#define ESP_WIFI_11N_MCS7_HT20_BITRATE 72 +#define ESP_WIFI_11N_MCS7_HT40_BITRATE 150 + +#ifndef CONFIG_EXAMPLE_WIFI_LISTEN_INTERVAL +#define CONFIG_EXAMPLE_WIFI_LISTEN_INTERVAL 3 +#endif + +#define DEFAULT_LISTEN_INTERVAL CONFIG_EXAMPLE_WIFI_LISTEN_INTERVAL + +#define RTC_CLK_CAL_FRACT 19 //!< Number of fractional bits in values returned by rtc_clk_cal + +#define ets_timer _ETSTIMER_ + +/* CONFIG_POWER_SAVE_MODEM */ + +#if defined(CONFIG_ESP_POWER_SAVE_MIN_MODEM) +# define DEFAULT_PS_MODE WIFI_PS_MIN_MODEM +#elif defined(CONFIG_ESP_POWER_SAVE_MAX_MODEM) +# define DEFAULT_PS_MODE WIFI_PS_MAX_MODEM +#elif defined(CONFIG_ESP_POWER_SAVE_NONE) +# define DEFAULT_PS_MODE WIFI_PS_NONE +#else +# define DEFAULT_PS_MODE WIFI_PS_NONE +#endif + +#define ESP_MAX_PRIORITIES (25) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Wi-Fi event ID */ + +enum wifi_adpt_evt_e +{ + WIFI_ADPT_EVT_SCAN_DONE = 0, + WIFI_ADPT_EVT_STA_START, + WIFI_ADPT_EVT_STA_CONNECT, + WIFI_ADPT_EVT_STA_DISCONNECT, + WIFI_ADPT_EVT_STA_AUTHMODE_CHANGE, + WIFI_ADPT_EVT_STA_STOP, + WIFI_ADPT_EVT_AP_START, + WIFI_ADPT_EVT_AP_STOP, + WIFI_ADPT_EVT_AP_STACONNECTED, + WIFI_ADPT_EVT_AP_STADISCONNECTED, + WIFI_ADPT_EVT_MAX, +}; + +/* Wi-Fi Station state */ + +enum wifi_sta_state +{ + WIFI_STA_STATE_NULL, + WIFI_STA_STATE_START, + WIFI_STA_STATE_CONNECT, + WIFI_STA_STATE_DISCONNECT, + WIFI_STA_STATE_STOP +}; + +/* Wi-Fi interrupt adapter private data */ + +struct irq_adpt +{ + void (*func)(void *arg); /* Interrupt callback function */ + void *arg; /* Interrupt private data */ +}; + +/* Wi-Fi message queue private data */ + +struct mq_adpt +{ + struct file mq; /* Message queue handle */ + uint32_t msgsize; /* Message size */ + char name[16]; /* Message queue name */ +}; + +/* Wi-Fi time private data */ + +struct time_adpt +{ + time_t sec; /* Second value */ + suseconds_t usec; /* Micro second value */ +}; + +/* Wi-Fi event private data */ + +struct evt_adpt +{ + sq_entry_t entry; /* Sequence entry */ + int32_t id; /* Event ID */ + uint8_t buf[0]; /* Event private data */ +}; + +/* Wi-Fi event notification private data */ + +struct wifi_notify +{ + bool assigned; /* Flag indicate if it is used */ + pid_t pid; /* Signal's target thread PID */ + struct sigevent event; /* Signal event private data */ + struct sigwork_s work; /* Signal work private data */ +}; + +/* Wi-Fi NVS private data */ + +struct nvs_adpt +{ + char *index_name; +}; + +/* Wi-Fi event callback function */ + +typedef void (*wifi_evt_cb_t)(void *p); + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Private functions order is defined as: + * - A first block containing the functions in the same order as of the + * ESP-IDF' corresponding `esp_adapter.c` to ease comparison; + * - A second block of auxiliary functions block ordered by ascending; + */ + +/* First block of functions */ + +static void *wifi_zalloc_wrapper(size_t size); +static void *wifi_create_queue(int queue_len, int item_size); +static void wifi_delete_queue(wifi_static_queue_t *queue); +static void *wifi_create_queue_wrapper(int queue_len, int item_size); +static void wifi_delete_queue_wrapper(void *queue); +static void set_intr_wrapper(int32_t cpu_no, uint32_t intr_source, + uint32_t intr_num, int32_t intr_prio); +static void clear_intr_wrapper(uint32_t intr_source, uint32_t intr_num); +static void set_isr_wrapper(int32_t n, void *f, void *arg); +static void enable_intr_wrapper(uint32_t intr_mask); +static void disable_intr_wrapper(uint32_t intr_mask); +static bool is_from_isr_wrapper(void); +static void wifi_thread_semphr_free(void *data); +static void *wifi_thread_semphr_get_wrapper(void); +static void *recursive_mutex_create_wrapper(void); +static void *mutex_create_wrapper(void); +static void mutex_delete_wrapper(void *mutex); +static int32_t mutex_lock_wrapper(void *mutex); +static int32_t mutex_unlock_wrapper(void *mutex); +static void *queue_create_wrapper(uint32_t queue_len, uint32_t item_size); +static int32_t queue_send_wrapper(void *queue, + void *item, + uint32_t block_time_tick); +static int32_t queue_send_from_isr_wrapper(void *queue, + void *item, + void *hptw); +static int32_t queue_send_to_back_wrapper(void *queue, + void *item, + uint32_t block_time_tick); +static int32_t queue_send_to_front_wrapper(void *queue, + void *item, + uint32_t block_time_tick); +static int32_t queue_recv_wrapper(void *queue, + void *item, + uint32_t block_time_tick); +static uint32_t event_group_wait_bits_wrapper(void *event, + uint32_t bits_to_wait_for, + int clear_on_exit, + int wait_for_all_bits, + uint32_t block_time_tick); +static int32_t task_create_pinned_to_core_wrapper(void *task_func, + const char *name, + uint32_t stack_depth, + void *param, + uint32_t prio, + void *task_handle, + uint32_t core_id); +static int32_t task_create_wrapper(void *task_func, + const char *name, + uint32_t stack_depth, + void *param, + uint32_t prio, + void *task_handle); +static int32_t task_ms_to_tick_wrapper(uint32_t ms); +static int32_t task_get_max_priority_wrapper(void); +int32_t esp_event_post_wrapper(const char *event_base, + int32_t event_id, + void *event_data, + size_t event_data_size, + uint32_t ticks); +static void wifi_apb80m_request_wrapper(void); +static void wifi_apb80m_release_wrapper(void); +static void timer_arm_wrapper(void *timer, uint32_t tmout, bool repeat); +static void wifi_reset_mac_wrapper(void); +static void wifi_rtc_enable_iso_wrapper(void); +static void IRAM_ATTR wifi_rtc_disable_iso_wrapper(void); +static void wifi_clock_enable_wrapper(void); +static void wifi_clock_disable_wrapper(void); +static int get_time_wrapper(void *t); +static void *realloc_internal_wrapper(void *ptr, size_t size); +static void *calloc_internal_wrapper(size_t n, size_t size); +static void *zalloc_internal_wrapper(size_t size); +static int nvs_open_wrapper(const char *name, unsigned int open_mode, + uint32_t *out_handle); +static void esp_log_writev_wrapper(unsigned int level, + const char *tag, + const char *format, + va_list args); +static void esp_log_write_wrapper(unsigned int level, + const char *tag, + const char *format, ...); +static int esp_read_mac_wrapper(uint8_t *mac, unsigned int type); +static int coex_init_wrapper(void); +static void coex_deinit_wrapper(void); +static int coex_enable_wrapper(void); +static void coex_disable_wrapper(void); +static uint32_t coex_status_get_wrapper(void); +static int coex_wifi_request_wrapper(uint32_t event, + uint32_t latency, + uint32_t duration); +static int coex_wifi_release_wrapper(uint32_t event); +static int coex_wifi_channel_set_wrapper(uint8_t primary, + uint8_t secondary); +static int coex_event_duration_get_wrapper(uint32_t event, + uint32_t *duration); +static int coex_pti_get_wrapper(uint32_t event, uint8_t *pti); +static void coex_schm_status_bit_clear_wrapper(uint32_t type, + uint32_t status); +static void coex_schm_status_bit_set_wrapper(uint32_t type, + uint32_t status); +static int coex_schm_interval_set_wrapper(uint32_t interval); +static uint32_t coex_schm_interval_get_wrapper(void); +static uint8_t coex_schm_curr_period_get_wrapper(void); +static void *coex_schm_curr_phase_get_wrapper(void); +static int coex_register_start_cb_wrapper(int (* cb)(void)); +static int coex_schm_process_restart_wrapper(void); +static int coex_schm_register_cb_wrapper(int type, int(*cb)(int)); +static void esp_empty_wrapper(void); + +/* Second block of functions + * These functions are auxiliary functions that are used by the first block + * of functions or software adapters for the Wi-Fi driver + */ + +static int esp_event_id_map(int event_id); +static void esp_evt_work_cb(void *arg); +static int esp_freq_to_channel(uint16_t freq); +static uint32_t esp_get_free_heap_size(void); +static void *event_group_create_wrapper(void); +static void event_group_delete_wrapper(void *event); +static uint32_t event_group_set_bits_wrapper(void *event, uint32_t bits); +static uint32_t event_group_clear_bits_wrapper(void *event, uint32_t bits); +static int esp_int_adpt_cb(int irq, void *context, void *arg); +static int esp_nvs_commit(uint32_t handle); +static int esp_nvs_erase_key(uint32_t handle, const char *key); +static int esp_nvs_get_blob(uint32_t handle, + const char *key, + void *out_value, + size_t *length); +static int esp_nvs_set_blob(uint32_t handle, + const char *key, + const void *value, + size_t length); +static int esp_nvs_get_i8(uint32_t handle, + const char *key, + int8_t *out_value); +static int esp_nvs_set_i8(uint32_t handle, const char *key, int8_t value); +static int esp_nvs_get_u8(uint32_t handle, + const char *key, + uint8_t *out_value); +static int esp_nvs_set_u8(uint32_t handle, const char *key, uint8_t value); +static int esp_nvs_get_u16(uint32_t handle, + const char *key, + uint16_t *out_value); +static int esp_nvs_set_u16(uint32_t handle, const char *key, uint16_t value); +static void esp_nvs_close(uint32_t handle); +static void esp_update_time(struct timespec *timespec, uint32_t ticks); +static int esp_wifi_auth_trans(uint32_t wifi_auth); +static int esp_wifi_cipher_trans(uint32_t wifi_cipher); +static int esp_wifi_lock(bool lock); +static uint32_t queue_msg_waiting_wrapper(void *queue); +static void task_delay_wrapper(uint32_t tick); +static void task_delete_wrapper(void *task_handle); +static void *task_get_current_task_wrapper(void); +static void vqueue_delete_adapter(void *queue); +static void vsemaphore_delete_adapter(void *semphr); +static void *xqueue_create_adapter(uint32_t queue_len, uint32_t item_size); +static int32_t xqueue_send_adapter(void *queue, + void *item, + uint32_t ticks, + int prio); +void *xsemaphore_create_counting_adapter(uint32_t max, uint32_t init); + +#ifdef CONFIG_PM +extern void wifi_apb80m_request(void); +extern void wifi_apb80m_release(void); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Wi-Fi event private data */ + +static struct work_s g_wifi_evt_work; +static sq_queue_t g_wifi_evt_queue; +static struct wifi_notify g_wifi_notify[WIFI_ADPT_EVT_MAX]; +static mutex_t g_wifiexcl_lock = NXMUTEX_INITIALIZER; + +/* Wi-Fi adapter reference */ + +static int g_wifi_ref; + +#ifdef ESP_WLAN_HAS_STA + +/* If reconnect automatically */ + +static bool g_sta_reconnect; + +/* If Wi-Fi sta starts */ + +static bool g_sta_started; + +/* If Wi-Fi sta connected */ + +static bool g_sta_connected; + +/* Wi-Fi interface configuration */ + +static wifi_config_t g_sta_wifi_cfg; + +#endif /* ESP_WLAN_HAS_STA */ + +#ifdef ESP_WLAN_HAS_SOFTAP + +/* If Wi-Fi SoftAP starts */ + +static bool g_softap_started; + +/* Wi-Fi interface configuration */ + +static wifi_config_t g_softap_wifi_cfg; + +#endif /* ESP_WLAN_HAS_SOFTAP */ + +/* Device specific lock */ + +static spinlock_t g_lock; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Wi-Fi OS adapter data */ + +wifi_osi_funcs_t g_wifi_osi_funcs = +{ + ._version = ESP_WIFI_OS_ADAPTER_VERSION, + ._env_is_chip = esp_coex_common_env_is_chip_wrapper, + ._set_intr = set_intr_wrapper, + ._clear_intr = clear_intr_wrapper, + ._set_isr = set_isr_wrapper, + ._ints_on = enable_intr_wrapper, + ._ints_off = disable_intr_wrapper, + ._is_from_isr = is_from_isr_wrapper, + ._spin_lock_create = esp_coex_common_spin_lock_create_wrapper, + ._spin_lock_delete = free, + ._wifi_int_disable = esp_coex_common_int_disable_wrapper, + ._wifi_int_restore = esp_coex_common_int_restore_wrapper, + ._task_yield_from_isr = esp_coex_common_task_yield_from_isr_wrapper, + ._semphr_create = esp_coex_common_semphr_create_wrapper, + ._semphr_delete = esp_coex_common_semphr_delete_wrapper, + ._semphr_take = esp_coex_common_semphr_take_wrapper, + ._semphr_give = esp_coex_common_semphr_give_wrapper, + ._wifi_thread_semphr_get = wifi_thread_semphr_get_wrapper, + ._mutex_create = mutex_create_wrapper, + ._recursive_mutex_create = recursive_mutex_create_wrapper, + ._mutex_delete = mutex_delete_wrapper, + ._mutex_lock = mutex_lock_wrapper, + ._mutex_unlock = mutex_unlock_wrapper, + ._queue_create = queue_create_wrapper, + ._queue_delete = vqueue_delete_adapter, + ._queue_send = queue_send_wrapper, + ._queue_send_from_isr = queue_send_from_isr_wrapper, + ._queue_send_to_back = queue_send_to_back_wrapper, + ._queue_send_to_front = queue_send_to_front_wrapper, + ._queue_recv = queue_recv_wrapper, + ._queue_msg_waiting = queue_msg_waiting_wrapper, + ._event_group_create = event_group_create_wrapper, + ._event_group_delete = event_group_delete_wrapper, + ._event_group_set_bits = event_group_set_bits_wrapper, + ._event_group_clear_bits = event_group_clear_bits_wrapper, + ._event_group_wait_bits = event_group_wait_bits_wrapper, + ._task_create_pinned_to_core = task_create_pinned_to_core_wrapper, + ._task_create = task_create_wrapper, + ._task_delete = task_delete_wrapper, + ._task_delay = task_delay_wrapper, + ._task_ms_to_tick = task_ms_to_tick_wrapper, + ._task_get_current_task = task_get_current_task_wrapper, + ._task_get_max_priority = task_get_max_priority_wrapper, + ._malloc = malloc, + ._free = free, + ._event_post = esp_event_post_wrapper, + ._get_free_heap_size = esp_get_free_heap_size, + ._rand = esp_random, + ._dport_access_stall_other_cpu_start_wrap = + esp_empty_wrapper, + ._dport_access_stall_other_cpu_end_wrap = + esp_empty_wrapper, + ._wifi_apb80m_request = wifi_apb80m_request_wrapper, + ._wifi_apb80m_release = wifi_apb80m_release_wrapper, + ._phy_disable = esp_phy_disable, + ._phy_enable = esp_phy_enable, + ._phy_update_country_info = esp_phy_update_country_info, + ._read_mac = esp_read_mac_wrapper, + ._timer_arm = timer_arm_wrapper, + ._timer_disarm = esp_coex_common_timer_disarm_wrapper, + ._timer_done = esp_coex_common_timer_done_wrapper, + ._timer_setfn = esp_coex_common_timer_setfn_wrapper, + ._timer_arm_us = esp_coex_common_timer_arm_us_wrapper, + ._wifi_reset_mac = wifi_reset_mac_wrapper, + ._wifi_clock_enable = wifi_clock_enable_wrapper, + ._wifi_clock_disable = wifi_clock_disable_wrapper, + ._wifi_rtc_enable_iso = wifi_rtc_enable_iso_wrapper, + ._wifi_rtc_disable_iso = wifi_rtc_disable_iso_wrapper, + ._esp_timer_get_time = (int64_t(*)(void))esp_hr_timer_time_us, + ._nvs_set_i8 = esp_nvs_set_i8, + ._nvs_get_i8 = esp_nvs_get_i8, + ._nvs_set_u8 = esp_nvs_set_u8, + ._nvs_get_u8 = esp_nvs_get_u8, + ._nvs_set_u16 = esp_nvs_set_u16, + ._nvs_get_u16 = esp_nvs_get_u16, + ._nvs_open = nvs_open_wrapper, + ._nvs_close = esp_nvs_close, + ._nvs_commit = esp_nvs_commit, + ._nvs_set_blob = esp_nvs_set_blob, + ._nvs_get_blob = esp_nvs_get_blob, + ._nvs_erase_key = esp_nvs_erase_key, + ._get_random = os_get_random, + ._get_time = get_time_wrapper, + ._random = os_random, + ._slowclk_cal_get = esp_coex_common_clk_slowclk_cal_get_wrapper, + ._log_write = esp_log_write_wrapper, + ._log_writev = esp_log_writev_wrapper, + ._log_timestamp = esp_log_timestamp, + ._malloc_internal = esp_coex_common_malloc_internal_wrapper, + ._realloc_internal = realloc_internal_wrapper, + ._calloc_internal = calloc_internal_wrapper, + ._zalloc_internal = zalloc_internal_wrapper, + ._wifi_malloc = wifi_malloc, + ._wifi_realloc = wifi_realloc, + ._wifi_calloc = wifi_calloc, + ._wifi_zalloc = wifi_zalloc_wrapper, + ._wifi_create_queue = wifi_create_queue_wrapper, + ._wifi_delete_queue = wifi_delete_queue_wrapper, + ._coex_init = coex_init_wrapper, + ._coex_deinit = coex_deinit_wrapper, + ._coex_enable = coex_enable_wrapper, + ._coex_disable = coex_disable_wrapper, + ._coex_status_get = coex_status_get_wrapper, + ._coex_wifi_request = coex_wifi_request_wrapper, + ._coex_wifi_release = coex_wifi_release_wrapper, + ._coex_wifi_channel_set = coex_wifi_channel_set_wrapper, + ._coex_event_duration_get = coex_event_duration_get_wrapper, + ._coex_pti_get = coex_pti_get_wrapper, + ._coex_schm_status_bit_clear = coex_schm_status_bit_clear_wrapper, + ._coex_schm_status_bit_set = coex_schm_status_bit_set_wrapper, + ._coex_schm_interval_set = coex_schm_interval_set_wrapper, + ._coex_schm_interval_get = coex_schm_interval_get_wrapper, + ._coex_schm_curr_period_get = coex_schm_curr_period_get_wrapper, + ._coex_schm_curr_phase_get = coex_schm_curr_phase_get_wrapper, + ._coex_register_start_cb = coex_register_start_cb_wrapper, + ._coex_schm_process_restart = coex_schm_process_restart_wrapper, + ._coex_schm_register_cb = coex_schm_register_cb_wrapper, + ._magic = ESP_WIFI_OS_ADAPTER_MAGIC, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/* Private functions order is defined as: + * - A first block containing the functions in the same order as of the + * ESP-IDF' corresponding `esp_adapter.c` to ease comparison; + * - A second block of auxiliary functions block ordered by ascending; + */ + +/* First block of functions */ + +/**************************************************************************** + * Name: wifi_zalloc_wrapper + * + * Description: + * Applications allocate a block of memory and clear it with 0 + * + * Input Parameters: + * size - memory size + * + * Returned Value: + * New memory pointer + * + ****************************************************************************/ + +static IRAM_ATTR void *wifi_zalloc_wrapper(size_t size) +{ + return zalloc(size); +} + +/**************************************************************************** + * Name: wifi_create_queue + * + * Description: + * Create Wi-Fi static message queue + * + * Input Parameters: + * queue_len - queue message number + * item_size - message size + * + * Returned Value: + * Wi-Fi static message queue data pointer + * + ****************************************************************************/ + +static void *wifi_create_queue(int queue_len, int item_size) +{ + wifi_static_queue_t *wifi_queue; + + wifi_queue = kmm_malloc(sizeof(wifi_static_queue_t)); + if (!wifi_queue) + { + wlerr("Failed to kmm_malloc\n"); + return NULL; + } + + wifi_queue->handle = xqueue_create_adapter(queue_len, item_size); + if (!wifi_queue->handle) + { + wlerr("Failed to create queue\n"); + kmm_free(wifi_queue); + return NULL; + } + + return wifi_queue; +} + +/**************************************************************************** + * Name: wifi_delete_queue + * + * Description: + * Delete message queue + * + * Input Parameters: + * queue - Message queue data pointer + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void wifi_delete_queue(wifi_static_queue_t *queue) +{ + if (queue) + { + vqueue_delete_adapter(queue->handle); + kmm_free(queue); + } +} + +/**************************************************************************** + * Name: wifi_create_queue_wrapper + * + * Description: + * This function creates a new queue for Wi-Fi operations. It is a wrapper + * around the wifi_create_queue function, providing a consistent interface + * for the Wi-Fi module. + * + * Input Parameters: + * queue_len - The maximum number of items that the queue can hold. + * item_size - The size of each item in the queue. + * + * Returned Value: + * A pointer to the newly created queue, or NULL if the operation failed. + * + ****************************************************************************/ + +static void *wifi_create_queue_wrapper(int queue_len, int item_size) +{ + return wifi_create_queue(queue_len, item_size); +} + +/**************************************************************************** + * Name: wifi_delete_queue_wrapper + * + * Description: + * Delete Wi-Fi static message queue + * + * Input Parameters: + * queue - Wi-Fi static message queue data pointer + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void wifi_delete_queue_wrapper(void *queue) +{ + wifi_delete_queue(queue); +} + +/**************************************************************************** + * Name: set_intr_wrapper + * + * Description: + * Do nothing + * + * Input Parameters: + * cpu_no - The CPU which the interrupt number belongs. + * intr_source - The interrupt hardware source number. + * intr_num - The interrupt number CPU. + * intr_prio - The interrupt priority. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void set_intr_wrapper(int32_t cpu_no, uint32_t intr_source, + uint32_t intr_num, int32_t intr_prio) +{ + wlinfo("cpu_no=%" PRId32 ", intr_source=%" PRIu32 + ", intr_num=%" PRIu32 ", intr_prio=%" PRId32 "\n", + cpu_no, intr_source, intr_num, intr_prio); + + esp_route_intr(intr_source, intr_num, intr_prio, ESP_IRQ_TRIGGER_LEVEL); + esp_set_irq(ESP_SOURCE2IRQ(intr_source), intr_num); +} + +/**************************************************************************** + * Name: clear_intr_wrapper + * + * Description: + * This function is intended to clear a specific interrupt. However, this + * functionality is not supported in the current implementation. + * + * Input Parameters: + * intr_source - The source of the interrupt. + * intr_num - The number of the interrupt. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void IRAM_ATTR clear_intr_wrapper(uint32_t intr_source, + uint32_t intr_num) +{ +} + +/**************************************************************************** + * Name: set_isr_wrapper + * + * Description: + * Register interrupt function + * + * Input Parameters: + * n - CPU interrupt number + * f - Interrupt function + * arg - Function private data + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void set_isr_wrapper(int32_t n, void *f, void *arg) +{ + int ret; + uint32_t tmp; + struct irq_adpt *adapter; + int irq = esp_get_irq(n); + + wlinfo("n=%ld f=%p arg=%p irq=%d\n", n, f, arg, irq); + + if (g_irqvector[irq].handler && + g_irqvector[irq].handler != irq_unexpected_isr) + { + wlinfo("irq=%d has been set handler=%p\n", irq, + g_irqvector[irq].handler); + return; + } + + tmp = sizeof(struct irq_adpt); + adapter = kmm_malloc(tmp); + if (!adapter) + { + wlerr("Failed to alloc %ld memory\n", tmp); + PANIC(); + return; + } + + adapter->func = f; + adapter->arg = arg; + + ret = irq_attach(irq, esp_int_adpt_cb, adapter); + if (ret) + { + wlerr("Failed to attach IRQ %d\n", irq); + PANIC(); + return; + } +} + +/**************************************************************************** + * Name: enable_intr_wrapper + * + * Description: + * Enable a specific Wi-Fi interrupt. + * + * Input Parameters: + * intr_mask - A mask where the bit corresponding to the interrupt to be + * enabled is set. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void enable_intr_wrapper(uint32_t intr_mask) +{ + int cpuint = __builtin_ffs(intr_mask) - 1; + int irq = esp_get_irq(cpuint); + + wlinfo("intr_mask=%08lx cpuint=%d irq=%d\n", intr_mask, cpuint, irq); + + up_enable_irq(irq); +} + +/**************************************************************************** + * Name: disable_intr_wrapper + * + * Description: + * Disable a specific Wi-Fi interrupt. + * + * Input Parameters: + * intr_mask - A mask where the bit corresponding to the interrupt to be + * disabled is set. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void disable_intr_wrapper(uint32_t intr_mask) +{ + int cpuint = __builtin_ffs(intr_mask) - 1; + int irq = esp_get_irq(cpuint); + + wlinfo("intr_mask=%08lx cpuint=%d irq=%d\n", intr_mask, cpuint, irq); + + up_disable_irq(irq); +} + +/**************************************************************************** + * Name: is_from_isr_wrapper + * + * Description: + * Check current is in interrupt + * + * Input Parameters: + * None + * + * Returned Value: + * true if in interrupt or false if not + * + ****************************************************************************/ + +static bool IRAM_ATTR is_from_isr_wrapper(void) +{ + return up_interrupt_context(); +} + +/**************************************************************************** + * Name: wifi_thread_semphr_free + * + * Description: + * Delete thread self's semaphore + * + * Input Parameters: + * data - Semaphore data pointer + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void wifi_thread_semphr_free(void *data) +{ + void *sem = (void *)data; + + if (sem) + { + vsemaphore_delete_adapter(sem); + } +} + +/**************************************************************************** + * Name: wifi_thread_semphr_get_wrapper + * + * Description: + * Get thread self's semaphore + * + * Input Parameters: + * None + * + * Returned Value: + * Semaphore data pointer + * + ****************************************************************************/ + +static void *wifi_thread_semphr_get_wrapper(void) +{ + static int wifi_task_key = -1; + int ret; + void *sem; + + if (wifi_task_key < 0) + { + ret = task_tls_alloc(wifi_thread_semphr_free); + if (ret < 0) + { + wlerr("Failed to create task local key\n"); + return NULL; + } + + wifi_task_key = ret; + } + + sem = (void *)task_tls_get_value(wifi_task_key); + if (sem == NULL) + { + sem = xsemaphore_create_counting_adapter(1, 0); + if (!sem) + { + wlerr("Failed to create semaphore\n"); + return NULL; + } + + ret = task_tls_set_value(wifi_task_key, (uintptr_t)sem); + if (ret != OK) + { + wlerr("Failed to save semaphore on task local storage: %d\n", ret); + vsemaphore_delete_adapter(sem); + return NULL; + } + } + + return sem; +} + +/**************************************************************************** + * Name: recursive_mutex_create_wrapper + * + * Description: + * Create recursive mutex + * + * Input Parameters: + * None + * + * Returned Value: + * Recursive mutex data pointer + * + ****************************************************************************/ + +static void *recursive_mutex_create_wrapper(void) +{ + int ret; + pthread_mutex_t *mutex; + pthread_mutexattr_t attr; + int tmp; + + ret = pthread_mutexattr_init(&attr); + if (ret) + { + wlerr("Failed to initialize attr error=%d\n", ret); + return NULL; + } + + ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + if (ret) + { + wlerr("Failed to set attr type error=%d\n", ret); + return NULL; + } + + tmp = sizeof(pthread_mutex_t); + mutex = kmm_malloc(tmp); + if (!mutex) + { + wlerr("Failed to alloc %d memory\n", tmp); + return NULL; + } + + ret = pthread_mutex_init(mutex, &attr); + if (ret) + { + wlerr("Failed to initialize mutex error=%d\n", ret); + kmm_free(mutex); + return NULL; + } + + return mutex; +} + +/**************************************************************************** + * Name: mutex_create_wrapper + * + * Description: + * Create mutex + * + * Input Parameters: + * None + * + * Returned Value: + * Mutex data pointer + * + ****************************************************************************/ + +static void *mutex_create_wrapper(void) +{ + int ret; + pthread_mutex_t *mutex; + int tmp; + + tmp = sizeof(pthread_mutex_t); + mutex = kmm_malloc(tmp); + if (!mutex) + { + wlerr("Failed to alloc %d memory\n", tmp); + return NULL; + } + + ret = pthread_mutex_init(mutex, NULL); + if (ret) + { + wlerr("Failed to initialize mutex error=%d\n", ret); + kmm_free(mutex); + return NULL; + } + + return mutex; +} + +/**************************************************************************** + * Name: mutex_delete_wrapper + * + * Description: + * Delete mutex + * + * Input Parameters: + * mutex - mutex data pointer + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void mutex_delete_wrapper(void *mutex) +{ + pthread_mutex_t *mutex_data = (pthread_mutex_t *)mutex; + + pthread_mutex_destroy(mutex_data); + kmm_free(mutex_data); +} + +/**************************************************************************** + * Name: mutex_lock_wrapper + * + * Description: + * Lock mutex + * + * Input Parameters: + * mutex - mutex data pointer + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +static int32_t IRAM_ATTR mutex_lock_wrapper(void *mutex) +{ + int ret; + pthread_mutex_t *mutex_data = (pthread_mutex_t *)mutex; + + ret = pthread_mutex_lock(mutex_data); + if (ret) + { + wlerr("Failed to lock mutex error=%d\n", ret); + } + + return nuttx_err_to_freertos(ret); +} + +/**************************************************************************** + * Name: mutex_unlock_wrapper + * + * Description: + * Unlock mutex + * + * Input Parameters: + * mutex - mutex data pointer + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +static int32_t IRAM_ATTR mutex_unlock_wrapper(void *mutex) +{ + int ret; + pthread_mutex_t *mutex_data = (pthread_mutex_t *)mutex; + + ret = pthread_mutex_unlock(mutex_data); + if (ret) + { + wlerr("Failed to unlock mutex error=%d\n", ret); + } + + return nuttx_err_to_freertos(ret); +} + +/**************************************************************************** + * Name: queue_create_wrapper + * + * Description: + * This function creates a new queue adapter with the specified length and + * item size. It is a wrapper around the xqueue_create_adapter function. + * + * Input Parameters: + * queue_len - The maximum number of items that the queue can hold. + * item_size - The size of each item in the queue. + * + * Returned Value: + * A pointer to the newly created queue adapter, or NULL if the operation + * failed. + * + ****************************************************************************/ + +static void *queue_create_wrapper(uint32_t queue_len, uint32_t item_size) +{ + return xqueue_create_adapter(queue_len, item_size); +} + +/**************************************************************************** + * Name: queue_send_wrapper + * + * Description: + * Send message of low priority to queue within a certain period of time + * + * Input Parameters: + * queue - Message queue data pointer + * item - Message data pointer + * ticks - Wait ticks + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +static int32_t queue_send_wrapper(void *queue, void *item, uint32_t ticks) +{ + return xqueue_send_adapter(queue, item, ticks, 0); +} + +/**************************************************************************** + * Name: queue_send_from_isr_wrapper + * + * Description: + * Send message of low priority to queue in ISR within + * a certain period of time + * + * Input Parameters: + * queue - Message queue data pointer + * item - Message data pointer + * hptw - Unused. + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +static int32_t IRAM_ATTR queue_send_from_isr_wrapper(void *queue, + void *item, + void *hptw) +{ + *(int *)hptw = 0; + + return xqueue_send_adapter(queue, item, 0, 0); +} + +/**************************************************************************** + * Name: queue_send_to_back_wrapper + * + * Description: + * Send message of low priority to queue within a certain period of time + * + * Input Parameters: + * queue - Message queue data pointer + * item - Message data pointer + * ticks - Wait ticks + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +static int32_t queue_send_to_back_wrapper(void *queue, + void *item, + uint32_t ticks) +{ + return xqueue_send_adapter(queue, item, ticks, 0); +} + +/**************************************************************************** + * Name: queue_send_to_front_wrapper + * + * Description: + * Send message of high priority to queue within a certain period of time + * + * Input Parameters: + * queue - Message queue data pointer + * item - Message data pointer + * ticks - Wait ticks + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +static int32_t queue_send_to_front_wrapper(void *queue, + void *item, + uint32_t ticks) +{ + return xqueue_send_adapter(queue, item, ticks, 1); +} + +/**************************************************************************** + * Name: queue_recv_wrapper + * + * Description: + * Receive message from queue within a certain period of time + * + * Input Parameters: + * queue - Message queue data pointer + * item - Message data pointer + * ticks - Wait ticks + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +static int32_t queue_recv_wrapper(void *queue, void *item, uint32_t ticks) +{ + ssize_t ret; + struct timespec timeout; + unsigned int prio; + struct mq_adpt *mq_adpt = (struct mq_adpt *)queue; + + if (ticks == OSI_FUNCS_TIME_BLOCKING) + { + ret = file_mq_receive(&mq_adpt->mq, (char *)item, + mq_adpt->msgsize, &prio); + if (ret < 0) + { + wlerr("Failed to receive from mqueue error=%d\n", ret); + } + } + else + { + ret = clock_gettime(CLOCK_REALTIME, &timeout); + if (ret < 0) + { + wlerr("Failed to get time\n"); + return false; + } + + if (ticks) + { + esp_update_time(&timeout, ticks); + } + + ret = file_mq_timedreceive(&mq_adpt->mq, (char *)item, + mq_adpt->msgsize, &prio, &timeout); + if (ret < 0) + { + wlerr("Failed to timedreceive from mqueue error=%d\n", + ret); + } + } + + return ret > 0 ? true : false; +} + +/**************************************************************************** + * Name: event_group_wait_bits_wrapper + * + * Description: + * Don't support + * + ****************************************************************************/ + +static uint32_t event_group_wait_bits_wrapper(void *event, + uint32_t bits_to_wait_for, + int clear_on_exit, + int wait_for_all_bits, + uint32_t block_time_tick) +{ + DEBUGPANIC(); + + return false; +} + +/**************************************************************************** + * Name: task_create_pinned_to_core_wrapper + * + * Description: + * Create task and bind it to target CPU, the task will run when it + * is created + * + * Input Parameters: + * entry - Task entry + * name - Task name + * stack_depth - Task stack size + * param - Task private data + * prio - Task priority + * task_handle - Task handle pointer which is used to pause, resume + * and delete the task + * core_id - CPU which the task runs in + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +static int32_t task_create_pinned_to_core_wrapper(void *entry, + const char *name, + uint32_t stack_depth, + void *param, + uint32_t prio, + void *task_handle, + uint32_t core_id) +{ + int pid; +#ifdef CONFIG_SMP + int ret; + cpu_set_t cpuset; +#endif + uint32_t target_prio = prio; + + if (target_prio < ESP_MAX_PRIORITIES) + { + target_prio += task_get_max_priority_wrapper() - ESP_MAX_PRIORITIES; + } + + pid = kthread_create(name, target_prio, stack_depth, entry, + (char * const *)param); + if (pid > 0) + { + if (task_handle != NULL) + { + *((int *)task_handle) = pid; + } + +#ifdef CONFIG_SMP + if (core_id < CONFIG_SMP_NCPUS) + { + CPU_ZERO(&cpuset); + CPU_SET(core_id, &cpuset); + ret = nxsched_set_affinity(pid, sizeof(cpuset), &cpuset); + if (ret) + { + wlerr("Failed to set affinity error=%d\n", ret); + return false; + } + } +#endif + } + else + { + wlerr("Failed to create task\n"); + } + + return pid > 0; +} + +/**************************************************************************** + * Name: task_create_wrapper + * + * Description: + * Create task and the task will run when it is created + * + * Input Parameters: + * entry - Task entry + * name - Task name + * stack_depth - Task stack size + * param - Task private data + * prio - Task priority + * task_handle - Task handle pointer which is used to pause, resume + * and delete the task + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +static int32_t task_create_wrapper(void *entry, + const char *name, + uint32_t stack_depth, + void *param, + uint32_t prio, + void *task_handle) +{ + return task_create_pinned_to_core_wrapper(entry, + name, + stack_depth, + param, + prio, + task_handle, + UINT32_MAX); +} + +/**************************************************************************** + * Name: task_ms_to_tick_wrapper + * + * Description: + * This function converts a duration from milliseconds to system ticks. + * It is a wrapper around the NuttX MSEC2TICK macro. + * + * Input Parameters: + * ms - The duration in milliseconds. + * + * Returned Value: + * The duration in system ticks. + * + ****************************************************************************/ + +static int32_t task_ms_to_tick_wrapper(uint32_t ms) +{ + return MSEC2TICK(ms); +} + +/**************************************************************************** + * Name: task_get_max_priority_wrapper + * + * Description: + * Get OS task maximum priority + * + * Input Parameters: + * None + * + * Returned Value: + * Task maximum priority + * + ****************************************************************************/ + +static int32_t task_get_max_priority_wrapper(void) +{ + return SCHED_PRIORITY_MAX; +} + +/**************************************************************************** + * Name: esp_event_post_wrapper + * + * Description: + * Active work queue and let the work to process the cached event + * + * Input Parameters: + * event_base - Event set name + * event_id - Event ID + * event_data - Event private data + * event_data_size - Event data size + * ticks - Waiting system ticks + * + * Returned Value: + * 0 if success or -1 if fail + * + ****************************************************************************/ + +int32_t esp_event_post_wrapper(const char *event_base, + int32_t event_id, + void *event_data, + size_t event_data_size, + uint32_t ticks) +{ + size_t size; + int32_t id; + irqstate_t flags; + struct evt_adpt *evt_adpt; + + wlinfo("Event: base=%s id=%ld data=%p data_size=%d ticks=%lu\n", + event_base, event_id, event_data, event_data_size, ticks); + + id = esp_event_id_map(event_id); + if (id < 0) + { + wlinfo("No process event %ld\n", event_id); + return -1; + } + + size = event_data_size + sizeof(struct evt_adpt); + evt_adpt = kmm_malloc(size); + if (!evt_adpt) + { + wlerr("Failed to alloc %d memory\n", size); + return -1; + } + + evt_adpt->id = id; + memcpy(evt_adpt->buf, event_data, event_data_size); + + flags = spin_lock_irqsave(&g_lock); + sq_addlast(&evt_adpt->entry, &g_wifi_evt_queue); + spin_unlock_irqrestore(&g_lock, flags); + + work_queue(LPWORK, &g_wifi_evt_work, esp_evt_work_cb, NULL, 0); + + return 0; +} + +/**************************************************************************** + * Name: wifi_apb80m_request_wrapper + * + * Description: + * This function acquires the Wi-Fi lock in auto-sleep mode. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void IRAM_ATTR wifi_apb80m_request_wrapper(void) +{ +#ifdef CONFIG_PM + wifi_apb80m_request(); +#endif +} + +/**************************************************************************** + * Name: wifi_apb80m_release_wrapper + * + * Description: + * This function releases the Wi-Fi lock in auto-sleep mode. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void IRAM_ATTR wifi_apb80m_release_wrapper(void) +{ +#ifdef CONFIG_PM + wifi_apb80m_release(); +#endif +} + +/**************************************************************************** + * Name: timer_arm_wrapper + * + * Description: + * Set timer timeout period and repeat flag + * + * Input Parameters: + * ptimer - timer data pointer + * ms - millim seconds + * repeat - true: run cycle, false: run once + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void IRAM_ATTR timer_arm_wrapper(void *ptimer, + uint32_t tmout, + bool repeat) +{ + ets_timer_arm(ptimer, tmout, repeat); +} + +/**************************************************************************** + * Name: wifi_reset_mac_wrapper + * + * Description: + * Reset Wi-Fi hardware MAC + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void wifi_reset_mac_wrapper(void) +{ + periph_module_reset(PERIPH_WIFI_MODULE); +} + +/**************************************************************************** + * Name: wifi_rtc_enable_iso_wrapper + * + * Description: + * This function is a wrapper for enabling the isolation of the Wi-Fi + * Real-Time Clock (RTC). If the MAC/BB power down configuration option + * is set, it powers down the MAC/BB. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void IRAM_ATTR wifi_rtc_enable_iso_wrapper(void) +{ +#if CONFIG_MAC_BB_PD + esp_mac_bb_power_down(); +#endif +} + +/**************************************************************************** + * Name: wifi_rtc_disable_iso_wrapper + * + * Description: + * This function is a wrapper for disabling the isolation of the Wi-Fi + * Real-Time Clock (RTC). If the MAC/BB power down configuration option + * is set, it powers up the MAC/BB. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void IRAM_ATTR wifi_rtc_disable_iso_wrapper(void) +{ +#if CONFIG_MAC_BB_PD + esp_mac_bb_power_up(); +#endif +} + +/**************************************************************************** + * Name: wifi_clock_enable_wrapper + * + * Description: + * Enable Wi-Fi clock + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void wifi_clock_enable_wrapper(void) +{ + wifi_module_enable(); +} + +/**************************************************************************** + * Name: wifi_clock_disable_wrapper + * + * Description: + * Disable Wi-Fi clock + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void wifi_clock_disable_wrapper(void) +{ + wifi_module_disable(); +} + +/**************************************************************************** + * Name: get_time_wrapper + * + * Description: + * Get std C time + * + * Input Parameters: + * t - buffer to store time of type timeval + * + * Returned Value: + * Zero (OK) on success; -1 is returned on failure with the errno variable + * set appropriately. + * + ****************************************************************************/ + +static int get_time_wrapper(void *t) +{ + return os_get_time(t); +} + +/**************************************************************************** + * Name: realloc_internal_wrapper + * + * Description: + * Drivers allocate a block of memory by old memory block + * + * Input Parameters: + * ptr - old memory pointer + * size - memory size + * + * Returned Value: + * New memory pointer + * + ****************************************************************************/ + +static IRAM_ATTR void *realloc_internal_wrapper(void *ptr, size_t size) +{ + return kmm_realloc(ptr, size); +} + +/**************************************************************************** + * Name: calloc_internal_wrapper + * + * Description: + * Drivers allocate some continuous blocks of memory + * + * Input Parameters: + * n - memory block number + * size - memory block size + * + * Returned Value: + * New memory pointer + * + ****************************************************************************/ + +static IRAM_ATTR void *calloc_internal_wrapper(size_t n, size_t size) +{ + return kmm_calloc(n, size); +} + +/**************************************************************************** + * Name: zalloc_internal_wrapper + * + * Description: + * Drivers allocate a block of memory and clear it with 0 + * + * Input Parameters: + * size - memory size + * + * Returned Value: + * New memory pointer + * + ****************************************************************************/ + +static IRAM_ATTR void *zalloc_internal_wrapper(size_t size) +{ + return kmm_zalloc(size); +} + +/**************************************************************************** + * Name: nvs_open_wrapper + * + * Description: + * Create a file system storage data object + * + * Input Parameters: + * name - Storage index + * open_mode - Storage mode + * out_handle - Storage handle + * + * Returned Value: + * 0 if success or -1 if fail + * + ****************************************************************************/ + +static int nvs_open_wrapper(const char *name, + unsigned int open_mode, + uint32_t *out_handle) +{ + DEBUGPANIC(); + + return -1; +} + +/**************************************************************************** + * Name: esp_log_writev_wrapper + * + * Description: + * Output log with by format string and its arguments + * + * Input Parameters: + * level - log level, no mean here + * tag - log TAG, no mean here + * format - format string + * args - arguments list + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void esp_log_writev_wrapper(unsigned int level, + const char *tag, + const char *format, + va_list args) +{ + esp_log_level_t max_level; + +#if defined (CONFIG_DEBUG_WIRELESS_INFO) + max_level = ESP_LOG_VERBOSE; +#elif defined (CONFIG_DEBUG_WIRELESS_WARN) + max_level = ESP_LOG_WARN; +#elif defined (CONFIG_DEBUG_WIRELESS_ERROR) + max_level = ESP_LOG_ERROR; +#else + max_level = ESP_LOG_NONE; +#endif + + if (level <= max_level) + { + esp_log_writev(level, tag, format, args); + } +} + +/**************************************************************************** + * Name: esp_log_write_wrapper + * + * Description: + * Output log with by format string and its arguments + * + * Input Parameters: + * level - log level, no mean here + * tag - log TAG, no mean here + * format - format string + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void esp_log_write_wrapper(unsigned int level, + const char *tag, + const char *format, ...) +{ + esp_log_level_t max_level; + +#if defined (CONFIG_DEBUG_WIRELESS_INFO) + max_level = ESP_LOG_VERBOSE; +#elif defined (CONFIG_DEBUG_WIRELESS_WARN) + max_level = ESP_LOG_WARN; +#elif defined (CONFIG_DEBUG_WIRELESS_ERROR) + max_level = ESP_LOG_ERROR; +#else + max_level = ESP_LOG_NONE; +#endif + + if (level <= max_level) + { + va_list list; + va_start(list, format); + esp_log_writev(level, tag, format, list); + va_end(list); + } +} + +/**************************************************************************** + * Name: esp_read_mac_wrapper + * + * Description: + * Read MAC address from efuse + * + * Input Parameters: + * mac - MAC address buffer pointer + * type - MAC address type + * + * Returned Value: + * 0 if success or -1 if fail + * + ****************************************************************************/ + +static int esp_read_mac_wrapper(uint8_t *mac, unsigned int type) +{ + return esp_read_mac(mac, type); +} + +/**************************************************************************** + * Name: coex_init_wrapper + * + * Description: + * Init software coexist + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. + * + ****************************************************************************/ + +static int coex_init_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + return coex_init(); +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: coex_deinit_wrapper + * + * Description: + * De-init software coexist + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void coex_deinit_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + coex_deinit(); +#endif +} + +/**************************************************************************** + * Name: coex_enable_wrapper + * + * Description: + * Enable software coexist + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. + * + ****************************************************************************/ + +static int coex_enable_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + return coex_enable(); +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: coex_disable_wrapper + * + * Description: + * Disable software coexist + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void coex_disable_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + coex_disable(); +#endif +} + +/**************************************************************************** + * Name: coex_status_get_wrapper + * + * Description: + * Get software coexist status. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. + * + ****************************************************************************/ + +static IRAM_ATTR uint32_t coex_status_get_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + return coex_status_get(); +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: coex_wifi_request_wrapper + * + * Description: + * Request Wi-Fi coexistence. + * + * Input Parameters: + * event - WiFi event + * latency - WiFi will request coexistence after latency + * duration - duration for WiFi to request coexistence + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. + * + ****************************************************************************/ + +static int coex_wifi_request_wrapper(uint32_t event, + uint32_t latency, + uint32_t duration) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + return coex_wifi_request(event, latency, duration); +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: coex_wifi_release_wrapper + * + * Description: + * Release Wi-Fi coexistence. + * + * Input Parameters: + * event - WiFi event + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. + * + ****************************************************************************/ + +static IRAM_ATTR int coex_wifi_release_wrapper(uint32_t event) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + return coex_wifi_release(event); +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: coex_wifi_channel_set_wrapper + * + * Description: + * Set Wi-Fi channel to coexistence module. + * + * Input Parameters: + * primary - WiFi primary channel + * secondary - WiFi secondary channel + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. + * + ****************************************************************************/ + +static int coex_wifi_channel_set_wrapper(uint8_t primary, uint8_t secondary) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + return coex_wifi_channel_set(primary, secondary); +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: coex_event_duration_get_wrapper + * + * Description: + * Get coexistence event duration. + * + * Input Parameters: + * event - Coexistence event + * duration - Coexistence event duration + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. + * + ****************************************************************************/ + +static IRAM_ATTR int coex_event_duration_get_wrapper(uint32_t event, + uint32_t *duration) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + return coex_event_duration_get(event, duration); +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: coex_pti_get_wrapper + * + * Description: + * Get coexistence event priority. + * + * Input Parameters: + * event - Coexistence event + * pti - Coexistence event priority + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. + * + ****************************************************************************/ + +static int coex_pti_get_wrapper(uint32_t event, uint8_t *pti) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + return coex_pti_get(event, pti); +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: coex_schm_status_bit_clear_wrapper + * + * Description: + * Clear coexistence status. + * + * Input Parameters: + * type - Coexistence status type + * status - Coexistence status + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void coex_schm_status_bit_clear_wrapper(uint32_t type, + uint32_t status) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + coex_schm_status_bit_clear(type, status); +#endif +} + +/**************************************************************************** + * Name: coex_schm_status_bit_set_wrapper + * + * Description: + * Set coexistence status. + * + * Input Parameters: + * type - Coexistence status type + * status - Coexistence status + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void coex_schm_status_bit_set_wrapper(uint32_t type, uint32_t status) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + coex_schm_status_bit_set(type, status); +#endif +} + +/**************************************************************************** + * Name: coex_schm_interval_set_wrapper + * + * Description: + * Set coexistence scheme interval. + * + * Input Parameters: + * interval - Coexistence scheme interval + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. + * + ****************************************************************************/ + +static IRAM_ATTR int coex_schm_interval_set_wrapper(uint32_t interval) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + return coex_schm_interval_set(interval); +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: coex_schm_interval_get_wrapper + * + * Description: + * Get coexistence scheme interval. + * + * Input Parameters: + * None + * + * Returned Value: + * Coexistence scheme interval + * + ****************************************************************************/ + +static uint32_t coex_schm_interval_get_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + return coex_schm_interval_get(); +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: coex_schm_curr_period_get_wrapper + * + * Description: + * Get current coexistence scheme period. + * + * Input Parameters: + * None + * + * Returned Value: + * Coexistence scheme period + * + ****************************************************************************/ + +static uint8_t coex_schm_curr_period_get_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + return coex_schm_curr_period_get(); +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: coex_schm_curr_phase_get_wrapper + * + * Description: + * Get current coexistence scheme phase. + * + * Input Parameters: + * None + * + * Returned Value: + * Coexistence scheme phase + * + ****************************************************************************/ + +static void *coex_schm_curr_phase_get_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + return coex_schm_curr_phase_get(); +#else + return NULL; +#endif +} + +/**************************************************************************** + * Name: coex_register_start_cb_wrapper + * + * Description: + * Register Wi-Fi callback for coexistence starts. + * + * Input Parameters: + * cb - WiFi callback + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. + * + ****************************************************************************/ + +static int coex_register_start_cb_wrapper(int (* cb)(void)) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_register_start_cb(cb); +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: coex_schm_process_restart_wrapper + * + * Description: + * Restart current coexistence scheme. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. + * + ****************************************************************************/ + +static int coex_schm_process_restart_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_schm_process_restart(); +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: coex_schm_register_cb_wrapper + * + * Description: + * Register callback for coexistence scheme. + * + * Input Parameters: + * type - callback type + * cb - callback + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. + * + ****************************************************************************/ + +static int coex_schm_register_cb_wrapper(int type, int(*cb)(int)) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_schm_register_callback(type, cb); +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: esp_empty_wrapper + * + * Description: + * This function is an empty wrapper, designed to be used where a function + * pointer is required but no operation is needed. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void IRAM_ATTR esp_empty_wrapper(void) +{ +} + +/* Second block of functions + * These functions are auxiliary functions that are used by the first block + * of functions or software adapters for the Wi-Fi driver + */ + +/**************************************************************************** + * Name: esp_event_id_map + * + * Description: + * Transform from esp-idf event ID to Wi-Fi adapter event ID + * + * Input Parameters: + * event_id - esp-idf event ID + * + * Returned Value: + * Wi-Fi adapter event ID + * + ****************************************************************************/ + +static int esp_event_id_map(int event_id) +{ + int id; + + switch (event_id) + { + case WIFI_EVENT_SCAN_DONE: + id = WIFI_ADPT_EVT_SCAN_DONE; + break; + +#ifdef ESP_WLAN_HAS_STA + case WIFI_EVENT_STA_START: + id = WIFI_ADPT_EVT_STA_START; + break; + + case WIFI_EVENT_STA_CONNECTED: + id = WIFI_ADPT_EVT_STA_CONNECT; + break; + + case WIFI_EVENT_STA_DISCONNECTED: + id = WIFI_ADPT_EVT_STA_DISCONNECT; + break; + + case WIFI_EVENT_STA_AUTHMODE_CHANGE: + id = WIFI_ADPT_EVT_STA_AUTHMODE_CHANGE; + break; + + case WIFI_EVENT_STA_STOP: + id = WIFI_ADPT_EVT_STA_STOP; + break; +#endif /* ESP_WLAN_HAS_STA */ + +#ifdef ESP_WLAN_HAS_SOFTAP + case WIFI_EVENT_AP_START: + id = WIFI_ADPT_EVT_AP_START; + break; + + case WIFI_EVENT_AP_STOP: + id = WIFI_ADPT_EVT_AP_STOP; + break; + + case WIFI_EVENT_AP_STACONNECTED: + id = WIFI_ADPT_EVT_AP_STACONNECTED; + break; + + case WIFI_EVENT_AP_STADISCONNECTED: + id = WIFI_ADPT_EVT_AP_STADISCONNECTED; + break; +#endif /* ESP_WLAN_HAS_SOFTAP */ + + default: + return -1; + } + + return id; +} + +/**************************************************************************** + * Name: esp_evt_work_cb + * + * Description: + * Process the cached event + * + * Input Parameters: + * arg - No mean + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void esp_evt_work_cb(void *arg) +{ + int ret; + irqstate_t flags; + struct evt_adpt *evt_adpt; + struct wifi_notify *notify; + wifi_ps_type_t ps_type = DEFAULT_PS_MODE; + + while (1) + { + flags = spin_lock_irqsave(&g_lock); + evt_adpt = (struct evt_adpt *)sq_remfirst(&g_wifi_evt_queue); + spin_unlock_irqrestore(&g_lock, flags); + if (!evt_adpt) + { + break; + } + + esp_wifi_lock(true); + + switch (evt_adpt->id) + { + case WIFI_ADPT_EVT_SCAN_DONE: + esp_wifi_scan_event_parse(); + break; + +#ifdef ESP_WLAN_HAS_STA + case WIFI_ADPT_EVT_STA_START: + wlinfo("Wi-Fi sta start\n"); + + g_sta_connected = false; + + ret = esp_wifi_set_ps(ps_type); + if (ret) + { + wlerr("Failed to set power save type\n"); + break; + } + else + { + wlinfo("INFO: Set ps type=%d\n", ps_type); + } + + ret = esp_wifi_get_config(WIFI_IF_STA, &g_sta_wifi_cfg); + if (ret) + { + wlerr("Failed to get Wi-Fi config data ret=%d\n", ret); + } + break; + + case WIFI_ADPT_EVT_STA_CONNECT: + wlinfo("Wi-Fi sta connect\n"); + g_sta_connected = true; + ret = esp_wlan_sta_set_linkstatus(true); + if (ret < 0) + { + wlerr("ERROR: Failed to set Wi-Fi station link status\n"); + } + + break; + + case WIFI_ADPT_EVT_STA_DISCONNECT: + wlinfo("Wi-Fi sta disconnect\n"); + g_sta_connected = false; + ret = esp_wlan_sta_set_linkstatus(false); + if (ret < 0) + { + wlerr("ERROR: Failed to set Wi-Fi station link status\n"); + } + + if (g_sta_reconnect) + { + ret = esp_wifi_connect(); + if (ret) + { + wlerr("Failed to connect AP error=%d\n", ret); + } + } + break; + + case WIFI_ADPT_EVT_STA_STOP: + wlinfo("Wi-Fi sta stop\n"); + g_sta_connected = false; + break; +#endif /* ESP_WLAN_HAS_STA */ + +#ifdef ESP_WLAN_HAS_SOFTAP + case WIFI_ADPT_EVT_AP_START: + wlinfo("INFO: Wi-Fi softap start\n"); + + ret = esp_wifi_set_ps(ps_type); + if (ret) + { + wlerr("Failed to set power save type\n"); + break; + } + else + { + wlinfo("INFO: Set ps type=%d\n", ps_type); + } + + ret = esp_wifi_get_config(WIFI_IF_AP, &g_softap_wifi_cfg); + if (ret) + { + wlerr("Failed to get Wi-Fi config data ret=%d\n", ret); + } + break; + + case WIFI_ADPT_EVT_AP_STOP: + wlinfo("INFO: Wi-Fi softap stop\n"); + break; + + case WIFI_ADPT_EVT_AP_STACONNECTED: + wlinfo("INFO: Wi-Fi station join\n"); + break; + + case WIFI_ADPT_EVT_AP_STADISCONNECTED: + wlinfo("INFO: Wi-Fi station leave\n"); + break; +#endif /* ESP_WLAN_HAS_SOFTAP */ + default: + break; + } + + notify = &g_wifi_notify[evt_adpt->id]; + if (notify->assigned) + { + notify->event.sigev_value.sival_ptr = evt_adpt->buf; + + ret = nxsig_notification(notify->pid, ¬ify->event, + SI_QUEUE, ¬ify->work); + if (ret < 0) + { + wlwarn("nxsig_notification event ID=%ld failed: %d\n", + evt_adpt->id, ret); + } + } + + esp_wifi_lock(false); + + kmm_free(evt_adpt); + } +} + +/**************************************************************************** + * Name: esp_freq_to_channel + * + * Description: + * Converts Wi-Fi frequency to channel. + * + * Input Parameters: + * freq - Wi-Fi frequency + * + * Returned Value: + * Wi-Fi channel + * + ****************************************************************************/ + +static int esp_freq_to_channel(uint16_t freq) +{ + int channel = 0; + if (freq >= 2412 && freq <= 2484) + { + if (freq == 2484) + { + channel = 14; + } + else + { + channel = freq - 2407; + if (channel % 5) + { + return 0; + } + + channel /= 5; + } + + return channel; + } + + if (freq >= 5005 && freq < 5900) + { + if (freq % 5) + { + return 0; + } + + channel = (freq - 5000) / 5; + return channel; + } + + if (freq >= 4905 && freq < 5000) + { + if (freq % 5) + { + return 0; + } + + channel = (freq - 4000) / 5; + return channel; + } + + return 0; +} + +/**************************************************************************** + * Name: esp_get_free_heap_size + * + * Description: + * Get free heap size by byte + * + * Input Parameters: + * None + * + * Returned Value: + * Free heap size + * + ****************************************************************************/ + +static uint32_t esp_get_free_heap_size(void) +{ + struct mallinfo info; + + info = kmm_mallinfo(); + return info.fordblks; +} + +/**************************************************************************** + * Name: event_group_create_wrapper + * + * Description: + * Don't support + * + ****************************************************************************/ + +static void *event_group_create_wrapper(void) +{ + DEBUGPANIC(); + + return NULL; +} + +/**************************************************************************** + * Name: event_group_delete_wrapper + * + * Description: + * Don't support + * + ****************************************************************************/ + +static void event_group_delete_wrapper(void *event) +{ + DEBUGPANIC(); +} + +/**************************************************************************** + * Name: event_group_set_bits_wrapper + * + * Description: + * Don't support + * + ****************************************************************************/ + +static uint32_t event_group_set_bits_wrapper(void *event, uint32_t bits) +{ + DEBUGPANIC(); + + return false; +} + +/**************************************************************************** + * Name: event_group_clear_bits_wrapper + * + * Description: + * Don't support + * + ****************************************************************************/ + +static uint32_t event_group_clear_bits_wrapper(void *event, uint32_t bits) +{ + DEBUGPANIC(); + + return false; +} + +/**************************************************************************** + * Name: esp_int_adpt_cb + * + * Description: + * This is the callback function for the Wi-Fi interrupt adapter. It + * retrieves the adapter from the argument, then calls the function + * stored in the adapter with its argument. + * + * Input Parameters: + * irq - The IRQ number that caused this interrupt. + * context - The register context at the time of the interrupt. + * arg - A pointer to the interrupt adapter's private data. + * + * Returned Value: + * Always returns 0. + * + ****************************************************************************/ + +static int esp_int_adpt_cb(int irq, void *context, void *arg) +{ + struct irq_adpt *adapter = (struct irq_adpt *)arg; + + adapter->func(adapter->arg); + + return 0; +} + +/**************************************************************************** + * Name: esp_nvs_commit + * + * Description: + * This function has no practical effect + * + ****************************************************************************/ + +static int esp_nvs_commit(uint32_t handle) +{ + return 0; +} + +/**************************************************************************** + * Name: esp_nvs_erase_key + * + * Description: + * Read a block of data from file system + * + * Input Parameters: + * handle - NVS handle + * key - Data index + * + * Returned Value: + * 0 if success or -1 if fail + * + ****************************************************************************/ + +static int esp_nvs_erase_key(uint32_t handle, const char *key) +{ + DEBUGPANIC(); + + return -1; +} + +/**************************************************************************** + * Name: esp_nvs_get_blob + * + * Description: + * Read a block of data from file system + * + * Input Parameters: + * handle - NVS handle + * key - Data index + * out_value - Read buffer pointer + * length - Buffer length + * + * Returned Value: + * 0 if success or -1 if fail + * + ****************************************************************************/ + +static int esp_nvs_get_blob(uint32_t handle, + const char *key, + void *out_value, + size_t *length) +{ + DEBUGPANIC(); + + return -1; +} + +/**************************************************************************** + * Name: esp_nvs_set_blob + * + * Description: + * Save a block of data into file system + * + * Input Parameters: + * handle - NVS handle + * key - Data index + * value - Stored buffer pointer + * length - Buffer length + * + * Returned Value: + * 0 if success or -1 if fail + * + ****************************************************************************/ + +static int esp_nvs_set_blob(uint32_t handle, + const char *key, + const void *value, + size_t length) +{ + DEBUGPANIC(); + + return -1; +} + +/**************************************************************************** + * Name: esp_nvs_get_i8 + * + * Description: + * Read data of type int8_t from file system + * + * Input Parameters: + * handle - NVS handle + * key - Data index + * out_value - Read buffer pointer + * + * Returned Value: + * 0 if success or -1 if fail + * + ****************************************************************************/ + +static int esp_nvs_get_i8(uint32_t handle, + const char *key, + int8_t *out_value) +{ + DEBUGPANIC(); + + return -1; +} + +/**************************************************************************** + * Name: esp_nvs_set_i8 + * + * Description: + * Save data of type int8_t into file system + * + * Input Parameters: + * handle - NVS handle + * key - Data index + * value - Stored data + * + * Returned Value: + * 0 if success or -1 if fail + * + ****************************************************************************/ + +static int esp_nvs_set_i8(uint32_t handle, + const char *key, + int8_t value) +{ + DEBUGPANIC(); + + return -1; +} + +/**************************************************************************** + * Name: esp_nvs_get_u8 + * + * Description: + * Read data of type uint8_t from file system + * + * Input Parameters: + * handle - NVS handle + * key - Data index + * out_value - Read buffer pointer + * + * Returned Value: + * 0 if success or -1 if fail + * + ****************************************************************************/ + +static int esp_nvs_get_u8(uint32_t handle, + const char *key, + uint8_t *out_value) +{ + DEBUGPANIC(); + + return -1; +} + +/**************************************************************************** + * Name: esp_nvs_set_u8 + * + * Description: + * Save data of type uint8_t into file system + * + * Input Parameters: + * handle - NVS handle + * key - Data index + * value - Stored data + * + * Returned Value: + * 0 if success or -1 if fail + * + ****************************************************************************/ + +static int esp_nvs_set_u8(uint32_t handle, + const char *key, + uint8_t value) +{ + DEBUGPANIC(); + + return -1; +} + +/**************************************************************************** + * Name: esp_nvs_get_u16 + * + * Description: + * Read data of type uint16_t from file system + * + * Input Parameters: + * handle - NVS handle + * key - Data index + * out_value - Read buffer pointer + * + * Returned Value: + * 0 if success or -1 if fail + * + ****************************************************************************/ + +static int esp_nvs_get_u16(uint32_t handle, + const char *key, + uint16_t *out_value) +{ + DEBUGPANIC(); + + return -1; +} + +/**************************************************************************** + * Name: esp_nvs_set_u16 + * + * Description: + * Save data of type uint16_t into file system + * + * Input Parameters: + * handle - NVS handle + * key - Data index + * value - Stored data + * + * Returned Value: + * 0 if success or -1 if fail + * + ****************************************************************************/ + +static int esp_nvs_set_u16(uint32_t handle, + const char *key, + uint16_t value) +{ + DEBUGPANIC(); + + return -1; +} + +/**************************************************************************** + * Name: esp_nvs_close + * + * Description: + * Close storage data object and free resource + * + * Input Parameters: + * handle - NVS handle + * + * Returned Value: + * 0 if success or -1 if fail + * + ****************************************************************************/ + +static void esp_nvs_close(uint32_t handle) +{ + DEBUGPANIC(); +} + +/**************************************************************************** + * Name: esp_update_time + * + * Description: + * Transform ticks to time and add this time to timespec value + * + * Input Parameters: + * timespec - Input timespec data pointer + * ticks - System ticks + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void esp_update_time(struct timespec *timespec, uint32_t ticks) +{ + uint32_t tmp; + + tmp = TICK2SEC(ticks); + timespec->tv_sec += tmp; + + ticks -= SEC2TICK(tmp); + tmp = TICK2NSEC(ticks); + + timespec->tv_nsec += tmp; +} + +#ifdef ESP_WLAN_HAS_STA + +/**************************************************************************** + * Name: esp_wifi_auth_trans + * + * Description: + * Converts an ESP32-C3 authenticate mode values to WEXT authenticate mode. + * + * Input Parameters: + * wifi_auth - ESP32-C3 authenticate mode + * + * Returned Value: + * authenticate mode + * + ****************************************************************************/ + +static int esp_wifi_auth_trans(uint32_t wifi_auth) +{ + int auth_mode = IW_AUTH_WPA_VERSION_DISABLED; + + switch (wifi_auth) + { + case WIFI_AUTH_OPEN: + auth_mode = IW_AUTH_WPA_VERSION_DISABLED; + break; + + case WIFI_AUTH_WPA_PSK: + auth_mode = IW_AUTH_WPA_VERSION_WPA; + break; + + case WIFI_AUTH_WPA2_PSK: + case WIFI_AUTH_WPA_WPA2_PSK: + auth_mode = IW_AUTH_WPA_VERSION_WPA2; + break; + + case WIFI_AUTH_WPA3_PSK: + case WIFI_AUTH_WPA2_WPA3_PSK: + auth_mode = IW_AUTH_WPA_VERSION_WPA3; + break; + + default: + wlerr("Failed to transfer wireless authmode: %ld", wifi_auth); + break; + } + + return auth_mode; +} + +/**************************************************************************** + * Name: esp_wifi_cipher_trans + * + * Description: + * Converts a ESP32-C3 cipher type values to WEXT cipher type values. + * + * Input Parameters: + * wifi_cipher - ESP32-C3 cipher type + * + * Returned Value: + * cipher type + * + ****************************************************************************/ + +static int esp_wifi_cipher_trans(uint32_t wifi_cipher) +{ + int cipher_mode = IW_AUTH_CIPHER_NONE; + + switch (wifi_cipher) + { + case WIFI_CIPHER_TYPE_NONE: + cipher_mode = IW_AUTH_CIPHER_NONE; + break; + + case WIFI_CIPHER_TYPE_WEP40: + cipher_mode = IW_AUTH_CIPHER_WEP40; + break; + + case WIFI_CIPHER_TYPE_WEP104: + cipher_mode = IW_AUTH_CIPHER_WEP104; + break; + + case WIFI_CIPHER_TYPE_TKIP: + cipher_mode = IW_AUTH_CIPHER_TKIP; + break; + + case WIFI_CIPHER_TYPE_CCMP: + case WIFI_CIPHER_TYPE_TKIP_CCMP: + cipher_mode = IW_AUTH_CIPHER_CCMP; + break; + + case WIFI_CIPHER_TYPE_AES_CMAC128: + cipher_mode = IW_AUTH_CIPHER_AES_CMAC; + break; + + default: + wlerr("Failed to transfer wireless authmode: %ld", + wifi_cipher); + break; + } + + return cipher_mode; +} + +#endif /* ESP_WLAN_HAS_STA */ + +/**************************************************************************** + * Name: esp_wifi_lock + * + * Description: + * Lock or unlock the event process + * + * Input Parameters: + * lock - true: Lock event process, false: unlock event process + * + * Returned Value: + * The result of lock or unlock the event process + * + ****************************************************************************/ + +static int esp_wifi_lock(bool lock) +{ + int ret; + + if (lock) + { + ret = nxmutex_lock(&g_wifiexcl_lock); + if (ret < 0) + { + wlinfo("Failed to lock Wi-Fi ret=%d\n", ret); + } + } + else + { + ret = nxmutex_unlock(&g_wifiexcl_lock); + if (ret < 0) + { + wlinfo("Failed to unlock Wi-Fi ret=%d\n", ret); + } + } + + return ret; +} + +/**************************************************************************** + * Name: queue_msg_waiting_wrapper + * + * Description: + * Get message number in the message queue + * + * Input Parameters: + * queue - Message queue data pointer + * + * Returned Value: + * Message number + * + ****************************************************************************/ + +static uint32_t queue_msg_waiting_wrapper(void *queue) +{ + int ret; + struct mq_attr attr; + struct mq_adpt *mq_adpt = (struct mq_adpt *)queue; + + ret = file_mq_getattr(&mq_adpt->mq, &attr); + if (ret < 0) + { + wlerr("Failed to get attr from mqueue error=%d\n", ret); + return 0; + } + + return attr.mq_curmsgs; +} + +/**************************************************************************** + * Name: task_delay_wrapper + * + * Description: + * Current task wait for some ticks + * + * Input Parameters: + * tick - Waiting ticks + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void task_delay_wrapper(uint32_t tick) +{ + useconds_t us = TICK2USEC(tick); + + nxsig_usleep(us); +} + +/**************************************************************************** + * Name: task_delete_wrapper + * + * Description: + * Delete the target task + * + * Input Parameters: + * task_handle - Task handle pointer which is used to pause, resume + * and delete the task + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void task_delete_wrapper(void *task_handle) +{ + pid_t pid = (pid_t)((uintptr_t)task_handle); + + kthread_delete(pid); +} + +/**************************************************************************** + * Name: task_get_current_task_wrapper + * + * Description: + * This function gets the current task's PID and returns it as a void + * pointer. This is a wrapper around the NuttX function nxsched_getpid. + * + * Input Parameters: + * None + * + * Returned Value: + * The current task's PID as a void pointer. + * + ****************************************************************************/ + +static void *task_get_current_task_wrapper(void) +{ + pid_t pid = nxsched_getpid(); + + return (void *)((uintptr_t)pid); +} + +/**************************************************************************** + * Name: vqueue_delete_adapter + * + * Description: + * This function deletes a queue adapter. It closes the message queue, + * unlinks it, and then frees the memory allocated for the queue adapter. + * + * Input Parameters: + * queue - A pointer to the queue adapter to be deleted. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void vqueue_delete_adapter(void *queue) +{ + struct mq_adpt *mq_adpt = (struct mq_adpt *)queue; + + file_mq_close(&mq_adpt->mq); + file_mq_unlink(mq_adpt->name); + kmm_free(mq_adpt); +} + +/**************************************************************************** + * Name: vsemaphore_delete_adapter + * + * Description: + * Delete semaphore + * + * Input Parameters: + * semphr - Semaphore data pointer + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void vsemaphore_delete_adapter(void *semphr) +{ + sem_t *sem = (sem_t *)semphr; + + nxsem_destroy(sem); + kmm_free(sem); +} + +/**************************************************************************** + * Name: xqueue_create_adapter + * + * Description: + * Create message queue + * + * Input Parameters: + * queue_len - queue message number + * item_size - message size + * + * Returned Value: + * Message queue data pointer + * + ****************************************************************************/ + +static void *xqueue_create_adapter(uint32_t queue_len, uint32_t item_size) +{ + struct mq_attr attr; + struct mq_adpt *mq_adpt; + int ret; + + mq_adpt = kmm_malloc(sizeof(struct mq_adpt)); + if (!mq_adpt) + { + wlerr("Failed to kmm_malloc\n"); + return NULL; + } + + snprintf(mq_adpt->name, sizeof(mq_adpt->name), + "/tmp/%p", mq_adpt); + + attr.mq_maxmsg = queue_len; + attr.mq_msgsize = item_size; + attr.mq_curmsgs = 0; + attr.mq_flags = 0; + + ret = file_mq_open(&mq_adpt->mq, mq_adpt->name, + O_RDWR | O_CREAT, 0644, &attr); + if (ret < 0) + { + wlerr("Failed to create mqueue\n"); + kmm_free(mq_adpt); + return NULL; + } + + mq_adpt->msgsize = item_size; + + return (void *)mq_adpt; +} + +/**************************************************************************** + * Name: xqueue_send_adapter + * + * Description: + * Generic send message to queue within a certain period of time + * + * Input Parameters: + * queue - Message queue data pointer + * item - Message data pointer + * ticks - Wait ticks + * prio - Message priority + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +static int32_t xqueue_send_adapter(void *queue, + void *item, + uint32_t ticks, + int prio) +{ + int ret; + struct timespec timeout; + struct mq_adpt *mq_adpt = (struct mq_adpt *)queue; + + if (ticks == OSI_FUNCS_TIME_BLOCKING || ticks == 0) + { + /* Wi-Fi interrupt function will call this adapter function to send + * message to message queue, so here we should call kernel API + * instead of application API + */ + + ret = file_mq_send(&mq_adpt->mq, (const char *)item, + mq_adpt->msgsize, prio); + if (ret < 0) + { + wlerr("Failed to send message to mqueue error=%d\n", + ret); + } + } + else + { + ret = clock_gettime(CLOCK_REALTIME, &timeout); + if (ret < 0) + { + wlerr("Failed to get time\n"); + return false; + } + + if (ticks) + { + esp_update_time(&timeout, ticks); + } + + ret = file_mq_timedsend(&mq_adpt->mq, (const char *)item, + mq_adpt->msgsize, prio, &timeout); + if (ret < 0) + { + wlerr("Failed to timedsend message to mqueue error=%d\n", + ret); + } + } + + return nuttx_err_to_freertos(ret); +} + +/**************************************************************************** + * Name: xsemaphore_create_counting_adapter + * + * Description: + * Create and initialize semaphore + * + * Input Parameters: + * max - No meanining for NuttX + * init - semaphore initialization value + * + * Returned Value: + * Semaphore data pointer + * + ****************************************************************************/ + +void *xsemaphore_create_counting_adapter(uint32_t max, uint32_t init) +{ + int ret; + sem_t *sem; + int tmp; + + tmp = sizeof(sem_t); + sem = kmm_malloc(tmp); + if (!sem) + { + wlerr("Failed to alloc %d memory\n", tmp); + return NULL; + } + + ret = nxsem_init(sem, 0, init); + if (ret) + { + wlerr("Failed to initialize sem error=%d\n", ret); + kmm_free(sem); + return NULL; + } + + return sem; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: wifi_malloc + * + * Description: + * Applications allocate a block of memory + * + * Input Parameters: + * size - memory size + * + * Returned Value: + * Memory pointer + * + ****************************************************************************/ + +IRAM_ATTR void *wifi_malloc(size_t size) +{ + return malloc(size); +} + +/**************************************************************************** + * Name: wifi_realloc + * + * Description: + * Applications allocate a block of memory by old memory block + * + * Input Parameters: + * ptr - old memory pointer + * size - memory size + * + * Returned Value: + * New memory pointer + * + ****************************************************************************/ + +IRAM_ATTR void *wifi_realloc(void *ptr, size_t size) +{ + return realloc(ptr, size); +} + +/**************************************************************************** + * Name: wifi_calloc + * + * Description: + * Applications allocate some continuous blocks of memory + * + * Input Parameters: + * n - memory block number + * size - memory block size + * + * Returned Value: + * New memory pointer + * + ****************************************************************************/ + +IRAM_ATTR void *wifi_calloc(size_t n, size_t size) +{ + return calloc(n, size); +} + +/**************************************************************************** + * Name: esp_wifi_notify_subscribe + * + * Description: + * Enable event notification + * + * Input Parameters: + * pid - Task PID + * event - Signal event data pointer + * + * Returned Value: + * 0 if success or -1 if fail + * + ****************************************************************************/ + +int esp_wifi_notify_subscribe(pid_t pid, struct sigevent *event) +{ + int id; + struct wifi_notify *notify; + int ret = -1; + + wlinfo("PID=%d event=%p\n", pid, event); + + esp_wifi_lock(true); + + if (event->sigev_notify == SIGEV_SIGNAL) + { + id = esp_event_id_map(event->sigev_signo); + if (id < 0) + { + wlerr("No process event %d\n", event->sigev_signo); + } + else + { + notify = &g_wifi_notify[id]; + + if (notify->assigned) + { + wlerr("sigev_signo %d has subscribed\n", + event->sigev_signo); + } + else + { + if (pid == 0) + { + pid = nxsched_getpid(); + wlinfo("Actual PID=%d\n", pid); + } + + notify->pid = pid; + notify->event = *event; + notify->assigned = true; + + ret = 0; + } + } + } + else if (event->sigev_notify == SIGEV_NONE) + { + id = esp_event_id_map(event->sigev_signo); + if (id < 0) + { + wlerr("No process event %d\n", event->sigev_signo); + } + else + { + notify = &g_wifi_notify[id]; + + if (!notify->assigned) + { + wlerr("sigev_signo %d has not subscribed\n", + event->sigev_signo); + } + else + { + notify->assigned = false; + + ret = 0; + } + } + } + else + { + wlerr("sigev_notify %d is invalid\n", event->sigev_signo); + } + + esp_wifi_lock(false); + + return ret; +} + +/**************************************************************************** + * Name: esp_wifi_adapter_init + * + * Description: + * Initialize ESP32-C3 Wi-Fi adapter + * + * Input Parameters: + * None + * + * Returned Value: + * 0 if success or -1 if fail + * + ****************************************************************************/ + +int esp_wifi_adapter_init(void) +{ + int ret; + wifi_init_config_t wifi_cfg = WIFI_INIT_CONFIG_DEFAULT(); + + esp_wifi_lock(true); + + if (g_wifi_ref) + { + wlinfo("Wi-Fi adapter is already initialized\n"); + g_wifi_ref++; + esp_wifi_lock(false); + return OK; + } + + sq_init(&g_wifi_evt_queue); + + wifi_cfg.nvs_enable = 0; + +#ifdef CONFIG_ESPRESSIF_WIFI_AMPDU_TX_ENABLED + wifi_cfg.ampdu_tx_enable = 1; +#else + wifi_cfg.ampdu_tx_enable = 0; +#endif + +#ifdef CONFIG_ESPRESSIF_WIFI_AMPDU_RX_ENABLED + wifi_cfg.ampdu_rx_enable = 1; +#else + wifi_cfg.ampdu_rx_enable = 0; +#endif + +#ifdef CONFIG_ESPRESSIF_WIFI_STA_DISCONNECT_PM + wifi_cfg.sta_disconnected_pm = true; +#else + wifi_cfg.sta_disconnected_pm = false; +#endif + + wifi_cfg.rx_ba_win = CONFIG_ESPRESSIF_WIFI_TX_BA_WIN; + wifi_cfg.static_rx_buf_num = CONFIG_ESPRESSIF_WIFI_STATIC_RX_BUFFER_NUM; + wifi_cfg.dynamic_rx_buf_num = CONFIG_ESPRESSIF_WIFI_DYNAMIC_RX_BUFFER_NUM; + wifi_cfg.dynamic_tx_buf_num = CONFIG_ESPRESSIF_WIFI_DYNAMIC_TX_BUFFER_NUM; + + ret = esp_wifi_init(&wifi_cfg); + if (ret) + { + wlerr("Failed to initialize Wi-Fi error=%d\n", ret); + ret = esp_wifi_to_errno(ret); + goto errout_init_wifi; + } + + ret = esp_wifi_set_tx_done_cb(esp_wifi_tx_done_cb); + if (ret) + { + wlerr("Failed to register TX done callback ret=%d\n", ret); + ret = esp_wifi_to_errno(ret); + goto errout_init_txdone; + } + + g_wifi_ref++; + + wlinfo("OK to initialize Wi-Fi adapter\n"); + + esp_wifi_lock(false); + + return OK; + +errout_init_txdone: + esp_wifi_deinit(); +errout_init_wifi: + esp_wifi_lock(false); + + return ret; +} + +/**************************************************************************** + * Station functions + ****************************************************************************/ + +#ifdef ESP_WLAN_HAS_STA + +/**************************************************************************** + * Name: esp_wifi_sta_start + * + * Description: + * Start Wi-Fi station. + * + * Input Parameters: + * None + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_start(void) +{ + int ret; + wifi_mode_t mode; + + esp_wifi_lock(true); + + ret = esp_wifi_stop(); + if (ret) + { + wlinfo("Failed to stop Wi-Fi ret=%d\n", ret); + } + +#ifdef ESP_WLAN_HAS_SOFTAP + if (g_softap_started) + { + mode = WIFI_MODE_APSTA; + } + else +#endif /* ESP_WLAN_HAS_SOFTAP */ + { + mode = WIFI_MODE_STA; + } + + ret = esp_wifi_set_mode(mode); + if (ret) + { + wlerr("Failed to set Wi-Fi mode=%d ret=%d\n", mode, ret); + ret = esp_wifi_to_errno(ret); + goto errout; + } + + ret = esp_wifi_start(); + if (ret) + { + wlerr("Failed to start Wi-Fi with mode=%d ret=%d\n", mode, ret); + ret = esp_wifi_to_errno(ret); + goto errout; + } + + g_sta_started = true; + + wlinfo("OK to start Wi-Fi station\n"); + +errout: + esp_wifi_lock(false); + return ret; +} + +/**************************************************************************** + * Name: esp_wifi_sta_stop + * + * Description: + * Stop Wi-Fi station. + * + * Input Parameters: + * None + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_stop(void) +{ + int ret; + + esp_wifi_lock(true); + + ret = esp_wifi_stop(); + if (ret) + { + wlinfo("Failed to stop Wi-Fi ret=%d\n", ret); + } + + g_sta_started = false; + +#ifdef ESP_WLAN_HAS_SOFTAP + if (g_softap_started) + { + ret = esp_wifi_set_mode(WIFI_MODE_AP); + if (ret) + { + wlerr("Failed to set Wi-Fi AP mode ret=%d\n", ret); + ret = esp_wifi_to_errno(ret); + goto errout; + } + + ret = esp_wifi_start(); + if (ret) + { + wlerr("Failed to start Wi-Fi AP ret=%d\n", ret); + ret = esp_wifi_to_errno(ret); + goto errout; + } + } +#endif /* ESP_WLAN_HAS_SOFTAP */ + + wlinfo("OK to stop Wi-Fi station\n"); + +#ifdef ESP_WLAN_HAS_SOFTAP +errout: +#endif /* ESP_WLAN_HAS_SOFTAP */ + + esp_wifi_lock(false); + return ret; +} + +/**************************************************************************** + * Name: esp_wifi_sta_send_data + * + * Description: + * Use Wi-Fi station interface to send 802.3 frame + * + * Input Parameters: + * pbuf - Packet buffer pointer + * len - Packet length + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_send_data(void *pbuf, size_t len) +{ + int ret; + + ret = esp_wifi_internal_tx(WIFI_IF_STA, pbuf, len); + + return esp_wifi_to_errno(ret); +} + +/**************************************************************************** + * Name: esp_wifi_set_password + * + * Description: + * Set/Get Wi-Fi station password + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_password(struct iwreq *iwr, bool set) +{ + int ret; + int size; + wifi_config_t wifi_cfg; + struct iw_encode_ext *ext = iwr->u.encoding.pointer; + uint8_t *pdata; + uint8_t len; +#ifdef CONFIG_DEBUG_WIRELESS_INFO + char buf[PWD_MAX_LEN + 1]; +#endif + + DEBUGASSERT(ext != NULL); + + pdata = ext->key; + + wifi_cfg = g_sta_wifi_cfg; + + if (set) + { + len = ext->key_len; + if (len > PWD_MAX_LEN) + { + return -EINVAL; + } + + memset(wifi_cfg.sta.password, 0x0, PWD_MAX_LEN); + + if (ext->alg != IW_ENCODE_ALG_NONE) + { + memcpy(wifi_cfg.sta.password, pdata, len); + } + + wifi_cfg.sta.pmf_cfg.capable = true; + + if (g_sta_connected) + { + ret = esp_wifi_sta_disconnect(); + if (ret) + { + wlerr("Failed to disconnect from Wi-Fi AP ret=%d\n", ret); + return ret; + } + + ret = esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg); + if (ret) + { + wlerr("Failed to set Wi-Fi config data ret=%d\n", ret); + return esp_wifi_to_errno(ret); + } + + ret = esp_wifi_sta_connect(); + if (ret) + { + wlerr("Failed to connect to Wi-Fi AP ret=%d\n", ret); + return ret; + } + } + + g_sta_wifi_cfg = wifi_cfg; + } + else + { + len = iwr->u.encoding.length - sizeof(*ext); + size = strnlen((char *)wifi_cfg.sta.password, PWD_MAX_LEN); + if (len < size) + { + return -EINVAL; + } + else + { + ext->key_len = size; + memcpy(pdata, wifi_cfg.sta.password, ext->key_len); + } + + if (g_sta_connected) + { + wifi_ap_record_t ap_info; + + ret = esp_wifi_sta_get_ap_info(&ap_info); + if (ret) + { + wlerr("Failed to get AP record ret=%d", ret); + return esp_wifi_to_errno(ret); + } + + switch (ap_info.pairwise_cipher) + { + case WIFI_CIPHER_TYPE_NONE: + ext->alg = IW_ENCODE_ALG_NONE; + break; + + case WIFI_CIPHER_TYPE_WEP40: + case WIFI_CIPHER_TYPE_WEP104: + ext->alg = IW_ENCODE_ALG_WEP; + break; + + case WIFI_CIPHER_TYPE_TKIP: + ext->alg = IW_ENCODE_ALG_TKIP; + break; + + case WIFI_CIPHER_TYPE_CCMP: + case WIFI_CIPHER_TYPE_TKIP_CCMP: + ext->alg = IW_ENCODE_ALG_CCMP; + break; + + case WIFI_CIPHER_TYPE_AES_CMAC128: + ext->alg = IW_ENCODE_ALG_AES_CMAC; + break; + + default: + wlerr("Failed to transfer wireless authmode: %d", + ap_info.pairwise_cipher); + return -EIO; + } + } + } + +#ifdef CONFIG_DEBUG_WIRELESS_INFO + memcpy(buf, pdata, len); + buf[len] = 0; + wlinfo("Wi-Fi station password=%s len=%d\n", buf, len); +#endif + + return OK; +} + +/**************************************************************************** + * Name: esp_wifi_sta_essid + * + * Description: + * Set/Get Wi-Fi station ESSID + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_essid(struct iwreq *iwr, bool set) +{ + int ret; + int size; + wifi_config_t wifi_cfg; + struct iw_point *essid = &iwr->u.essid; + uint8_t *pdata; + uint8_t len; +#ifdef CONFIG_DEBUG_WIRELESS_INFO + char buf[SSID_MAX_LEN + 1]; +#endif + + DEBUGASSERT(essid != NULL); + + pdata = essid->pointer; + len = essid->length; + + if (set && len > SSID_MAX_LEN) + { + return -EINVAL; + } + + wifi_cfg = g_sta_wifi_cfg; + + if (set) + { + memset(wifi_cfg.sta.ssid, 0x0, SSID_MAX_LEN); + memcpy(wifi_cfg.sta.ssid, pdata, len); + memset(wifi_cfg.sta.sae_h2e_identifier, 0x0, SAE_H2E_IDENTIFIER_LEN); + wifi_cfg.sta.sae_pwe_h2e = WPA3_SAE_PWE_BOTH; + + if (g_sta_connected) + { + ret = esp_wifi_sta_disconnect(); + if (ret) + { + wlerr("Failed to disconnect from Wi-Fi AP ret=%d\n", ret); + return ret; + } + + ret = esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg); + if (ret) + { + wlerr("Failed to set Wi-Fi config data ret=%d\n", ret); + return esp_wifi_to_errno(ret); + } + + ret = esp_wifi_sta_connect(); + if (ret) + { + wlerr("Failed to connect to Wi-Fi AP ret=%d\n", ret); + return ret; + } + } + + g_sta_wifi_cfg = wifi_cfg; + } + else + { + size = strnlen((char *)wifi_cfg.sta.ssid, SSID_MAX_LEN); + if (len < size) + { + return -EINVAL; + } + else + { + len = size; + memcpy(pdata, wifi_cfg.sta.ssid, len); + } + + if (g_sta_connected) + { + essid->flags = IW_ESSID_ON; + } + else + { + essid->flags = IW_ESSID_OFF; + } + } + +#ifdef CONFIG_DEBUG_WIRELESS_INFO + memcpy(buf, pdata, len); + buf[len] = 0; + wlinfo("Wi-Fi station ssid=%s len=%d\n", buf, len); +#endif + + return OK; +} + +/**************************************************************************** + * Name: esp_wifi_sta_bssid + * + * Description: + * Set/Get Wi-Fi station BSSID + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_bssid(struct iwreq *iwr, bool set) +{ + int ret; + wifi_config_t wifi_cfg; + struct sockaddr *sockaddr; + char *pdata; + + sockaddr = &iwr->u.ap_addr; + pdata = sockaddr->sa_data; + + wifi_cfg = g_sta_wifi_cfg; + + if (set) + { + wifi_cfg.sta.bssid_set = true; + memcpy(wifi_cfg.sta.bssid, pdata, MAC_LEN); + + if (g_sta_connected) + { + ret = esp_wifi_sta_disconnect(); + if (ret) + { + wlerr("Failed to disconnect from Wi-Fi AP ret=%d\n", ret); + return ret; + } + + ret = esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg); + if (ret) + { + wlerr("Failed to set Wi-Fi config data ret=%d\n", ret); + return esp_wifi_to_errno(ret); + } + + ret = esp_wifi_sta_connect(); + if (ret) + { + wlerr("Failed to connect to Wi-Fi AP ret=%d\n", ret); + return ret; + } + } + + g_sta_wifi_cfg = wifi_cfg; + } + else + { + memcpy(pdata, wifi_cfg.sta.bssid, MAC_LEN); + } + + return OK; +} + +/**************************************************************************** + * Name: esp_wifi_sta_connect + * + * Description: + * Trigger Wi-Fi station connection action + * + * Input Parameters: + * None + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_connect(void) +{ + int ret; + uint32_t ticks; + + esp_wifi_lock(true); + + if (g_sta_connected) + { + wlinfo("Wi-Fi has connected AP\n"); + esp_wifi_lock(false); + return OK; + } + + g_sta_reconnect = true; + + ret = esp_wifi_set_config(WIFI_IF_STA, &g_sta_wifi_cfg); + if (ret) + { + wlerr("Failed to set Wi-Fi config data ret=%d\n", ret); + return esp_wifi_to_errno(ret); + } + + ret = esp_wifi_connect(); + if (ret) + { + wlerr("Failed to connect ret=%d\n", ret); + ret = esp_wifi_to_errno(ret); + goto errout; + } + + esp_wifi_lock(false); + + ticks = SEC2TICK(WIFI_CONNECT_TIMEOUT); + do + { + if (g_sta_connected) + { + break; + } + + task_delay_wrapper(1); + } + while (ticks--); + + if (!g_sta_connected) + { + g_sta_reconnect = false; + wlinfo("Failed to connect to AP\n"); + return -1; + } + + return OK; + +errout: + g_sta_reconnect = false; + esp_wifi_lock(false); + return ret; +} + +/**************************************************************************** + * Name: esp_wifi_sta_disconnect + * + * Description: + * Trigger Wi-Fi station disconnection action + * + * Input Parameters: + * None + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_disconnect(void) +{ + int ret; + + esp_wifi_lock(true); + + g_sta_reconnect = false; + + ret = esp_wifi_disconnect(); + if (ret) + { + wlerr("Failed to disconnect ret=%d\n", ret); + ret = esp_wifi_to_errno(ret); + } + else + { + wlinfo("OK to disconnect Wi-Fi station\n"); + } + + esp_wifi_lock(false); + return ret; +} + +/**************************************************************************** + * Name: esp_wifi_sta_mode + * + * Description: + * Set/Get Wi-Fi Station mode code. + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_mode(struct iwreq *iwr, bool set) +{ + if (set == false) + { + iwr->u.mode = IW_MODE_INFRA; + } + + return OK; +} + +/**************************************************************************** + * Name: esp_wifi_sta_auth + * + * Description: + * Set/Get station authentication mode params. + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_auth(struct iwreq *iwr, bool set) +{ + int ret; + int cmd; + wifi_config_t wifi_cfg; + wifi_ap_record_t ap_info; + + wifi_cfg = g_sta_wifi_cfg; + + if (set) + { + cmd = iwr->u.param.flags & IW_AUTH_INDEX; + switch (cmd) + { + case IW_AUTH_WPA_VERSION: + { + switch (iwr->u.param.value) + { + case IW_AUTH_WPA_VERSION_DISABLED: + wifi_cfg.sta.threshold.authmode = WIFI_AUTH_OPEN; + break; + + case IW_AUTH_WPA_VERSION_WPA: + wifi_cfg.sta.threshold.authmode = WIFI_AUTH_WPA_PSK; + break; + + case IW_AUTH_WPA_VERSION_WPA2: + wifi_cfg.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK; + break; + + case IW_AUTH_WPA_VERSION_WPA3: + wifi_cfg.sta.threshold.authmode = WIFI_AUTH_WPA3_PSK; + break; + + default: + wlerr("Invalid wpa version %" PRId32 "\n", + iwr->u.param.value); + return -EINVAL; + } + } + + break; + case IW_AUTH_CIPHER_PAIRWISE: + case IW_AUTH_CIPHER_GROUP: + { + switch (iwr->u.param.value) + { + case IW_AUTH_CIPHER_NONE: + wifi_cfg.sta.threshold.authmode = WIFI_AUTH_OPEN; + break; + + case IW_AUTH_CIPHER_WEP40: + case IW_AUTH_CIPHER_WEP104: + wifi_cfg.sta.threshold.authmode = WIFI_AUTH_WEP; + break; + + case IW_AUTH_CIPHER_TKIP: + case IW_AUTH_CIPHER_CCMP: + case IW_AUTH_CIPHER_AES_CMAC: + break; + + default: + wlerr("Invalid cipher mode %" PRId32 "\n", + iwr->u.param.value); + return -EINVAL; + } + } + + break; + case IW_AUTH_KEY_MGMT: + case IW_AUTH_TKIP_COUNTERMEASURES: + case IW_AUTH_DROP_UNENCRYPTED: + case IW_AUTH_80211_AUTH_ALG: + case IW_AUTH_WPA_ENABLED: + case IW_AUTH_RX_UNENCRYPTED_EAPOL: + case IW_AUTH_ROAMING_CONTROL: + case IW_AUTH_PRIVACY_INVOKED: + default: + wlerr("Unknown cmd %d\n", cmd); + return -EINVAL; + } + + size_t password_len = strlen((const char *)wifi_cfg.sta.password); + wifi_auth_mode_t authmode = wifi_cfg.sta.threshold.authmode; + + if (g_sta_connected && + ((password_len > 0 && authmode != WIFI_AUTH_OPEN) || + (password_len == 0 && authmode == WIFI_AUTH_OPEN))) + { + ret = esp_wifi_sta_disconnect(); + if (ret) + { + wlerr("Failed to disconnect from Wi-Fi AP ret=%d\n", ret); + return ret; + } + + ret = esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg); + if (ret) + { + wlerr("Failed to set Wi-Fi config data ret=%d\n", ret); + return esp_wifi_to_errno(ret); + } + + ret = esp_wifi_sta_connect(); + if (ret) + { + wlerr("Failed to connect to Wi-Fi AP ret=%d\n", ret); + return ret; + } + } + + g_sta_wifi_cfg = wifi_cfg; + } + else + { + if (g_sta_connected == false) + { + return -ENOTCONN; + } + + ret = esp_wifi_sta_get_ap_info(&ap_info); + if (ret) + { + wlerr("Failed to get AP record ret=%d\n", ret); + return esp_wifi_to_errno(ret); + } + + cmd = iwr->u.param.flags & IW_AUTH_INDEX; + switch (cmd) + { + case IW_AUTH_WPA_VERSION: + iwr->u.param.value = esp_wifi_auth_trans(ap_info.authmode); + break; + + case IW_AUTH_CIPHER_PAIRWISE: + iwr->u.param.value = + esp_wifi_cipher_trans(ap_info.pairwise_cipher); + break; + + case IW_AUTH_CIPHER_GROUP: + iwr->u.param.value = esp_wifi_cipher_trans(ap_info.group_cipher); + break; + + case IW_AUTH_KEY_MGMT: + case IW_AUTH_TKIP_COUNTERMEASURES: + case IW_AUTH_DROP_UNENCRYPTED: + case IW_AUTH_80211_AUTH_ALG: + case IW_AUTH_WPA_ENABLED: + case IW_AUTH_RX_UNENCRYPTED_EAPOL: + case IW_AUTH_ROAMING_CONTROL: + case IW_AUTH_PRIVACY_INVOKED: + default: + wlerr("Unknown cmd %d\n", cmd); + return -ENOSYS; + } + } + + return OK; +} + +/**************************************************************************** + * Name: esp_wifi_sta_freq + * + * Description: + * Set/Get station frequency. + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_freq(struct iwreq *iwr, bool set) +{ + int ret; + + if (set && (iwr->u.freq.flags == IW_FREQ_FIXED)) + { + wifi_config_t wifi_cfg = g_sta_wifi_cfg; + + wifi_cfg.sta.channel = esp_freq_to_channel(iwr->u.freq.m); + + if (g_sta_connected) + { + ret = esp_wifi_sta_disconnect(); + if (ret) + { + wlerr("Failed to disconnect from Wi-Fi AP ret=%d\n", ret); + return ret; + } + + ret = esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg); + if (ret) + { + wlerr("Failed to set Wi-Fi config data ret=%d\n", ret); + return esp_wifi_to_errno(ret); + } + + ret = esp_wifi_sta_connect(); + if (ret) + { + wlerr("Failed to connect to Wi-Fi AP ret=%d\n", ret); + return ret; + } + } + + g_sta_wifi_cfg = wifi_cfg; + } + else + { + if (g_sta_connected) + { + wifi_ap_record_t ap_info; + + ret = esp_wifi_sta_get_ap_info(&ap_info); + if (ret) + { + wlerr("Failed to get AP record ret=%d\n", ret); + return esp_wifi_to_errno(ret); + } + + iwr->u.freq.flags = IW_FREQ_FIXED; + iwr->u.freq.e = 0; + iwr->u.freq.m = 2407 + 5 * ap_info.primary; + } + else + { + iwr->u.freq.flags = IW_FREQ_AUTO; + iwr->u.freq.e = 0; + iwr->u.freq.m = 2412; + } + } + + return OK; +} + +/**************************************************************************** + * Name: esp_wifi_sta_bitrate + * + * Description: + * Get station default bit rate (Mbps). + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_bitrate(struct iwreq *iwr, bool set) +{ + int ret; + wifi_ap_record_t ap_info; + + if (set) + { + return -ENOSYS; + } + else + { + if (g_sta_connected == false) + { + iwr->u.bitrate.fixed = IW_FREQ_AUTO; + return OK; + } + + ret = esp_wifi_sta_get_ap_info(&ap_info); + if (ret) + { + wlerr("Failed to get AP record ret=%d\n", ret); + return esp_wifi_to_errno(ret); + } + + iwr->u.bitrate.fixed = IW_FREQ_FIXED; + if (ap_info.phy_11n) + { + if (ap_info.second) + { + iwr->u.bitrate.value = ESP_WIFI_11N_MCS7_HT40_BITRATE; + } + else + { + iwr->u.bitrate.value = ESP_WIFI_11N_MCS7_HT20_BITRATE; + } + } + else if (ap_info.phy_11g) + { + iwr->u.bitrate.value = ESP_WIFI_11G_MAX_BITRATE; + } + else if (ap_info.phy_11b) + { + iwr->u.bitrate.value = ESP_WIFI_11B_MAX_BITRATE; + } + else + { + return -EIO; + } + } + + return OK; +} + +#endif /* ESP_WLAN_HAS_STA */ + +/**************************************************************************** + * Name: esp_wifi_sta_get_txpower + * + * Description: + * Get station transmit power (dBm). + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_txpower(struct iwreq *iwr, bool set) +{ + int ret; + int8_t power; + double power_dbm; + + if (set) + { + if (iwr->u.txpower.flags == IW_TXPOW_RELATIVE) + { + power = (int8_t)iwr->u.txpower.value; + } + else + { + if (iwr->u.txpower.flags == IW_TXPOW_MWATT) + { + power_dbm = ceil(10 * log10(iwr->u.txpower.value)); + } + else + { + power_dbm = iwr->u.txpower.value; + } + + power = (int8_t)(power_dbm * 4); + } + + /* The value set by this API will be mapped to the max_tx_power + * of the structure wifi_country_t variable. Param power unit is + * 0.25dBm, range is [8, 84] corresponding to 2dBm - 20dBm. + * Relationship between set value and actual value. + * As follows: {set value range, actual value} = + * {{[8, 19],8}, {[20, 27],20}, {[28, 33],28}, + * {[34, 43],34}, {[44, 51],44}, {[52, 55],52}, + * {[56, 59],56}, {[60, 65],60}, {[66, 71],66}, + * {[72, 79],72}, {[80, 84],80}}. + */ + + if (power < 8 || power > 84) + { + wlerr("Failed to set transmit power =%d\n", power); + return -ENOSYS; + } + + esp_wifi_set_max_tx_power(power); + return OK; + } + else + { + ret = esp_wifi_get_max_tx_power(&power); + if (ret) + { + wlerr("Failed to get transmit power ret=%d\n", ret); + return esp_wifi_to_errno(ret); + } + + iwr->u.txpower.disabled = 0; + iwr->u.txpower.flags = IW_TXPOW_DBM; + iwr->u.txpower.value = power / 4; + } + + return OK; +} + +/**************************************************************************** + * Name: esp_wifi_sta_channel + * + * Description: + * Get station range of channel parameters. + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_channel(struct iwreq *iwr, bool set) +{ + int ret; + int k; + wifi_country_t country; + struct iw_range *range; + + if (set) + { + return -ENOSYS; + } + else + { + ret = esp_wifi_get_country(&country); + if (ret) + { + wlerr("Failed to get country info ret=%d\n", ret); + return esp_wifi_to_errno(ret); + } + + range = (struct iw_range *)iwr->u.data.pointer; + range->num_frequency = country.nchan; + for (k = 1; k <= range->num_frequency; k++) + { + range->freq[k - 1].i = k; + range->freq[k - 1].e = 0; + range->freq[k - 1].m = 2407 + 5 * k; + } + } + + return OK; +} + +/**************************************************************************** + * Name: esp_wifi_sta_country + * + * Description: + * Configure country info. + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_country(struct iwreq *iwr, bool set) +{ + int ret; + char *country_code; + wifi_country_t country; + + if (set) + { + memset(&country, 0x00, sizeof(wifi_country_t)); + country.schan = 1; + country.policy = 0; + + country_code = (char *)iwr->u.data.pointer; + if (strlen(country_code) != 2) + { + wlerr("Invalid input arguments\n"); + return -EINVAL; + } + + if (strncmp(country_code, "US", 3) == 0 || + strncmp(country_code, "CA", 3) == 0) + { + country.nchan = 11; + } + else if(strncmp(country_code, "JP", 3) == 0) + { + country.nchan = 14; + } + else + { + country.nchan = 13; + } + + memcpy(country.cc, country_code, 2); + ret = esp_wifi_set_country(&country); + if (ret) + { + wlerr("Failed to Configure country ret=%d\n", ret); + return esp_wifi_to_errno(ret); + } + } + else + { + return -ENOSYS; + } + + return OK; +} + +#ifdef ESP_WLAN_HAS_STA + +/**************************************************************************** + * Name: esp_wifi_sta_rssi + * + * Description: + * Get Wi-Fi sensitivity (dBm). + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_rssi(struct iwreq *iwr, bool set) +{ + int ret; + wifi_ap_record_t ap_info; + + if (set) + { + return -ENOSYS; + } + else + { + if (g_sta_connected == false) + { + iwr->u.sens.value = 128; + return OK; + } + + ret = esp_wifi_sta_get_ap_info(&ap_info); + if (ret) + { + wlerr("Failed to get AP record ret=%d\n", ret); + return esp_wifi_to_errno(ret); + } + + iwr->u.sens.value = -(ap_info.rssi); + } + + return OK; +} +#endif /* ESP_WLAN_HAS_STA */ + +/**************************************************************************** + * SoftAP functions + ****************************************************************************/ + +#ifdef ESP_WLAN_HAS_SOFTAP + +/**************************************************************************** + * Name: esp_wifi_softap_start + * + * Description: + * Start Wi-Fi SoftAP. + * + * Input Parameters: + * None + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_start(void) +{ + int ret; + wifi_mode_t mode; + + esp_wifi_lock(true); + + ret = esp_wifi_stop(); + if (ret) + { + wlinfo("Failed to stop Wi-Fi ret=%d\n", ret); + } + +#ifdef ESP_WLAN_HAS_STA + if (g_sta_started) + { + mode = WIFI_MODE_APSTA; + } + else +#endif /* ESP_WLAN_HAS_STA */ + { + mode = WIFI_MODE_AP; + } + + ret = esp_wifi_set_mode(mode); + if (ret) + { + wlerr("Failed to set Wi-Fi mode=%d ret=%d\n", mode, ret); + ret = esp_wifi_to_errno(ret); + goto errout; + } + + ret = esp_wifi_start(); + if (ret) + { + wlerr("Failed to start Wi-Fi with mode=%d ret=%d\n", mode, ret); + ret = esp_wifi_to_errno(ret); + goto errout; + } + + g_softap_started = true; + + wlinfo("OK to start Wi-Fi SoftAP\n"); + +errout: + esp_wifi_lock(false); + return ret; +} + +/**************************************************************************** + * Name: esp_wifi_softap_stop + * + * Description: + * Stop Wi-Fi SoftAP. + * + * Input Parameters: + * None + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_stop(void) +{ + int ret; + + esp_wifi_lock(true); + + ret = esp_wifi_stop(); + if (ret) + { + wlinfo("Failed to stop Wi-Fi ret=%d\n", ret); + } + + g_softap_started = false; + +#ifdef ESP_WLAN_HAS_STA + if (g_sta_started) + { + ret = esp_wifi_set_mode(WIFI_MODE_STA); + if (ret) + { + wlerr("Failed to set Wi-Fi AP mode ret=%d\n", ret); + ret = esp_wifi_to_errno(ret); + goto errout; + } + + ret = esp_wifi_start(); + if (ret) + { + wlerr("Failed to start Wi-Fi STA ret=%d\n", ret); + ret = esp_wifi_to_errno(ret); + goto errout; + } + } +#endif /* ESP_WLAN_HAS_STA */ + + wlinfo("OK to stop Wi-Fi SoftAP\n"); + +#ifdef ESP_WLAN_HAS_STA +errout: +#endif /* ESP_WLAN_HAS_STA */ + + esp_wifi_lock(false); + return ret; +} + +/**************************************************************************** + * Name: esp_wifi_softap_send_data + * + * Description: + * Use Wi-Fi SoftAP interface to send 802.3 frame + * + * Input Parameters: + * pbuf - Packet buffer pointer + * len - Packet length + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_send_data(void *pbuf, size_t len) +{ + int ret; + + ret = esp_wifi_internal_tx(WIFI_IF_AP, pbuf, len); + + return esp_wifi_to_errno(ret); +} + +/**************************************************************************** + * Name: esp_wifi_softap_password + * + * Description: + * Set/Get Wi-Fi SoftAP password + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_password(struct iwreq *iwr, bool set) +{ + int ret; + int size; + wifi_config_t wifi_cfg; + struct iw_encode_ext *ext = iwr->u.encoding.pointer; + uint8_t *pdata; + uint8_t len; +#ifdef CONFIG_DEBUG_WIRELESS_INFO + char buf[PWD_MAX_LEN + 1]; +#endif + + DEBUGASSERT(ext != NULL); + + pdata = ext->key; + len = ext->key_len; + + if (set && len > PWD_MAX_LEN) + { + return -EINVAL; + } + + pdata = ext->key; + len = ext->key_len; + + wifi_cfg = g_softap_wifi_cfg; + + if (set) + { + /* Clear the password field and copy the user password to it */ + + memset(wifi_cfg.ap.password, 0x0, PWD_MAX_LEN); + + if (ext->alg != IW_ENCODE_ALG_NONE) + { + memcpy(wifi_cfg.sta.password, pdata, len); + } + + if (g_softap_started) + { + ret = esp_wifi_set_config(WIFI_IF_AP, &wifi_cfg); + if (ret) + { + wlerr("Failed to set Wi-Fi config data ret=%d\n", ret); + return esp_wifi_to_errno(ret); + } + } + + g_softap_wifi_cfg = wifi_cfg; + } + else + { + size = strnlen((char *)wifi_cfg.ap.password, PWD_MAX_LEN); + if (len < size) + { + return -EINVAL; + } + else + { + len = size; + memcpy(pdata, wifi_cfg.ap.password, len); + } + } + +#ifdef CONFIG_DEBUG_WIRELESS_INFO + memcpy(buf, pdata, len); + buf[len] = 0; + wlinfo("Wi-Fi SoftAP password=%s len=%d\n", buf, len); +#endif + + return OK; +} + +/**************************************************************************** + * Name: esp_wifi_softap_essid + * + * Description: + * Set/Get Wi-Fi SoftAP ESSID + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_essid(struct iwreq *iwr, bool set) +{ + int ret; + int size; + wifi_config_t wifi_cfg; + struct iw_point *essid = &iwr->u.essid; + uint8_t *pdata; + uint8_t len; +#ifdef CONFIG_DEBUG_WIRELESS_INFO + char buf[SSID_MAX_LEN + 1]; +#endif + + DEBUGASSERT(essid != NULL); + + pdata = essid->pointer; + len = essid->length; + + if (set && len > SSID_MAX_LEN) + { + return -EINVAL; + } + + wifi_cfg = g_softap_wifi_cfg; + + if (set) + { + memset(wifi_cfg.ap.ssid, 0x0, SSID_MAX_LEN); + memcpy(wifi_cfg.ap.ssid, pdata, len); + wifi_cfg.ap.ssid_len = len; + if (g_softap_started) + { + ret = esp_wifi_set_config(WIFI_IF_AP, &wifi_cfg); + if (ret) + { + wlerr("Failed to set Wi-Fi config data ret=%d\n", ret); + return esp_wifi_to_errno(ret); + } + } + + g_softap_wifi_cfg = wifi_cfg; + } + else + { + size = strnlen((char *)wifi_cfg.ap.ssid, SSID_MAX_LEN); + if (len < size) + { + return -EINVAL; + } + else + { + len = size; + memcpy(pdata, wifi_cfg.ap.ssid, len); + } + } + +#ifdef CONFIG_DEBUG_WIRELESS_INFO + memcpy(buf, pdata, len); + buf[len] = 0; + wlinfo("Wi-Fi SoftAP ssid=%s len=%d\n", buf, len); +#endif + + return OK; +} + +/**************************************************************************** + * Name: esp_wifi_softap_bssid + * + * Description: + * Set/Get Wi-Fi softAP BSSID + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_bssid(struct iwreq *iwr, bool set) +{ + return -ENOSYS; +} + +/**************************************************************************** + * Name: esp_wifi_softap_connect + * + * Description: + * Trigger Wi-Fi SoftAP accept connection action + * + * Input Parameters: + * None + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_connect(void) +{ + int ret; + + ret = esp_wifi_set_config(WIFI_IF_AP, &g_softap_wifi_cfg); + if (ret) + { + wlerr("Failed to set Wi-Fi config data ret=%d\n", ret); + return esp_wifi_to_errno(ret); + } + + return OK; +} + +/**************************************************************************** + * Name: esp_wifi_softap_disconnect + * + * Description: + * Trigger Wi-Fi SoftAP drop connection action + * + * Input Parameters: + * None + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_disconnect(void) +{ + return OK; +} + +/**************************************************************************** + * Name: esp_wifi_softap_mode + * + * Description: + * Set/Get Wi-Fi SoftAP mode code. + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_mode(struct iwreq *iwr, bool set) +{ + if (set == false) + { + iwr->u.mode = IW_MODE_MASTER; + } + + return OK; +} + +/**************************************************************************** + * Name: esp_wifi_softap_auth + * + * Description: + * Set/get authentication mode params. + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_auth(struct iwreq *iwr, bool set) +{ + int ret; + int cmd; + wifi_config_t wifi_cfg; + + wifi_cfg = g_softap_wifi_cfg; + + if (set) + { + cmd = iwr->u.param.flags & IW_AUTH_INDEX; + switch (cmd) + { + case IW_AUTH_WPA_VERSION: + { + switch (iwr->u.param.value) + { + case IW_AUTH_WPA_VERSION_DISABLED: + wifi_cfg.ap.authmode = WIFI_AUTH_OPEN; + break; + + case IW_AUTH_WPA_VERSION_WPA: + wifi_cfg.ap.authmode = WIFI_AUTH_WPA_PSK; + break; + + case IW_AUTH_WPA_VERSION_WPA2: + wifi_cfg.ap.authmode = WIFI_AUTH_WPA2_PSK; + break; + + case IW_AUTH_WPA_VERSION_WPA3: + wifi_cfg.ap.pmf_cfg.required = true; + wifi_cfg.ap.pmf_cfg.capable = false; + wifi_cfg.ap.sae_pwe_h2e = WPA3_SAE_PWE_BOTH; + wifi_cfg.ap.authmode = WIFI_AUTH_WPA3_PSK; + break; + + default: + wlerr("Invalid wpa version %" PRId32 "\n", + iwr->u.param.value); + return -EINVAL; + } + } + + break; + case IW_AUTH_CIPHER_PAIRWISE: + case IW_AUTH_CIPHER_GROUP: + { + switch (iwr->u.param.value) + { + case IW_AUTH_CIPHER_NONE: + wifi_cfg.ap.authmode = WIFI_AUTH_OPEN; + break; + + case IW_AUTH_CIPHER_WEP40: + case IW_AUTH_CIPHER_WEP104: + wifi_cfg.ap.authmode = WIFI_AUTH_WEP; + break; + + case IW_AUTH_CIPHER_TKIP: + case IW_AUTH_CIPHER_CCMP: + case IW_AUTH_CIPHER_AES_CMAC: + break; + + default: + wlerr("Invalid cipher mode %" PRId32 "\n", + iwr->u.param.value); + return -EINVAL; + } + } + + break; + case IW_AUTH_KEY_MGMT: + case IW_AUTH_TKIP_COUNTERMEASURES: + case IW_AUTH_DROP_UNENCRYPTED: + case IW_AUTH_80211_AUTH_ALG: + case IW_AUTH_WPA_ENABLED: + case IW_AUTH_RX_UNENCRYPTED_EAPOL: + case IW_AUTH_ROAMING_CONTROL: + case IW_AUTH_PRIVACY_INVOKED: + default: + wlerr("Unknown cmd %d\n", cmd); + return -EINVAL; + } + + size_t password_len = strlen((const char *)wifi_cfg.ap.password); + + if (g_softap_started && + ((password_len > 0 && wifi_cfg.ap.authmode != WIFI_AUTH_OPEN) || + (password_len == 0 && wifi_cfg.ap.authmode == WIFI_AUTH_OPEN))) + { + ret = esp_wifi_set_config(WIFI_IF_AP, &wifi_cfg); + if (ret) + { + wlerr("Failed to set Wi-Fi config data ret=%d\n", ret); + return esp_wifi_to_errno(ret); + } + } + + g_softap_wifi_cfg = wifi_cfg; + } + else + { + return -ENOSYS; + } + + return OK; +} + +/**************************************************************************** + * Name: esp_wifi_softap_freq + * + * Description: + * Set/Get SoftAP frequency. + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_freq(struct iwreq *iwr, bool set) +{ + int ret; + wifi_config_t wifi_cfg; + + wifi_cfg = g_softap_wifi_cfg; + + if (set) + { + int channel = esp_freq_to_channel(iwr->u.freq.m); + + wifi_cfg.ap.channel = channel; + + if (g_softap_started) + { + ret = esp_wifi_set_config(WIFI_IF_AP, &wifi_cfg); + if (ret) + { + wlerr("Failed to set Wi-Fi config data ret=%d\n", ret); + return esp_wifi_to_errno(ret); + } + } + + g_softap_wifi_cfg = wifi_cfg; + } + else + { + iwr->u.freq.flags = IW_FREQ_FIXED; + iwr->u.freq.e = 0; + iwr->u.freq.m = 2407 + 5 * wifi_cfg.ap.channel; + } + + return OK; +} + +/**************************************************************************** + * Name: esp_wifi_softap_get_bitrate + * + * Description: + * Get SoftAP default bit rate (Mbps). + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_bitrate(struct iwreq *iwr, bool set) +{ + return -ENOSYS; +} + +/**************************************************************************** + * Name: esp_wifi_softap_txpower + * + * Description: + * Get SoftAP transmit power (dBm). + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_txpower(struct iwreq *iwr, bool set) +{ + return esp_wifi_sta_txpower(iwr, set); +} + +/**************************************************************************** + * Name: esp_wifi_softap_channel + * + * Description: + * Get SoftAP range of channel parameters. + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_channel(struct iwreq *iwr, bool set) +{ + return esp_wifi_sta_channel(iwr, set); +} + +/**************************************************************************** + * Name: esp_wifi_softap_country + * + * Description: + * Configure country info. + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_country(struct iwreq *iwr, bool set) +{ + return esp_wifi_sta_country(iwr, set); +} + +/**************************************************************************** + * Name: esp_wifi_softap_rssi + * + * Description: + * Get Wi-Fi sensitivity (dBm). + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_rssi(struct iwreq *iwr, bool set) +{ + return -ENOSYS; +} + +#endif /* ESP_WLAN_HAS_SOFTAP */ diff --git a/arch/risc-v/src/esp32c3/esp_wifi_adapter.h b/arch/risc-v/src/esp32c3/esp_wifi_adapter.h new file mode 100644 index 0000000000..9ffb186a71 --- /dev/null +++ b/arch/risc-v/src/esp32c3/esp_wifi_adapter.h @@ -0,0 +1,672 @@ +/**************************************************************************** + * arch/risc-v/src/esp32c3/esp_wifi_adapter.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_ESP32C3_ESP_WIFI_ADAPTER_H +#define __ARCH_RISCV_SRC_ESP32C3_ESP_WIFI_ADAPTER_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include + +#include "esp_wlan.h" + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define SSID_MAX_LEN (32) +#define PWD_MAX_LEN (64) + +#define CONFIG_IDF_TARGET_ESP32C3 1 + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_wifi_adapter_init + * + * Description: + * Initialize ESP32S3 Wi-Fi adapter + * + * Input Parameters: + * None + * + * Returned Value: + * 0 if success or -1 if fail + * + ****************************************************************************/ + +int esp_wifi_adapter_init(void); + +/**************************************************************************** + * Name: esp_wifi_notify_subscribe + * + * Description: + * Enable event notification + * + * Input Parameters: + * pid - Task PID + * event - Signal event data pointer + * + * Returned Value: + * 0 if success or -1 if fail + * + ****************************************************************************/ + +int esp_wifi_notify_subscribe(pid_t pid, struct sigevent *event); + +#ifdef ESP_WLAN_HAS_STA + +/**************************************************************************** + * Name: esp_wifi_sta_start + * + * Description: + * Start Wi-Fi station. + * + * Input Parameters: + * None + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_start(void); + +/**************************************************************************** + * Name: esp_wifi_sta_stop + * + * Description: + * Stop Wi-Fi station. + * + * Input Parameters: + * None + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_stop(void); + +/**************************************************************************** + * Name: esp_wifi_sta_send_data + * + * Description: + * Use Wi-Fi station interface to send 802.3 frame + * + * Input Parameters: + * pbuf - Packet buffer pointer + * len - Packet length + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_send_data(void *pbuf, size_t len); + +/**************************************************************************** + * Name: esp_wifi_set_password + * + * Description: + * Set/Get Wi-Fi station password + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_password(struct iwreq *iwr, bool set); + +/**************************************************************************** + * Name: esp_wifi_sta_essid + * + * Description: + * Set/Get Wi-Fi station ESSID + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_essid(struct iwreq *iwr, bool set); + +/**************************************************************************** + * Name: esp_wifi_sta_bssid + * + * Description: + * Set/Get Wi-Fi station BSSID + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_bssid(struct iwreq *iwr, bool set); + +/**************************************************************************** + * Name: esp_wifi_sta_connect + * + * Description: + * Trigger Wi-Fi station connection action + * + * Input Parameters: + * None + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_connect(void); + +/**************************************************************************** + * Name: esp_wifi_sta_disconnect + * + * Description: + * Trigger Wi-Fi station disconnection action + * + * Input Parameters: + * None + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_disconnect(void); + +/**************************************************************************** + * Name: esp_wifi_sta_mode + * + * Description: + * Set/Get Wi-Fi Station mode code. + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_mode(struct iwreq *iwr, bool set); + +/**************************************************************************** + * Name: esp_wifi_sta_auth + * + * Description: + * Set/Get station authentication mode params. + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_auth(struct iwreq *iwr, bool set); + +/**************************************************************************** + * Name: esp_wifi_sta_freq + * + * Description: + * Get station frequency. + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_freq(struct iwreq *iwr, bool set); + +/**************************************************************************** + * Name: esp_wifi_sta_bitrate + * + * Description: + * Get station default bit rate (Mbps). + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_bitrate(struct iwreq *iwr, bool set); + +/**************************************************************************** + * Name: esp_wifi_sta_get_txpower + * + * Description: + * Get station transmit power (dBm). + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_txpower(struct iwreq *iwr, bool set); + +/**************************************************************************** + * Name: esp_wifi_sta_get_channel_range + * + * Description: + * Get station range of channel parameters. + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_channel(struct iwreq *iwr, bool set); + +/**************************************************************************** + * Name: esp_wifi_sta_country + * + * Description: + * Configure country info. + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_country(struct iwreq *iwr, bool set); + +/**************************************************************************** + * Name: esp_wifi_sta_rssi + * + * Description: + * Get Wi-Fi sensitivity (dBm). + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_sta_rssi(struct iwreq *iwr, bool set); +#endif /* ESP_WLAN_HAS_STA */ + +#ifdef ESP_WLAN_HAS_SOFTAP + +/**************************************************************************** + * Name: esp_wifi_softap_start + * + * Description: + * Start Wi-Fi softAP. + * + * Input Parameters: + * None + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_start(void); + +/**************************************************************************** + * Name: esp_wifi_softap_stop + * + * Description: + * Stop Wi-Fi softAP. + * + * Input Parameters: + * None + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_stop(void); + +/**************************************************************************** + * Name: esp_wifi_softap_send_data + * + * Description: + * Use Wi-Fi softAP interface to send 802.3 frame + * + * Input Parameters: + * pbuf - Packet buffer pointer + * len - Packet length + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_send_data(void *pbuf, size_t len); + +/**************************************************************************** + * Name: esp_wifi_softap_password + * + * Description: + * Set/Get Wi-Fi SoftAP password + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_password(struct iwreq *iwr, bool set); + +/**************************************************************************** + * Name: esp_wifi_softap_essid + * + * Description: + * Set/Get Wi-Fi SoftAP ESSID + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_essid(struct iwreq *iwr, bool set); + +/**************************************************************************** + * Name: esp_wifi_softap_bssid + * + * Description: + * Set/Get Wi-Fi softAP BSSID + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_bssid(struct iwreq *iwr, bool set); + +/**************************************************************************** + * Name: esp_wifi_softap_connect + * + * Description: + * Trigger Wi-Fi softAP accept connection action + * + * Input Parameters: + * None + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_connect(void); + +/**************************************************************************** + * Name: esp_wifi_softap_disconnect + * + * Description: + * Trigger Wi-Fi softAP drop connection action + * + * Input Parameters: + * None + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_disconnect(void); + +/**************************************************************************** + * Name: esp_wifi_softap_mode + * + * Description: + * Set/Get Wi-Fi SoftAP mode code. + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_mode(struct iwreq *iwr, bool set); + +/**************************************************************************** + * Name: esp_wifi_softap_auth + * + * Description: + * Set/Get authentication mode params. + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_auth(struct iwreq *iwr, bool set); + +/**************************************************************************** + * Name: esp_wifi_softap_freq + * + * Description: + * Set/Get SoftAP frequency. + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_freq(struct iwreq *iwr, bool set); + +/**************************************************************************** + * Name: esp_wifi_softap_get_bitrate + * + * Description: + * Get SoftAP default bit rate (Mbps). + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_bitrate(struct iwreq *iwr, bool set); + +/**************************************************************************** + * Name: esp_wifi_softap_txpower + * + * Description: + * Get SoftAP transmit power (dBm). + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_txpower(struct iwreq *iwr, bool set); + +/**************************************************************************** + * Name: esp_wifi_softap_channel + * + * Description: + * Get SoftAP range of channel parameters. + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_channel(struct iwreq *iwr, bool set); + +/**************************************************************************** + * Name: esp_wifi_softap_country + * + * Description: + * Configure country info. + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_country(struct iwreq *iwr, bool set); + +/**************************************************************************** + * Name: esp_wifi_softap_rssi + * + * Description: + * Get Wi-Fi sensitivity (dBm). + * + * Input Parameters: + * iwr - The argument of the ioctl cmd + * set - true: set data; false: get data + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp_wifi_softap_rssi(struct iwreq *iwr, bool set); +#endif /* ESP_WLAN_HAS_SOFTAP */ + +#ifdef __cplusplus +} +#endif +#undef EXTERN + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_RISCV_SRC_ESP32C3_ESP_WIFI_ADAPTER_H */ diff --git a/arch/risc-v/src/esp32c3/hal_esp32c3.mk b/arch/risc-v/src/esp32c3/hal_esp32c3.mk index df41b6c302..188aaf1ab5 100644 --- a/arch/risc-v/src/esp32c3/hal_esp32c3.mk +++ b/arch/risc-v/src/esp32c3/hal_esp32c3.mk @@ -28,12 +28,15 @@ INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)$(CHIP_SERIES)$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)$(CHIP_SERIES)$(DELIM)private_include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_common$(DELIM)include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_event$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)include$(DELIM)esp_private INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)include$(DELIM)soc INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)port$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)port$(DELIM)$(CHIP_SERIES) INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)port$(DELIM)$(CHIP_SERIES)$(DELIM)private_include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_phy$(DELIM)$(CHIP_SERIES)$(DELIM)include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_phy$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_rom$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_rom$(DELIM)include$(DELIM)$(CHIP_SERIES) INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_rom$(DELIM)$(CHIP_SERIES) @@ -42,6 +45,7 @@ INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_system$(DELIM)port$(DELIM)include$(DELIM)private INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_system$(DELIM)port$(DELIM)public_compat INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_timer$(DELIM)include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_wifi$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)$(CHIP_SERIES)$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)platform_port$(DELIM)include @@ -76,15 +80,21 @@ ARCHSCRIPT += $(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM) CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)src$(DELIM)esp_efuse_api.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)src$(DELIM)esp_efuse_utility.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)$(CHIP_SERIES)$(DELIM)esp_efuse_fields.c +CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)$(CHIP_SERIES)$(DELIM)esp_efuse_rtc_calib.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)$(CHIP_SERIES)$(DELIM)esp_efuse_table.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)$(CHIP_SERIES)$(DELIM)esp_efuse_utility.c +CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_common$(DELIM)src$(DELIM)esp_err_to_name.c +CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)adc_share_hw_ctrl.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)clk_ctrl_os.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)cpu.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)esp_clk.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)hw_random.c +CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)mac_addr.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)periph_ctrl.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)regi2c_ctrl.c +CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)sleep_modem.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)port$(DELIM)esp_clk_tree_common.c +CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)port$(DELIM)$(CHIP_SERIES)$(DELIM)adc2_init_cal.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)port$(DELIM)$(CHIP_SERIES)$(DELIM)esp_clk_tree.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)port$(DELIM)$(CHIP_SERIES)$(DELIM)cpu_region_protect.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)port$(DELIM)$(CHIP_SERIES)$(DELIM)rtc_clk.c @@ -94,9 +104,14 @@ CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_ CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)port$(DELIM)$(CHIP_SERIES)$(DELIM)rtc_time.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)port$(DELIM)$(CHIP_SERIES)$(DELIM)sar_periph_ctrl.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)port$(DELIM)$(CHIP_SERIES)$(DELIM)systimer.c +CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_phy$(DELIM)src$(DELIM)lib_printf.c +CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_phy$(DELIM)src$(DELIM)phy_init.c +CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_rom$(DELIM)patches$(DELIM)esp_rom_systimer.c +CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_system$(DELIM)esp_err.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_system$(DELIM)port$(DELIM)brownout.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_system$(DELIM)port$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)clk.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_system$(DELIM)port$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)system_internal.c +CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)adc_hal_common.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)brownout_hal.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)efuse_hal.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)gpio_hal.c diff --git a/boards/risc-v/esp32c3/common/include/esp_board_wlan.h b/boards/risc-v/esp32c3/common/include/esp_board_wlan.h new file mode 100644 index 0000000000..4d51ebec4b --- /dev/null +++ b/boards/risc-v/esp32c3/common/include/esp_board_wlan.h @@ -0,0 +1,73 @@ +/**************************************************************************** + * boards/risc-v/esp32c3/common/include/esp_board_wlan.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __BOARDS_RISCV_ESP32C3_COMMON_INCLUDE_ESP_BOARD_WLAN_H +#define __BOARDS_RISCV_ESP32C3_COMMON_INCLUDE_ESP_BOARD_WLAN_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef CONFIG_ESPRESSIF_WIFI + +/**************************************************************************** + * Name: board_wlan_init + * + * Description: + * Configure the wireless subsystem. + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned + * to indicate the nature of any failure. + * + ****************************************************************************/ + +int board_wlan_init(void); + +#endif /* CONFIG_ESPRESSIF_WIFI */ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __BOARDS_RISCV_ESP32C3_COMMON_INCLUDE_ESP_BOARD_WLAN_H */ diff --git a/boards/risc-v/esp32c3/common/scripts/esp32c3_aliases.ld b/boards/risc-v/esp32c3/common/scripts/esp32c3_aliases.ld index 6ac02f119c..3606cec4f5 100644 --- a/boards/risc-v/esp32c3/common/scripts/esp32c3_aliases.ld +++ b/boards/risc-v/esp32c3/common/scripts/esp32c3_aliases.ld @@ -18,6 +18,7 @@ * ****************************************************************************/ +cache_set_idrom_mmu_size = Cache_Set_IDROM_MMU_Size; cache_dbus_mmu_set = Cache_Dbus_MMU_Set; cache_ibus_mmu_set = Cache_Ibus_MMU_Set; cache_invalidate_icache_all = Cache_Invalidate_ICache_All; diff --git a/boards/risc-v/esp32c3/common/scripts/esp32c3_mcuboot_sections.ld b/boards/risc-v/esp32c3/common/scripts/esp32c3_mcuboot_sections.ld index d44fa9230d..7549e40fa2 100644 --- a/boards/risc-v/esp32c3/common/scripts/esp32c3_mcuboot_sections.ld +++ b/boards/risc-v/esp32c3/common/scripts/esp32c3_mcuboot_sections.ld @@ -59,6 +59,17 @@ SECTIONS _image_drom_lma = LOADADDR(.flash.rodata); _image_drom_size = LOADADDR(.flash.rodata) + SIZEOF(.flash.rodata) - _image_drom_lma; + .flash.appdesc : ALIGN(0x10) + { + _rodata_reserved_start = ABSOLUTE(.); /* This is a symbol marking the flash.rodata start, this can be used for mmu driver to maintain virtual address */ + _rodata_start = ABSOLUTE(.); + + /* Create an empty gap within this section. Thanks to this, the end of this + * section will match .flash.rodata's begin address. Thus, both sections + * will be merged when creating the final bin image. */ + . = ALIGN(ALIGNOF(.flash.rodata)); + } >default_rodata_seg + .flash.rodata : { _srodata = ABSOLUTE(.); @@ -115,6 +126,16 @@ SECTIONS . = ALIGN(4); } >drom0_0_seg AT>ROM + .flash.rodata_noload (NOLOAD) : + { + /* + This is a symbol marking the flash.rodata end, this can be used for mmu driver to maintain virtual address + We don't need to include the noload rodata in this section + */ + _rodata_reserved_end = ABSOLUTE(.); + . = ALIGN (4); + } > default_rodata_seg AT > ROM + .iram0.text : { _iram_start = ABSOLUTE(.); @@ -263,6 +284,8 @@ SECTIONS .flash.text : ALIGN(0x0000FFFF) { _stext = .; + _instruction_reserved_start = ABSOLUTE(.); /* This is a symbol marking the flash.text start, this can be used for mmu driver to maintain virtual address */ + _text_start = ABSOLUTE(.); *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ @@ -271,6 +294,8 @@ SECTIONS *(.gnu.version) . = ALIGN(4); + _text_end = ABSOLUTE(.); + _instruction_reserved_end = ABSOLUTE(.); /* This is a symbol marking the flash.text end, this can be used for mmu driver to maintain virtual address */ _etext = .; } >irom0_0_seg AT>ROM diff --git a/boards/risc-v/esp32c3/common/scripts/esp32c3_simple_boot_sections.ld b/boards/risc-v/esp32c3/common/scripts/esp32c3_simple_boot_sections.ld index 765facd9ff..e45c748124 100644 --- a/boards/risc-v/esp32c3/common/scripts/esp32c3_simple_boot_sections.ld +++ b/boards/risc-v/esp32c3/common/scripts/esp32c3_simple_boot_sections.ld @@ -47,6 +47,8 @@ SECTIONS *libarch.a:*esp_clk_tree_common.*(.text .text.* .literal .literal.*) *libarch.a:*clk_tree_hal.*(.text .text.* .literal .literal.*) *libarch.a:*rtc_init.*(.text .text.* .literal .literal.*) + *libarch.a:*regi2c_ctrl.*(.text .text.* .literal .literal.*) + *libarch.a:*gpio_periph.*(.text .text.* .literal .literal.*) *libarch.a:*rtc_clk.*(.text .text.* .literal .literal.*) *libarch.a:*rtc_clk_init.*(.text .text.* .literal .literal.*) *libarch.a:*rtc_sleep.*(.text .text.* .literal .literal.*) @@ -85,6 +87,7 @@ SECTIONS *libarch.a:*esp_rom_spiflash.*(.text .text.* .literal .literal.*) *libarch.a:*esp_efuse_fields.*(.text .text.* .literal .literal.*) *libarch.a:*esp_efuse_api_key.*(.text .text.* .literal .literal.*) + *libarch.a:*efuse_hal.*(.text .text.* .literal .literal.*) *libarch.a:*log.*(.text .text.* .literal .literal.*) *libarch.a:*log_noos.*(.text .text.* .literal .literal.*) *libarch.a:esp_spiflash.*(.literal .text .literal.* .text.*) @@ -92,6 +95,12 @@ SECTIONS esp_head.*(.literal .text .literal.* .text.*) esp_start.*(.literal .text .literal.* .text.*) + *(.wifi0iram.*) + *(.wifirxiram.*) + *(.wifislpiram.*) + *(.wifiorslpiram.*) + *(.wifislprxiram.*) + } >iram0_0_seg AT > ROM /* This section is required to skip .iram0.text area because iram0_0_seg @@ -144,6 +153,8 @@ SECTIONS *libarch.a:*esp_clk_tree_common.*(.rodata .rodata.*) *libarch.a:*clk_tree_hal.*(.rodata .rodata.*) *libarch.a:*rtc_init.*(.rodata .rodata.*) + *libarch.a:*regi2c_ctrl.*(.rodata .rodata.*) + *libarch.a:*gpio_periph.*(.rodata .rodata.*) *libarch.a:*rtc_clk.*(.rodata .rodata.*) *libarch.a:*rtc_clk_init.*(.rodata .rodata.*) *libarch.a:*rtc_sleep.*(.rodata .rodata.*) @@ -182,6 +193,7 @@ SECTIONS *libarch.a:*esp_rom_spiflash.*(.rodata .rodata.*) *libarch.a:*esp_efuse_fields.*(.rodata .rodata.*) *libarch.a:*esp_efuse_api_key.*(.rodata .rodata.*) + *libarch.a:*efuse_hal.*(.rodata .rodata.*) *libarch.a:*log.*(.rodata .rodata.*) *libarch.a:*log_noos.*(.rodata .rodata.*) *libarch.a:esp_spiflash.*(.rodata .rodata.*) @@ -228,12 +240,17 @@ SECTIONS .flash.text : ALIGN(0xFFFF) { _stext = .; + _instruction_reserved_start = ABSOLUTE(.); /* This is a symbol marking the flash.text start, this can be used for mmu driver to maintain virtual address */ + _text_start = ABSOLUTE(.); *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ *(.fini.literal) *(.fini) *(.gnu.version) + + _text_end = ABSOLUTE(.); + _instruction_reserved_end = ABSOLUTE(.); /* This is a symbol marking the flash.text end, this can be used for mmu driver to maintain virtual address */ _etext = .; /* Similar to _iram_start, this symbol goes here so it is @@ -265,6 +282,17 @@ SECTIONS _image_drom_lma = LOADADDR(.flash.rodata); _image_drom_size = LOADADDR(.flash.rodata) + SIZEOF(.flash.rodata) - _image_drom_lma; + .flash.appdesc : ALIGN(0x10) + { + _rodata_reserved_start = ABSOLUTE(.); /* This is a symbol marking the flash.rodata start, this can be used for mmu driver to maintain virtual address */ + _rodata_start = ABSOLUTE(.); + + /* Create an empty gap within this section. Thanks to this, the end of this + * section will match .flash.rodata's begin address. Thus, both sections + * will be merged when creating the final bin image. */ + . = ALIGN(ALIGNOF(.flash.rodata)); + } >default_rodata_seg + .flash.rodata : ALIGN(0xFFFF) { _srodata = ABSOLUTE(.); @@ -273,6 +301,11 @@ SECTIONS *(.rodata) *(.rodata.*) + *(.rodata_wlog_verbose.*) + *(.rodata_wlog_debug.*) + *(.rodata_wlog_info.*) + *(.rodata_wlog_warning.*) + *(.rodata_wlog_error.*) *(.srodata.*) @@ -324,6 +357,16 @@ SECTIONS . = ALIGN(4); } >default_rodata_seg AT > ROM + .flash.rodata_noload (NOLOAD) : + { + /* + This is a symbol marking the flash.rodata end, this can be used for mmu driver to maintain virtual address + We don't need to include the noload rodata in this section + */ + _rodata_reserved_end = ABSOLUTE(.); + . = ALIGN (4); + } > default_rodata_seg AT > ROM + /* Marks the end of IRAM code segment */ .iram0.text_end (NOLOAD) : diff --git a/boards/risc-v/esp32c3/common/src/Make.defs b/boards/risc-v/esp32c3/common/src/Make.defs index cb67d40f57..ab73484da0 100644 --- a/boards/risc-v/esp32c3/common/src/Make.defs +++ b/boards/risc-v/esp32c3/common/src/Make.defs @@ -36,6 +36,10 @@ ifeq ($(CONFIG_ESPRESSIF_TWAI),y) CSRCS += esp_board_twai.c endif +ifeq ($(CONFIG_ESPRESSIF_WIFI),y) + CSRCS += esp_board_wlan.c +endif + DEPPATH += --dep-path src VPATH += :src CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)src diff --git a/boards/risc-v/esp32c3/common/src/esp_board_wlan.c b/boards/risc-v/esp32c3/common/src/esp_board_wlan.c new file mode 100644 index 0000000000..24a7fe17b0 --- /dev/null +++ b/boards/risc-v/esp32c3/common/src/esp_board_wlan.c @@ -0,0 +1,81 @@ +/**************************************************************************** + * boards/risc-v/esp32c3/common/src/esp_board_wlan.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "espressif/esp_wlan.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_wlan_init + * + * Description: + * Configure the wireless subsystem. + * + * Input Parameters: + * None. + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned + * to indicate the nature of any failure. + * + ****************************************************************************/ + +int board_wlan_init(void) +{ + int ret = OK; + +#ifdef ESP_WLAN_HAS_STA + ret = esp_wlan_sta_initialize(); + if (ret) + { + wlerr("ERROR: Failed to initialize Wi-Fi station\n"); + return ret; + } +#endif /* ESP_WLAN_HAS_STA */ + +#ifdef ESP_WLAN_HAS_SOFTAP + ret = esp_wlan_softap_initialize(); + if (ret) + { + wlerr("ERROR: Failed to initialize Wi-Fi softAP\n"); + return ret; + } +#endif /* ESP_WLAN_HAS_SOFTAP */ + + return ret; +} + diff --git a/boards/risc-v/esp32c3/esp32c3-generic/configs/sta_softap/defconfig b/boards/risc-v/esp32c3/esp32c3-generic/configs/sta_softap/defconfig new file mode 100644 index 0000000000..21b3732119 --- /dev/null +++ b/boards/risc-v/esp32c3/esp32c3-generic/configs/sta_softap/defconfig @@ -0,0 +1,82 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_NDEBUG is not set +# CONFIG_NSH_ARGCAT is not set +# CONFIG_NSH_CMDOPT_HEXDUMP is not set +CONFIG_ALLOW_BSD_COMPONENTS=y +CONFIG_ARCH="risc-v" +CONFIG_ARCH_BOARD="esp32c3-generic" +CONFIG_ARCH_BOARD_COMMON=y +CONFIG_ARCH_BOARD_ESP32C3_GENERIC=y +CONFIG_ARCH_CHIP="esp32c3" +CONFIG_ARCH_CHIP_ESP32C3_GENERIC=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_RISCV=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BOARD_LOOPSPERMSEC=15000 +CONFIG_BUILTIN=y +CONFIG_DEV_ZERO=y +CONFIG_DRIVERS_IEEE80211=y +CONFIG_DRIVERS_WIRELESS=y +CONFIG_ESPRESSIF_SPIFLASH=y +CONFIG_ESPRESSIF_SPIFLASH_SPIFFS=y +CONFIG_ESPRESSIF_WIFI=y +CONFIG_ESPRESSIF_WIFI_STATION_SOFTAP=y +CONFIG_EXAMPLES_DHCPD=y +CONFIG_EXAMPLES_RANDOM=y +CONFIG_FS_PROCFS=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INIT_STACKSIZE=8192 +CONFIG_INTELHEX_BINARY=y +CONFIG_IOB_THROTTLE=24 +CONFIG_LIBC_PERROR_STDOUT=y +CONFIG_LIBC_STRERROR=y +CONFIG_NETDB_DNSCLIENT=y +CONFIG_NETDEV_LATEINIT=y +CONFIG_NETDEV_PHY_IOCTL=y +CONFIG_NETDEV_WIRELESS_IOCTL=y +CONFIG_NETDEV_WORK_THREAD=y +CONFIG_NETUTILS_CJSON=y +CONFIG_NETUTILS_DHCPD=y +CONFIG_NET_BROADCAST=y +CONFIG_NET_ICMP=y +CONFIG_NET_ICMP_SOCKET=y +CONFIG_NET_TCP=y +CONFIG_NET_TCP_DELAYED_ACK=y +CONFIG_NET_TCP_WRITE_BUFFERS=y +CONFIG_NET_UDP=y +CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_READLINE=y +CONFIG_NSH_STRERROR=y +CONFIG_PREALLOC_TIMERS=0 +CONFIG_PTHREAD_MUTEX_TYPES=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_BACKTRACE=y +CONFIG_SCHED_LPWORK=y +CONFIG_SCHED_WAITPID=y +CONFIG_SIG_DEFAULT=y +CONFIG_START_DAY=29 +CONFIG_START_MONTH=11 +CONFIG_START_YEAR=2019 +CONFIG_SYSTEM_DHCPC_RENEW=y +CONFIG_SYSTEM_DUMPSTACK=y +CONFIG_SYSTEM_NSH=y +CONFIG_SYSTEM_PING=y +CONFIG_TESTING_GETPRIME=y +CONFIG_TESTING_OSTEST=y +CONFIG_TLS_TASK_NELEM=4 +CONFIG_UART0_SERIAL_CONSOLE=y +CONFIG_WIRELESS=y +CONFIG_WIRELESS_WAPI=y +CONFIG_WIRELESS_WAPI_CMDTOOL=y +CONFIG_WIRELESS_WAPI_INITCONF=y diff --git a/boards/risc-v/esp32c3/esp32c3-generic/configs/wifi/defconfig b/boards/risc-v/esp32c3/esp32c3-generic/configs/wifi/defconfig new file mode 100644 index 0000000000..57b13c7375 --- /dev/null +++ b/boards/risc-v/esp32c3/esp32c3-generic/configs/wifi/defconfig @@ -0,0 +1,78 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_NDEBUG is not set +# CONFIG_NSH_ARGCAT is not set +# CONFIG_NSH_CMDOPT_HEXDUMP is not set +CONFIG_ALLOW_BSD_COMPONENTS=y +CONFIG_ARCH="risc-v" +CONFIG_ARCH_BOARD="esp32c3-generic" +CONFIG_ARCH_BOARD_COMMON=y +CONFIG_ARCH_BOARD_ESP32C3_GENERIC=y +CONFIG_ARCH_CHIP="esp32c3" +CONFIG_ARCH_CHIP_ESP32C3_GENERIC=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_RISCV=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BOARD_LOOPSPERMSEC=15000 +CONFIG_BUILTIN=y +CONFIG_DEV_ZERO=y +CONFIG_DRIVERS_IEEE80211=y +CONFIG_DRIVERS_WIRELESS=y +CONFIG_ESPRESSIF_SPIFLASH=y +CONFIG_ESPRESSIF_SPIFLASH_SPIFFS=y +CONFIG_ESPRESSIF_WIFI=y +CONFIG_EXAMPLES_RANDOM=y +CONFIG_FS_PROCFS=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INIT_STACKSIZE=8192 +CONFIG_INTELHEX_BINARY=y +CONFIG_IOB_THROTTLE=24 +CONFIG_LIBC_PERROR_STDOUT=y +CONFIG_LIBC_STRERROR=y +CONFIG_NETDB_DNSCLIENT=y +CONFIG_NETDEV_LATEINIT=y +CONFIG_NETDEV_PHY_IOCTL=y +CONFIG_NETDEV_WIRELESS_IOCTL=y +CONFIG_NETDEV_WORK_THREAD=y +CONFIG_NETUTILS_CJSON=y +CONFIG_NET_BROADCAST=y +CONFIG_NET_ICMP=y +CONFIG_NET_ICMP_SOCKET=y +CONFIG_NET_TCP=y +CONFIG_NET_TCP_DELAYED_ACK=y +CONFIG_NET_TCP_WRITE_BUFFERS=y +CONFIG_NET_UDP=y +CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_READLINE=y +CONFIG_NSH_STRERROR=y +CONFIG_PREALLOC_TIMERS=0 +CONFIG_PTHREAD_MUTEX_TYPES=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_BACKTRACE=y +CONFIG_SCHED_LPWORK=y +CONFIG_SCHED_WAITPID=y +CONFIG_SIG_DEFAULT=y +CONFIG_START_DAY=29 +CONFIG_START_MONTH=11 +CONFIG_START_YEAR=2019 +CONFIG_SYSTEM_DHCPC_RENEW=y +CONFIG_SYSTEM_DUMPSTACK=y +CONFIG_SYSTEM_NSH=y +CONFIG_SYSTEM_PING=y +CONFIG_TESTING_GETPRIME=y +CONFIG_TESTING_OSTEST=y +CONFIG_TLS_TASK_NELEM=4 +CONFIG_UART0_SERIAL_CONSOLE=y +CONFIG_WIRELESS=y +CONFIG_WIRELESS_WAPI=y +CONFIG_WIRELESS_WAPI_CMDTOOL=y +CONFIG_WIRELESS_WAPI_INITCONF=y diff --git a/boards/risc-v/esp32c3/esp32c3-generic/src/esp32c3_bringup.c b/boards/risc-v/esp32c3/esp32c3-generic/src/esp32c3_bringup.c index 88f5c5f34d..04d4eaf771 100644 --- a/boards/risc-v/esp32c3/esp32c3-generic/src/esp32c3_bringup.c +++ b/boards/risc-v/esp32c3/esp32c3-generic/src/esp32c3_bringup.c @@ -65,6 +65,14 @@ # include "esp_board_rmt.h" #endif +#ifdef CONFIG_ESPRESSIF_WIFI_BT_COEXIST +# include "esp_coexist_internal.h" +#endif + +#ifdef CONFIG_ESPRESSIF_WIFI +# include "esp_board_wlan.h" +#endif + #include "esp32c3-generic.h" /**************************************************************************** @@ -152,6 +160,20 @@ int esp_bringup(void) } #endif +#ifdef CONFIG_ESPRESSIF_WIFI_BT_COEXIST + esp_coex_adapter_register(&g_coex_adapter_funcs); + coex_pre_init(); +#endif + +#ifdef CONFIG_ESPRESSIF_WIFI + ret = board_wlan_init(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to initialize wireless subsystem=%d\n", + ret); + } +#endif + #ifdef CONFIG_ONESHOT ret = esp_oneshot_initialize(); if (ret < 0)