From 58b7fc1d8b6eaf7880a8d7cff5d80adcb21f3c34 Mon Sep 17 00:00:00 2001 From: yuexia Date: Tue, 20 Dec 2022 22:05:47 +0800 Subject: [PATCH 1/6] esp32c6: enable wifi --- components/esp_hw_support/sleep_modes.c | 12 + components/esp_wifi/esp32c6/esp_adapter.c | 796 ++++++++++++++++++ .../esp32c6/include/soc/Kconfig.soc_caps.in | 4 + components/soc/esp32c6/include/soc/soc_caps.h | 2 +- 4 files changed, 813 insertions(+), 1 deletion(-) create mode 100644 components/esp_wifi/esp32c6/esp_adapter.c diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 067ef09a91..b51a2705ba 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -375,6 +375,9 @@ inline static bool is_light_sleep(uint32_t pd_flags) static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) { +#if CONFIG_IDF_TARGET_ESP32C6 + return 0; // TODO: WIFI-5150 +#else // Stop UART output so that output is not lost due to APB frequency change. // For light sleep, suspend UART output — it will resume after wakeup. // For deep sleep, wait for the contents of UART FIFO to be sent. @@ -539,6 +542,7 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) resume_uarts(); return result; +#endif } inline static uint32_t IRAM_ATTR call_rtc_sleep_start(uint32_t reject_triggers, uint32_t lslp_mem_inf_fpu) @@ -617,6 +621,9 @@ static esp_err_t esp_light_sleep_inner(uint32_t pd_flags, uint32_t flash_enable_time_us, rtc_vddsdio_config_t vddsdio_config) { +#if CONFIG_IDF_TARGET_ESP32C6 + return ESP_ERR_NOT_SUPPORTED; // TODO: WIFI-5150 +#else // Enter sleep uint32_t reject = esp_sleep_start(pd_flags); @@ -633,6 +640,7 @@ static esp_err_t esp_light_sleep_inner(uint32_t pd_flags, } return reject ? ESP_ERR_SLEEP_REJECT : ESP_OK; +#endif } /** @@ -653,6 +661,9 @@ static inline bool can_power_down_vddsdio(const uint32_t vddsdio_pd_sleep_durati esp_err_t esp_light_sleep_start(void) { +#if CONFIG_IDF_TARGET_ESP32C6 + return ESP_ERR_NOT_SUPPORTED; // TODO: WIFI-5150 +#else #if CONFIG_ESP_TASK_WDT_USE_ESP_TIMER esp_err_t timerret = ESP_OK; @@ -843,6 +854,7 @@ esp_err_t esp_light_sleep_start(void) #endif // CONFIG_ESP_TASK_WDT_USE_ESP_TIMER return err; +#endif } esp_err_t esp_sleep_disable_wakeup_source(esp_sleep_source_t source) diff --git a/components/esp_wifi/esp32c6/esp_adapter.c b/components/esp_wifi/esp32c6/esp_adapter.c new file mode 100644 index 0000000000..ea4a676797 --- /dev/null +++ b/components/esp_wifi/esp32c6/esp_adapter.c @@ -0,0 +1,796 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/semphr.h" +#include "freertos/event_groups.h" +#include "freertos/portmacro.h" +#include "riscv/interrupt.h" +#include "esp_types.h" +#include "esp_random.h" +#include "esp_mac.h" +#include "esp_task.h" +#include "esp_intr_alloc.h" +#include "esp_attr.h" +#include "esp_log.h" +#include "esp_event.h" +#include "esp_heap_caps.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_periph.h" +#include "soc/rtc.h" +#include "esp_private/sleep_retention.h" +#include "phy_init_data.h" +#include "esp_private/periph_ctrl.h" +#include "esp_private/esp_clk.h" +#include "nvs.h" +#include "os.h" +#include "esp_smartconfig.h" +#include "esp_coexist_internal.h" +#include "esp_coexist_adapter.h" +#include "esp32c6/rom/ets_sys.h" + +#define TAG "esp_adapter" + +#ifdef CONFIG_PM_ENABLE +extern void wifi_apb80m_request(void); +extern void wifi_apb80m_release(void); +#endif + +IRAM_ATTR void *wifi_malloc( size_t size ) +{ + return malloc(size); +} + +IRAM_ATTR void *wifi_realloc( void *ptr, size_t size ) +{ + return realloc(ptr, size); +} + +IRAM_ATTR void *wifi_calloc( size_t n, size_t size ) +{ + return calloc(n, size); +} + +static void *IRAM_ATTR wifi_zalloc_wrapper(size_t size) +{ + void *ptr = wifi_calloc(1, size); + return ptr; +} + +wifi_static_queue_t *wifi_create_queue( int queue_len, int item_size) +{ + wifi_static_queue_t *queue = NULL; + + queue = (wifi_static_queue_t *)heap_caps_malloc(sizeof(wifi_static_queue_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + if (!queue) { + return NULL; + } + + queue->handle = xQueueCreate( queue_len, item_size); + return queue; +} + +void wifi_delete_queue(wifi_static_queue_t *queue) +{ + if (queue) { + vQueueDelete(queue->handle); + free(queue); + } +} + +static void *wifi_create_queue_wrapper(int queue_len, int item_size) +{ + return wifi_create_queue(queue_len, item_size); +} + +static void wifi_delete_queue_wrapper(void *queue) +{ + wifi_delete_queue(queue); +} + +static bool IRAM_ATTR env_is_chip_wrapper(void) +{ +#ifdef CONFIG_IDF_ENV_FPGA + return false; +#else + return true; +#endif +} + +static void set_intr_wrapper(int32_t cpu_no, uint32_t intr_source, uint32_t intr_num, int32_t intr_prio) +{ + intr_matrix_route(intr_source, intr_num); + esprv_intc_int_set_priority(intr_num, intr_prio); + esprv_intc_int_set_type(intr_num, INTR_TYPE_LEVEL); +} + +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) +{ + intr_handler_set(n, (intr_handler_t)f, arg); +} + +static void enable_intr_wrapper(uint32_t intr_mask) +{ + esprv_intc_int_enable(intr_mask); +} + +static void disable_intr_wrapper(uint32_t intr_mask) +{ + esprv_intc_int_disable(intr_mask); +} + +static void *spin_lock_create_wrapper(void) +{ + portMUX_TYPE tmp = portMUX_INITIALIZER_UNLOCKED; + void *mux = malloc(sizeof(portMUX_TYPE)); + + if (mux) { + memcpy(mux, &tmp, sizeof(portMUX_TYPE)); + return mux; + } + return NULL; +} + +static uint32_t IRAM_ATTR wifi_int_disable_wrapper(void *wifi_int_mux) +{ + if (xPortInIsrContext()) { + portENTER_CRITICAL_ISR(wifi_int_mux); + } else { + portENTER_CRITICAL(wifi_int_mux); + } + + return 0; +} + +static void IRAM_ATTR wifi_int_restore_wrapper(void *wifi_int_mux, uint32_t tmp) +{ + if (xPortInIsrContext()) { + portEXIT_CRITICAL_ISR(wifi_int_mux); + } else { + portEXIT_CRITICAL(wifi_int_mux); + } +} + +static bool IRAM_ATTR is_from_isr_wrapper(void) +{ + return !xPortCanYield(); +} + +static void IRAM_ATTR task_yield_from_isr_wrapper(void) +{ + portYIELD_FROM_ISR(); +} + +static void *semphr_create_wrapper(uint32_t max, uint32_t init) +{ + return (void *)xSemaphoreCreateCounting(max, init); +} + +static void semphr_delete_wrapper(void *semphr) +{ + vSemaphoreDelete(semphr); +} + +static void wifi_thread_semphr_free(void *data) +{ + SemaphoreHandle_t *sem = (SemaphoreHandle_t *)(data); + + if (sem) { + vSemaphoreDelete(sem); + } +} + +static void *wifi_thread_semphr_get_wrapper(void) +{ + static bool s_wifi_thread_sem_key_init = false; + static pthread_key_t s_wifi_thread_sem_key; + SemaphoreHandle_t sem = NULL; + + if (s_wifi_thread_sem_key_init == false) { + if (0 != pthread_key_create(&s_wifi_thread_sem_key, wifi_thread_semphr_free)) { + return NULL; + } + s_wifi_thread_sem_key_init = true; + } + + sem = pthread_getspecific(s_wifi_thread_sem_key); + if (!sem) { + sem = xSemaphoreCreateCounting(1, 0); + if (sem) { + pthread_setspecific(s_wifi_thread_sem_key, sem); + ESP_LOGV(TAG, "thread sem create: sem=%p", sem); + } + } + + ESP_LOGV(TAG, "thread sem get: sem=%p", sem); + return (void *)sem; +} + +static int32_t IRAM_ATTR semphr_take_from_isr_wrapper(void *semphr, void *hptw) +{ + return (int32_t)xSemaphoreTakeFromISR(semphr, hptw); +} + +static int32_t IRAM_ATTR semphr_give_from_isr_wrapper(void *semphr, void *hptw) +{ + return (int32_t)xSemaphoreGiveFromISR(semphr, hptw); +} + +static int32_t semphr_take_wrapper(void *semphr, uint32_t block_time_tick) +{ + if (block_time_tick == OSI_FUNCS_TIME_BLOCKING) { + return (int32_t)xSemaphoreTake(semphr, portMAX_DELAY); + } else { + return (int32_t)xSemaphoreTake(semphr, block_time_tick); + } +} + +static int32_t semphr_give_wrapper(void *semphr) +{ + return (int32_t)xSemaphoreGive(semphr); +} + +static void *recursive_mutex_create_wrapper(void) +{ + return (void *)xSemaphoreCreateRecursiveMutex(); +} + +static void *mutex_create_wrapper(void) +{ + return (void *)xSemaphoreCreateMutex(); +} + +static void mutex_delete_wrapper(void *mutex) +{ + vSemaphoreDelete(mutex); +} + +static int32_t IRAM_ATTR mutex_lock_wrapper(void *mutex) +{ + return (int32_t)xSemaphoreTakeRecursive(mutex, portMAX_DELAY); +} + +static int32_t IRAM_ATTR mutex_unlock_wrapper(void *mutex) +{ + return (int32_t)xSemaphoreGiveRecursive(mutex); +} + +static void *queue_create_wrapper(uint32_t queue_len, uint32_t item_size) +{ + return (void *)xQueueCreate(queue_len, item_size); +} + +static int32_t queue_send_wrapper(void *queue, void *item, uint32_t block_time_tick) +{ + if (block_time_tick == OSI_FUNCS_TIME_BLOCKING) { + return (int32_t)xQueueSend(queue, item, portMAX_DELAY); + } else { + return (int32_t)xQueueSend(queue, item, block_time_tick); + } +} + +static int32_t IRAM_ATTR queue_send_from_isr_wrapper(void *queue, void *item, void *hptw) +{ + return (int32_t)xQueueSendFromISR(queue, item, hptw); +} + +static int32_t queue_send_to_back_wrapper(void *queue, void *item, uint32_t block_time_tick) +{ + return (int32_t)xQueueGenericSend(queue, item, block_time_tick, queueSEND_TO_BACK); +} + +static int32_t queue_send_to_front_wrapper(void *queue, void *item, uint32_t block_time_tick) +{ + return (int32_t)xQueueGenericSend(queue, item, block_time_tick, queueSEND_TO_FRONT); +} + +static int32_t queue_recv_wrapper(void *queue, void *item, uint32_t block_time_tick) +{ + if (block_time_tick == OSI_FUNCS_TIME_BLOCKING) { + return (int32_t)xQueueReceive(queue, item, portMAX_DELAY); + } else { + return (int32_t)xQueueReceive(queue, item, 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) +{ + if (block_time_tick == OSI_FUNCS_TIME_BLOCKING) { + return (uint32_t)xEventGroupWaitBits(event, bits_to_wait_for, clear_on_exit, wait_for_all_bits, portMAX_DELAY); + } else { + return (uint32_t)xEventGroupWaitBits(event, bits_to_wait_for, clear_on_exit, wait_for_all_bits, 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) +{ + return (uint32_t)xTaskCreatePinnedToCore(task_func, name, stack_depth, param, prio, task_handle, (core_id < portNUM_PROCESSORS ? core_id : tskNO_AFFINITY)); +} + +static int32_t task_create_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle) +{ + return (uint32_t)xTaskCreate(task_func, name, stack_depth, param, prio, task_handle); +} + +static int32_t IRAM_ATTR task_ms_to_tick_wrapper(uint32_t ms) +{ + return (int32_t)(ms / portTICK_PERIOD_MS); +} + +static int32_t task_get_max_priority_wrapper(void) +{ + return (int32_t)(configMAX_PRIORITIES); +} + +static 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_to_wait) +{ + if (ticks_to_wait == OSI_FUNCS_TIME_BLOCKING) { + return (int32_t)esp_event_post(event_base, event_id, event_data, event_data_size, portMAX_DELAY); + } else { + return (int32_t)esp_event_post(event_base, event_id, event_data, event_data_size, ticks_to_wait); + } +} + +static void IRAM_ATTR wifi_apb80m_request_wrapper(void) +{ +#ifdef CONFIG_PM_ENABLE + wifi_apb80m_request(); +#endif +} + +static void IRAM_ATTR wifi_apb80m_release_wrapper(void) +{ +#ifdef CONFIG_PM_ENABLE + wifi_apb80m_release(); +#endif +} + +static void IRAM_ATTR timer_arm_wrapper(void *timer, uint32_t tmout, bool repeat) +{ + ets_timer_arm(timer, tmout, repeat); +} + +static void IRAM_ATTR timer_disarm_wrapper(void *timer) +{ + ets_timer_disarm(timer); +} + +static void timer_done_wrapper(void *ptimer) +{ + ets_timer_done(ptimer); +} + +static void timer_setfn_wrapper(void *ptimer, void *pfunction, void *parg) +{ + ets_timer_setfn(ptimer, pfunction, parg); +} + +static void IRAM_ATTR timer_arm_us_wrapper(void *ptimer, uint32_t us, bool repeat) +{ + ets_timer_arm_us(ptimer, us, repeat); +} + +static void wifi_reset_mac_wrapper(void) +{ + // TODO: IDF-5713 + ESP_LOGW(TAG, "wifi_reset_mac_wrapper() has not been implemented yet"); +} + +static void IRAM_ATTR wifi_rtc_enable_iso_wrapper(void) +{ + // TODO: IDF-5351 + ESP_LOGW(TAG, "wifi_rtc_enable_iso_wrapper() has not been implemented yet"); +} + +static void IRAM_ATTR wifi_rtc_disable_iso_wrapper(void) +{ + // TODO: IDF-5351 + ESP_LOGW(TAG, "wifi_rtc_disable_iso_wrapper() has not been implemented yet"); +} + +static void wifi_clock_enable_wrapper(void) +{ + wifi_module_enable(); +} + +static void wifi_clock_disable_wrapper(void) +{ + wifi_module_disable(); +} + +static int get_time_wrapper(void *t) +{ + return os_get_time(t); +} + +static uint32_t esp_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. + */ + return (esp_clk_slowclk_cal_get() >> (RTC_CLK_CAL_FRACT - SOC_WIFI_LIGHT_SLEEP_CLK_WIDTH)); +} + +static void *IRAM_ATTR malloc_internal_wrapper(size_t size) +{ + return heap_caps_malloc(size, MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); +} + +static void *IRAM_ATTR realloc_internal_wrapper(void *ptr, size_t size) +{ + return heap_caps_realloc(ptr, size, MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); +} + +static void *IRAM_ATTR calloc_internal_wrapper(size_t n, size_t size) +{ + return heap_caps_calloc(n, size, MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); +} + +static void *IRAM_ATTR zalloc_internal_wrapper(size_t size) +{ + void *ptr = heap_caps_calloc(1, size, MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); + return ptr; +} + +static esp_err_t nvs_open_wrapper(const char *name, unsigned int open_mode, nvs_handle_t *out_handle) +{ + return nvs_open(name, (nvs_open_mode_t)open_mode, out_handle); +} + +static void esp_log_writev_wrapper(unsigned int level, const char *tag, const char *format, va_list args) +{ + return esp_log_writev((esp_log_level_t)level, tag, format, args); +} + +static void esp_log_write_wrapper(unsigned int level, const char *tag, const char *format, ...) +{ + va_list list; + va_start(list, format); + esp_log_writev((esp_log_level_t)level, tag, format, list); + va_end(list); +} + +static esp_err_t esp_read_mac_wrapper(uint8_t *mac, unsigned int type) +{ + return esp_read_mac(mac, (esp_mac_type_t)type); +} + +static int coex_init_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + return coex_init(); +#else + return 0; +#endif +} + +static void coex_deinit_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + coex_deinit(); +#endif +} + +static int coex_enable_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + return coex_enable(); +#else + return 0; +#endif +} + +static void coex_disable_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + coex_disable(); +#endif +} + +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 +} + +static void coex_condition_set_wrapper(uint32_t type, bool dissatisfy) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + coex_condition_set(type, dissatisfy); +#endif +} + +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 +} + +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 +} + +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 +} + +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 +} + +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 +} + +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 +} + +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 +} + +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 +} + +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 +} + +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 +} + +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 +} + +static int coex_schm_curr_phase_idx_set_wrapper(int idx) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + return coex_schm_curr_phase_idx_set(idx); +#else + return 0; +#endif +} + +static int coex_schm_curr_phase_idx_get_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + return coex_schm_curr_phase_idx_get(); +#else + return 0; +#endif +} + +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 +} + +static void IRAM_ATTR esp_empty_wrapper(void) +{ + +} + +wifi_osi_funcs_t g_wifi_osi_funcs = { + ._version = ESP_WIFI_OS_ADAPTER_VERSION, + ._env_is_chip = 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 = spin_lock_create_wrapper, + ._spin_lock_delete = free, + ._wifi_int_disable = wifi_int_disable_wrapper, + ._wifi_int_restore = wifi_int_restore_wrapper, + ._task_yield_from_isr = task_yield_from_isr_wrapper, + ._semphr_create = semphr_create_wrapper, + ._semphr_delete = semphr_delete_wrapper, + ._semphr_take = semphr_take_wrapper, + ._semphr_give = 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 = (void(*)(void *))vQueueDelete, + ._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 = (uint32_t(*)(void *))uxQueueMessagesWaiting, + ._event_group_create = (void *(*)(void))xEventGroupCreate, + ._event_group_delete = (void(*)(void *))vEventGroupDelete, + ._event_group_set_bits = (uint32_t(*)(void *, uint32_t))xEventGroupSetBits, + ._event_group_clear_bits = (uint32_t(*)(void *, uint32_t))xEventGroupClearBits, + ._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 = (void(*)(void *))vTaskDelete, + ._task_delay = vTaskDelay, + ._task_ms_to_tick = task_ms_to_tick_wrapper, + ._task_get_current_task = (void *(*)(void))xTaskGetCurrentTaskHandle, + ._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_internal_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 = timer_disarm_wrapper, + ._timer_done = timer_done_wrapper, + ._timer_setfn = timer_setfn_wrapper, + ._timer_arm_us = 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 = esp_timer_get_time, + ._nvs_set_i8 = nvs_set_i8, + ._nvs_get_i8 = nvs_get_i8, + ._nvs_set_u8 = nvs_set_u8, + ._nvs_get_u8 = nvs_get_u8, + ._nvs_set_u16 = nvs_set_u16, + ._nvs_get_u16 = nvs_get_u16, + ._nvs_open = nvs_open_wrapper, + ._nvs_close = nvs_close, + ._nvs_commit = nvs_commit, + ._nvs_set_blob = nvs_set_blob, + ._nvs_get_blob = nvs_get_blob, + ._nvs_erase_key = nvs_erase_key, + ._get_random = os_get_random, + ._get_time = get_time_wrapper, + ._random = os_random, + ._slowclk_cal_get = esp_clk_slowclk_cal_get_wrapper, + ._log_write = esp_log_write_wrapper, + ._log_writev = esp_log_writev_wrapper, + ._log_timestamp = esp_log_timestamp, + ._malloc_internal = 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_condition_set = coex_condition_set_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_schm_curr_phase_idx_set = coex_schm_curr_phase_idx_set_wrapper, + ._coex_schm_curr_phase_idx_get = coex_schm_curr_phase_idx_get_wrapper, + ._coex_register_start_cb = coex_register_start_cb_wrapper, +#if 0//CONFIG_IDF_TARGET_ESP32C6 + // TODO: WIFI-5150 + ._regdma_link_set_write_wait_content = regdma_link_set_write_wait_content, + ._sleep_retention_find_link_by_id = sleep_retention_find_link_by_id, + ._sleep_retention_entries_create = (int (*)(const void *, int, int, int))sleep_retention_entries_create, + ._sleep_retention_entries_destroy = sleep_retention_entries_destroy, +#endif + ._magic = ESP_WIFI_OS_ADAPTER_MAGIC, +}; + +coex_adapter_funcs_t g_coex_adapter_funcs = { + ._version = COEX_ADAPTER_VERSION, + ._task_yield_from_isr = task_yield_from_isr_wrapper, + ._semphr_create = semphr_create_wrapper, + ._semphr_delete = semphr_delete_wrapper, + ._semphr_take_from_isr = semphr_take_from_isr_wrapper, + ._semphr_give_from_isr = semphr_give_from_isr_wrapper, + ._semphr_take = semphr_take_wrapper, + ._semphr_give = semphr_give_wrapper, + ._is_in_isr = xPortInIsrContext, + ._malloc_internal = malloc_internal_wrapper, + ._free = free, + ._esp_timer_get_time = esp_timer_get_time, + ._env_is_chip = env_is_chip_wrapper, + ._slowclk_cal_get = esp_clk_slowclk_cal_get_wrapper, + ._magic = COEX_ADAPTER_MAGIC, +}; diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index 085a860374..6e07656bba 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -51,6 +51,10 @@ config SOC_TEMP_SENSOR_SUPPORTED bool default y +config SOC_WIFI_SUPPORTED + bool + default y + config SOC_SUPPORTS_SECURE_DL_MODE bool default y diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index 4b78381fb4..fcdc667d22 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -37,7 +37,7 @@ #define SOC_ASYNC_MEMCPY_SUPPORTED 1 #define SOC_USB_SERIAL_JTAG_SUPPORTED 1 #define SOC_TEMP_SENSOR_SUPPORTED 1 -// #define SOC_WIFI_SUPPORTED 1 // TODO: IDF-5679 +#define SOC_WIFI_SUPPORTED 1 // TODO: IDF-5679 #define SOC_SUPPORTS_SECURE_DL_MODE 1 //#define SOC_RISCV_COPROC_SUPPORTED 1 // TODO: IDF-5816 #define SOC_EFUSE_KEY_PURPOSE_FIELD 1 From 032ebd76cbcbaf1f14397a1521ef4b41021a765e Mon Sep 17 00:00:00 2001 From: yuexia Date: Tue, 20 Dec 2022 22:07:09 +0800 Subject: [PATCH 2/6] esp32c6: support wifi 6 --- components/esp_common/src/esp_err_to_name.c | 3 + .../esp_rom/esp32c6/ld/esp32c6.rom.pp.ld | 68 +- components/esp_wifi/Kconfig | 30 +- .../include/esp_private/esp_wifi_he_private.h | 192 +++ .../esp_private/esp_wifi_he_types_private.h | 318 +++++ .../esp_wifi/include/esp_private/wifi.h | 29 +- .../include/esp_private/wifi_os_adapter.h | 8 +- components/esp_wifi/include/esp_wifi.h | 7 +- components/esp_wifi/include/esp_wifi_he.h | 155 +++ .../esp_wifi/include/esp_wifi_he_types.h | 225 ++++ components/esp_wifi/include/esp_wifi_types.h | 128 +- components/lwip/Kconfig | 7 + components/lwip/port/esp32/include/lwipopts.h | 2 +- .../esp32c6/include/soc/Kconfig.soc_caps.in | 4 + components/soc/esp32c6/include/soc/soc_caps.h | 4 +- .../common_components/iperf/CMakeLists.txt | 7 + .../iperf/include/wifi_cmd.h | 21 + .../iperf/include/wifi_stats.h | 26 + examples/common_components/iperf/iperf.c | 43 +- examples/common_components/iperf/wifi_cmd.c | 1079 +++++++++++++++++ examples/common_components/iperf/wifi_stats.c | 585 +++++++++ examples/common_components/iperf/wifi_twt.c | 180 +++ examples/wifi/iperf/main/cmd_wifi.c | 115 +- .../wifi/iperf/sdkconfig.defaults.esp32c6 | 19 +- 24 files changed, 3164 insertions(+), 91 deletions(-) create mode 100644 components/esp_wifi/include/esp_private/esp_wifi_he_private.h create mode 100644 components/esp_wifi/include/esp_private/esp_wifi_he_types_private.h create mode 100644 components/esp_wifi/include/esp_wifi_he.h create mode 100644 components/esp_wifi/include/esp_wifi_he_types.h create mode 100644 examples/common_components/iperf/include/wifi_cmd.h create mode 100644 examples/common_components/iperf/include/wifi_stats.h create mode 100644 examples/common_components/iperf/wifi_cmd.c create mode 100644 examples/common_components/iperf/wifi_stats.c create mode 100644 examples/common_components/iperf/wifi_twt.c diff --git a/components/esp_common/src/esp_err_to_name.c b/components/esp_common/src/esp_err_to_name.c index d49aae5d31..01017e2c53 100644 --- a/components/esp_common/src/esp_err_to_name.c +++ b/components/esp_common/src/esp_err_to_name.c @@ -393,6 +393,9 @@ static const esp_err_msg_t esp_err_msg_table[] = { # endif # ifdef ESP_ERR_WIFI_TX_DISALLOW ERR_TBL_IT(ESP_ERR_WIFI_TX_DISALLOW), /* 12310 0x3016 The WiFi TX is disallowed */ +# endif +# ifdef ESP_ERR_WIFI_TWT_FULL + ERR_TBL_IT(ESP_ERR_WIFI_TWT_FULL), /* 12311 0x3017 no available flow id */ # endif // components/wpa_supplicant/esp_supplicant/include/esp_wps.h # ifdef ESP_ERR_WIFI_REGISTRAR diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld index b29b5f95ce..83c383a86d 100644 --- a/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld @@ -23,14 +23,14 @@ ppCalTxopRTSThreshold = 0x40000bdc; RC_GetBlockAckTime = 0x40000be0; ebuf_list_remove = 0x40000be4; esf_buf_alloc = 0x40000be8; -esf_buf_alloc_dynamic = 0x40000bec; +//esf_buf_alloc_dynamic = 0x40000bec; esf_buf_recycle = 0x40000bf0; GetAccess = 0x40000bf4; hal_mac_is_low_rate_enabled = 0x40000bf8; hal_mac_tx_get_blockack = 0x40000bfc; -hal_mac_tx_set_ppdu = 0x40000c00; +//hal_mac_tx_set_ppdu = 0x40000c00; ic_get_trc = 0x40000c04; -ic_mac_deinit = 0x40000c08; +//ic_mac_deinit = 0x40000c08; ic_mac_init = 0x40000c0c; ic_interface_enabled = 0x40000c10; is_lmac_idle = 0x40000c14; @@ -44,16 +44,16 @@ lmacMSDUAged = 0x40000c30; lmacPostTxComplete = 0x40000c34; lmacProcessAllTxTimeout = 0x40000c38; lmacProcessCollisions = 0x40000c3c; -lmacProcessRxSucData = 0x40000c40; +//lmacProcessRxSucData = 0x40000c40; lmacReachLongLimit = 0x40000c44; lmacReachShortLimit = 0x40000c48; lmacRecycleMPDU = 0x40000c4c; lmacRxDone = 0x40000c50; -lmacSetTxFrame = 0x40000c54; +//lmacSetTxFrame = 0x40000c54; lmacTxDone = 0x40000c58; lmacTxFrame = 0x40000c5c; mac_tx_set_duration = 0x40000c60; -mac_tx_set_plcp0 = 0x40000c64; +//mac_tx_set_plcp0 = 0x40000c64; mac_tx_set_plcp1 = 0x40000c68; mac_tx_set_plcp2 = 0x40000c6c; pm_check_state = 0x40000c70; @@ -62,23 +62,23 @@ pm_disable_sleep_delay_timer = 0x40000c78; pm_dream = 0x40000c7c; pm_mac_wakeup = 0x40000c80; pm_mac_sleep = 0x40000c84; -pm_enable_active_timer = 0x40000c88; +//pm_enable_active_timer = 0x40000c88; pm_enable_sleep_delay_timer = 0x40000c8c; pm_local_tsf_process = 0x40000c90; -pm_set_beacon_filter = 0x40000c94; +//pm_set_beacon_filter = 0x40000c94; pm_is_in_wifi_slice_threshold = 0x40000c98; pm_is_waked = 0x40000c9c; -pm_keep_alive = 0x40000ca0; +//pm_keep_alive = 0x40000ca0; pm_on_beacon_rx = 0x40000ca4; pm_on_data_rx = 0x40000ca8; pm_on_tbtt = 0x40000cac; pm_parse_beacon = 0x40000cb0; -pm_process_tim = 0x40000cb4; -pm_rx_beacon_process = 0x40000cb8; +//pm_process_tim = 0x40000cb4; +//pm_rx_beacon_process = 0x40000cb8; pm_rx_data_process = 0x40000cbc; -pm_sleep = 0x40000cc0; +//pm_sleep = 0x40000cc0; pm_sleep_for = 0x40000cc4; -pm_tbtt_process = 0x40000cc8; +//pm_tbtt_process = 0x40000cc8; ppAMPDU2Normal = 0x40000ccc; ppAssembleAMPDU = 0x40000cd0; ppCalFrameTimes = 0x40000cd4; @@ -91,24 +91,24 @@ ppEmptyDelimiterLength = 0x40000cec; ppEnqueueRxq = 0x40000cf0; ppEnqueueTxDone = 0x40000cf4; ppGetTxframe = 0x40000cf8; -ppMapTxQueue = 0x40000cfc; +//ppMapTxQueue = 0x40000cfc; ppProcTxSecFrame = 0x40000d00; ppProcessRxPktHdr = 0x40000d04; -ppProcessTxQ = 0x40000d08; +//ppProcessTxQ = 0x40000d08; ppRecordBarRRC = 0x40000d0c; ppRecycleAmpdu = 0x40000d10; ppRecycleRxPkt = 0x40000d14; -ppResortTxAMPDU = 0x40000d18; +//ppResortTxAMPDU = 0x40000d18; ppResumeTxAMPDU = 0x40000d1c; ppRxFragmentProc = 0x40000d20; -ppRxPkt = 0x40000d24; +//ppRxPkt = 0x40000d24; ppRxProtoProc = 0x40000d28; ppSearchTxQueue = 0x40000d2c; ppSearchTxframe = 0x40000d30; ppSelectNextQueue = 0x40000d34; ppSubFromAMPDU = 0x40000d38; -ppTask = 0x40000d3c; -ppTxPkt = 0x40000d40; +//ppTask = 0x40000d3c; +//ppTxPkt = 0x40000d40; ppTxProtoProc = 0x40000d44; ppTxqUpdateBitmap = 0x40000d48; pp_coex_tx_request = 0x40000d4c; @@ -157,19 +157,19 @@ wdev_mac_special_reg_store = 0x40000df4; wdev_mac_wakeup = 0x40000df8; wdev_mac_sleep = 0x40000dfc; hal_mac_is_dma_enable = 0x40000e00; -wDev_ProcessFiq = 0x40000e04; -wDev_ProcessRxSucData = 0x40000e08; -wdevProcessRxSucDataAll = 0x40000e0c; +//wDev_ProcessFiq = 0x40000e04; +//wDev_ProcessRxSucData = 0x40000e08; +//wdevProcessRxSucDataAll = 0x40000e0c; wdev_csi_len_align = 0x40000e10; ppDequeueTxDone_Locked = 0x40000e14; ppProcTxDone = 0x40000e18; -pm_tx_data_done_process = 0x40000e1c; +//pm_tx_data_done_process = 0x40000e1c; config_is_cache_tx_buf_enabled = 0x40000e20; ppMapWaitTxq = 0x40000e24; ppProcessWaitingQueue = 0x40000e28; ppDisableQueue = 0x40000e2c; pm_allow_tx = 0x40000e30; -wdev_is_data_in_rxlist = 0x40000e34; +//wdev_is_data_in_rxlist = 0x40000e34; ppProcTxCallback = 0x40000e38; mac_tx_set_hesig = 0x40000e3c; ppCalPreFecPaddingFactor = 0x40000e40; @@ -179,11 +179,11 @@ hal_get_tsf_timer = 0x40000e4c; ppTxPktForceWaked = 0x40000e50; lmacProcessLongFrameSuccess = 0x40000e54; lmacProcessShortFrameSuccess = 0x40000e58; -lmacDiscardFrameExchangeSequence = 0x40000e5c; +//lmacDiscardFrameExchangeSequence = 0x40000e5c; lmacProcessTBSuccess = 0x40000e60; lmacProcessTxSuccess = 0x40000e64; lmacProcessAckTimeout = 0x40000e68; -lmacProcessTxComplete = 0x40000e6c; +//lmacProcessTxComplete = 0x40000e6c; ppRemoveHTC = 0x40000e70; get_estimated_batime = 0x40000e74; is_use_muedca = 0x40000e78; @@ -208,8 +208,8 @@ pwr_hal_get_mac_modem_state_sleep_limit_exceeded_status = 0x40000ec0; pwr_hal_set_beacon_filter_abort_disable = 0x40000ec4; pwr_hal_set_beacon_filter_abort_enable = 0x40000ec8; pwr_hal_set_beacon_filter_abort_length = 0x40000ecc; -pwr_hal_set_beacon_filter_broadcast_wakeup_disable = 0x40000ed0; -pwr_hal_set_beacon_filter_broadcast_wakeup_enable = 0x40000ed4; +//pwr_hal_set_beacon_filter_broadcast_wakeup_disable = 0x40000ed0; +//pwr_hal_set_beacon_filter_broadcast_wakeup_enable = 0x40000ed4; pwr_hal_set_beacon_filter_disable = 0x40000ed8; pwr_hal_set_beacon_filter_enable = 0x40000edc; pwr_hal_set_beacon_filter_force_dump_disable = 0x40000ee0; @@ -296,16 +296,16 @@ tsf_hal_set_tsf_time_deviation_sync_enable = 0x40001020; tsf_hal_unmap_tbtt_target_to_rx_frame = 0x40001024; ppSelectTxFormat = 0x40001028; ppCertSetRate = 0x4000102c; -ppHEAMPDU2Normal = 0x40001030; +//ppHEAMPDU2Normal = 0x40001030; ppCalTxHEAMPDULength = 0x40001034; ppCalTxHESMPDULength = 0x40001038; rcGetRate = 0x4000103c; rcGetDCMMaxRate = 0x40001040; -rcGetSMPDURate = 0x40001044; +//rcGetSMPDURate = 0x40001044; ppDirectRecycleAmpdu = 0x40001048; ppCheckTxHEAMPDUlength = 0x4000104c; rx11AXRate2AMPDULimit = 0x40001050; -ppRegressAmpdu = 0x40001054; +//ppRegressAmpdu = 0x40001054; ppCalDeliNum = 0x40001058; ppAdd2AMPDUTail = 0x4000105c; esp_test_disable_tx_statistics = 0x40001060; @@ -315,9 +315,9 @@ esp_test_get_tx_statistics = 0x4000106c; esp_test_clr_tx_tb_statistics = 0x40001070; esp_test_get_tx_tb_statistics = 0x40001074; test_tx_fail_statistics = 0x40001078; -test_tx_succ_statistics = 0x4000107c; -esp_test_tx_process_complete = 0x40001080; -esp_test_tx_process_txq_state = 0x40001084; +//test_tx_succ_statistics = 0x4000107c; +//esp_test_tx_process_complete = 0x40001080; +//esp_test_tx_process_txq_state = 0x40001084; esp_test_tx_enab_statistics = 0x40001088; esp_test_tx_tb_complete = 0x4000108c; esp_test_tx_count_retry = 0x40001090; diff --git a/components/esp_wifi/Kconfig b/components/esp_wifi/Kconfig index 37ffdf4e84..bc54c2546e 100644 --- a/components/esp_wifi/Kconfig +++ b/components/esp_wifi/Kconfig @@ -20,7 +20,8 @@ menu "Wi-Fi" config ESP32_WIFI_STATIC_RX_BUFFER_NUM int "Max number of WiFi static RX buffers" - range 2 25 + range 2 25 if !SOC_WIFI_HE_SUPPORT + range 2 128 if SOC_WIFI_HE_SUPPORT default 10 if !SPIRAM_TRY_ALLOCATE_WIFI_LWIP default 16 if SPIRAM_TRY_ALLOCATE_WIFI_LWIP help @@ -142,7 +143,8 @@ menu "Wi-Fi" config ESP32_WIFI_TX_BA_WIN int "WiFi AMPDU TX BA window size" depends on ESP32_WIFI_AMPDU_TX_ENABLED - range 2 32 + range 2 32 if !SOC_WIFI_HE_SUPPORT + range 2 64 if SOC_WIFI_HE_SUPPORT default 6 help Set the size of WiFi Block Ack TX window. Generally a bigger value means higher throughput but @@ -159,7 +161,8 @@ menu "Wi-Fi" config ESP32_WIFI_RX_BA_WIN int "WiFi AMPDU RX BA window size" depends on ESP32_WIFI_AMPDU_RX_ENABLED - range 2 32 + range 2 32 if !SOC_WIFI_HE_SUPPORT + range 2 64 if SOC_WIFI_HE_SUPPORT default 6 if !SPIRAM_TRY_ALLOCATE_WIFI_LWIP default 16 if SPIRAM_TRY_ALLOCATE_WIFI_LWIP help @@ -399,5 +402,26 @@ menu "Wi-Fi" When using ESP mesh, this value should be set to a maximum of 6. + config ENABLE_WIFI_TX_STATS + bool "Enable Wi-Fi transmission statistics" + depends on SOC_WIFI_HE_SUPPORT + default "y" + help + Enable Wi-Fi transmission statistics. Total support 4 access category. Each access category will use 346 bytes memory. + + config ENABLE_WIFI_RX_STATS + bool "Enable Wi-Fi reception statistics" + depends on SOC_WIFI_HE_SUPPORT + default "y" + help + Enable Wi-Fi reception statistics. Total support 2 access category. Each access category will use 190 bytes memory. + + config ENABLE_WIFI_RX_MU_STATS + bool "Enable Wi-Fi DL MU-MIMO and DL OFDMA reception statistics" + depends on SOC_WIFI_HE_SUPPORT + depends on ENABLE_WIFI_RX_STATS + default "y" + help + Enable Wi-Fi DL MU-MIMO and DL OFDMA reception statistics. Will use 10932 bytes memory. endmenu # Wi-Fi diff --git a/components/esp_wifi/include/esp_private/esp_wifi_he_private.h b/components/esp_wifi/include/esp_private/esp_wifi_he_private.h new file mode 100644 index 0000000000..7c046e78bb --- /dev/null +++ b/components/esp_wifi/include/esp_private/esp_wifi_he_private.h @@ -0,0 +1,192 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "esp_err.h" +#include "esp_wifi_types.h" +#include "esp_wifi_he_types.h" +#include "esp_wifi_he_types_private.h" + +#ifdef __cplusplus +extern "C" { +#endif + +float esp_test_get_bfr_avgsnr(void); + +void esp_test_enable_edca_tx(esp_wifi_aci_t aci); +void esp_test_disable_edca_tx(esp_wifi_aci_t aci); + +esp_err_t esp_wifi_enable_htc_uph(bool enable); +esp_err_t esp_wifi_set_htc_omc(const esp_wifi_htc_omc_t *om); +void esp_wifi_enable_rx_stbc(bool enable); +void esp_wifi_enable_su_bmfmee(bool enable); +esp_err_t esp_wifi_set_tf_padding_duration(int tf_padding_duration); +void esp_test_set_tx_mcs_pwr(wifi_phy_rate_t rate, int8_t max_pwr); + +void hal_he_set_ul_mu(bool ul_mu_disable, bool ul_mu_data_disable); +void hal_he_set_bf_report_rate(sig_mode_t sig_mode, wifi_phy_rate_t rate); + +void dbg_read_muedca_timer(uint8_t aci); +void dbg_read_axtb_diag(void); +void dbg_read_ax_diag(bool verbose); +void dbg_tb_ignore_cca_enable(bool enable); + +esp_err_t esp_wifi_sta_report_bsscolor_collision(void); +esp_err_t esp_wifi_sta_report_bsscolor_inuse(void); + +/* RX */ +esp_err_t esp_test_clr_rx_error_occurs(void); +esp_err_t esp_test_get_rx_error_occurs(esp_test_rx_error_occurs_t *err_occurs); + +/* HW */ +void esp_test_clr_hw_statistics(void); +esp_err_t esp_test_get_hw_rx_statistics(esp_test_hw_rx_statistics_t *hw_rx_stats); +esp_err_t esp_test_get_hw_tb_statistics(esp_test_hw_tb_statistics_t *hw_tb_stats); + +/** + * @brief Clear DL MU-MIMO and DL OFDMA reception statistics. + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t esp_wifi_clr_rx_mu_statistics(void); + +/** + * @brief Get the DL MU-MIMO and DL OFDMA reception statistics. + * + * @param[in] mu_stats the DL MU-MIMO and DL OFDMA reception statistics + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t esp_wifi_get_rx_mu_statistics(esp_test_rx_mu_statistics_t *mu_stats); + +/** + * @brief Clear the reception statistics excluding DL MU-MIMO and DL OFDMA. + * + * @param[in] tid the traffic id, accept tid = 0, tid = 7 and tid = 8. tid = 8 will clear reception statistics for both tid = 0 and tid = 7 + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t esp_wifi_clr_rx_statistics(uint8_t tid); + +/** + * @brief Get the reception statistics excluding DL MU-MIMO and DL OFDMA. + * + * @param[in] tid the traffic id, only accept tid = 0 or tid = 7 + * @param[in] rx_stats the reception statistics + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t esp_wifi_get_rx_statistics(uint8_t tid, esp_test_rx_statistics_t *rx_stats); + +/** + * @brief Clear the transmission statistics. + * + * @param[in] aci access category id. + * Generally, for data frames, aci = ESP_WIFI_ACI_BE; for management frames, aci = ESP_WIFI_ACI_VO. + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t esp_wifi_clr_tx_statistics(esp_wifi_aci_t aci); + +/** + * @brief Get the transmission statistics. + * + * @param[in] aci access category id. + * @param[in] tx_stats the transmission statistics + * @param[in] tx_fail the common failure state and reason + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t esp_wifi_get_tx_statistics(esp_wifi_aci_t aci, esp_test_tx_statistics_t *tx_stats, esp_test_tx_fail_statistics_t *tx_fail); + +/** + * @brief Clear the TB PPDU transmission statistics. + * + * @param[in] aci access category id. + * Generally, for data frames, aci = ESP_WIFI_ACI_BE; for management frames, aci = ESP_WIFI_ACI_VO. + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t esp_wifi_clr_tx_tb_statistics(esp_wifi_aci_t aci); + +/** + * @brief Get the TB PPDU transmission statistics. + * + * @param[in] aci access category id. + * @param[in] tb_stats TB PPDU statistics. + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t esp_wifi_get_tx_tb_statistics(esp_wifi_aci_t aci, esp_test_tx_tb_statistics_t *tb_stats); + +/** +* @brief Add BSS color change announcement IE +* +* @attention This API should be called after esp_wifi_start(). +* +* @param color new bss color, 0 means disable. +* +* @return +* - ESP_OK: succeed +* - others: failed +*/ +esp_err_t esp_wifi_softap_add_color_change_announcement(uint8_t color); + +/** +* @brief Add bss max idle ie +* +* @attention This API should be called after esp_wifi_start(). +* +* @param[in] bss_max_idle_enable enbale bss max idle +* @param[in] bss_max_idle_period_secs bss max idle period, unit seconds +* @param[in] protected_keep_alive using protected/unprotected frame to keep alive +* +* @return +* - ESP_OK: succeed +* - others: failed +*/ +esp_err_t esp_wifi_softap_set_bss_max_idle(bool bss_max_idle_enable, uint16_t bss_max_idle_period_secs, bool protected_keep_alive); + +/** +* @brief Reset MU EDCA Timer +* +* @attention This API should be called after esp_wifi_start(). +* +* @param aci_bitmap bit0: BK +* bit1: BE +* bit2: VI +* bit3: VO +* +* @return +* - ESP_OK: succeed +* - others: failed +*/ +esp_err_t esp_wifi_sta_reset_muedca_timer(uint8_t aci_bitmap); + + +#ifdef __cplusplus +} +#endif + diff --git a/components/esp_wifi/include/esp_private/esp_wifi_he_types_private.h b/components/esp_wifi/include/esp_private/esp_wifi_he_types_private.h new file mode 100644 index 0000000000..e3c12749db --- /dev/null +++ b/components/esp_wifi/include/esp_private/esp_wifi_he_types_private.h @@ -0,0 +1,318 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "sys/queue.h" +#include "esp_err.h" +#include "esp_interface.h" +#include "esp_event_base.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + SIG_MODE_LEGACY = 0, + SIG_MODE_HT = 1, + SIG_MODE_HE = 2, + SIG_MODE_VHT = 3, +} sig_mode_t; + +typedef struct { + unsigned mcs : 7; + unsigned cwb : 1; + unsigned ht_length : 16; + unsigned smoothing : 1; + unsigned not_sounding : 1; + unsigned : 1; + unsigned aggregation : 1; + unsigned stbc : 2; + unsigned fec_coding : 1; + unsigned sgi : 1; +} esp_wifi_htsig_t; + +typedef struct { + uint32_t format : 1; + uint32_t beam_change : 1; + uint32_t ul_dl : 1; + uint32_t he_mcs : 4; + uint32_t dcm : 1; + uint32_t bss_color : 6; + uint32_t rsvd : 1; + uint32_t spatial_reuse : 4; + uint32_t bw : 2; + uint32_t gi_and_he_ltf_size : 2; + uint32_t nsts_and_midamble_periodicity : 3; + uint32_t rsvd1 : 6; +} esp_wifi_su_siga1_t; + +typedef struct { + uint32_t format : 1; + uint32_t bss_color : 6; + uint32_t spatial_reuse1 : 4; + uint32_t spatial_reuse2 : 4; + uint32_t spatial_reuse3 : 4; + uint32_t spatial_reuse4 : 4; + uint32_t rsvd : 1; + uint32_t bw : 2; + uint32_t rsvd1 : 6; +} esp_wifi_tb_siga1_t; + +typedef struct { + uint32_t ul_dl : 1; + uint32_t sigb_mcs : 3; + uint32_t sigb_dcm : 1; + uint32_t bss_color : 6; + uint32_t spatial_reuse : 4; + uint32_t bw : 3; + uint32_t sigb_sym_num_or_mu_mimo_users : 4; + uint32_t sigb_compression : 1; + uint32_t gi_and_he_ltf_size : 2; + uint32_t doppler : 1; + uint32_t rsvd : 6; +} esp_wifi_mu_siga1_t; + +typedef struct { + uint16_t txop : 7; + uint16_t coding : 1; + uint16_t ldpc_extra_symbol_segment : 1; + uint16_t stbc : 1; + uint16_t beamformed : 1; + uint16_t pre_fec_padding_factor : 2; + uint16_t pe_disambiguity : 1; + uint16_t rsvd : 1; + uint16_t doppler : 1; +} __attribute__((packed)) esp_wifi_su_siga2_t; + +typedef struct { + uint16_t txop : 7; + uint16_t siga2_rsvd : 9; +} __attribute__((packed)) esp_wifi_tb_siga2_t; + +typedef struct { + uint16_t txop : 7; + uint16_t rsvd : 1; + uint16_t nltf_and_midamble_periodicity : 3; + uint16_t ldpc_extra_symbol_segment : 1; + uint16_t stbc : 1; + uint16_t pre_fec_padding_factor : 2; + uint16_t pe_disambiguation : 1; +} __attribute__((packed)) esp_wifi_mu_siga2_t; + +#define ESP_TEST_RX_MU_USER_NUM (9) +//support buffer mu-users for 4 duts +typedef struct { + uint16_t aid; + /* MIMO */ + int mimo_rx; + int mimo_sigb_mcs[6]; //MCS[0, 5] + /* + * count sigb info, max: 8 users + * + * mimo_user_num_occu[0] = the number of occurrences of user_num=2 within a period of rx + * mimo_user_num_occu[1] = the number of occurrences of user_num=3 within a period of rx + * ...... + * mimo_user_num_occu[6] = the number of occurrences of user_num=8 within a period of rx + */ + int mimo_user_num_occu[7]; //UserNum[2, 8] + struct { + uint16_t aid; + int occu_mcs[12]; + /* + * occu_ss[0] = the number of occurrences of SS0 within a period of rx + * occu_ss[1] = the number of occurrences of SS1 within a period of rx + * ...... + * occu_ss[7] = the number of occurrences of SS7 within a period of rx + */ + int occu_ss[8]; + } mimo[ESP_TEST_RX_MU_USER_NUM]; + /* Non-MIMO */ + int nonmimo_rx; + int nonmimo_sigb_mcs[6]; //MCS[0, 5] + int nonmimo_ru_alloc[256][9]; //size: 9216 bytes + int nonmimo_user_num_occu[9]; //UserNum[1, 9] + struct { + uint16_t aid; + int occu_nsts[8]; + int occu_mcs[12]; + int txbf; + int dcm; + } nonmimo[ESP_TEST_RX_MU_USER_NUM]; + int ru_alloc_96_num_2046; //106+106 + int ru_alloc_112_num_2046; //52+52+52+52 +} esp_test_rx_mu_statistics_t; //10932 bytes + +typedef struct { + int legacy; + int legacy_noeb; + int ht; + int ht_noeb; + int ht_retry; + int ersu; + int ersu_noeb; + int ersu_dcm; + int su; + int su_noeb; + int su_stbc; + int su_txbf; + int su_retry; + int mu; + int mu_noeb; + int mu_stbc; + int mu_mimo; + int mu_ofdma; + int mu_txbf; + int mu_retry; + int rx_isr; + int rx_nblks; +} esp_test_rx_statistics_t; //88 bytes + +typedef enum { + TEST_TX_SUCCESS, + TEST_TX_FAIL_RTS, + TEST_TX_WAIT_CTS, //RX + TEST_TX_FAIL_CTS, + TEST_TX_FAIL_DATA, + TEST_TX_WAIT_ACK, //RX + TEST_TX_FAIL_MAX, +} esp_test_tx_fail_state_t; + +/* only happen when TEST_TX_WAIT_CTS(2), TEST_TX_WAIT_ACK(5) */ +typedef enum { + TEST_TX_WAIT_MATCH, + TEST_TX_WAIT_NOT2SELF, + TEST_TX_MISMATCH, + TEST_TX_WAIT_TIMEOUT, + TEST_TX_WAIT_MAX, +} esp_test_tx_fail_match_t; + +/* only happen when TEST_TX_WAIT_MATCH(0) */ +typedef enum { + TEST_TX_FAIL_ERROR_H00, + TEST_TX_FAIL_ERROR_H53, + TEST_TX_FAIL_ERROR_H63, + TEST_TX_FAIL_ERROR_H75, + TEST_TX_FAIL_ERROR_H41, + TEST_TX_FAIL_ERROR_H42, + TEST_TX_FAIL_ERROR_H47, + TEST_TX_FAIL_ERROR_H80, + TEST_TX_FAIL_ERROR_H5A, + TEST_TX_FAIL_ERROR_HXX, + TEST_TX_FAIL_ERROR_MAX, //10 +} esp_test_tx_fail_error_t; + +typedef struct { + int match[TEST_TX_WAIT_MAX][TEST_TX_FAIL_ERROR_MAX]; + int count; +} esp_test_tx_fail_statistics_t; //164 bytes + +typedef struct { + int tb_last; /* count times of the last TX through TB */ + int tb_times; /* count total TX times through TB */ + int tb_rx_ba; /* can't know the exact packets number of BA or ACK*/ + int retry_edca; + int retry_tb; + int rx_ack; /* count ACKs response to TX through EDCA */ + int rx_ba; /* count BAs response to TX through EDCA */ + int rx_dump_ba; + uint8_t rx_max_bitmap; + uint8_t rx_min_bitmap; + int rx_tot_bitmap; + int tx_enable; + int tx_complete; + int tx_succ; + int tx_no_mem; + int tx_max_rtt; + int tx_min_rtt; + int tx_tot_rtt; + int tx_seq_max_rtt; /* rtt of a sequence number containing the time of retries */ + int tx_seq_min_rtt; + int64_t tx_start_time; + int64_t tx_seqno_time; + int64_t tx_muedca_time; + int tx_max_muedca_time; + int tx_min_muedca_time; + int tx_tot_muedca_time; + int muedca_times; + int tx_muedca_enable; /* count TX times within mu-timer working */ + int collision; + int timeout; +} esp_test_tx_statistics_t; //136 bytes + +typedef struct { + int complete_suc_tb; + int complete_ack_tb; + int complete_err_tb; + int complete_tb_suc_count; + int complete_tb_ack_count; + int complete_tb_err_count; + int complete_tb_tot_count; + int complete_tb_pack_sent; +} esp_test_tx_tb_statistics_t; //32 bytes + +typedef struct { + uint16_t rx_trig; + uint16_t tb_times; + uint16_t tb_qos_null; + uint16_t tx_bfrpt; + uint16_t tb_cca_cancel; + uint16_t tb_sifs_abort; + uint16_t tb_pwr_outof_range; +} esp_test_hw_tb_statistics_t; //14 bytes + +typedef struct { + uint16_t rx_fcs_err; + uint16_t rx_abort; + uint16_t rx_abort_fcs_pass; + uint16_t nrx_err_pwrdrop; + uint16_t nrx_hesigb_err; + uint16_t rx_samebm_errcnt; + uint16_t rx_mpdu; + uint16_t rx_end_cnt; + uint16_t rx_datasuc; + int16_t rx_cfo_hz; + uint16_t rx_sf; + uint16_t rx_other_ucast; + uint16_t rx_buf_fullcnt; + uint16_t rx_fifo_ovfcnt; + uint16_t rx_tkip_errcnt; + uint16_t rx_btblock_err; + uint16_t rx_freqhop_err; + uint16_t rx_lastunmatch_err; + uint16_t rx_ack_int_cnt; + uint16_t rx_rts_int_cnt; + uint16_t brx_err_agc; + uint16_t brx_err; + uint16_t nrx_err; + uint16_t nrx_err_abort; + uint16_t nrx_err_agcexit; + uint16_t nrx_err_bboff; + uint16_t nrx_err_fdm_wdg; + uint16_t nrx_err_restart; + uint16_t nrx_err_serv; + uint16_t nrx_err_txover; + uint16_t nrx_err_unsupport; + uint16_t nrx_htsig_err; + uint16_t nrx_heunsupport; + uint16_t nrx_hesiga_crc; + uint16_t rxhung_statis; + uint16_t txhung_statis; + int rxtxhung; +} esp_test_hw_rx_statistics_t; //76 bytes + +typedef struct { + int tot; + int occurs[2]; //0: 0xc6 same bitmap; 1: 0xf5 tkip error +} esp_test_rx_error_occurs_t; //12 bytes + + +#ifdef __cplusplus +} +#endif + diff --git a/components/esp_wifi/include/esp_private/wifi.h b/components/esp_wifi/include/esp_private/wifi.h index b3f7342a0c..25a7f1776d 100644 --- a/components/esp_wifi/include/esp_private/wifi.h +++ b/components/esp_wifi/include/esp_private/wifi.h @@ -126,7 +126,7 @@ void esp_wifi_internal_free_rx_buffer(void* buffer); * copy to WiFi driver. * * @param wifi_interface_t wifi_if : wifi interface id - * @param void *buffer : the buffer to be tansmit + * @param void *buffer : the buffer to be transmit * @param uint16_t len : the length of buffer * * @return @@ -143,6 +143,33 @@ void esp_wifi_internal_free_rx_buffer(void* buffer); */ int esp_wifi_internal_tx(wifi_interface_t wifi_if, void *buffer, uint16_t len); +#if CONFIG_SOC_WIFI_HE_SUPPORT +/** + * @brief transmit eapol frames via wifi driver + * + * This API makes a copy of the input buffer and then forwards the buffer + * copy to WiFi driver. + * + * @param wifi_interface_t wifi_if : wifi interface id + * @param void *buffer : the buffer to be transmit + * @param uint16_t len : the length of buffer + * @param uint8_t msg_id : eapol message id + * + * @return + * - ESP_OK : Successfully transmit the buffer to wifi driver + * - ESP_ERR_NO_MEM: out of memory + * - ESP_ERR_WIFI_ARG: invalid argument + * - ESP_ERR_WIFI_IF : WiFi interface is invalid + * - ESP_ERR_WIFI_CONN : WiFi interface is not created, e.g. send the data to STA while WiFi mode is AP mode + * - ESP_ERR_WIFI_NOT_STARTED : WiFi is not started + * - ESP_ERR_WIFI_STATE : WiFi internal state is not ready, e.g. WiFi is not started + * - ESP_ERR_WIFI_NOT_ASSOC : WiFi is not associated + * - ESP_ERR_WIFI_TX_DISALLOW : WiFi TX is disallowed, e.g. WiFi hasn't pass the authentication + * - ESP_ERR_WIFI_POST : caller fails to post event to WiFi task + */ +int esp_wifi_eapol_tx(wifi_interface_t wifi_if, void *buffer, uint16_t len, uint8_t msg_id); +#endif + /** * @brief The net stack buffer reference counter callback function * diff --git a/components/esp_wifi/include/esp_private/wifi_os_adapter.h b/components/esp_wifi/include/esp_private/wifi_os_adapter.h index dbab9dbeb1..d17b5fc47d 100644 --- a/components/esp_wifi/include/esp_private/wifi_os_adapter.h +++ b/components/esp_wifi/include/esp_private/wifi_os_adapter.h @@ -109,7 +109,7 @@ typedef struct { int (* _get_random)(uint8_t *buf, size_t len); int (* _get_time)(void *t); unsigned long (* _random)(void); -#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 +#if !CONFIG_IDF_TARGET_ESP32 uint32_t (* _slowclk_cal_get)(void); #endif void (* _log_write)(unsigned int level, const char* tag, const char* format, ...); @@ -145,6 +145,12 @@ typedef struct { int (* _coex_schm_curr_phase_idx_set)(int idx); int (* _coex_schm_curr_phase_idx_get)(void); int (* _coex_register_start_cb)(int (* cb)(void)); +#if CONFIG_IDF_TARGET_ESP32C6 + void (* _regdma_link_set_write_wait_content)(void *, uint32_t, uint32_t); + void * (* _sleep_retention_find_link_by_id)(int); + int (* _sleep_retention_entries_create)(const void *, int, int, int); + void (* _sleep_retention_entries_destroy)(int); +#endif int32_t _magic; } wifi_osi_funcs_t; diff --git a/components/esp_wifi/include/esp_wifi.h b/components/esp_wifi/include/esp_wifi.h index 87736e460d..bc329bb43e 100644 --- a/components/esp_wifi/include/esp_wifi.h +++ b/components/esp_wifi/include/esp_wifi.h @@ -83,6 +83,8 @@ extern "C" { #define ESP_ERR_WIFI_NOT_ASSOC (ESP_ERR_WIFI_BASE + 21) /*!< The WiFi connection is not associated */ #define ESP_ERR_WIFI_TX_DISALLOW (ESP_ERR_WIFI_BASE + 22) /*!< The WiFi TX is disallowed */ +#define ESP_ERR_WIFI_TWT_FULL (ESP_ERR_WIFI_BASE + 23) /*!< no available flow id */ + /** * @brief WiFi stack configuration parameters passed to esp_wifi_init call. */ @@ -511,9 +513,10 @@ esp_err_t esp_wifi_get_ps(wifi_ps_type_t *type); /** * @brief Set protocol type of specified interface - * The default protocol is (WIFI_PROTOCOL_11B|WIFI_PROTOCOL_11G|WIFI_PROTOCOL_11N) + * The default protocol is (WIFI_PROTOCOL_11B|WIFI_PROTOCOL_11G|WIFI_PROTOCOL_11N). + * if CONFIG_SOC_WIFI_HE_SUPPORT, the default protocol is (WIFI_PROTOCOL_11B|WIFI_PROTOCOL_11G|WIFI_PROTOCOL_11N|WIFI_PROTOCOL_11AX). * - * @attention Support 802.11b or 802.11bg or 802.11bgn or LR mode + * @attention Support 802.11b or 802.11bg or 802.11bgn or 802.11bgnax or LR mode * * @param ifx interfaces * @param protocol_bitmap WiFi protocol bitmap diff --git a/components/esp_wifi/include/esp_wifi_he.h b/components/esp_wifi/include/esp_wifi_he.h new file mode 100644 index 0000000000..de270292ee --- /dev/null +++ b/components/esp_wifi/include/esp_wifi_he.h @@ -0,0 +1,155 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "esp_err.h" +#include "esp_wifi_he_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief Set up an individual TWT agreement (NegotiationType=0) or change TWT parameters of the existing TWT agreement + * - TWT Wake Interval = TWT Wake Interval Mantissa * (2 ^ TWT Wake Interval Exponent), unit: us + * - e.g. TWT Wake Interval Mantissa = 512, TWT Wake Interval Exponent = 12, then TWT Wake Interval is 2097.152 ms + * Nominal Minimum Wake Duration = 255, then TWT Wake Duration is 65.28 ms + * + * @attention Support at most 4 TWT agreements, otherwise ESP_ERR_WIFI_TWT_FULL will be returned. + * Support sleep time up to (1 << 35) us. + * + * @param[in] setup_cmd Indicates the type of TWT command + * @param[in] trigger true: a trigger-enabled TWT, false: a non-trigger-enabled TWT + * @param[in] flow_type 0: an announced TWT, 1: an unannounced TWT + * @param[in] min_wake_dura Nominal Minimum Wake Duration, indicates the minimum amount of time, in unit of 256 us, that the TWT requesting STA expects that it needs to be awake. The value range is [1, 255]. + * @param[in] wake_invl_expn TWT Wake Interval Exponent. The value range is [0, 31]. + * @param[in] wake_invl_mant TWT Wake Interval Mantissa. The value range is [1, 65535]. + * @param[in/out] flow_id When set up an individual TWT agreement, the flow id will be assigned by AP after a successful agreement setup. + * flow_id is allowed to be NULL. flow_id could be specified to a value in the range of [0, 7], but it might be changed by AP in the response. + * When change TWT parameters of the existing TWT agreement, flow_id should be an existing one. The value range is [0, 7]. + * + * @return + * - ESP_OK: succeed + * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init + * - ESP_ERR_WIFI_NOT_STARTED: WiFi is not started by esp_wifi_start + * - ESP_ERR_WIFI_CONN: WiFi internal error, station or soft-AP control block wrong + * - ESP_ERR_WIFI_NOT_CONNECT: The station is in disconnect status + * - ESP_ERR_WIFI_TWT_FULL: no available flow id + * - ESP_ERR_INVALID_ARG: invalid argument + */ +esp_err_t esp_wifi_sta_itwt_setup(wifi_twt_setup_cmds_t setup_cmd, bool trigger, int flow_type, int min_wake_dura, int wake_invl_expn, int wake_invl_mant, int *flow_id); + +/** + * @brief Tear down individual TWT agreements + * + * @param[in] flow_id The value range is [0, 8]. 8 indicates tear down all individual TWT agreements. + * + * @return + * - ESP_OK: succeed + * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init + * - ESP_ERR_WIFI_NOT_STARTED: WiFi is not started by esp_wifi_start + * - ESP_ERR_WIFI_CONN: WiFi internal error, station or soft-AP control block wrong + * - ESP_ERR_WIFI_NOT_CONNECT: The station is in disconnect status + * - ESP_ERR_INVALID_ARG: invalid argument + */ +esp_err_t esp_wifi_sta_itwt_teardown(int flow_id); + +/** + * @brief Send a TWT Information frame to AP for suspending/resuming established iTWT agreements. + * + * @param[in] flow_id The value range is [0, 8]. 8 indicates suspend all individual TWT agreements + * @param[in] suspend_time_ms If the value is 0, indicates the specified flow_id or all established agreements will be suspended until resume by users. + * If the value is greater than 0, indicates the specified flow_id or all established agreements will be suspended until suspend_time_ms timeout, unit: ms. + * + * @return + * - ESP_OK: succeed + * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init + * - ESP_ERR_WIFI_NOT_STARTED: WiFi is not started by esp_wifi_start + * - ESP_ERR_WIFI_CONN: WiFi internal error, station or soft-AP control block wrong + * - ESP_ERR_WIFI_NOT_ASSOC: WiFi is not associated + * - ESP_ERR_INVALID_ARG: invalid argument + */ +esp_err_t esp_wifi_sta_itwt_suspend(int flow_id, int suspend_time_ms); + +/** + * @brief Get flow id status + * + * @param[in] flow_id_bitmap Flow id status bitmap with 8 bit. Each bit represents that whether the corresponding flow id is setup. + * 1: setup, 0: not setup. + * + * @return + * - ESP_OK: succeed + * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init + * - ESP_ERR_WIFI_NOT_STARTED: WiFi is not started by esp_wifi_start + * - ESP_ERR_WIFI_CONN: WiFi internal error, station or soft-AP control block wrong + * - ESP_ERR_WIFI_NOT_CONNECT: The station is in disconnect status + * - ESP_ERR_INVALID_ARG: invalid argument + */ +esp_err_t esp_wifi_sta_itwt_get_flow_id_status(int *flow_id_bitmap); + +/** + * @brief Send probe to update TSF time + * + * @attention In bad network, timeout_ms is variable with the network + * + * @param[in] timeout_ms The estimated time includes sending probe request and receiving probe response, unit: ms. + * + * @return + * - ESP_OK: succeed + * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init + * - ESP_ERR_WIFI_NOT_STARTED: WiFi is not started by esp_wifi_start + * - ESP_ERR_WIFI_CONN: WiFi internal error, station or soft-AP control block wrong + * - ESP_ERR_WIFI_NOT_ASSOC: WiFi is not associated + */ +esp_err_t esp_wifi_sta_itwt_send_probe_req(int timeout_ms); + +/** + * @brief Set time offset with TBTT of target wake time field in itwt setup request frame. + * + * @param[in] offset_us Offset with TBTT of target wake time field in itwt setup request frame, range is [0, 102400], unit microseconds. + * + * @return + * - ESP_OK: succeed + * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init + * - ESP_ERR_WIFI_NOT_STARTED: WiFi is not started by esp_wifi_start + * - ESP_ERR_WIFI_CONN: WiFi internal error, station or soft-AP control block wrong + * - ESP_ERR_WIFI_NOT_ASSOC: WiFi is not associated + * - ESP_ERR_INVALID_ARG: invalid argument + */ +esp_err_t esp_wifi_sta_itwt_set_target_wake_time_offset(int offset_us); + +/** + * @brief Enable the reception statistics. + * + * @param[in] rx_stats indicate whether enable the reception statistics for HT, HE SU, HE ER SU and legacy + * @param[in] rx_mu_stats indicate whether enable the reception statistics for DL MU-MIMO and DL OFDMA + * + * @return + * - ESP_OK: succeed + * - ESP_ERR_NO_MEM: out of memory + */ +esp_err_t esp_wifi_enable_rx_statistics(bool rx_stats, bool rx_mu_stats); + +/** + * @brief Enable the transmission statistics. + * + * @param[in] aci access category of the transmission + * @param[in] tx_stats indicate whether enable the transmission statistics + * + * @return + * - ESP_OK: succeed + * - ESP_ERR_NO_MEM: out of memory + */ +esp_err_t esp_wifi_enable_tx_statistics(esp_wifi_aci_t aci, bool tx_stats); + + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_wifi/include/esp_wifi_he_types.h b/components/esp_wifi/include/esp_wifi_he_types.h new file mode 100644 index 0000000000..7e34a4a34a --- /dev/null +++ b/components/esp_wifi/include/esp_wifi_he_types.h @@ -0,0 +1,225 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Access category + */ +typedef enum { + ESP_WIFI_ACI_VO, /**< voice traffic */ + ESP_WIFI_ACI_VI, /**< video traffic */ + ESP_WIFI_ACI_BE, /**< best effort traffic */ + ESP_WIFI_ACI_BK, /**< background traffic */ + ESP_WIFI_ACI_MAX, /**< the max value */ +} esp_wifi_aci_t; + +/** + * @brief Channel state information(CSI) HE STBC CSI selection + */ +enum { + ESP_CSI_ACQUIRE_STBC_HELTF1, /**< HE STBC: select the first HE-LTF */ + ESP_CSI_ACQUIRE_STBC_HELTF2, /**< HE STBC: select the second HE-LTF */ + ESP_CSI_ACQUIRE_STBC_SAMPLE_HELTFS, /**< HE STBC: sample alternating scarier of HE-LTF1 and HE-LTF2 */ +}; + +/** + * @brief Channel state information(CSI) configuration type + */ +typedef struct { + uint32_t enable : 1; /**< enable to acquire CSI */ + uint32_t acquire_csi_legacy : 1; /**< enable to acquire L-LTF when receiving a 11g PPDU */ + uint32_t acquire_csi_ht20 : 1; /**< enable to acquire HT-LTF when receiving an HT20 PPDU */ + uint32_t acquire_csi_ht40 : 1; /**< enable to acquire HT-LTF when receiving an HT40 PPDU */ + uint32_t acquire_csi_su : 1; /**< enable to acquire HE-LTF when receiving an HE20 SU PPDU */ + uint32_t acquire_csi_mu : 1; /**< enable to acquire HE-LTF when receiving an HE20 MU PPDU */ + uint32_t acquire_csi_dcm : 1; /**< enable to acquire HE-LTF when receiving an HE20 DCM applied PPDU */ + uint32_t acquire_csi_beamformed : 1; /**< enable to acquire HE-LTF when receiving an HE20 Beamformed applied PPDU */ + uint32_t acquire_csi_he_stbc : 2; /**< when receiving an STBC applied HE PPDU, + 0- acquire the complete HE-LTF1, + 1- acquire the complete HE-LTF2 + 2- sample evenly among the HE-LTF1 and HE-LTF2 */ + uint32_t val_scale_cfg : 2; /**< value 0-3 */ + uint32_t reserved : 20; /**< reserved */ +} wifi_csi_acquire_config_t; + +/** + * @brief HE variant HT Control field including UPH(UL power headroom) and OM(Operation mode) + */ +typedef struct { + uint32_t id : 2; /**< HE Variant ID = 3 */ + uint32_t uph_id : 4; /**< UPH control ID: 4 */ + uint32_t ul_pw_headroom : 5; /**< the available UL power headroom for the current HE-MCS, unit: dB, value[0, 31] */ + uint32_t min_tx_pw_flag : 1; /**< indicate that the min. transmit power for current HE-MCS is reached, set to 0 otherwise */ + uint32_t rsvd : 2; /**< reserved */ + uint32_t ctrl_id : 4; /**< OM control ID: 1 */ + uint32_t rx_nss : 3; /**< the max. number of spatial streams for the reception, only accept 0. */ + uint32_t bw : 2; /**< the operating channel width for both reception and transmission, only accept 0. */ + uint32_t ul_mu_disable : 1; /**< disable UL MU operations */ + uint32_t tx_nsts : 3; /**< the max. number of spatial streams for the transmission, only accept 0. */ + uint32_t er_su_disable : 1; /**< disable the reception of 242-tone HE ER SU PPDU */ + uint32_t dl_mu_mimo_resounding_recommendation : 1; /**< indicate the STA suggests the AP either resounding the channel or increase the channel sounding frequency with the STA */ + uint32_t ul_mu_data_disable : 1; /**< disable UL MU data operations */ + uint32_t padding : 2; /**< padding bits */ +} esp_wifi_htc_omc_t; + +/** + * @brief TWT setup commands + */ +typedef enum { + TWT_REQUEST, /**< request to join a TWT without providing a set of TWT parameters */ + TWT_SUGGEST, /**< request to join a TWT and offer a set of preferred TWT parameters but might accept alternative TWT parameters */ + TWT_DEMAND, /**< request to join a TWT and currently accept only the indicated TWT parameters */ + TWT_GROUPING, /**< for S1G STA */ + TWT_ACCEPT, /**< accept the TWT request with the TWT parameters, also used in unsolicited TWT response */ + TWT_ALTERNATE, /**< indicate a counter-offer of TWT parameters without creation of a TWT agreement */ + TWT_DICTATE, /**< indicate no TWT agreement is created, but one is likely to be accepted only if the requesting STA transmits a new TWT setup request with the indicated TWT parameters */ + TWT_REJECT, /**< indicate that the negotiation has ended in failure to crate a new TWT agreement */ +} wifi_twt_setup_cmds_t; + +/** + * @brief HE SU GI and LTF types + */ +typedef enum { + HE_SU_ERSU_1_LTF_0_8_US_GI, /**< 1 LTF and 0.8 us GI */ + HE_SU_ERSU_2_LTF_0_8_US_GI, /**< 2 LTF and 0.8 us GI */ + HE_SU_ERSU_2_LTF_1_6_US_GI, /**< 2 LTF and 1.6 us GI */ + HE_SU_ERSU_4_LTF_3_2_US_GI, /**< 4 LTF and 3.2 us GI */ +} he_su_gi_and_ltf_type_t; + +/** + * @brief Reception format + */ +typedef enum { + RX_BB_FORMAT_11B = 0, /**< the reception frame is a 11b MPDU */ + RX_BB_FORMAT_11G = 1, /**< the reception frame is a 11g MPDU */ + RX_BB_FORMAT_HT = 2, /**< the reception frame is a HT MPDU */ + RX_BB_FORMAT_VHT = 3, /**< the reception frame is a VHT MPDU */ + RX_BB_FORMAT_HE_SU = 4, /**< the reception frame is a HE SU MPDU */ + RX_BB_FORMAT_HE_MU = 5, /**< the reception frame is a HE MU MPDU */ + RX_BB_FORMAT_HE_ERSU = 6, /**< the reception frame is a HE ER SU MPDU */ + RX_BB_FORMAT_HE_TB = 7, /**< the reception frame is a HE TB MPDU */ +} wifi_rx_bb_format_t; + +/** + * @brief RxControl Info + */ +typedef struct { + signed rssi : 8; /**< the RSSI of the reception frame */ + unsigned rate : 5; /**< if cur_bb_format is RX_BB_FORMAT_11B, it's the transmission rate. otherwise it's Rate field of L-SIG */ + unsigned : 1; /**< reserved */ + unsigned : 2; /**< reserved */ + unsigned : 12; /**< reserved */ + unsigned rxmatch0 : 1; /**< indicate whether the reception frame is from interface 0 */ + unsigned rxmatch1 : 1; /**< indicate whether the reception frame is from interface 1 */ + unsigned rxmatch2 : 1; /**< indicate whether the reception frame is from interface 2 */ + unsigned rxmatch3 : 1; /**< indicate whether the reception frame is from interface 3 */ + uint32_t he_siga1; /**< HE-SIGA1 or HT-SIG */ + unsigned rxend_state : 8; /**< reception state, 0: successful, others: failure */ + uint16_t he_siga2; /**< HE-SIGA2 */ + unsigned : 7; /**< reserved */ + unsigned is_group : 1; /**< indicate whether the reception is a group addressed frame */ + unsigned : 32; /**< reserved */ + unsigned : 15; /**< reserved */ + unsigned : 15; /**< reserved */ + unsigned : 2; /**< reserved */ + unsigned noise_floor : 8; /**< the noise floor of the reception frame */ + signed data_rssi : 8; /**< the RSSI of the DATA field */ + unsigned : 8; /**< reserved */ + unsigned : 8; /**< reserved */ + unsigned channel : 4; /**< the primary channel */ + unsigned second : 4; /**< the second channel if in HT40 */ + unsigned : 24; /**< reserved */ + unsigned : 32; /**< reserved */ + unsigned : 2; /**< reserved */ + unsigned : 4; /**< reserved */ + unsigned : 2; /**< reserved */ + unsigned rx_channel_estimate_len : 10; /**< the length of the channel information */ + unsigned rx_channel_estimate_info_vld : 1; /**< indicate the channel information is valid */ + unsigned : 1; /**< reserved */ + unsigned : 11; /**< reserved */ + unsigned : 1; /**< reserved */ + unsigned : 24; /**< reserved */ + unsigned cur_bb_format : 4; /**< the format of the reception frame */ + unsigned cur_single_mpdu : 1; /**< indicate whether the reception MPDU is a S-MPDU */ + unsigned : 3; /**< reserved */ + unsigned : 32; /**< reserved */ + unsigned : 32; /**< reserved */ + unsigned : 32; /**< reserved */ + unsigned : 32; /**< reserved */ + unsigned : 32; /**< reserved */ + unsigned : 32; /**< reserved */ + unsigned : 32; /**< reserved */ + unsigned : 32; /**< reserved */ + unsigned : 8; /**< reserved */ + unsigned he_sigb_len : 6; /**< the length of HE-SIGB */ + unsigned : 2; /**< reserved */ + unsigned : 8; /**< reserved */ + unsigned : 8; /**< reserved */ + unsigned : 32; /**< reserved */ + unsigned : 7; /**< reserved */ + unsigned : 1; /**< reserved */ + unsigned : 8; /**< reserved */ + unsigned : 16; /**< reserved */ + unsigned sig_len : 14; /**< the length of the reception MPDU */ + unsigned : 2; /**< reserved */ + unsigned dump_len : 14; /**< the length of the reception MPDU excluding the FCS */ + unsigned : 2; /**< reserved */ + unsigned rx_state : 8; /**< reception state, 0: successful, others: failure */ + unsigned : 24; /**< reserved */ +} __attribute__((packed)) esp_wifi_rxctrl_t; + +/** Argument structure for WIFI_EVENT_TWT_SET_UP event */ +typedef struct { + wifi_twt_setup_cmds_t setup_cmd; /**< TWT setup command */ + uint8_t flow_id; /**< flow id */ + uint8_t min_wake_dura; /**< the min. wake duration, unit: 256 us by default */ + uint8_t wake_invl_expn; /**< the exponent of the TWT wake interval in microseconds, base 2 */ + uint16_t wake_invl_mant; /**< the value of the mantissa of the TWT wake interval value in microseconds, base 2 */ + bool trigger; /**< true: indicates a trigger-enabled TWT, false: indicates a non-trigger-enabled TWT */ + uint8_t flow_type; /**< 0: indicate an announced TWT, 1: indicates an unannounced TWT */ +} wifi_event_sta_itwt_setup_t; + +/** Argument structure for WIFI_EVENT_TWT_TEARDOWN event */ +typedef struct { + uint8_t flow_id; /**< flow id */ +} wifi_event_sta_itwt_teardown_t; + +/** + * @brief iTWT probe status + */ +typedef enum { + ITWT_PROBE_FAIL, /**< station sends probe request fail */ + ITWT_PROBE_SUCCESS, /**< 1) station receives beacon from AP; 2) station receives probe response from AP */ + ITWT_PROBE_TIMEOUT, /**< 1) timeout of receiving ACK in response of previously probe request sending by station + 2) timeout of receiving probe response in response of previously probe request sending by station */ + ITWT_PROBE_STA_DISCONNECTED, /**< station is not connected */ +} wifi_itwt_probe_status_t; + +/** Argument structure for WIFI_EVENT_ITWT_SEND_PROBE event */ +typedef struct { + wifi_itwt_probe_status_t status; /**< probe status */ + uint8_t reason; /**< failure reason */ +} wifi_event_sta_itwt_probe_t; + +/** Argument structure for WIFI_EVENT_ITWT_SUSPEND event */ +typedef struct { + esp_err_t status; /**< suspend status */ + uint8_t flow_id_bitmap; /**< bitmap of the suspended flow id */ + uint32_t actual_suspend_time_ms[8]; /**< the actual suspend time for each flow id, unit: ms */ +} wifi_event_sta_itwt_suspend_t; + +#ifdef __cplusplus +} +#endif + diff --git a/components/esp_wifi/include/esp_wifi_types.h b/components/esp_wifi/include/esp_wifi_types.h index ac3e55715c..3706175f14 100644 --- a/components/esp_wifi/include/esp_wifi_types.h +++ b/components/esp_wifi/include/esp_wifi_types.h @@ -9,6 +9,9 @@ #define __ESP_WIFI_TYPES_H__ #include "esp_private/esp_wifi_types_private.h" +#if CONFIG_SOC_WIFI_HE_SUPPORT +#include "esp_wifi_he_types.h" +#endif #ifdef __cplusplus extern "C" { @@ -184,6 +187,13 @@ typedef enum { WIFI_ANT_MAX, /**< Invalid WiFi antenna */ } wifi_ant_t; +typedef struct { + uint8_t bss_color:6; /**< an unsigned integer whose value is the BSS Color of the BSS corresponding to the AP */ + uint8_t partial_bss_color:1; /**< indicate if an AID assignment rule based on the BSS color */ + uint8_t bss_color_disabled:1; /**< indicate if the use of BSS color is disabled */ + uint8_t bssid_index; /**< in M-BSSID set, identifies the nontransmitted BSSID */ +} wifi_he_ap_info_t; + /** @brief Description of a WiFi AP */ typedef struct { uint8_t bssid[6]; /**< MAC address of AP */ @@ -199,11 +209,13 @@ typedef struct { uint32_t phy_11g:1; /**< bit: 1 flag to identify if 11g mode is enabled or not */ uint32_t phy_11n:1; /**< bit: 2 flag to identify if 11n mode is enabled or not */ uint32_t phy_lr:1; /**< bit: 3 flag to identify if low rate is enabled or not */ - uint32_t wps:1; /**< bit: 4 flag to identify if WPS is supported or not */ - uint32_t ftm_responder:1; /**< bit: 5 flag to identify if FTM is supported in responder mode */ - uint32_t ftm_initiator:1; /**< bit: 6 flag to identify if FTM is supported in initiator mode */ - uint32_t reserved:25; /**< bit: 7..31 reserved */ + uint32_t phy_11ax:1; /**< bit: 4 flag to identify if 11ax mode is enabled or not */ + uint32_t wps:1; /**< bit: 5 flag to identify if WPS is supported or not */ + uint32_t ftm_responder:1; /**< bit: 6 flag to identify if FTM is supported in responder mode */ + uint32_t ftm_initiator:1; /**< bit: 7 flag to identify if FTM is supported in initiator mode */ + uint32_t reserved:24; /**< bit: 8..31 reserved */ wifi_country_t country; /**< country information of AP */ + wifi_he_ap_info_t he_ap; /**< HE AP info */ } wifi_ap_record_t; typedef enum { @@ -233,6 +245,7 @@ typedef enum { #define WIFI_PROTOCOL_11G 2 #define WIFI_PROTOCOL_11N 4 #define WIFI_PROTOCOL_LR 8 +#define WIFI_PROTOCOL_11AX 16 typedef enum { WIFI_BW_HT20 = 1, /* Bandwidth is HT20 */ @@ -270,25 +283,32 @@ typedef struct { /** @brief STA configuration settings for the ESP32 */ typedef struct { - uint8_t ssid[32]; /**< SSID of target AP. */ - uint8_t password[64]; /**< Password of target AP. */ - wifi_scan_method_t scan_method; /**< do all channel scan or fast scan */ - bool bssid_set; /**< whether set MAC address of target AP or not. Generally, station_config.bssid_set needs to be 0; and it needs to be 1 only when users need to check the MAC address of the AP.*/ - uint8_t bssid[6]; /**< MAC address of target AP*/ - uint8_t channel; /**< channel of target AP. Set to 1~13 to scan starting from the specified channel before connecting to AP. If the channel of AP is unknown, set it to 0.*/ - uint16_t listen_interval; /**< Listen interval for ESP32 station to receive beacon when WIFI_PS_MAX_MODEM is set. Units: AP beacon intervals. Defaults to 3 if set to 0. */ - wifi_sort_method_t sort_method; /**< sort the connect AP in the list by rssi or security mode */ - wifi_scan_threshold_t threshold; /**< When sort_method is set, only APs which have an auth mode that is more secure than the selected auth mode and a signal stronger than the minimum RSSI will be used. */ - wifi_pmf_config_t pmf_cfg; /**< Configuration for Protected Management Frame. Will be advertized in RSN Capabilities in RSN IE. */ - uint32_t rm_enabled:1; /**< Whether Radio Measurements are enabled for the connection */ - uint32_t btm_enabled:1; /**< Whether BSS Transition Management is enabled for the connection */ - uint32_t mbo_enabled:1; /**< Whether MBO is enabled for the connection */ - uint32_t ft_enabled:1; /**< Whether FT is enabled for the connection */ - uint32_t owe_enabled:1; /**< Whether OWE is enabled for the connection */ - uint32_t transition_disable:1; /**< Whether to enable transition disable feature */ - uint32_t reserved:26; /**< Reserved for future feature set */ - wifi_sae_pwe_method_t sae_pwe_h2e; /**< Whether SAE hash to element is enabled */ - uint8_t failure_retry_cnt; /**< Number of connection retries station will do before moving to next AP. scan_method should be set as WIFI_ALL_CHANNEL_SCAN to use this config. Note: Enabling this may cause connection time to increase incase best AP doesn't behave properly. */ + uint8_t ssid[32]; /**< SSID of target AP. */ + uint8_t password[64]; /**< Password of target AP. */ + wifi_scan_method_t scan_method; /**< do all channel scan or fast scan */ + bool bssid_set; /**< whether set MAC address of target AP or not. Generally, station_config.bssid_set needs to be 0; and it needs to be 1 only when users need to check the MAC address of the AP.*/ + uint8_t bssid[6]; /**< MAC address of target AP*/ + uint8_t channel; /**< channel of target AP. Set to 1~13 to scan starting from the specified channel before connecting to AP. If the channel of AP is unknown, set it to 0.*/ + uint16_t listen_interval; /**< Listen interval for ESP32 station to receive beacon when WIFI_PS_MAX_MODEM is set. Units: AP beacon intervals. Defaults to 3 if set to 0. */ + wifi_sort_method_t sort_method; /**< sort the connect AP in the list by rssi or security mode */ + wifi_scan_threshold_t threshold; /**< When sort_method is set, only APs which have an auth mode that is more secure than the selected auth mode and a signal stronger than the minimum RSSI will be used. */ + wifi_pmf_config_t pmf_cfg; /**< Configuration for Protected Management Frame. Will be advertised in RSN Capabilities in RSN IE. */ + uint32_t rm_enabled:1; /**< Whether Radio Measurements are enabled for the connection */ + uint32_t btm_enabled:1; /**< Whether BSS Transition Management is enabled for the connection */ + uint32_t mbo_enabled:1; /**< Whether MBO is enabled for the connection */ + uint32_t ft_enabled:1; /**< Whether FT is enabled for the connection */ + uint32_t owe_enabled:1; /**< Whether OWE is enabled for the connection */ + uint32_t transition_disable:1; /**< Whether to enable transition disable feature */ + uint32_t aid:12; /**< Authentication id assigned by the connected AP. aid = 0 if the STA is not connected. */ + uint32_t phymode:6; /**< Operation phy mode, BIT[5]: indicate whether LR enabled, BIT[0-4]: wifi_phy_mode_t. */ + uint32_t reserved:8; /**< Reserved for future feature set */ + wifi_sae_pwe_method_t sae_pwe_h2e; /**< Whether SAE hash to element is enabled */ + uint8_t failure_retry_cnt; /**< Number of connection retries station will do before moving to next AP. scan_method should be set as WIFI_ALL_CHANNEL_SCAN to use this config. + Note: Enabling this may cause connection time to increase incase best AP doesn't behave properly. */ + uint8_t he_dcm_set:1; /**< Whether DCM max.constellation for transmission and reception is set. */ + uint8_t he_dcm_max_constellation_tx:2; /**< Indicate the max.constellation for DCM in TB PPDU the STA supported. 0: not supported. 1: BPSK, 2: QPSK, 3: 16-QAM. The default value is 3. */ + uint8_t he_dcm_max_constellation_rx:2; /**< Indicate the max.constellation for DCM in both Data field and HE-SIG-B field the STA supported. 0: not supported. 1: BPSK, 2: QPSK, 3: 16-QAM. The default value is 3. */ + uint8_t he_mcs9_enabled:1; /**< Whether to support HE-MCS 0 to 9. The default value is 0. */ } wifi_sta_config_t; /** @brief Configuration data for ESP32 AP or STA. @@ -304,19 +324,20 @@ typedef union { /** @brief Description of STA associated with AP */ typedef struct { - uint8_t mac[6]; /**< mac address */ - int8_t rssi; /**< current average rssi of sta connected */ + uint8_t mac[6]; /**< mac address */ + int8_t rssi; /**< current average rssi of sta connected */ uint32_t phy_11b:1; /**< bit: 0 flag to identify if 11b mode is enabled or not */ uint32_t phy_11g:1; /**< bit: 1 flag to identify if 11g mode is enabled or not */ uint32_t phy_11n:1; /**< bit: 2 flag to identify if 11n mode is enabled or not */ uint32_t phy_lr:1; /**< bit: 3 flag to identify if low rate is enabled or not */ - uint32_t is_mesh_child:1;/**< bit: 4 flag to identify mesh child */ - uint32_t reserved:27; /**< bit: 5..31 reserved */ + uint32_t phy_11ax:1; /**< bit: 4 flag to identify if 11ax mode is enabled or not */ + uint32_t is_mesh_child:1;/**< bit: 5 flag to identify mesh child */ + uint32_t reserved:26; /**< bit: 6..31 reserved */ } wifi_sta_info_t; #if CONFIG_IDF_TARGET_ESP32C2 #define ESP_WIFI_MAX_CONN_NUM (4) /**< max number of stations which can connect to ESP32C2 soft-AP */ -#elif CONFIG_IDF_TARGET_ESP32C3 +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 #define ESP_WIFI_MAX_CONN_NUM (10) /**< max number of stations which can connect to ESP32C3 soft-AP */ #else #define ESP_WIFI_MAX_CONN_NUM (15) /**< max number of stations which can connect to ESP32/ESP32S3/ESP32S2 soft-AP */ @@ -358,6 +379,19 @@ typedef enum { #define WIFI_VENDOR_IE_ELEMENT_ID 0xDD +/** + * @brief Operation Phymode + */ +typedef enum +{ + WIFI_PHY_MODE_LR, /**< PHY mode for Low Rate */ + WIFI_PHY_MODE_11B, /**< PHY mode for 11b */ + WIFI_PHY_MODE_11G, /**< PHY mode for 11g */ + WIFI_PHY_MODE_HT20, /**< PHY mode for Bandwidth HT20 */ + WIFI_PHY_MODE_HT40, /**< PHY mode for Bandwidth HT40 */ + WIFI_PHY_MODE_HE20, /**< PHY mode for Bandwidth HE20 */ +} wifi_phy_mode_t; + /** * @brief Vendor Information Element header * @@ -371,6 +405,9 @@ typedef struct { uint8_t payload[0]; /**< Payload. Length is equal to value in 'length' field, minus 4. */ } vendor_ie_data_t; +#if CONFIG_SOC_WIFI_HE_SUPPORT +typedef esp_wifi_rxctrl_t wifi_pkt_rx_ctrl_t; +#else /** @brief Received packet radio metadata header, this is the common header at the beginning of all promiscuous mode RX callback buffers */ typedef struct { signed rssi:8; /**< Received Signal Strength Indicator(RSSI) of packet. unit: dBm */ @@ -420,6 +457,7 @@ typedef struct { unsigned :12; /**< reserved */ unsigned rx_state:8; /**< state of the packet. 0: no error; others: error numbers which are not public */ } wifi_pkt_rx_ctrl_t; +#endif /** @brief Payload passed to 'buf' parameter of promiscuous mode RX callback. */ @@ -475,6 +513,9 @@ typedef struct { * @brief Channel state information(CSI) configuration type * */ +#if CONFIG_SOC_WIFI_HE_SUPPORT +typedef wifi_csi_acquire_config_t wifi_csi_config_t; +#else typedef struct { bool lltf_en; /**< enable to receive legacy long training field(lltf) data. Default enabled */ bool htltf_en; /**< enable to receive HT long training field(htltf) data. Default enabled */ @@ -484,6 +525,7 @@ typedef struct { bool manu_scale; /**< manually scale the CSI data by left shifting or automatically scale the CSI data. If set true, please set the shift bits. false: automatically. true: manually. Default false */ uint8_t shift; /**< manually left shift bits of the scale of the CSI data. The range of the left shift bits is 0~15 */ } wifi_csi_config_t; +#endif /** * @brief CSI data type @@ -603,14 +645,22 @@ typedef enum { WIFI_PHY_RATE_MCS5_LGI = 0x15, /**< MCS5 with long GI, 52 Mbps for 20MHz, 108 Mbps for 40MHz */ WIFI_PHY_RATE_MCS6_LGI = 0x16, /**< MCS6 with long GI, 58.5 Mbps for 20MHz, 121.5 Mbps for 40MHz */ WIFI_PHY_RATE_MCS7_LGI = 0x17, /**< MCS7 with long GI, 65 Mbps for 20MHz, 135 Mbps for 40MHz */ - WIFI_PHY_RATE_MCS0_SGI = 0x18, /**< MCS0 with short GI, 7.2 Mbps for 20MHz, 15 Mbps for 40MHz */ - WIFI_PHY_RATE_MCS1_SGI = 0x19, /**< MCS1 with short GI, 14.4 Mbps for 20MHz, 30 Mbps for 40MHz */ - WIFI_PHY_RATE_MCS2_SGI = 0x1A, /**< MCS2 with short GI, 21.7 Mbps for 20MHz, 45 Mbps for 40MHz */ - WIFI_PHY_RATE_MCS3_SGI = 0x1B, /**< MCS3 with short GI, 28.9 Mbps for 20MHz, 60 Mbps for 40MHz */ - WIFI_PHY_RATE_MCS4_SGI = 0x1C, /**< MCS4 with short GI, 43.3 Mbps for 20MHz, 90 Mbps for 40MHz */ - WIFI_PHY_RATE_MCS5_SGI = 0x1D, /**< MCS5 with short GI, 57.8 Mbps for 20MHz, 120 Mbps for 40MHz */ - WIFI_PHY_RATE_MCS6_SGI = 0x1E, /**< MCS6 with short GI, 65 Mbps for 20MHz, 135 Mbps for 40MHz */ - WIFI_PHY_RATE_MCS7_SGI = 0x1F, /**< MCS7 with short GI, 72.2 Mbps for 20MHz, 150 Mbps for 40MHz */ +#if CONFIG_SOC_WIFI_HE_SUPPORT + WIFI_PHY_RATE_MCS8_LGI, /**< MCS8 */ + WIFI_PHY_RATE_MCS9_LGI, /**< MCS9 */ +#endif + WIFI_PHY_RATE_MCS0_SGI, /**< MCS0 with short GI, 7.2 Mbps for 20MHz, 15 Mbps for 40MHz */ + WIFI_PHY_RATE_MCS1_SGI, /**< MCS1 with short GI, 14.4 Mbps for 20MHz, 30 Mbps for 40MHz */ + WIFI_PHY_RATE_MCS2_SGI, /**< MCS2 with short GI, 21.7 Mbps for 20MHz, 45 Mbps for 40MHz */ + WIFI_PHY_RATE_MCS3_SGI, /**< MCS3 with short GI, 28.9 Mbps for 20MHz, 60 Mbps for 40MHz */ + WIFI_PHY_RATE_MCS4_SGI, /**< MCS4 with short GI, 43.3 Mbps for 20MHz, 90 Mbps for 40MHz */ + WIFI_PHY_RATE_MCS5_SGI, /**< MCS5 with short GI, 57.8 Mbps for 20MHz, 120 Mbps for 40MHz */ + WIFI_PHY_RATE_MCS6_SGI, /**< MCS6 with short GI, 65 Mbps for 20MHz, 135 Mbps for 40MHz */ + WIFI_PHY_RATE_MCS7_SGI, /**< MCS7 with short GI, 72.2 Mbps for 20MHz, 150 Mbps for 40MHz */ +#if CONFIG_SOC_WIFI_HE_SUPPORT + WIFI_PHY_RATE_MCS8_SGI, /**< MCS8 */ + WIFI_PHY_RATE_MCS9_SGI, /**< MCS9 */ +#endif WIFI_PHY_RATE_LORA_250K = 0x29, /**< 250 Kbps */ WIFI_PHY_RATE_LORA_500K = 0x2A, /**< 500 Kbps */ WIFI_PHY_RATE_MAX, @@ -656,6 +706,11 @@ typedef enum { WIFI_EVENT_AP_WPS_RG_PIN, /**< Soft-AP wps pin code in registrar mode */ WIFI_EVENT_AP_WPS_RG_PBC_OVERLAP, /**< Soft-AP wps overlap in registrar mode */ + WIFI_EVENT_ITWT_SETUP, /**< iTWT setup */ + WIFI_EVENT_ITWT_TEARDOWN, /**< iTWT teardown */ + WIFI_EVENT_ITWT_PROBE, /**< iTWT probe */ + WIFI_EVENT_ITWT_SUSPEND, /**< iTWT suspend */ + WIFI_EVENT_MAX, /**< Invalid WiFi event ID */ } wifi_event_t; @@ -678,6 +733,7 @@ typedef struct { uint8_t bssid[6]; /**< BSSID of connected AP*/ uint8_t channel; /**< channel of connected AP*/ wifi_auth_mode_t authmode;/**< authentication mode used by AP*/ + uint16_t aid; /**< authentication id assigned by the connected AP */ } wifi_event_sta_connected_t; /** Argument structure for WIFI_EVENT_STA_DISCONNECTED event */ diff --git a/components/lwip/Kconfig b/components/lwip/Kconfig index ce74095d88..ff9140eacb 100644 --- a/components/lwip/Kconfig +++ b/components/lwip/Kconfig @@ -163,6 +163,13 @@ menu "LWIP" help Enabling this option allows reassemblying incoming fragmented IP6 packets. + config LWIP_IP_REASS_MAX_PBUFS + int "The maximum amount of pbufs waiting to be reassembled" + range 10 100 + default 10 + help + Set the maximum amount of pbufs waiting to be reassembled. + config LWIP_IP_FORWARD bool "Enable IP forwarding" default n diff --git a/components/lwip/port/esp32/include/lwipopts.h b/components/lwip/port/esp32/include/lwipopts.h index f9ea53198e..97dfa2b65b 100644 --- a/components/lwip/port/esp32/include/lwipopts.h +++ b/components/lwip/port/esp32/include/lwipopts.h @@ -215,7 +215,7 @@ extern "C" { * PBUF_POOL_SIZE > IP_REASS_MAX_PBUFS so that the stack is still able to receive * packets even if the maximum amount of fragments is enqueued for reassembly! */ -#define IP_REASS_MAX_PBUFS 10 +#define IP_REASS_MAX_PBUFS CONFIG_LWIP_IP_REASS_MAX_PBUFS /* ---------------------------------- diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index 6e07656bba..64e05113e2 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -971,6 +971,10 @@ config SOC_WIFI_MESH_SUPPORT bool default y +config SOC_WIFI_HE_SUPPORT + bool + default y + config SOC_BLE_SUPPORTED bool default y diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index fcdc667d22..4e21cf58fa 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -37,7 +37,7 @@ #define SOC_ASYNC_MEMCPY_SUPPORTED 1 #define SOC_USB_SERIAL_JTAG_SUPPORTED 1 #define SOC_TEMP_SENSOR_SUPPORTED 1 -#define SOC_WIFI_SUPPORTED 1 // TODO: IDF-5679 +#define SOC_WIFI_SUPPORTED 1 #define SOC_SUPPORTS_SECURE_DL_MODE 1 //#define SOC_RISCV_COPROC_SUPPORTED 1 // TODO: IDF-5816 #define SOC_EFUSE_KEY_PURPOSE_FIELD 1 @@ -435,7 +435,6 @@ #define SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC (1) #define SOC_TEMPERATURE_SENSOR_SUPPORT_XTAL (1) -// TODO: IDF-5679 (Copy from esp32c3, need check) /*------------------------------------ WI-FI CAPS ------------------------------------*/ #define SOC_WIFI_HW_TSF (1) /*!< Support hardware TSF */ #define SOC_WIFI_FTM_SUPPORT (1) /*!< Support FTM */ @@ -443,6 +442,7 @@ #define SOC_WIFI_WAPI_SUPPORT (1) /*!< Support WAPI */ #define SOC_WIFI_CSI_SUPPORT (1) /*!< Support CSI */ #define SOC_WIFI_MESH_SUPPORT (1) /*!< Support WIFI MESH */ +#define SOC_WIFI_HE_SUPPORT (1) /*!< Support Wi-Fi 6 */ /*---------------------------------- Bluetooth CAPS ----------------------------------*/ #define SOC_BLE_SUPPORTED (1) /*!< Support Bluetooth Low Energy hardware */ diff --git a/examples/common_components/iperf/CMakeLists.txt b/examples/common_components/iperf/CMakeLists.txt index 673acc2e43..fa43ad42a0 100644 --- a/examples/common_components/iperf/CMakeLists.txt +++ b/examples/common_components/iperf/CMakeLists.txt @@ -1,6 +1,13 @@ idf_component_register(SRCS "iperf.c" + "wifi_stats.c" + "wifi_twt.c" + "wifi_cmd.c" INCLUDE_DIRS "include" REQUIRES lwip PRIV_REQUIRES esp_timer) target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") + +if(CONFIG_SOC_WIFI_HE_SUPPORT) + idf_component_optional_requires(PRIVATE esp_wifi console) +endif() \ No newline at end of file diff --git a/examples/common_components/iperf/include/wifi_cmd.h b/examples/common_components/iperf/include/wifi_cmd.h new file mode 100644 index 0000000000..5c3093e2ba --- /dev/null +++ b/examples/common_components/iperf/include/wifi_cmd.h @@ -0,0 +1,21 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + + +void register_wifi_cmd(void); +void register_wifi_itwt(void); +void register_wifi_stats(void); + + +#ifdef __cplusplus +} +#endif diff --git a/examples/common_components/iperf/include/wifi_stats.h b/examples/common_components/iperf/include/wifi_stats.h new file mode 100644 index 0000000000..1908444509 --- /dev/null +++ b/examples/common_components/iperf/include/wifi_stats.h @@ -0,0 +1,26 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + + +#if CONFIG_ENABLE_WIFI_TX_STATS || CONFIG_ENABLE_WIFI_RX_STATS + +int wifi_cmd_get_tx_statistics(int argc, char **argv); +int wifi_cmd_clr_tx_statistics(int argc, char **argv); + +int wifi_cmd_get_rx_statistics(int argc, char **argv); +int wifi_cmd_clr_rx_statistics(int argc, char **argv); + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/examples/common_components/iperf/iperf.c b/examples/common_components/iperf/iperf.c index 48ed4c1013..e8987a819c 100644 --- a/examples/common_components/iperf/iperf.c +++ b/examples/common_components/iperf/iperf.c @@ -18,6 +18,8 @@ #include "esp_rom_sys.h" #include "esp_timer.h" #include "iperf.h" +#include "wifi_stats.h" + typedef struct { iperf_cfg_t cfg; @@ -277,7 +279,20 @@ static esp_err_t IRAM_ATTR iperf_run_tcp_server(void) timeout.tv_sec = IPERF_SOCKET_RX_TIMEOUT; setsockopt(client_socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); +#if CONFIG_ENABLE_WIFI_TX_STATS + wifi_cmd_clr_tx_statistics(0, NULL); +#endif +#if CONFIG_ENABLE_WIFI_RX_STATS + wifi_cmd_clr_rx_statistics(0, NULL); +#endif socket_recv(client_socket, listen_addr, IPERF_TRANS_TYPE_TCP); +#if CONFIG_ENABLE_WIFI_RX_STATS + wifi_cmd_get_rx_statistics(0, NULL); +#endif +#if CONFIG_ENABLE_WIFI_TX_STATS + wifi_cmd_get_tx_statistics(0, NULL); +#endif + exit: if (client_socket != -1) { close(client_socket); @@ -328,7 +343,21 @@ static esp_err_t iperf_run_tcp_client(void) memcpy(&dest_addr, &dest_addr4, sizeof(dest_addr4)); } + +#if CONFIG_ENABLE_WIFI_RX_STATS + wifi_cmd_clr_rx_statistics(0, NULL); +#endif +#if CONFIG_ENABLE_WIFI_TX_STATS + wifi_cmd_clr_tx_statistics(0, NULL); +#endif socket_send(client_socket, dest_addr, IPERF_TRANS_TYPE_TCP, s_iperf_ctrl.cfg.bw_lim); +#if CONFIG_ENABLE_WIFI_TX_STATS + wifi_cmd_get_tx_statistics(0, NULL); +#endif +#if CONFIG_ENABLE_WIFI_RX_STATS + wifi_cmd_get_rx_statistics(0, NULL); +#endif + exit: if (client_socket != -1) { shutdown(client_socket, 0); @@ -388,8 +417,13 @@ static esp_err_t IRAM_ATTR iperf_run_udp_server(void) timeout.tv_sec = IPERF_SOCKET_RX_TIMEOUT; setsockopt(listen_socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); - +#if CONFIG_ENABLE_WIFI_RX_STATS + wifi_cmd_clr_rx_statistics(0, NULL); +#endif socket_recv(listen_socket, listen_addr, IPERF_TRANS_TYPE_UDP); +#if CONFIG_ENABLE_WIFI_RX_STATS + wifi_cmd_get_rx_statistics(0, NULL); +#endif exit: if (listen_socket != -1) { shutdown(listen_socket, 0); @@ -434,8 +468,13 @@ static esp_err_t iperf_run_udp_client(void) setsockopt(client_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); memcpy(&dest_addr, &dest_addr4, sizeof(dest_addr4)); } - +#if CONFIG_ENABLE_WIFI_TX_STATS + wifi_cmd_clr_tx_statistics(0, NULL); +#endif socket_send(client_socket, dest_addr, IPERF_TRANS_TYPE_UDP, s_iperf_ctrl.cfg.bw_lim); +#if CONFIG_ENABLE_WIFI_TX_STATS + wifi_cmd_get_tx_statistics(0, NULL); +#endif exit: if (client_socket != -1) { shutdown(client_socket, 0); diff --git a/examples/common_components/iperf/wifi_cmd.c b/examples/common_components/iperf/wifi_cmd.c new file mode 100644 index 0000000000..16afffd46b --- /dev/null +++ b/examples/common_components/iperf/wifi_cmd.c @@ -0,0 +1,1079 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "freertos/event_groups.h" +#include "ping/ping_sock.h" +#include "lwip/inet.h" +#include "lwip/netdb.h" +#include "esp_mac.h" +#include "wifi_cmd.h" + +#if CONFIG_SOC_WIFI_HE_SUPPORT + +#include "esp_console.h" +#include "argtable3/argtable3.h" +#include "esp_netif.h" +#include "esp_event.h" +#include "esp_wifi.h" +#include "esp_wifi_types.h" +#include "esp_wifi_he.h" +#include "esp_private/esp_wifi_he_private.h" + + +/******************************************************* + * Macros + *******************************************************/ +/* + * enable/disable rx/tx statistics after wifi started: + * (1) esp_wifi_enable_rx_statistics(true, true); + * (2) esp_wifi_enable_tx_statistics(ESP_WIFI_ACI_BE, true); + */ + +/******************************************************* + * Constants + *******************************************************/ +static const char *TAG = "cmd"; + +/******************************************************* + * Structures + *******************************************************/ +typedef struct { + struct arg_dbl *read; + struct arg_dbl *write; + struct arg_dbl *value; + struct arg_end *end; +} reg_rw_args_t; + +typedef struct { + struct arg_dbl *disable; + struct arg_end *end; +} wifi_stbc_args_t; + +typedef struct { + struct arg_dbl *disable; + struct arg_end *end; +} wifi_bmfmee_args_t; + +typedef struct { + struct arg_dbl *ul_mu_disable; + struct arg_dbl *ul_mu_data_disable; + struct arg_dbl *ersu_disable; + struct arg_dbl *report; + struct arg_dbl *resounding; + struct arg_end *end; +} wifi_omctrl_args_t; + +typedef struct { + struct arg_dbl *tf_padding; + struct arg_end *end; +} wifi_tf_padding_args_t; + +typedef struct { + struct arg_int *enable; + struct arg_int *txq; + struct arg_end *end; +} wifi_edca_args_t; + +typedef struct { + struct arg_int *reset_timer; + struct arg_int *read_timer; + struct arg_end *end; +} wifi_muedca_args_t; + +typedef struct { + struct arg_dbl *enable; + struct arg_end *end; +} wifi_cca_ignore_args_t; + +typedef struct { + struct arg_dbl *timeout; + struct arg_dbl *interval; + struct arg_int *data_size; + struct arg_int *count; + struct arg_int *tos; + struct arg_str *host; + struct arg_lit *abort; + struct arg_end *end; +} wifi_ping_args_t; + +typedef struct { + struct arg_str *ip; + struct arg_str *gw; + struct arg_str *netmask; + struct arg_end *end; +} static_ip_args_t; + +typedef struct { + struct arg_str *proto; + struct arg_end *end; +} wifi_proto_args_t; + +typedef struct { + struct arg_int *val; + struct arg_end *end; +} wifi_inactive_time_args_t; + +typedef struct { + struct arg_int *format; + struct arg_int *rate; + struct arg_end *end; +} wifi_sounding_rate_t; + +typedef struct { + struct arg_int *mcs; + struct arg_int *power; + struct arg_end *end; +} wifi_tx_pwr_t; + +/******************************************************* + * Variable Definitions + *******************************************************/ +static reg_rw_args_t reg_rw_args; +static wifi_stbc_args_t stbc_args; +static wifi_bmfmee_args_t bmfmee_args; +static wifi_omctrl_args_t omctrl_args; +static wifi_tf_padding_args_t tf_padding_args; +static wifi_edca_args_t edca_args; +static wifi_cca_ignore_args_t cca_args; +static wifi_ping_args_t ping_args; +static static_ip_args_t static_ip_args; +static wifi_proto_args_t proto_args; +static wifi_inactive_time_args_t inactive_time_args; +static wifi_sounding_rate_t wifi_sounding_rate_args; +static wifi_muedca_args_t muedca_args; +static wifi_tx_pwr_t tx_pwr_args; + + +extern esp_netif_t *netif_ap; +extern esp_netif_t *netif_sta; +extern EventGroupHandle_t wifi_event_group; +extern const int CONNECTED_BIT; + +/******************************************************* + * Function Declarations + *******************************************************/ + +/******************************************************* + * Function Definitions + *******************************************************/ +static int wifi_cmd_get_mac(int argc, char **argv) +{ + uint8_t mac[6] = { 0, }; + if (esp_wifi_get_mac(WIFI_IF_STA, mac) == ESP_OK) { + ESP_LOGW(TAG, "sta mac: " MACSTR "", MAC2STR(mac)); + } + if (esp_wifi_get_mac(WIFI_IF_AP, mac) == ESP_OK) { + ESP_LOGW(TAG, "ap mac: " MACSTR "", MAC2STR(mac)); + } + return 0; +} + +static int wifi_cmd_set_omc(int argc, char **argv) +{ + //TODO ER-SU + esp_wifi_htc_omc_t omc = { 0, }; + esp_err_t err = ESP_OK; + int nerrors = arg_parse(argc, argv, (void **) &omctrl_args); + if (nerrors != 0) { + arg_print_errors(stderr, omctrl_args.end, argv[0]); + return 1; + } + do { + if (!omctrl_args.ul_mu_disable->count && !omctrl_args.ul_mu_data_disable->count) { + omc.ul_mu_disable = 1; + omc.ul_mu_data_disable = 0; + break; + } + /* parse inputs */ + if (omctrl_args.ul_mu_disable->count) { + omc.ul_mu_disable = omctrl_args.ul_mu_disable->dval[0]; + } + if (omctrl_args.ul_mu_data_disable->count) { + omc.ul_mu_data_disable = omctrl_args.ul_mu_data_disable->dval[0]; + } + if (omctrl_args.ersu_disable->count) { + omc.er_su_disable = omctrl_args.ersu_disable->dval[0]; + } + if (omctrl_args.resounding->count) { + omc.dl_mu_mimo_resounding_recommendation = omctrl_args.resounding->dval[0]; + } + } while (0); + + if (omctrl_args.report->count && omctrl_args.report->dval[0] == 0) { + /* not report to ap the om control */ + hal_he_set_ul_mu(omc.ul_mu_disable, omc.ul_mu_data_disable); + ESP_LOGW(TAG, "(omc)(internal)disable ul mu(%d, data:%d) successfully", omc.ul_mu_disable, + omc.ul_mu_data_disable); + } else { + err = esp_wifi_set_htc_omc(&omc); + if (err != ESP_OK) { + ESP_LOGW(TAG, "(omc)disable ul mu(%d, data:%d) failed, err:0x%x", omc.ul_mu_disable, omc.ul_mu_data_disable, + err); + } else { + ESP_LOGW(TAG, "(omc)disable ul mu(%d, data:%d) successfully", omc.ul_mu_disable, omc.ul_mu_data_disable); + } + } + return 0; +} + +static int wifi_cmd_edca_tx(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **) &edca_args); + if (nerrors != 0) { + arg_print_errors(stderr, edca_args.end, argv[0]); + return 1; + } + + int txq = 2; + if (!edca_args.enable->count && !edca_args.txq->count) { + esp_test_disable_edca_tx(txq); + ESP_LOGW(TAG, "(tx)disable edca, txq[%d]", txq); + return 0; + } + txq = edca_args.txq->count ? edca_args.txq->ival[0] : txq; + if (edca_args.enable->ival[0] == 0) { + esp_test_disable_edca_tx(txq); + ESP_LOGW(TAG, "(tx)disable edca, txq[%d]", txq); + } else { + esp_test_enable_edca_tx(txq); + ESP_LOGW(TAG, "(tx)enable edca, txq[%d]", txq); + } + return 0; +} + +static int wifi_cmd_reg_rw(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **) ®_rw_args); + uint32_t addr; + if (nerrors != 0) { + arg_print_errors(stderr, reg_rw_args.end, argv[0]); + return 1; + } + if (reg_rw_args.read->count) { + addr = (uint32_t) reg_rw_args.read->dval[0]; + ESP_LOGW(TAG, "reg read 0x%08x : 0x%08x\n", addr, REG_READ(addr)); + } else if (reg_rw_args.write->count && (uint32_t) reg_rw_args.value->count) { + addr = (uint32_t) reg_rw_args.write->dval[0]; + ESP_LOGW(TAG, "reg write 0x%8x : 0x%8x\n", addr, (uint32_t) reg_rw_args.value->dval[0]); + REG_WRITE(addr, (uint32_t ) reg_rw_args.value->dval[0]); + ESP_LOGW(TAG, "reg read 0x%08x : 0x%08x\n", addr, REG_READ(addr)); + } else { + printf("Input Error\n"); + } + return 0; +} + +static int wifi_cmd_set_tf_padding(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **) &tf_padding_args); + if (nerrors != 0) { + arg_print_errors(stderr, tf_padding_args.end, argv[0]); + return 1; + } + if (tf_padding_args.tf_padding->count) { + esp_wifi_set_tf_padding_duration((int)tf_padding_args.tf_padding->dval[0]); + ESP_LOGW(TAG, "(test)set trigger frame mac padding duration:%d", (int)tf_padding_args.tf_padding->dval[0]); + } else { + printf("Input Error\n"); + } + return 0; +} + +static int wifi_cmd_tb(int argc, char **argv) +{ + dbg_read_axtb_diag(); + dbg_read_ax_diag(1); + return 0; +} + +static int wifi_cmd_stbc(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **) &stbc_args); + if (nerrors != 0) { + arg_print_errors(stderr, stbc_args.end, argv[0]); + return 1; + } + if (stbc_args.disable->count) { + esp_wifi_enable_rx_stbc(0); + ESP_LOGI(TAG, "(cfg)disable he stbc"); + } else { + esp_wifi_enable_rx_stbc(1); + ESP_LOGI(TAG, "(cfg)enable he stbc"); + } + return 0; +} + +static int wifi_cmd_su_bmfmee(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **) &bmfmee_args); + if (nerrors != 0) { + arg_print_errors(stderr, bmfmee_args.end, argv[0]); + return 1; + } + if (bmfmee_args.disable->count) { + esp_wifi_enable_su_bmfmee(0); + ESP_LOGI(TAG, "(cfg)disable he su bmfmee"); + } else { + esp_wifi_enable_su_bmfmee(1); + ESP_LOGI(TAG, "(cfg)enable he su bmfmee"); + } + return 0; +} + +static int wifi_cmd_ignore_cca(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **) &cca_args); + if (nerrors != 0) { + arg_print_errors(stderr, cca_args.end, argv[0]); + return 1; + } + if (cca_args.enable->count) { + dbg_tb_ignore_cca_enable(1); + } else { + dbg_tb_ignore_cca_enable(0); + } + return 0; +} + +static int wifi_cmd_set_ps_type(int argc, char **argv) +{ + ESP_LOGW(TAG, "set to WIFI_PS_MIN_MODEM"); + ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_MIN_MODEM)); + return 0; +} + +static void cmd_ping_on_ping_success(esp_ping_handle_t hdl, void *args) +{ + uint8_t ttl; + uint16_t seqno; + uint32_t elapsed_time, recv_len; + ip_addr_t target_addr; + esp_ping_get_profile(hdl, ESP_PING_PROF_SEQNO, &seqno, sizeof(seqno)); + esp_ping_get_profile(hdl, ESP_PING_PROF_TTL, &ttl, sizeof(ttl)); + esp_ping_get_profile(hdl, ESP_PING_PROF_IPADDR, &target_addr, sizeof(target_addr)); + esp_ping_get_profile(hdl, ESP_PING_PROF_SIZE, &recv_len, sizeof(recv_len)); + esp_ping_get_profile(hdl, ESP_PING_PROF_TIMEGAP, &elapsed_time, sizeof(elapsed_time)); + printf("%d bytes from %s icmp_seq=%d ttl=%d time=%d ms\n", + recv_len, inet_ntoa(target_addr.u_addr.ip4), seqno, ttl, elapsed_time); +} + +static void cmd_ping_on_ping_timeout(esp_ping_handle_t hdl, void *args) +{ + uint16_t seqno; + ip_addr_t target_addr; + esp_ping_get_profile(hdl, ESP_PING_PROF_SEQNO, &seqno, sizeof(seqno)); + esp_ping_get_profile(hdl, ESP_PING_PROF_IPADDR, &target_addr, sizeof(target_addr)); + printf("From %s icmp_seq=%d timeout\n", inet_ntoa(target_addr.u_addr.ip4), seqno); +} + +static void cmd_ping_on_ping_end(esp_ping_handle_t hdl, void *args) +{ + ip_addr_t target_addr; + uint32_t transmitted; + uint32_t received; + uint32_t total_time_ms; + esp_ping_get_profile(hdl, ESP_PING_PROF_REQUEST, &transmitted, sizeof(transmitted)); + esp_ping_get_profile(hdl, ESP_PING_PROF_REPLY, &received, sizeof(received)); + esp_ping_get_profile(hdl, ESP_PING_PROF_IPADDR, &target_addr, sizeof(target_addr)); + esp_ping_get_profile(hdl, ESP_PING_PROF_DURATION, &total_time_ms, sizeof(total_time_ms)); + uint32_t loss = (uint32_t)((1 - ((float)received) / transmitted) * 100); + if (IP_IS_V4(&target_addr)) { + printf("\n--- %s ping statistics ---\n", inet_ntoa(*ip_2_ip4(&target_addr))); + } else { + printf("\n--- %s ping statistics ---\n", inet6_ntoa(*ip_2_ip6(&target_addr))); + } + printf("%d packets transmitted, %d received, %d%% packet loss, time %dms\n", + transmitted, received, loss, total_time_ms); + // delete the ping sessions, so that we clean up all resources and can create a new ping session + // we don't have to call delete function in the callback, instead we can call delete function from other tasks + esp_ping_delete_session(hdl); +} + +static int do_ping_cmd(int argc, char **argv) +{ + esp_ping_config_t config = ESP_PING_DEFAULT_CONFIG(); + static esp_ping_handle_t ping; + int nerrors = arg_parse(argc, argv, (void **)&ping_args); + if (nerrors != 0) { + arg_print_errors(stderr, ping_args.end, argv[0]); + return 1; + } + + if (ping_args.timeout->count > 0) { + config.timeout_ms = (uint32_t)(ping_args.timeout->dval[0] * 1000); + } + + if (ping_args.interval->count > 0) { + config.interval_ms = (uint32_t)(ping_args.interval->dval[0] * 1000); + } + + if (ping_args.data_size->count > 0) { + config.data_size = (uint32_t)(ping_args.data_size->ival[0]); + } + + if (ping_args.count->count > 0) { + config.count = (uint32_t)(ping_args.count->ival[0]); + } + + if (ping_args.tos->count > 0) { + config.tos = (uint32_t)(ping_args.tos->ival[0]); + } + + if (ping_args.abort->count) { + esp_ping_stop(ping); + return 0; + } + + // parse IP address + ip_addr_t target_addr; + struct addrinfo hint; + struct addrinfo *res = NULL; + memset(&hint, 0, sizeof(hint)); + memset(&target_addr, 0, sizeof(target_addr)); + /* convert domain name to IP address */ + if (getaddrinfo(ping_args.host->sval[0], NULL, &hint, &res) != 0) { + printf("ping: unknown host %s\n", ping_args.host->sval[0]); + return 1; + } + if (res->ai_family == AF_INET) { + struct in_addr addr4 = ((struct sockaddr_in *) (res->ai_addr))->sin_addr; + inet_addr_to_ip4addr(ip_2_ip4(&target_addr), &addr4); + } else { + struct in6_addr addr6 = ((struct sockaddr_in6 *) (res->ai_addr))->sin6_addr; + inet6_addr_to_ip6addr(ip_2_ip6(&target_addr), &addr6); + } + freeaddrinfo(res); + config.target_addr = target_addr; + + /* set callback functions */ + esp_ping_callbacks_t cbs = { + .on_ping_success = cmd_ping_on_ping_success, + .on_ping_timeout = cmd_ping_on_ping_timeout, + .on_ping_end = cmd_ping_on_ping_end, + .cb_args = NULL + }; + + esp_ping_new_session(&config, &cbs, &ping); + esp_ping_start(ping); + return 0; +} + +extern bool pm_is_waked(); +extern bool pm_is_sleeping(); +extern bool pm_is_dream(); +static int wifi_cmd_get_ps_state(int argc, char **argv) +{ + ESP_LOGW(TAG, "ps: awake:%d, sleep:%d, dream:%d", pm_is_waked(), pm_is_sleeping(), pm_is_dream()); + return 0; +} + +esp_err_t esp_netif_set_static_ip(esp_netif_t *netif_sta, uint32_t ip, uint32_t gw, + uint32_t netmask) +{ + esp_netif_dhcpc_stop(netif_sta); + esp_netif_ip_info_t ip_info; + esp_netif_set_ip4_addr(&ip_info.ip, ip & 0xFF, (ip >> 8) & 0xFF, (ip >> 16) & 0xFF, + (ip >> 24) & 0xFF); + esp_netif_set_ip4_addr(&ip_info.gw, gw & 0xFF, (gw >> 8) & 0xFF, (gw >> 16) & 0xFF, + (gw >> 24) & 0xFF); + esp_netif_set_ip4_addr(&ip_info.netmask, netmask & 0xFF, (netmask >> 8) & 0xFF, + (netmask >> 16) & 0xFF, (netmask >> 24) & 0xFF); + esp_netif_set_ip_info(netif_sta, &ip_info); + return ESP_OK; +} + +static int wifi_cmd_set_ip(int argc, char **argv) +{ + uint32_t ip = 0, gw = 0, netmask = 0; + int nerrors = arg_parse(argc, argv, (void **) &static_ip_args); + if (nerrors != 0) { + arg_print_errors(stderr, static_ip_args.end, argv[0]); + return 0; + } + if (static_ip_args.ip->count != 0) { + ip = esp_ip4addr_aton(static_ip_args.ip->sval[0]); + } + if (static_ip_args.gw->count != 0) { + gw = esp_ip4addr_aton(static_ip_args.gw->sval[0]); + } + if (static_ip_args.netmask->count != 0) { + netmask = esp_ip4addr_aton(static_ip_args.netmask->sval[0]); + } + if (!ip || !netmask) { + return 0; + } + /* set static IP settings */ + esp_netif_set_static_ip(netif_sta, ip, gw, netmask); + + ESP_LOGD(TAG, "ip:%d.%d.%d.%d, gateway:%d.%d.%d.%d, netmask:%d.%d.%d.%d,", ip & 0xFF, + (ip >> 8) & 0xFF, (ip >> 16) & 0xFF, (ip >> 24) & 0xFF, gw & 0xFF, (gw >> 8) & 0xFF, + (gw >> 16) & 0xFF, (gw >> 24) & 0xFF, netmask & 0xFF, (netmask >> 8) & 0xFF, + (netmask >> 16) & 0xFF, (netmask >> 24) & 0xFF); + return 0; +} + +void wifi_get_local_ip(esp_netif_ip_info_t *ip_info) +{ + int bits = xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, 0, 1, 0); + esp_netif_t *netif = netif_ap; + wifi_mode_t mode; + + esp_wifi_get_mode(&mode); + if (WIFI_MODE_STA == mode) { + bits = xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, 0, 1, 0); + if (bits & CONNECTED_BIT) { + netif = netif_sta; + } else { + ESP_LOGE(TAG, "sta has no IP"); + } + } + esp_netif_get_ip_info(netif, ip_info); +} + +static int wifi_cmd_query(int argc, char **argv) +{ + wifi_config_t cfg; + wifi_bandwidth_t cbw; + uint8_t mac[6]; + esp_netif_ip_info_t ip_info = { 0, }; + + wifi_mode_t mode; + esp_wifi_get_mode(&mode); + wifi_get_local_ip(&ip_info); + bool is_sta_disconnect = false; + char temp_ssid[33] = { 0 }; + printf("Wireless info:"); + if (WIFI_MODE_AP == mode) { + esp_wifi_get_config(WIFI_IF_AP, &cfg); + esp_wifi_get_bandwidth(WIFI_IF_AP, &cbw); + + printf("\n"); + printf("\tmode: ap\n"); + strncpy(temp_ssid, (char *) cfg.ap.ssid, 32); + printf("\tssid: %s\n", temp_ssid); + printf("\tpassword: %s\n", cfg.ap.password); + printf("\tchannel: %d\n", cfg.ap.channel); + if (cbw == WIFI_BW_HT20) { + printf("\tcbw: 20 MHz\n"); + } else if (cbw == WIFI_BW_HT40) { + printf("\tcbw: 40 MHz\n"); + } + + if (esp_wifi_get_mac(WIFI_IF_AP, mac) == ESP_OK) { + printf("\tap mac: "MACSTR, MAC2STR(mac)); + printf("\n"); + } + printf("\tip: %d.%d.%d.%d\n", ip_info.ip.addr & 0xFF, (ip_info.ip.addr >> 8) & 0xFF, + (ip_info.ip.addr >> 16) & 0xFF, (ip_info.ip.addr >> 24) & 0xFF); + printf("\tnetmask: %d.%d.%d.%d\n", ip_info.netmask.addr & 0xFF, + (ip_info.netmask.addr >> 8) & 0xFF, (ip_info.netmask.addr >> 16) & 0xFF, + (ip_info.netmask.addr >> 24) & 0xFF); + printf("\tgateway: %d.%d.%d.%d\n", ip_info.gw.addr & 0xFF, (ip_info.gw.addr >> 8) & 0xFF, + (ip_info.gw.addr >> 16) & 0xFF, (ip_info.gw.addr >> 24) & 0xFF); + printf("\n"); + } else if (WIFI_MODE_STA == mode) { + int bits = xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, 0, 1, 0); + if (bits & CONNECTED_BIT) { + is_sta_disconnect = false; + esp_wifi_get_config(WIFI_IF_STA, &cfg); + esp_wifi_get_bandwidth(WIFI_IF_STA, &cbw); + printf("\n"); + printf("\tmode: station\n"); + printf("\tstatus: connected\n"); + strncpy(temp_ssid, (char *) cfg.sta.ssid, 32); + printf("\tssid: %s\n", temp_ssid); + printf("\tbssid: "MACSTR, MAC2STR(cfg.sta.bssid)); + printf("\n"); + printf("\tchannel: %d\n", cfg.sta.channel); + printf("\taid: %d\n", cfg.sta.aid); + if (cfg.sta.pmf_cfg.capable) { + if (cfg.sta.pmf_cfg.required) { + printf("\tpmf: required\n"); + } else { + printf("\tpmf: optional\n"); + } + } else { + printf("\tpmf: disabled\n"); + } + if (cbw == WIFI_BW_HT20) { + printf("\tcbw: 20 MHz\n"); + } else if (cbw == WIFI_BW_HT40) { + printf("\tcbw: 40 MHz\n"); + } + + if (esp_wifi_get_mac(WIFI_IF_STA, mac) == ESP_OK) { + printf("\tsta mac: "MACSTR, MAC2STR(mac)); + printf("\n"); + } + printf("\tip: %d.%d.%d.%d\n", ip_info.ip.addr & 0xFF, (ip_info.ip.addr >> 8) & 0xFF, + (ip_info.ip.addr >> 16) & 0xFF, (ip_info.ip.addr >> 24) & 0xFF); + printf("\tnetmask: %d.%d.%d.%d\n", ip_info.netmask.addr & 0xFF, + (ip_info.netmask.addr >> 8) & 0xFF, (ip_info.netmask.addr >> 16) & 0xFF, + (ip_info.netmask.addr >> 24) & 0xFF); + printf("\tgateway: %d.%d.%d.%d\n", ip_info.gw.addr & 0xFF, + (ip_info.gw.addr >> 8) & 0xFF, (ip_info.gw.addr >> 16) & 0xFF, + (ip_info.gw.addr >> 24) & 0xFF); + printf("\n"); + + } else { + printf("\n"); + printf("\tmode: disconnected\n"); + is_sta_disconnect = true; + } + } + if (WIFI_MODE_NULL == mode || is_sta_disconnect) { + printf("\n"); + if (WIFI_MODE_NULL == mode) { + printf("\tmode: null\n"); + } + if (esp_wifi_get_mac(WIFI_IF_AP, mac) == ESP_OK) { + printf("\tap mac: "MACSTR, MAC2STR(mac)); + printf("\n"); + } + + if (esp_wifi_get_mac(WIFI_IF_STA, mac) == ESP_OK) { + printf("\tsta mac: "MACSTR, MAC2STR(mac)); + printf("\n"); + } + return 0; + } + + return 0; +} + +static int wifi_cmd_proto(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **)&proto_args); + if (nerrors != 0) { + arg_print_errors(stderr, proto_args.end, argv[0]); + return 1; + } + wifi_mode_t mode; + esp_wifi_get_mode(&mode); + int ifx = (WIFI_MODE_STA == mode) ? 0 : 1; + if (proto_args.proto->count) { + if (!strcmp(proto_args.proto->sval[0], "ax")) { + ESP_ERROR_CHECK(esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N | WIFI_PROTOCOL_11AX)); + printf("(%s)set to 11ax\n", (ifx == WIFI_IF_STA) ? "sta" : "ap"); + } else if (!strcmp(proto_args.proto->sval[0], "bgn")) { + ESP_ERROR_CHECK(esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N)); + printf("(%s)set to bgn\n", (ifx == WIFI_IF_STA) ? "sta" : "ap"); + } else if (!strcmp(proto_args.proto->sval[0], "bg")) { + ESP_ERROR_CHECK(esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G)); + printf("(%s)set to bg\n", (ifx == WIFI_IF_STA) ? "sta" : "ap"); + } else { + ESP_ERROR_CHECK(esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B)); + printf("(%s)set to b\n", (ifx == WIFI_IF_STA) ? "sta" : "ap"); + } + } + uint8_t protocol_bitmap = 0; + ESP_ERROR_CHECK(esp_wifi_get_protocol(ifx, &protocol_bitmap) ); + if (protocol_bitmap & WIFI_PROTOCOL_11AX) { + printf("(%s)11ax\n", (ifx == WIFI_IF_STA) ? "sta" : "ap"); + } else if (protocol_bitmap & WIFI_PROTOCOL_11N) { + printf("(%s)bgn\n", (ifx == WIFI_IF_STA) ? "sta" : "ap"); + } else if (protocol_bitmap & WIFI_PROTOCOL_11G) { + printf("(%s)bg\n", (ifx == WIFI_IF_STA) ? "sta" : "ap"); + } else if (protocol_bitmap & WIFI_PROTOCOL_11B) { + printf("(%s)b\n", (ifx == WIFI_IF_STA) ? "sta" : "ap"); + } + return 0; +} + +static int wifi_disconnect(int argc, char **argv) +{ + wifi_mode_t mode; + esp_wifi_get_mode(&mode); + if (WIFI_MODE_AP == mode) { + // TODO + ESP_LOGI(TAG, "WIFI_MODE_AP, not support"); + } else if (WIFI_MODE_STA == mode) { + esp_wifi_disconnect(); + printf("disconnect\n"); + } else { + ESP_LOGI(TAG, "NULL mode"); + } + return 0; +} + +static int wifi_cmd_inactive_time(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **)&inactive_time_args); + if (nerrors != 0) { + arg_print_errors(stderr, inactive_time_args.end, argv[0]); + return 1; + } + + esp_err_t err = ESP_OK; + wifi_mode_t mode; + esp_wifi_get_mode(&mode); + if ((mode & WIFI_MODE_AP) && inactive_time_args.val->count) { + err = esp_wifi_set_inactive_time(ESP_IF_WIFI_AP, inactive_time_args.val->ival[0]); + if (err != ESP_OK) { + ESP_LOGW(TAG, "set softAP inactive time to %d seconds, err:0x%x\n", inactive_time_args.val->ival[0], err); + } else { + ESP_LOGI(TAG, "set softAP inactive time to %d seconds, err:0x%x\n", inactive_time_args.val->ival[0]); + } + } + //WIFI_MODE_STA or WIFI_MODE_APSTA + if ((mode & WIFI_MODE_STA) && inactive_time_args.val->count) { + err = esp_wifi_set_inactive_time(ESP_IF_WIFI_STA, inactive_time_args.val->ival[0]); + if (err != ESP_OK) { + ESP_LOGW(TAG, "set STA inactive time to %d seconds, err:0x%x\n", inactive_time_args.val->ival[0], err); + } else { + ESP_LOGI(TAG, "set STA inactive time to %d seconds, err:0x%x\n", inactive_time_args.val->ival[0]); + } + } + uint16_t secs = 0; + esp_wifi_get_inactive_time(ESP_IF_WIFI_STA, &secs); + printf("inactive time: %d seconds\n", secs); + return 0; +} + +static int wifi_cmd_sounding_rate(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **)&wifi_sounding_rate_args); + if (nerrors != 0) { + arg_print_errors(stderr, wifi_sounding_rate_args.end, argv[0]); + return 1; + } + + if (wifi_sounding_rate_args.format->count && wifi_sounding_rate_args.rate->count) { + if (wifi_sounding_rate_args.format->ival[0] == SIG_MODE_LEGACY) { + if (wifi_sounding_rate_args.rate->ival[0] < WIFI_PHY_RATE_MCS0_LGI && + wifi_sounding_rate_args.rate->ival[0] >= 0) { + hal_he_set_bf_report_rate(SIG_MODE_LEGACY, wifi_sounding_rate_args.rate->ival[0]); + } else { + ESP_LOGW(TAG, "need correct legacy rate(0-%d)", WIFI_PHY_RATE_9M); + } + } else { + if (wifi_sounding_rate_args.rate->ival[0] >= WIFI_PHY_RATE_MCS0_LGI && + wifi_sounding_rate_args.rate->ival[0] <= WIFI_PHY_RATE_MCS9_SGI) { + hal_he_set_bf_report_rate(wifi_sounding_rate_args.format->ival[0], + wifi_sounding_rate_args.rate->ival[0]); + } else { + ESP_LOGW(TAG, "need correct mcs(%d-%d)", WIFI_PHY_RATE_MCS0_LGI, WIFI_PHY_RATE_MCS9_SGI); + } + } + } else { + ESP_LOGW(TAG, "set rate fail"); + } + return 0; +} + +static int wifi_cmd_muedca(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **)&muedca_args); + if (nerrors != 0) { + arg_print_errors(stderr, muedca_args.end, argv[0]); + return 1; + } + + if (muedca_args.reset_timer->count) { + esp_wifi_sta_reset_muedca_timer(muedca_args.reset_timer->ival[0]); + } + + uint8_t aci_bitmap = 0; + if (muedca_args.read_timer->count) { + aci_bitmap = muedca_args.read_timer->ival[0]; + if (aci_bitmap & BIT(0)) { + dbg_read_muedca_timer(3); + } + if (aci_bitmap & BIT(1)) { + dbg_read_muedca_timer(2); + } + if (aci_bitmap & BIT(2)) { + dbg_read_muedca_timer(1); + } + if (aci_bitmap & BIT(3)) { + dbg_read_muedca_timer(0); + } + } + return 0; +} + +static int wifi_cmd_set_tx_pwr(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **)&tx_pwr_args); + if (nerrors != 0) { + arg_print_errors(stderr, tx_pwr_args.end, argv[0]); + return 1; + } + if (tx_pwr_args.mcs->count && tx_pwr_args.power->count) { + if (tx_pwr_args.mcs->ival[0] <= 9 && tx_pwr_args.mcs->ival[0] >= 0) { + if (tx_pwr_args.power->ival[0] >= -13 && + tx_pwr_args.power->ival[0] <= 20) { + esp_test_set_tx_mcs_pwr(tx_pwr_args.mcs->ival[0] + WIFI_PHY_RATE_MCS0_LGI, tx_pwr_args.power->ival[0]); + ESP_LOGW(TAG, "set MCS%d TX PWR to %d", tx_pwr_args.mcs->ival[0], tx_pwr_args.power->ival[0]); + } else if (tx_pwr_args.power->ival[0] == 0xff) { + esp_test_set_tx_mcs_pwr(tx_pwr_args.mcs->ival[0] + WIFI_PHY_RATE_MCS0_LGI, tx_pwr_args.power->ival[0]); + ESP_LOGW(TAG, "set MCS%d TX PWR to default value", tx_pwr_args.mcs->ival[0], tx_pwr_args.power->ival[0]); + } + } else { + ESP_LOGW(TAG, "Set TX power fail, MCS should in range [0,9], power should in range [-13, 30] or set 0xFF for default"); + } + } + return 0; +} + +static int wifi_read_avgsnr(int argc, char **argv) +{ + wifi_mode_t mode; + esp_wifi_get_mode(&mode); + if (WIFI_MODE_AP == mode) { + // TODO + ESP_LOGI(TAG, "WIFI_MODE_AP, not support"); + } else if (WIFI_MODE_STA == mode || WIFI_MODE_APSTA == mode) { + printf("%.2f\n", esp_test_get_bfr_avgsnr()); + } else { + ESP_LOGI(TAG, "NULL mode"); + } + return 0; +} + +void register_wifi_cmd(void) +{ + /* mac */ + const esp_console_cmd_t maccmd = { + .command = "mac", + .help = "get mac", + .hint = NULL, + .func = &wifi_cmd_get_mac, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&maccmd)); + /* disable edca */ + edca_args.enable = arg_int0("e", "enable", "[enable]", "enable edca tx"); + edca_args.txq = arg_int0("q", "txq", "[txq]", "enable edca txq"); + edca_args.end = arg_end(1); + const esp_console_cmd_t edca_cmd = { + .command = "edca", + .help = "enable/disable edca", + .hint = NULL, + .func = &wifi_cmd_edca_tx, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&edca_cmd)); + /* read/write hw registers */ + reg_rw_args.read = arg_dbl0("r", NULL, "", "read register address"); + reg_rw_args.write = arg_dbl0("w", NULL, "", "write register address"); + reg_rw_args.value = arg_dbl0("v", NULL, "", "write value"); + reg_rw_args.end = arg_end(2); + const esp_console_cmd_t reg_rw_cmd = { + .command = "reg", + .help = "r/w hw register", + .hint = NULL, + .func = &wifi_cmd_reg_rw, + .argtable = ®_rw_args, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(®_rw_cmd)); + /* om control */ + omctrl_args.ul_mu_disable = arg_dbl0("u", "ulmu", "[ulmu]", "disable ul mu"); + omctrl_args.ul_mu_data_disable = arg_dbl0("d", "uldata", "[uldata]", "disable ul mu data"); + omctrl_args.ersu_disable = arg_dbl0("e", "ersu", "[ersu]", "disable ersu"); + omctrl_args.report = arg_dbl0("r", "report", "[report]", "report om control to ap"); + omctrl_args.resounding = arg_dbl0("s", "resounding", "[resounding]", "DL MU-MIMO resound Recoummendation"); + omctrl_args.end = arg_end(1); + const esp_console_cmd_t omctrl_cmd = { + .command = "omc", + .help = "om control", + .hint = NULL, + .func = &wifi_cmd_set_omc, + .argtable = &omctrl_args, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&omctrl_cmd)); + /* stbc */ + stbc_args.disable = arg_dbl0("d", "disable", "[disable]", "disable stbc"); + stbc_args.end = arg_end(1); + const esp_console_cmd_t stbc_cmd = { + .command = "stbc", + .help = "configure stbc", + .hint = NULL, + .func = &wifi_cmd_stbc, + .argtable = &stbc_args + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&stbc_cmd)); + /* su bmfmee */ + bmfmee_args.disable = arg_dbl0("d", "disable", "[disable]", "disable bmfmee"); + bmfmee_args.end = arg_end(1); + const esp_console_cmd_t bmfmee_cmd = { + .command = "bmfmee", + .help = "configure su bmfmee", + .hint = NULL, + .func = &wifi_cmd_su_bmfmee, + .argtable = &bmfmee_args + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&bmfmee_cmd)); + /* set trigger frame mac padding duration */ + tf_padding_args.tf_padding = arg_dbl0("p", "padding", "[padding]", "set trigger frame mac padding duration"); + tf_padding_args.end = arg_end(1); + const esp_console_cmd_t tf_padding_cmd = { + .command = "tf", + .help = "set padding", + .hint = NULL, + .func = &wifi_cmd_set_tf_padding, + .argtable = &tf_padding_args, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&tf_padding_cmd)); + /* ignore cca */ + cca_args.enable = arg_dbl0("e", "enable", "[enable]", "enable ignore cca"); + cca_args.end = arg_end(1); + const esp_console_cmd_t cca_cmd = { + .command = "cca", + .help = "ignore cca", + .hint = NULL, + .func = &wifi_cmd_ignore_cca, + .argtable = &cca_args, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&cca_cmd)); + /* dump tx tb ppdu */ + const esp_console_cmd_t tb_cmd = { + .command = "tb", + .help = "dump tx tb ppdu", + .hint = NULL, + .func = &wifi_cmd_tb, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&tb_cmd)); + /* set ps type */ + const esp_console_cmd_t ps_cmd = { + .command = "ps", + .help = "set ps type", + .hint = NULL, + .func = &wifi_cmd_set_ps_type, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&ps_cmd)); + /* ping test */ + ping_args.timeout = arg_dbl0("W", "timeout", "", "Time to wait for a response, in seconds"); + ping_args.interval = arg_dbl0("i", "interval", "", "Wait interval seconds between sending each packet"); + ping_args.data_size = arg_int0("s", "size", "", "Specify the number of data bytes to be sent"); + ping_args.count = arg_int0("c", "count", "", "Stop after sending count packets"); + ping_args.tos = arg_int0("Q", "tos", "", "Set Type of Service related bits in IP datagrams"); + ping_args.host = arg_str0(NULL, NULL, "[host]", "Host address"); + ping_args.abort = arg_lit0("a", "abort", "abort"); + ping_args.end = arg_end(1); + const esp_console_cmd_t ping_cmd = { + .command = "ping", + .help = "send ICMP ECHO_REQUEST to network hosts", + .hint = NULL, + .func = &do_ping_cmd, + .argtable = &ping_args + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&ping_cmd)); + /* get ps state */ + const esp_console_cmd_t pss_cmd = { + .command = "pss", + .help = "get ps state", + .hint = NULL, + .func = &wifi_cmd_get_ps_state, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&pss_cmd)); + /* ip */ + static_ip_args.ip = arg_str0("i", "ip", "", "ip address"); + static_ip_args.gw = arg_str0("g", "gateway", "", "gateway address"); + static_ip_args.netmask = arg_str0("n", "netmask", "", "netmask addess"); + static_ip_args.end = arg_end(1); + const esp_console_cmd_t static_ip_cmd = { + .command = "ip", + .help = "ip settings", + .hint = NULL, + .func = &wifi_cmd_set_ip, + .argtable = &static_ip_args, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&static_ip_cmd)); + /* query */ + const esp_console_cmd_t query_cmd = { + .command = "query", + .help = "query WiFi info", + .hint = NULL, + .func = &wifi_cmd_query, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&query_cmd)); + /* proto */ + proto_args.proto = arg_str0(NULL, NULL, "", "proto [ax,bgn,bg,b]"); + proto_args.end = arg_end(1); + const esp_console_cmd_t proto_cmd = { + .command = "proto", + .help = "set wifi protocol", + .hint = NULL, + .func = &wifi_cmd_proto, + .argtable = &proto_args + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&proto_cmd)); + /* disconnect */ + const esp_console_cmd_t disconnect_cmd = { + .command = "disconnect", + .help = "disconnect", + .hint = NULL, + .func = &wifi_disconnect, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&disconnect_cmd)); + /* inactive time */ + inactive_time_args.val = arg_int0("t", "time", "time", "set inactive time, in seconds"); + inactive_time_args.end = arg_end(1); + const esp_console_cmd_t inactive_cmd = { + .command = "inactive", + .help = "inactive time, unit: seconds", + .hint = NULL, + .func = &wifi_cmd_inactive_time, + .argtable = &inactive_time_args, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&inactive_cmd)); + /* set beamforming report rate */ + wifi_sounding_rate_args.format = arg_int0("f", "format", "format", "set format"); + wifi_sounding_rate_args.rate = arg_int0("r", "rate", "rate", "set rate"); + wifi_sounding_rate_args.end = arg_end(1); + const esp_console_cmd_t sounding_rate_cmd = { + .command = "sounding", + .help = "set beamforming report rate", + .hint = NULL, + .func = &wifi_cmd_sounding_rate, + .argtable = &wifi_sounding_rate_args, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&sounding_rate_cmd)); + /* muedca */ + muedca_args.reset_timer = arg_int0("r", NULL, "reset timer", "reset muedca timer"); + muedca_args.read_timer = arg_int0("d", NULL, "read timer", "read muedca timer"); + muedca_args.end = arg_end(1); + const esp_console_cmd_t reg_muedca_cmd = { + .command = "muedca", + .help = "Reset/Read muedca timer", + .hint = NULL, + .func = &wifi_cmd_muedca, + .argtable = &muedca_args, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(®_muedca_cmd)); + /* tx_pwr */ + tx_pwr_args.mcs = arg_int0("m", NULL, "[0, 9]", "force tx power on MCSX"); + tx_pwr_args.power = arg_int0("p", NULL, "[-13, 20]", "set max power, set 0xFF for default"); + tx_pwr_args.end = arg_end(1); + const esp_console_cmd_t reg_tx_pwr_cmd = { + .command = "txpwr", + .help = "force tx power on MCSX", + .hint = NULL, + .func = &wifi_cmd_set_tx_pwr, + .argtable = &tx_pwr_args, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(®_tx_pwr_cmd)); + /* avgSNR */ + const esp_console_cmd_t avgsnr_cmd = { + .command = "avgsnr", + .help = "show avgSnr in beamforming memory", + .hint = NULL, + .func = &wifi_read_avgsnr, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&avgsnr_cmd)); +} +#else + +void register_wifi_cmd(void) +{ + ; +} + +#endif /* CONFIG_SOC_WIFI_HE_SUPPORT */ + diff --git a/examples/common_components/iperf/wifi_stats.c b/examples/common_components/iperf/wifi_stats.c new file mode 100644 index 0000000000..380e49940e --- /dev/null +++ b/examples/common_components/iperf/wifi_stats.c @@ -0,0 +1,585 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "esp_log.h" + +#if CONFIG_ENABLE_WIFI_TX_STATS || CONFIG_ENABLE_WIFI_RX_STATS + +#include "esp_console.h" +#include "argtable3/argtable3.h" +#include "esp_event.h" +#include "esp_wifi.h" +#include "esp_wifi_types.h" +#include "wifi_stats.h" +#include "esp_private/esp_wifi_he_private.h" + +/******************************************************* + * Macros + *******************************************************/ +/* + * enable/disable rx/tx statistics after Wi-Fi started: + * (1) esp_wifi_enable_rx_statistics(true, true); //rx_stats=true, rx_mu_stats=true + * (2) esp_wifi_enable_tx_statistics(ESP_WIFI_ACI_BE, true); //aci=ESP_WIFI_ACI_BE, tx_stats=true + */ + +/******************************************************* + * Constants + *******************************************************/ +static const char *TAG = "stats"; + +/******************************************************* + * Structures + *******************************************************/ + +/******************************************************* + * Variable Definitions + *******************************************************/ +#if CONFIG_ENABLE_WIFI_RX_MU_STATS +esp_test_rx_mu_statistics_t rx_mu_stats = { 0, }; //10932 bytes +#endif + +/******************************************************* + * Function Declarations + *******************************************************/ + +/******************************************************* + * Function Definitions + *******************************************************/ +const char *tx_fail_error2str(esp_test_tx_fail_error_t error) +{ + switch (error) { + case TEST_TX_FAIL_ERROR_H00: + return "0x00"; + case TEST_TX_FAIL_ERROR_H53: + return "0x53"; + case TEST_TX_FAIL_ERROR_H63: + return "0x63"; + case TEST_TX_FAIL_ERROR_H75: + return "0x75"; + case TEST_TX_FAIL_ERROR_H41: + return "0x41"; + case TEST_TX_FAIL_ERROR_H42: + return "0x42"; + case TEST_TX_FAIL_ERROR_H47: + return "0x47"; + case TEST_TX_FAIL_ERROR_H80: + return "0x80"; + case TEST_TX_FAIL_ERROR_H5A: + return "0x5A"; + case TEST_TX_FAIL_ERROR_HXX: + return "Others"; + case TEST_TX_FAIL_ERROR_MAX: + return "Undefined"; + } + return "Undefined"; +} + +const char *tx_fail_match2str(esp_test_tx_fail_match_t match) +{ + switch (match) { + case TEST_TX_WAIT_MATCH: + return "MATCH"; + case TEST_TX_WAIT_NOT2SELF: + return "NOT2SELF"; + case TEST_TX_MISMATCH: + return "MISMATCH"; + case TEST_TX_WAIT_TIMEOUT: + return "TIMEOUT"; + case TEST_TX_WAIT_MAX: + return "Undefined"; + } + return "Undefined"; +} + +const char *tx_fail_state2str(esp_test_tx_fail_state_t state) +{ + switch (state) { + case TEST_TX_SUCCESS: + return "TX Success"; + case TEST_TX_FAIL_RTS: + return "TX RTS"; + case TEST_TX_WAIT_CTS: //RX + return "Wait CTS"; + case TEST_TX_FAIL_CTS: + return "TX RTS"; + case TEST_TX_FAIL_DATA: + return "TX DATA"; + case TEST_TX_WAIT_ACK: //RX + return "Wait ACK/BA"; + case TEST_TX_FAIL_MAX: + return "Undefined"; + } + return "Undefined"; +} + +int wifi_cmd_clr_tx_statistics(int argc, char **argv) +{ + ESP_LOGW(TAG, "Clear tx statistics"); + int i; + for (i = 0; i < 3; i++) { + esp_wifi_clr_tx_statistics(i); //BE + esp_wifi_clr_tx_tb_statistics(i); + } + esp_test_clr_hw_statistics(); + return 0; +} + +void print_hw_tb_statistics(void) +{ + esp_test_hw_tb_statistics_t hw_tb_stats = { 0, }; + esp_test_get_hw_tb_statistics(&hw_tb_stats); + printf("(test)rx_trig:%d, tx_bfrpt:%d, tb_times:%d, tb_qos_null:%d, tb_qos_data:%d, tb_cca_cancel:%d, tb_sifs_abort:%d, tb_pwr_outof_range:%d\n", + hw_tb_stats.rx_trig, + hw_tb_stats.tx_bfrpt, //including TB and Non-TB + hw_tb_stats.tb_times, + hw_tb_stats.tb_qos_null, + hw_tb_stats.tb_times - hw_tb_stats.tb_qos_null, + hw_tb_stats.tb_cca_cancel, + hw_tb_stats.tb_sifs_abort, + hw_tb_stats.tb_pwr_outof_range); +} + +int wifi_cmd_get_tx_statistics(int argc, char **argv) +{ + uint8_t i, h, j, k; + + ESP_LOGW(TAG, "Get tx statistics\n"); + esp_test_tx_tb_statistics_t tb_stats = { 0, }; //32 bytes + esp_test_tx_statistics_t tx_stats = { 0, }; //136 bytes + esp_test_tx_fail_statistics_t tx_fail[TEST_TX_FAIL_MAX] = { 0, }; //TEST_TX_FAIL_MAX * 164 bytes + + print_hw_tb_statistics(); + //only check BE + for (i = 2; i < 3; i++) { + esp_wifi_get_tx_tb_statistics(i, &tb_stats); + /* TB */ + printf("(test)aci:%d, tb(suc:%d, ack:%d, err:%d), " + "count(suc:%d, ack:%d, err:%d, tot:%d, max_sent:%d)\n", + i, + tb_stats.complete_suc_tb, + tb_stats.complete_ack_tb, + tb_stats.complete_err_tb, + tb_stats.complete_tb_suc_count, + tb_stats.complete_tb_ack_count, + tb_stats.complete_tb_err_count, + tb_stats.complete_tb_tot_count, + tb_stats.complete_tb_pack_sent); + + esp_wifi_get_tx_statistics(i, &tx_stats, (esp_test_tx_fail_statistics_t *) &tx_fail); + int tot_tx_times = tx_stats.tb_times + (tx_stats.tx_enable - tx_stats.tb_last); //TB + EDCA + int tot_fail = tx_fail[1].count + tx_fail[2].count + tx_fail[3].count + tx_fail[4].count + tx_fail[5].count; + printf("(test)aci:%d, enable:%d, complete:%d, tb_times:%d, tb_last:%d, edca:%d, " + "succ:%d, fail(%d,%d,%d, cts:%d/%2.2f%%, ack:%d/%2.2f%%, tot:%d, %.2f%%), " + "edca(ack:%d, ba:%d), tb(hw-ba:%d, sw-ba:%d)\n", + i, tx_stats.tx_enable, + tx_stats.tx_complete, + tx_stats.tb_times, + tx_stats.tb_last, + tx_stats.tx_enable - tx_stats.tb_last, + tx_fail[0].count, + tx_fail[1].count, + tx_fail[3].count, + tx_fail[4].count, + tx_fail[2].count, + (float) ((float) tx_fail[2].count / (float) tot_tx_times) * 100, //rx cts + tx_fail[5].count, (float) ((float) tx_fail[5].count / (float) tot_tx_times) * 100, //rx ack + tot_fail, + (float) ((float) tot_fail / (float) tot_tx_times) * 100, + tx_stats.rx_ack, + tx_stats.rx_ba, + tx_stats.tb_rx_ba, //including ACKs + tx_stats.rx_dump_ba); + + printf("(test)aci:%d, txFrames:%d, s-mpdu:%d(%.2f%%), " + "bitmap(max:%d, min:%d, tot:%d, avg:%.2f), " + "retry(edca:%d, tb:%d, %.2f%%), collision:%d, timeout:%d\n", + i, + tx_stats.tx_succ, + tx_stats.rx_ack, + ((float) (tx_stats.rx_ack) / (float) tot_tx_times) * 100, + tx_stats.rx_max_bitmap, + tx_stats.rx_min_bitmap, + tx_stats.rx_tot_bitmap, + (float) tx_stats.rx_tot_bitmap / (float) (tx_stats.tb_rx_ba + tx_stats.rx_ba), + tx_stats.retry_edca, tx_stats.retry_tb, (float) (tx_stats.retry_edca + tx_stats.retry_tb) / (float) tx_stats.tx_succ * 100, + tx_stats.collision, tx_stats.timeout); + + float tot_rtt_ms = (float) tx_stats.tx_tot_rtt / (float) 1000; + printf("(test)aci:%d, seqno_rtt[%d,%d], hw_rtt[%d, %d], muedca[enable:%d, times:%d, %.2f, %.2f, tot:%.2f], avg:%.3f ms, tot:%.3f secs\n", + i, + tx_stats.tx_seq_min_rtt, + tx_stats.tx_seq_max_rtt, + tx_stats.tx_min_rtt, + tx_stats.tx_max_rtt, + tx_stats.tx_muedca_enable, + tx_stats.muedca_times, + (float) tx_stats.tx_min_muedca_time / (float) 1000, + (float) tx_stats.tx_max_muedca_time / (float) 1000, + (float) tx_stats.tx_tot_muedca_time / (float) 1000, //ms + (float) tot_rtt_ms / (float) tot_tx_times, //ms + (float) tot_rtt_ms / (float) 1000); //seconds + /* fail state */ + for (h = 1; h < TEST_TX_FAIL_MAX; h++) { //state + for (j = 0; j < TEST_TX_WAIT_MAX; j++) { //match + for (k = 0; k < TEST_TX_FAIL_ERROR_MAX; k++) { //error + if (tx_fail[h].match[j][k]) { + printf("(test)[%d][%d][%d](%16s + %16s + %16s)%3d/%3d(%.2f%%)\n", h, j, k, tx_fail_state2str(h), + tx_fail_match2str(j), tx_fail_error2str(k), + tx_fail[h].match[j][k], tx_fail[h].count, + ((float) tx_fail[h].match[j][k] / (float) tx_fail[h].count) * 100); + } + } + } + } + printf("\n"); + } + wifi_cmd_clr_tx_statistics(0, 0); + return 0; +} + +void print_rx_statistics_nonmimo(const esp_test_rx_mu_statistics_t *mu_stats) +{ + if (!mu_stats->nonmimo_rx) { + return; + } + + int i, j; + int tot_rx_nonmimo = 0; + ESP_LOGW(TAG, "(nonmimo)dut rx:%d", mu_stats->nonmimo_rx); + ESP_LOGW(TAG, "(nonmimo)ru_alloc_96_num_2046:%d, ru_alloc_112_num_2046:%d", mu_stats->ru_alloc_96_num_2046, mu_stats->ru_alloc_112_num_2046); + ESP_LOGW(TAG, "(nonmimo)sigb, mcs0:%d(%2.2f%%), mcs1:%d(%2.2f%%), mcs2:%d(%2.2f%%), mcs3:%d(%2.2f%%), mcs4:%d(%2.2f%%), mcs5:%d(%2.2f%%)", + mu_stats->nonmimo_sigb_mcs[0], ((float) mu_stats->nonmimo_sigb_mcs[0] / (float) mu_stats->nonmimo_rx) * 100, + mu_stats->nonmimo_sigb_mcs[1], ((float) mu_stats->nonmimo_sigb_mcs[1] / (float) mu_stats->nonmimo_rx) * 100, + mu_stats->nonmimo_sigb_mcs[2], ((float) mu_stats->nonmimo_sigb_mcs[2] / (float) mu_stats->nonmimo_rx) * 100, + mu_stats->nonmimo_sigb_mcs[3], ((float) mu_stats->nonmimo_sigb_mcs[3] / (float) mu_stats->nonmimo_rx) * 100, + mu_stats->nonmimo_sigb_mcs[4], ((float) mu_stats->nonmimo_sigb_mcs[4] / (float) mu_stats->nonmimo_rx) * 100, + mu_stats->nonmimo_sigb_mcs[5], ((float) mu_stats->nonmimo_sigb_mcs[5] / (float) mu_stats->nonmimo_rx) * 100); + ESP_LOGW(TAG, "(nonmimo)users, num1:%d(%2.2f%%), num2:%d(%2.2f%%), num3:%d(%2.2f%%), num4:%d(%2.2f%%), num5:%d(%2.2f%%), num6:%d(%2.2f%%), num7:%d(%2.2f%%), num8:%d(%2.2f%%), num9:%d(%2.2f%%)", + mu_stats->nonmimo_user_num_occu[0], ((float) mu_stats->nonmimo_user_num_occu[0] / (float) mu_stats->nonmimo_rx) * 100, + mu_stats->nonmimo_user_num_occu[1], ((float) mu_stats->nonmimo_user_num_occu[1] / (float) mu_stats->nonmimo_rx) * 100, + mu_stats->nonmimo_user_num_occu[2], ((float) mu_stats->nonmimo_user_num_occu[2] / (float) mu_stats->nonmimo_rx) * 100, + mu_stats->nonmimo_user_num_occu[3], ((float) mu_stats->nonmimo_user_num_occu[3] / (float) mu_stats->nonmimo_rx) * 100, + mu_stats->nonmimo_user_num_occu[4], ((float) mu_stats->nonmimo_user_num_occu[4] / (float) mu_stats->nonmimo_rx) * 100, + mu_stats->nonmimo_user_num_occu[5], ((float) mu_stats->nonmimo_user_num_occu[5] / (float) mu_stats->nonmimo_rx) * 100, + mu_stats->nonmimo_user_num_occu[6], ((float) mu_stats->nonmimo_user_num_occu[6] / (float) mu_stats->nonmimo_rx) * 100, + mu_stats->nonmimo_user_num_occu[7], ((float) mu_stats->nonmimo_user_num_occu[7] / (float) mu_stats->nonmimo_rx) * 100, + mu_stats->nonmimo_user_num_occu[8], ((float) mu_stats->nonmimo_user_num_occu[8] / (float) mu_stats->nonmimo_rx) * 100); + for (i = 0; i < 256; i++) { + for (j = 0; j < 9; j++) { + if (!mu_stats->nonmimo_ru_alloc[i][j]) { + continue; + } + ESP_LOGI(TAG, "(nonmimo)ru_allocation:0x%2x(%3d), position:%d, %5d(%2.2f%%)", i, i, j + 1, mu_stats->nonmimo_ru_alloc[i][j], + ((float) mu_stats->nonmimo_ru_alloc[i][j] / (float) mu_stats->nonmimo_rx) * 100); + } + } + for (i = 0; i < ESP_TEST_RX_MU_USER_NUM; i++) { + if (!mu_stats->nonmimo[i].aid) { + continue; + } + if (mu_stats->aid != mu_stats->nonmimo[i].aid) { + continue; + } + tot_rx_nonmimo = mu_stats->nonmimo[i].occu_nsts[0] + mu_stats->nonmimo[i].occu_nsts[1] + mu_stats->nonmimo[i].occu_nsts[2] + mu_stats->nonmimo[i].occu_nsts[3]; + printf("[%d]%said:0x%x, txbf:%d, dcm:%d\n", i, (mu_stats->aid == mu_stats->nonmimo[i].aid) ? "#" : " ", mu_stats->nonmimo[i].aid, + mu_stats->nonmimo[i].txbf, mu_stats->nonmimo[i].dcm); + printf("[%d]%said:0x%x, " + "mcs0:%d(%2.2f%%), mcs1:%d(%2.2f%%), mcs2:%d(%2.2f%%), mcs3:%d(%2.2f%%), mcs4:%d(%2.2f%%), " + "mcs5:%d(%2.2f%%), mcs6:%d(%2.2f%%), mcs7:%d(%2.2f%%), mcs8:%d(%2.2f%%), mcs9:%d(%2.2f%%), " + "mcs10:%d(%2.2f%%), mcs11:%d(%2.2f%%)\n", + i, (mu_stats->aid == mu_stats->nonmimo[i].aid) ? "#" : " ", mu_stats->nonmimo[i].aid, + mu_stats->nonmimo[i].occu_mcs[0], ((float) mu_stats->nonmimo[i].occu_mcs[0] / (float) tot_rx_nonmimo) * 100, + mu_stats->nonmimo[i].occu_mcs[1], ((float) mu_stats->nonmimo[i].occu_mcs[1] / (float) tot_rx_nonmimo) * 100, + mu_stats->nonmimo[i].occu_mcs[2], ((float) mu_stats->nonmimo[i].occu_mcs[2] / (float) tot_rx_nonmimo) * 100, + mu_stats->nonmimo[i].occu_mcs[3], ((float) mu_stats->nonmimo[i].occu_mcs[3] / (float) tot_rx_nonmimo) * 100, + mu_stats->nonmimo[i].occu_mcs[4], ((float) mu_stats->nonmimo[i].occu_mcs[4] / (float) tot_rx_nonmimo) * 100, + mu_stats->nonmimo[i].occu_mcs[5], ((float) mu_stats->nonmimo[i].occu_mcs[5] / (float) tot_rx_nonmimo) * 100, + mu_stats->nonmimo[i].occu_mcs[6], ((float) mu_stats->nonmimo[i].occu_mcs[6] / (float) tot_rx_nonmimo) * 100, + mu_stats->nonmimo[i].occu_mcs[7], ((float) mu_stats->nonmimo[i].occu_mcs[7] / (float) tot_rx_nonmimo) * 100, + mu_stats->nonmimo[i].occu_mcs[8], ((float) mu_stats->nonmimo[i].occu_mcs[8] / (float) tot_rx_nonmimo) * 100, + mu_stats->nonmimo[i].occu_mcs[9], ((float) mu_stats->nonmimo[i].occu_mcs[9] / (float) tot_rx_nonmimo) * 100, + mu_stats->nonmimo[i].occu_mcs[10], ((float) mu_stats->nonmimo[i].occu_mcs[10] / (float) tot_rx_nonmimo) * 100, + mu_stats->nonmimo[i].occu_mcs[11], ((float) mu_stats->nonmimo[i].occu_mcs[11] / (float) tot_rx_nonmimo) * 100); + printf("[%d]%said:0x%x, " + "nsts0:%d(%2.2f%%), nsts1:%d(%2.2f%%), nsts2:%d(%2.2f%%), nsts3:%d(%2.2f%%)\n", + i, (mu_stats->aid == mu_stats->nonmimo[i].aid) ? "#" : " ", mu_stats->nonmimo[i].aid, + mu_stats->nonmimo[i].occu_nsts[0], ((float) mu_stats->nonmimo[i].occu_nsts[0] / (float) tot_rx_nonmimo) * 100, + mu_stats->nonmimo[i].occu_nsts[1], ((float) mu_stats->nonmimo[i].occu_nsts[1] / (float) tot_rx_nonmimo) * 100, + mu_stats->nonmimo[i].occu_nsts[2], ((float) mu_stats->nonmimo[i].occu_nsts[2] / (float) tot_rx_nonmimo) * 100, + mu_stats->nonmimo[i].occu_nsts[3], ((float) mu_stats->nonmimo[i].occu_nsts[3] / (float) tot_rx_nonmimo) * 100); + printf("[%d]%said:0x%x, " + "tot_rx_nonmimo:%8d, sta/dut:%2.2f%%\n", + i, (mu_stats->aid == mu_stats->nonmimo[i].aid) ? "#" : " ", mu_stats->nonmimo[i].aid, + tot_rx_nonmimo, ((float) tot_rx_nonmimo / (float) mu_stats->nonmimo_rx) * 100); + } +} + +void print_rx_statistics_mimo(const esp_test_rx_mu_statistics_t *mu_stats) +{ + if (!mu_stats->mimo_rx) { + return; + } + + int i; + int tot_rx_mimo = 0; + ESP_LOGW(TAG, "(mimo)dut rx:%d", mu_stats->mimo_rx); + ESP_LOGW(TAG, "(mimo)sigb, mcs0:%d(%2.2f%%), mcs1:%d(%2.2f%%), mcs2:%d(%2.2f%%), mcs3:%d(%2.2f%%), mcs4:%d(%2.2f%%), mcs5:%d(%2.2f%%)", + mu_stats->mimo_sigb_mcs[0], ((float) mu_stats->mimo_sigb_mcs[0] / (float) mu_stats->mimo_rx) * 100, + mu_stats->mimo_sigb_mcs[1], ((float) mu_stats->mimo_sigb_mcs[1] / (float) mu_stats->mimo_rx) * 100, + mu_stats->mimo_sigb_mcs[2], ((float) mu_stats->mimo_sigb_mcs[2] / (float) mu_stats->mimo_rx) * 100, + mu_stats->mimo_sigb_mcs[3], ((float) mu_stats->mimo_sigb_mcs[3] / (float) mu_stats->mimo_rx) * 100, + mu_stats->mimo_sigb_mcs[4], ((float) mu_stats->mimo_sigb_mcs[4] / (float) mu_stats->mimo_rx) * 100, + mu_stats->mimo_sigb_mcs[5], ((float) mu_stats->mimo_sigb_mcs[5] / (float) mu_stats->mimo_rx) * 100); + ESP_LOGW(TAG, "(mimo)users num2:%d(%2.2f%%), num3:%d(%2.2f%%), num4:%d(%2.2f%%), num5:%d(%2.2f%%), num6:%d(%2.2f%%), num7:%d(%2.2f%%), num8:%d(%2.2f%%)", + mu_stats->mimo_user_num_occu[0], ((float) mu_stats->mimo_user_num_occu[0] / (float) mu_stats->mimo_rx) * 100, + mu_stats->mimo_user_num_occu[1], ((float) mu_stats->mimo_user_num_occu[1] / (float) mu_stats->mimo_rx) * 100, + mu_stats->mimo_user_num_occu[2], ((float) mu_stats->mimo_user_num_occu[2] / (float) mu_stats->mimo_rx) * 100, + mu_stats->mimo_user_num_occu[3], ((float) mu_stats->mimo_user_num_occu[3] / (float) mu_stats->mimo_rx) * 100, + mu_stats->mimo_user_num_occu[4], ((float) mu_stats->mimo_user_num_occu[4] / (float) mu_stats->mimo_rx) * 100, + mu_stats->mimo_user_num_occu[5], ((float) mu_stats->mimo_user_num_occu[5] / (float) mu_stats->mimo_rx) * 100, + mu_stats->mimo_user_num_occu[6], ((float) mu_stats->mimo_user_num_occu[6] / (float) mu_stats->mimo_rx) * 100); + for (i = 0; i < ESP_TEST_RX_MU_USER_NUM; i++) { + if (!mu_stats->mimo[i].aid) { + continue; + } + tot_rx_mimo = mu_stats->mimo[i].occu_ss[0] + mu_stats->mimo[i].occu_ss[1] + mu_stats->mimo[i].occu_ss[2] + mu_stats->mimo[i].occu_ss[3]; + printf("[%d]%said:0x%x, " + "mcs0:%d(%2.2f%%), mcs1:%d(%2.2f%%), mcs2:%d(%2.2f%%), mcs3:%d(%2.2f%%), mcs4:%d(%2.2f%%), " + "mcs5:%d(%2.2f%%), mcs6:%d(%2.2f%%), mcs7:%d(%2.2f%%), mcs8:%d(%2.2f%%), mcs9:%d(%2.2f%%), " + "mcs10:%d(%2.2f%%), mcs11:%d(%2.2f%%)\n", + i, (mu_stats->aid == mu_stats->mimo[i].aid) ? "#" : " ", mu_stats->mimo[i].aid, + mu_stats->mimo[i].occu_mcs[0], ((float) mu_stats->mimo[i].occu_mcs[0] / (float) tot_rx_mimo) * 100, + mu_stats->mimo[i].occu_mcs[1], ((float) mu_stats->mimo[i].occu_mcs[1] / (float) tot_rx_mimo) * 100, + mu_stats->mimo[i].occu_mcs[2], ((float) mu_stats->mimo[i].occu_mcs[2] / (float) tot_rx_mimo) * 100, + mu_stats->mimo[i].occu_mcs[3], ((float) mu_stats->mimo[i].occu_mcs[3] / (float) tot_rx_mimo) * 100, + mu_stats->mimo[i].occu_mcs[4], ((float) mu_stats->mimo[i].occu_mcs[4] / (float) tot_rx_mimo) * 100, + mu_stats->mimo[i].occu_mcs[5], ((float) mu_stats->mimo[i].occu_mcs[5] / (float) tot_rx_mimo) * 100, + mu_stats->mimo[i].occu_mcs[6], ((float) mu_stats->mimo[i].occu_mcs[6] / (float) tot_rx_mimo) * 100, + mu_stats->mimo[i].occu_mcs[7], ((float) mu_stats->mimo[i].occu_mcs[7] / (float) tot_rx_mimo) * 100, + mu_stats->mimo[i].occu_mcs[8], ((float) mu_stats->mimo[i].occu_mcs[8] / (float) tot_rx_mimo) * 100, + mu_stats->mimo[i].occu_mcs[9], ((float) mu_stats->mimo[i].occu_mcs[9] / (float) tot_rx_mimo) * 100, + mu_stats->mimo[i].occu_mcs[10], ((float) mu_stats->mimo[i].occu_mcs[10] / (float) tot_rx_mimo) * 100, + mu_stats->mimo[i].occu_mcs[11], ((float) mu_stats->mimo[i].occu_mcs[11] / (float) tot_rx_mimo) * 100); + printf("[%d]%said:0x%x, " + "ss0:%d(%2.2f%%), ss1:%d(%2.2f%%), ss2:%d(%2.2f%%), ss3:%d(%2.2f%%)\n", + i, (mu_stats->aid == mu_stats->mimo[i].aid) ? "#" : " ", mu_stats->mimo[i].aid, + mu_stats->mimo[i].occu_ss[0], ((float) mu_stats->mimo[i].occu_ss[0] / (float) tot_rx_mimo) * 100, + mu_stats->mimo[i].occu_ss[1], ((float) mu_stats->mimo[i].occu_ss[1] / (float) tot_rx_mimo) * 100, + mu_stats->mimo[i].occu_ss[2], ((float) mu_stats->mimo[i].occu_ss[2] / (float) tot_rx_mimo) * 100, + mu_stats->mimo[i].occu_ss[3], ((float) mu_stats->mimo[i].occu_ss[3] / (float) tot_rx_mimo) * 100); + printf("[%d]%said:0x%x, " + "tot_rx_mimo:%8d, sta/dut:%2.2f%%\n", + i, (mu_stats->aid == mu_stats->mimo[i].aid) ? "#" : " ", mu_stats->mimo[i].aid, + tot_rx_mimo, ((float) tot_rx_mimo / (float) mu_stats->mimo_rx) * 100); + } +} + +void print_hw_rx_statistics(void) +{ + esp_test_hw_rx_statistics_t hw_rx_stats = { 0, }; + esp_test_get_hw_rx_statistics(&hw_rx_stats); + printf( + "WDEVRX_FCS_ERR :%d\n" + "WDEVRX_ABORT :%d\n" + "WDEVRX_ABORT_FCS_PASS :%d\n" + "NRX_ERR_PWRDROP :%d\n" + "NRX_HESIGB_ERR :%d\n" + "WDEVRX_SAMEBM_ERRCNT :%d\n" + "WDEVRX_MPDU :%d\n" + "WDEVRX_END_CNT :%d\n" + "WDEVRX_DATASUC :%d\n" + "WDEVRX_LASTUNMATCH_ERR :%d\n" + "RXHUNG_STATIS :%d\n" + "TXHUNG_STATIS :%d\n" + "RXTXHUNG :%d\n" + "WDEVRX_CFO :%d\n" + "WDEVRX_SF :%d\n" + "WDEVRX_OTHER_UCAST :%d\n" + "WDEVRX_BUF_FULLCNT :%d\n" + "WDEVRX_FIFO_OVFCNT :%d\n" + "WDEVRX_TKIP_ERRCNT :%d\n" + "WDEVRX_BTBLOCK_ERR :%d\n" + "WDEVRX_FREQHOP_ERR :%d\n" + "WDEVRX_ACK_INT_CNT :%d\n" + "WDEVRX_RTS_INT_CNT :%d\n" + "BRX_ERR_AGC :%d\n" + "BRX_ERR :%d\n" + "NRX_ERR :%d\n" + "NRX_ERR_ABORT :%d\n" + "NRX_ERR_AGCEXIT :%d\n" + "NRX_ERR_BBOFF :%d\n" + "NRX_ERR_FDM_WDG :%d\n" + "NRX_ERR_RESTART :%d\n" + "NRX_ERR_SERV :%d\n" + "NRX_ERR_TXOVER :%d\n" + "NRX_HE_UNSUPPORT :%d\n" + "NRX_HTSIG_ERR :%d\n" + "NRX_HEUNSUPPORT :%d\n" + "NRX_HESIGA_CRC :%d\n", + hw_rx_stats.rx_fcs_err, + hw_rx_stats.rx_abort, + hw_rx_stats.rx_abort_fcs_pass, + hw_rx_stats.nrx_err_pwrdrop, + hw_rx_stats.nrx_hesigb_err, + hw_rx_stats.rx_samebm_errcnt, + hw_rx_stats.rx_mpdu, + hw_rx_stats.rx_end_cnt, + hw_rx_stats.rx_datasuc, + hw_rx_stats.rx_lastunmatch_err, + hw_rx_stats.rxhung_statis, + hw_rx_stats.txhung_statis, + hw_rx_stats.rxtxhung, + hw_rx_stats.rx_cfo_hz, + hw_rx_stats.rx_sf, + hw_rx_stats.rx_other_ucast, + hw_rx_stats.rx_buf_fullcnt, + hw_rx_stats.rx_fifo_ovfcnt, + hw_rx_stats.rx_tkip_errcnt, + hw_rx_stats.rx_btblock_err, + hw_rx_stats.rx_freqhop_err, + hw_rx_stats.rx_ack_int_cnt, + hw_rx_stats.rx_rts_int_cnt, + hw_rx_stats.brx_err_agc, + hw_rx_stats.brx_err, + hw_rx_stats.nrx_err, + hw_rx_stats.nrx_err_abort, + hw_rx_stats.nrx_err_agcexit, + hw_rx_stats.nrx_err_bboff, + hw_rx_stats.nrx_err_fdm_wdg, + hw_rx_stats.nrx_err_restart, + hw_rx_stats.nrx_err_serv, + hw_rx_stats.nrx_err_txover, + hw_rx_stats.nrx_err_unsupport, + hw_rx_stats.nrx_htsig_err, + hw_rx_stats.nrx_heunsupport, + hw_rx_stats.nrx_hesiga_crc + ); +} + +int wifi_cmd_clr_rx_statistics(int argc, char **argv) +{ + ESP_LOGW(TAG, "Clear rx statistics"); + esp_wifi_clr_rx_statistics(0); + esp_wifi_clr_rx_statistics(7); +#if CONFIG_ENABLE_WIFI_RX_MU_STATS + esp_test_clr_rx_error_occurs(); + esp_wifi_clr_rx_mu_statistics(); +#endif + esp_test_clr_hw_statistics(); + return 0; +} + +void print_rx_mu_statistics(void) +{ + /* mu */ + esp_wifi_get_rx_mu_statistics(&rx_mu_stats); + /* MIMO */ + print_rx_statistics_mimo(&rx_mu_stats); + /* non-MIMO */ + print_rx_statistics_nonmimo(&rx_mu_stats); +} + +int wifi_cmd_get_rx_statistics(int argc, char **argv) +{ + ESP_LOGW(TAG, "Get rx statistics"); + esp_test_rx_statistics_t rx_stats = { 0, }; + esp_test_rx_error_occurs_t rx_error_occurs = { 0, }; + + esp_wifi_get_rx_statistics(0, &rx_stats); //tid=0 + print_hw_tb_statistics(); + + ESP_LOGW(TAG, "(0)legacy:%d, ht(ht:%d, ht_retry:%d/%2.2f%%, ht_noeb:%d/%2.2f%%)", + rx_stats.legacy, + rx_stats.ht, rx_stats.ht_retry, + rx_stats.ht_retry ? ((float) ((float) rx_stats.ht_retry / (float) rx_stats.ht) * 100) : 0, + rx_stats.ht_noeb, rx_stats.ht_noeb ? ((float) ((float) rx_stats.ht_noeb / (float) rx_stats.ht) * 100) : 0); + ESP_LOGW(TAG, "(0)su(su:%d, su_txbf:%d, su_stbc:%d, su_retry:%d/%2.2f%%, ersu:%d, ersu_dcm:%d, su_noeb:%d/%2.2f%%)", + rx_stats.su, + rx_stats.su_txbf, rx_stats.su_stbc, + rx_stats.su_retry, + rx_stats.su_retry ? ((float) ((float) rx_stats.su_retry / (float) rx_stats.su) * 100) : 0, + rx_stats.ersu, + rx_stats.ersu_dcm, + rx_stats.su_noeb, rx_stats.su_noeb ? ((float) ((float) rx_stats.su_noeb / (float) rx_stats.su) * 100) : 0); + ESP_LOGW(TAG, "(0)mu(mu:%d, mimo:%d, non-mimo:%d, txbf:%d, stbc:%d, mu_retry:%d/%2.2f%%, mu_noeb:%d/%2.2f%%)", + rx_stats.mu, + rx_stats.mu_mimo, + rx_stats.mu_ofdma, rx_stats.mu_txbf, rx_stats.mu_stbc, + rx_stats.mu_retry, + rx_stats.mu_retry ? ((float) ((float) rx_stats.mu_retry / (float) rx_stats.mu) * 100) : 0, + rx_stats.mu_noeb, rx_stats.mu_noeb ? ((float) ((float) rx_stats.mu_noeb / (float) rx_stats.mu) * 100) : 0); + + memset(&rx_stats, 0, sizeof(rx_stats)); + esp_wifi_get_rx_statistics(7, &rx_stats); //tid=7 + ESP_LOGW(TAG, "(7)legacy:%d, ht:%d, su:%d, su_txbf:%d, ersu:%d, mu:%d", rx_stats.legacy, + rx_stats.ht, rx_stats.su, rx_stats.su_txbf, rx_stats.ersu, rx_stats.mu); + ESP_LOGW(TAG, "(hw)isr:%d, nblks:%d", rx_stats.rx_isr, rx_stats.rx_nblks); + /* hw rx statistics */ + print_hw_rx_statistics(); +#if CONFIG_ENABLE_WIFI_RX_MU_STATS + print_rx_mu_statistics(); +#endif + esp_test_get_rx_error_occurs(&rx_error_occurs); + ESP_LOGW(TAG, "(rx)tot_errors:%d", rx_error_occurs.tot); + int known_errors = 0; //rx error: 0x40-0xff + int i; + for (i = 0; i < 2; i++) { + if (rx_error_occurs.occurs[i]) { + known_errors += rx_error_occurs.occurs[i]; + printf("[%3d] 0x%x, %8d, %2.2f%%\n", i, (i ? 0xf5 : 0xc6), rx_error_occurs.occurs[i], ((float) rx_error_occurs.occurs[i] / (float) rx_error_occurs.tot) * 100); + } + } + if (rx_error_occurs.tot - known_errors) { + printf("[%3d]others, %8d, %2.2f%%\n\n", i, rx_error_occurs.tot - known_errors, ((float) known_errors / (float) rx_error_occurs.tot) * 100); + } + wifi_cmd_clr_rx_statistics(0, 0); + return 0; +} + +#endif /* CONFIG_ENABLE_WIFI_TX_STATS || CONFIG_ENABLE_WIFI_RX_STATS */ + +void register_wifi_stats(void) +{ +#if CONFIG_ENABLE_WIFI_TX_STATS + /* get tx statistics */ + const esp_console_cmd_t tx_stats_cmd = { + .command = "tx", + .help = "get tx statistics", + .hint = NULL, + .func = &wifi_cmd_get_tx_statistics, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&tx_stats_cmd)); + /* clear tx statistics */ + const esp_console_cmd_t clr_cmd = { + .command = "clrtx", + .help = "clear tx statistics", + .hint = NULL, + .func = &wifi_cmd_clr_tx_statistics, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&clr_cmd)); +#endif + +#if CONFIG_ENABLE_WIFI_RX_STATS + /* get rx statistics */ + const esp_console_cmd_t rx_stats_cmd = { + .command = "rx", + .help = "get rx statistics", + .hint = NULL, + .func = &wifi_cmd_get_rx_statistics, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&rx_stats_cmd)); + /* clear rx statistics */ + const esp_console_cmd_t clr_rx_cmd = { + .command = "clrrx", + .help = "clear rx statistics", + .hint = NULL, + .func = &wifi_cmd_clr_rx_statistics, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&clr_rx_cmd)); +#endif +} diff --git a/examples/common_components/iperf/wifi_twt.c b/examples/common_components/iperf/wifi_twt.c new file mode 100644 index 0000000000..be6f6f6bf6 --- /dev/null +++ b/examples/common_components/iperf/wifi_twt.c @@ -0,0 +1,180 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "freertos/event_groups.h" + +#if CONFIG_SOC_WIFI_HE_SUPPORT + +#include "esp_console.h" +#include "argtable3/argtable3.h" +#include "esp_netif.h" +#include "esp_event.h" +#include "esp_wifi.h" +#include "esp_wifi_he.h" + +/******************************************************* + * Constants + *******************************************************/ +static const char *TAG = "twt"; + +/******************************************************* + * Structures + *******************************************************/ +typedef struct { + struct arg_int *setup; + struct arg_int *teardown; + struct arg_int *suspend; + struct arg_int *trigger; //1-trigger-enabled, 0-non-trigger-enabled, setup + struct arg_int *flowtype; //1-unannounced, 0-announced, setup + struct arg_int *negtype; + struct arg_int *wakeinvlexp; //setup + struct arg_int *wakeinvlman; //setup + struct arg_int *minwakedur; //setup + struct arg_int *flowid; + struct arg_int *suspend_time_ms; + struct arg_int *all_twt; + struct arg_end *end; +} wifi_itwt_args_t; + +typedef struct { + struct arg_int *timeout; + struct arg_end *end; +} wifi_itwt_send_probereq_t; + +/******************************************************* + * Variable Definitions + *******************************************************/ +static wifi_itwt_args_t itwt_args; +static wifi_itwt_send_probereq_t itwt_probe_args; + +/******************************************************* + * Function Declarations + *******************************************************/ + +/******************************************************* + * Function Definitions + *******************************************************/ +static int wifi_cmd_itwt(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **) &itwt_args); + if (nerrors != 0) { + arg_print_errors(stderr, itwt_args.end, argv[0]); + return 1; + } + + esp_err_t err = ESP_OK; + if (itwt_args.setup->count) { + // setup command, trigger, flow type, min wake duration, wake interval exponent, wake interval mantissa + wifi_twt_setup_cmds_t setup = (itwt_args.setup->ival[0] <= TWT_DEMAND) ? itwt_args.setup->ival[0] : TWT_REQUEST; + bool trigger = itwt_args.trigger->count ? (itwt_args.trigger->ival[0] ? true : false) : true; + uint8_t flowtype = itwt_args.flowtype->count ? ((itwt_args.flowtype->ival[0] == 0) ? 0 : 1) : 0; + int minwakedur = itwt_args.minwakedur->count ? itwt_args.minwakedur->ival[0] : 255; + int wakeinvlexp = itwt_args.wakeinvlexp->count ? itwt_args.wakeinvlexp->ival[0] : 10; + int wakeinvlman = itwt_args.wakeinvlman->count ? itwt_args.wakeinvlman->ival[0] : 512; + int flow_id = 0; + err = esp_wifi_sta_itwt_setup(setup, trigger, flowtype, minwakedur, wakeinvlexp, wakeinvlman, &flow_id); + ESP_LOGI(TAG, "(itwt)setup, trigger:%d, %s, flow_id:%d, err:0x%x", trigger, flowtype ? "unannounce" : "announced", flow_id, err); + } + if (itwt_args.teardown->count) { + // teardown a given flow id, all_twt has a high priority + int flow_id = itwt_args.flowid->count ? itwt_args.flowid->ival[0] : (-1); + bool all_twt = itwt_args.all_twt->count ? ((itwt_args.all_twt->ival[0] == 1) ? true : false) : false; + flow_id = (all_twt == true) ? 8 : flow_id; + if (flow_id >= 0) { + err = esp_wifi_sta_itwt_teardown(flow_id); + ESP_LOGI(TAG, "(itwt)teardown, flow_id:%d, all_twt:%d, err:0x%x", flow_id, all_twt, err); + } else { + ESP_LOGE(TAG, "(itwt)teardown, should specify an existing flow id"); + } + } + if (itwt_args.suspend->count) { + // suspend a given flow id + int flow_id = itwt_args.flowid->count ? itwt_args.flowid->ival[0] : (-1); + bool all_twt = itwt_args.all_twt->count ? (itwt_args.all_twt->ival[0] ? true : false) : false; + flow_id = (all_twt == true) ? 8 : flow_id; + int suspend_time_ms = itwt_args.suspend_time_ms->count ? itwt_args.suspend_time_ms->ival[0] : 0; + if (flow_id > 0) { + err = esp_wifi_sta_itwt_suspend(flow_id, suspend_time_ms); + ESP_LOGI(TAG, "(itwt)suspend, flow_id:%d, all_twt:%d, suspend:%d ms, err:0x%x", flow_id, all_twt, suspend_time_ms, err); + } else { + ESP_LOGE(TAG, "(itwt)suspend, should specify an existing flow id"); + } + } + + return 0; +} + +static int wifi_cmd_itwt_probe(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **) &itwt_probe_args); + if (nerrors != 0) { + arg_print_errors(stderr, itwt_probe_args.end, argv[0]); + return 1; + } + + esp_err_t err = ESP_OK; + if (itwt_probe_args.timeout->count) { + if (itwt_probe_args.timeout->ival[0] > 0) { + ESP_LOGI(TAG, "(itwt)send probe req, timeout:%d ms", itwt_probe_args.timeout->ival[0]); + err = esp_wifi_sta_itwt_send_probe_req(itwt_probe_args.timeout->ival[0]); + } else { + ESP_LOGE(TAG, "(itwt)invalid input, timeout:%d ms", itwt_probe_args.timeout->ival[0]); + } + } + ESP_LOGI(TAG, "err:0x%x", err); + return err; +} + +void register_wifi_itwt(void) +{ + /* itwt setup/teardown */ + itwt_args.setup = arg_int0(NULL, "setup", "", "twt setup/teardown an individual flow id"); + itwt_args.teardown = arg_int0(NULL, "teardown", "", "twt setup/teardown an individual flow id"); + itwt_args.suspend = arg_int0(NULL, "suspend", "", "twt setup/teardown an individual flow id"); + itwt_args.trigger = arg_int0("t", NULL, "", "trigger"); + itwt_args.flowtype = arg_int0("f", NULL, "", "flow type: 0-announced, 1-unannounced"); + itwt_args.negtype = arg_int0("n", NULL, "", "negotiate type"); + itwt_args.minwakedur = arg_int0("d", NULL, "", "Norminal Min. Wake Duration"); + itwt_args.wakeinvlexp = arg_int0("e", NULL, "", "Wake Interval Exponent"); + itwt_args.wakeinvlman = arg_int0("m", NULL, "", "Wake Interval Mantissa"); + itwt_args.flowid = arg_int0("i", NULL, "", "Flow ID"); + itwt_args.suspend_time_ms = arg_int0("s", NULL, "", "time of suspending iTWT agreements, unit ms"); + itwt_args.all_twt = arg_int0("a", NULL, "", "All TWT"); + itwt_args.end = arg_end(1); + const esp_console_cmd_t itwt_cmd = { + .command = "itwt", + .help = "itwt setup, teardown or suspend", + .hint = NULL, + .func = &wifi_cmd_itwt, + .argtable = &itwt_args + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&itwt_cmd)); + + /* itwt probe */ + itwt_probe_args.timeout = arg_int0("t", NULL, "[timeout]", "time of sending a probe request frame and receiving a probe response frame from ap, unit ms"); + itwt_probe_args.end = arg_end(1); + const esp_console_cmd_t itwt_probe_cmd = { + .command = "probe", + .help = "send probe request for TSF update when at lease one itwt agreement setup", + .hint = NULL, + .func = &wifi_cmd_itwt_probe, + .argtable = &itwt_probe_args + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&itwt_probe_cmd)); +} + +#else + +void register_wifi_itwt(void) +{ + ; +} + +#endif /* CONFIG_SOC_WIFI_HE_SUPPORT */ diff --git a/examples/wifi/iperf/main/cmd_wifi.c b/examples/wifi/iperf/main/cmd_wifi.c index 69593faa6f..6b45992cf1 100644 --- a/examples/wifi/iperf/main/cmd_wifi.c +++ b/examples/wifi/iperf/main/cmd_wifi.c @@ -19,8 +19,11 @@ #include "esp_wifi.h" #include "esp_netif.h" #include "esp_event.h" +#include "esp_mac.h" #include "iperf.h" #include "esp_coexist.h" +#include "wifi_cmd.h" +#include "esp_wifi_he.h" typedef struct { struct arg_str *ip; @@ -35,7 +38,6 @@ typedef struct { struct arg_lit *abort; struct arg_end *end; } wifi_iperf_t; -static wifi_iperf_t iperf_args; typedef struct { struct arg_str *ssid; @@ -48,15 +50,16 @@ typedef struct { struct arg_end *end; } wifi_scan_arg_t; +static wifi_iperf_t iperf_args; static wifi_args_t sta_args; static wifi_scan_arg_t scan_args; static wifi_args_t ap_args; static bool reconnect = true; static const char *TAG = "cmd_wifi"; -static esp_netif_t *netif_ap = NULL; -static esp_netif_t *netif_sta = NULL; +esp_netif_t *netif_ap = NULL; +esp_netif_t *netif_sta = NULL; -static EventGroupHandle_t wifi_event_group; +EventGroupHandle_t wifi_event_group; const int CONNECTED_BIT = BIT0; const int DISCONNECTED_BIT = BIT1; @@ -81,7 +84,30 @@ static void scan_done_handler(void *arg, esp_event_base_t event_base, if (esp_wifi_scan_get_ap_records(&sta_number, (wifi_ap_record_t *)ap_list_buffer) == ESP_OK) { for (i = 0; i < sta_number; i++) { +#if CONFIG_SOC_WIFI_HE_SUPPORT + char ssid_rssi[45] = { 0, }; + sprintf(ssid_rssi, "[%s][rssi=%d]", ap_list_buffer[i].ssid, ap_list_buffer[i].rssi); + if (ap_list_buffer[i].phy_11ax) { + ESP_LOGW(TAG, + "[%2d]%45s authmode:0x%x, channel:%2d[%d], phymode:%4s, "MACSTR", bssid-index:%d, bss_color:%d, disabled:%d", + i, ssid_rssi, ap_list_buffer[i].authmode, + ap_list_buffer[i].primary, ap_list_buffer[i].second, + ap_list_buffer[i].phy_11ax ? "11ax" : (ap_list_buffer[i].phy_11n ? "11n" : + (ap_list_buffer[i].phy_11g ? "11g" : (ap_list_buffer[i].phy_11b ? "11b" : ""))), + MAC2STR(ap_list_buffer[i].bssid), ap_list_buffer[i].he_ap.bssid_index, + ap_list_buffer[i].he_ap.bss_color, ap_list_buffer[i].he_ap.bss_color_disabled); + } else { + ESP_LOGI(TAG, + "[%2d]%45s authmode:0x%x, channel:%2d[%d], phymode:%4s, "MACSTR"", + i, ssid_rssi, ap_list_buffer[i].authmode, + ap_list_buffer[i].primary, ap_list_buffer[i].second, + ap_list_buffer[i].phy_11ax ? "11ax" : (ap_list_buffer[i].phy_11n ? "11n" : + (ap_list_buffer[i].phy_11g ? "11g" : (ap_list_buffer[i].phy_11b ? "11b" : ""))), + MAC2STR(ap_list_buffer[i].bssid)); + } +#else ESP_LOGI(TAG, "[%s][rssi=%d]", ap_list_buffer[i].ssid, ap_list_buffer[i].rssi); +#endif } } free(ap_list_buffer); @@ -108,7 +134,6 @@ static void disconnect_handler(void *arg, esp_event_base_t event_base, xEventGroupSetBits(wifi_event_group, DISCONNECTED_BIT); } - void initialise_wifi(void) { esp_log_level_set("wifi", ESP_LOG_WARN); @@ -161,10 +186,21 @@ void initialise_wifi(void) #endif #endif + +#if CONFIG_ENABLE_WIFI_RX_STATS +#if CONFIG_ENABLE_WIFI_RX_MU_STATS + esp_wifi_enable_rx_statistics(true, true); +#else + esp_wifi_enable_rx_statistics(true, false); +#endif +#endif +#if CONFIG_ENABLE_WIFI_TX_STATS + esp_wifi_enable_tx_statistics(ESP_WIFI_ACI_BE, true); +#endif initialized = true; } -static bool wifi_cmd_sta_join(const char *ssid, const char *pass) +static bool wifi_cmd_sta_join(const char *ssid, const char *pass, bool enable_he_mcs9) { int bits = xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, 0, 1, 0); @@ -175,6 +211,10 @@ static bool wifi_cmd_sta_join(const char *ssid, const char *pass) strlcpy((char *) wifi_config.sta.password, pass, sizeof(wifi_config.sta.password)); } + if (enable_he_mcs9 == true) { + wifi_config.sta.he_mcs9_enabled = 1; + } + if (bits & CONNECTED_BIT) { reconnect = false; xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); @@ -202,7 +242,45 @@ static int wifi_cmd_sta(int argc, char **argv) } ESP_LOGI(TAG, "sta connecting to '%s'", sta_args.ssid->sval[0]); - wifi_cmd_sta_join(sta_args.ssid->sval[0], sta_args.password->sval[0]); + wifi_cmd_sta_join(sta_args.ssid->sval[0], sta_args.password->sval[0], false); + return 0; +} + +static int wifi_cmd_sta40(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **) &sta_args); + + if (nerrors != 0) { + arg_print_errors(stderr, sta_args.end, argv[0]); + return 1; + } + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_protocol(0, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N)); + ESP_ERROR_CHECK(esp_wifi_set_bandwidth(0, WIFI_BW_HT40)); + ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE)); + + ESP_LOGI(TAG, "sta connecting to '%s'", sta_args.ssid->sval[0]); + wifi_cmd_sta_join(sta_args.ssid->sval[0], sta_args.password->sval[0], false); + return 0; +} + +static int wifi_cmd_sta_mcs89(int argc, char **argv) +{ +#if CONFIG_SOC_WIFI_HE_SUPPORT + int nerrors = arg_parse(argc, argv, (void **) &sta_args); + if (nerrors != 0) { + arg_print_errors(stderr, sta_args.end, argv[0]); + return 1; + } + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_protocol(0, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N | WIFI_PROTOCOL_11AX)); + ESP_ERROR_CHECK(esp_wifi_set_bandwidth(0, WIFI_BW_HT20)); + + ESP_LOGI(TAG, "sta connecting to '%s'", sta_args.ssid->sval[0]); + wifi_cmd_sta_join(sta_args.ssid->sval[0], sta_args.password->sval[0], true); +#else + ESP_LOGW(TAG, "HE-MCS[0, 9] is not supported"); +#endif return 0; } @@ -453,6 +531,26 @@ void register_wifi(void) ESP_ERROR_CHECK( esp_console_cmd_register(&sta_cmd) ); + const esp_console_cmd_t sta40_cmd = { + .command = "sta40", + .help = "WiFi is station mode, set protocol to bgn and cbw to 40MHz, join a specified AP", + .hint = NULL, + .func = &wifi_cmd_sta40, + .argtable = &sta_args + }; + + ESP_ERROR_CHECK( esp_console_cmd_register(&sta40_cmd) ); + + const esp_console_cmd_t stamcs89_cmd = { + .command = "stamcs89", + .help = "WiFi is station mode, set protocol to ax and mcs set to HE-MCS[0,9], join a specified AP", + .hint = NULL, + .func = &wifi_cmd_sta_mcs89, + .argtable = &sta_args + }; + + ESP_ERROR_CHECK( esp_console_cmd_register(&stamcs89_cmd) ); + scan_args.ssid = arg_str0(NULL, NULL, "", "SSID of AP want to be scanned"); scan_args.end = arg_end(1); @@ -509,4 +607,7 @@ void register_wifi(void) }; ESP_ERROR_CHECK( esp_console_cmd_register(&iperf_cmd) ); + + register_wifi_cmd(); + register_wifi_stats(); } diff --git a/examples/wifi/iperf/sdkconfig.defaults.esp32c6 b/examples/wifi/iperf/sdkconfig.defaults.esp32c6 index d80cbcd798..54e3c82b7b 100644 --- a/examples/wifi/iperf/sdkconfig.defaults.esp32c6 +++ b/examples/wifi/iperf/sdkconfig.defaults.esp32c6 @@ -1,4 +1,19 @@ # -# ESP32-C6 +# ESP32C6-Specific # -# To be updated when wifi bringup is done IDF-5679 +CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=20 +CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=38 +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=35 +CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP32_WIFI_TX_BA_WIN=20 +CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP32_WIFI_RX_BA_WIN=20 +CONFIG_ESP32_WIFI_NVS_ENABLED=n + +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=30000 +CONFIG_LWIP_TCP_WND_DEFAULT=34000 +CONFIG_LWIP_TCP_RECVMBOX_SIZE=64 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=64 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=64 + +CONFIG_LWIP_IP_REASS_MAX_PBUFS=15 From a10779c557e50bfa39f034bb7bf193e6643647a9 Mon Sep 17 00:00:00 2001 From: yuexia Date: Tue, 20 Dec 2022 22:07:54 +0800 Subject: [PATCH 3/6] esp32c6: add itwt example --- examples/wifi/itwt/CMakeLists.txt | 8 + examples/wifi/itwt/README.md | 26 ++ examples/wifi/itwt/main/CMakeLists.txt | 2 + examples/wifi/itwt/main/Kconfig.projbuild | 107 +++++++ examples/wifi/itwt/main/itwt.c | 296 ++++++++++++++++++ examples/wifi/itwt/sdkconfig.defaults | 21 ++ examples/wifi/itwt/sdkconfig.defaults.esp32c6 | 19 ++ 7 files changed, 479 insertions(+) create mode 100644 examples/wifi/itwt/CMakeLists.txt create mode 100644 examples/wifi/itwt/README.md create mode 100644 examples/wifi/itwt/main/CMakeLists.txt create mode 100644 examples/wifi/itwt/main/Kconfig.projbuild create mode 100644 examples/wifi/itwt/main/itwt.c create mode 100644 examples/wifi/itwt/sdkconfig.defaults create mode 100644 examples/wifi/itwt/sdkconfig.defaults.esp32c6 diff --git a/examples/wifi/itwt/CMakeLists.txt b/examples/wifi/itwt/CMakeLists.txt new file mode 100644 index 0000000000..de90c34187 --- /dev/null +++ b/examples/wifi/itwt/CMakeLists.txt @@ -0,0 +1,8 @@ +# The following lines of boilerplate have to be in your project's CMakeLists +# in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/system/console/advanced/components + $ENV{IDF_PATH}/examples/common_components/iperf) +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(itwt) diff --git a/examples/wifi/itwt/README.md b/examples/wifi/itwt/README.md new file mode 100644 index 0000000000..14c753355d --- /dev/null +++ b/examples/wifi/itwt/README.md @@ -0,0 +1,26 @@ +| Supported Targets | ESP32-C6 | +| ----------------- | -------- | + +# Wifi itwt Example + +## Introduction +This example shows how to use itwt of wifi. + +Itwt only works in station mode. And AP needs to support the capability of itwt. + +This example support command "itwt, itwt_probe, itwt_info" to config itwt. + +* itwt: this command is for itwt setup/teardown. + +* itwt_probe: this command will send a probe request to update tsf time with ap + +* itwt_info: this command will send a TWT Information frame to AP for suspending/resuming extablished iTWT agreements. + +### Typical current consumption with Itwt enabled + + + +### Typical current consumption with Itwt disabled + + +Note that current consumption and average current are higher when disabled. diff --git a/examples/wifi/itwt/main/CMakeLists.txt b/examples/wifi/itwt/main/CMakeLists.txt new file mode 100644 index 0000000000..3a2fe809a1 --- /dev/null +++ b/examples/wifi/itwt/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "itwt.c" + INCLUDE_DIRS ".") \ No newline at end of file diff --git a/examples/wifi/itwt/main/Kconfig.projbuild b/examples/wifi/itwt/main/Kconfig.projbuild new file mode 100644 index 0000000000..d7a8c0f71d --- /dev/null +++ b/examples/wifi/itwt/main/Kconfig.projbuild @@ -0,0 +1,107 @@ +menu "Example Configuration" + + config EXAMPLE_WIFI_SSID + string "WiFi SSID" + default "myssid" + help + SSID (network name) for the example to connect to. + + config EXAMPLE_WIFI_PASSWORD + string "WiFi Password" + default "mypassword" + help + WiFi password (WPA or WPA2) for the example to use. + + menu "iTWT Configuration" + config EXAMPLE_ITWT_TRIGGER_ENABLE + bool "trigger-enabled" + default y + help + 0- a non-trigger-enabled TWT, 1-a trigger-enabled TWT + config EXAMPLE_ITWT_ANNOUNCED + bool "announced" + default y + help + 0- an unannounced TWT, 1-an announced TWT + config EXAMPLE_ITWT_MIN_WAKE_DURA + int "itwt minimum wake duration" + range 1 255 + default 255 + help + Nominal Minimum Wake Duration, indicates the minimum amount of time, in unit of 256 us, that the TWT + requesting STA expects that it needs to be awake. The value range is [1, 255]. + config EXAMPLE_ITWT_WAKE_INVL_EXPN + int "itwt wake interval exponent" + range 0 31 + default 10 + help + TWT Wake Interval Exponent, in microseconds. The value range is [0, 31]. + config EXAMPLE_ITWT_WAKE_INVL_MANT + int "itwt wake interval mantissa" + range 1 65535 + default 512 + help + TWT Wake Interval Mantissa, in microseconds. The value range is [1, 65535]. + endmenu + + choice EXAMPLE_MAX_CPU_FREQ + prompt "Maximum CPU frequency" + default EXAMPLE_MAX_CPU_FREQ_80 + depends on PM_ENABLE + help + Maximum CPU frequency to use for dynamic frequency scaling. + + config EXAMPLE_MAX_CPU_FREQ_80 + bool "80 MHz" + config EXAMPLE_MAX_CPU_FREQ_120 + bool "120 MHz" + depends on IDF_TARGET_ESP32C2 + config EXAMPLE_MAX_CPU_FREQ_160 + bool "160 MHz" + depends on !IDF_TARGET_ESP32C2 + config EXAMPLE_MAX_CPU_FREQ_240 + bool "240 MHz" + depends on IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 + endchoice + + config EXAMPLE_MAX_CPU_FREQ_MHZ + int + default 80 if EXAMPLE_MAX_CPU_FREQ_80 + default 120 if EXAMPLE_MAX_CPU_FREQ_120 + default 160 if EXAMPLE_MAX_CPU_FREQ_160 + default 240 if EXAMPLE_MAX_CPU_FREQ_240 + + choice EXAMPLE_MIN_CPU_FREQ + prompt "Minimum CPU frequency" + default EXAMPLE_MIN_CPU_FREQ_10M + depends on PM_ENABLE + help + Minimum CPU frequency to use for dynamic frequency scaling. + Should be set to XTAL frequency or XTAL frequency divided by integer. + + config EXAMPLE_MIN_CPU_FREQ_40M + bool "40 MHz (use with 40MHz XTAL)" + depends on XTAL_FREQ_40 || XTAL_FREQ_AUTO + config EXAMPLE_MIN_CPU_FREQ_20M + bool "20 MHz (use with 40MHz XTAL)" + depends on XTAL_FREQ_40 || XTAL_FREQ_AUTO + config EXAMPLE_MIN_CPU_FREQ_10M + bool "10 MHz (use with 40MHz XTAL)" + depends on XTAL_FREQ_40 || XTAL_FREQ_AUTO + config EXAMPLE_MIN_CPU_FREQ_26M + bool "26 MHz (use with 26MHz XTAL)" + depends on XTAL_FREQ_26 || XTAL_FREQ_AUTO + config EXAMPLE_MIN_CPU_FREQ_13M + bool "13 MHz (use with 26MHz XTAL)" + depends on XTAL_FREQ_26 || XTAL_FREQ_AUTO + endchoice + + config EXAMPLE_MIN_CPU_FREQ_MHZ + int + default 40 if EXAMPLE_MIN_CPU_FREQ_40M + default 20 if EXAMPLE_MIN_CPU_FREQ_20M + default 10 if EXAMPLE_MIN_CPU_FREQ_10M + default 26 if EXAMPLE_MIN_CPU_FREQ_26M + default 13 if EXAMPLE_MIN_CPU_FREQ_13M + +endmenu diff --git a/examples/wifi/itwt/main/itwt.c b/examples/wifi/itwt/main/itwt.c new file mode 100644 index 0000000000..5f35d8b568 --- /dev/null +++ b/examples/wifi/itwt/main/itwt.c @@ -0,0 +1,296 @@ +/* itwt Example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ + +/* + this example shows how to use itwt + set a router or a AP using the same SSID&PASSWORD as configuration of this example. + start esp32c6 and when it connected to AP it will setup itwt. +*/ +#include "freertos/FreeRTOS.h" +#include "freertos/event_groups.h" +#include "esp_wifi.h" +#include "esp_log.h" +#include "esp_event.h" +#include "nvs_flash.h" +#include "esp_console.h" +#include "cmd_system.h" +#include "wifi_cmd.h" +#include "esp_wifi_he.h" + +/******************************************************* + * Constants + *******************************************************/ +static const char *TAG = "itwt"; + +/******************************************************* + * Structures + *******************************************************/ + +/******************************************************* + * Variable Definitions + *******************************************************/ +/*set the ssid and password via "idf.py menuconfig"*/ +#define DEFAULT_SSID CONFIG_EXAMPLE_WIFI_SSID +#define DEFAULT_PWD CONFIG_EXAMPLE_WIFI_PASSWORD + +#if CONFIG_EXAMPLE_ITWT_TRIGGER_ENABLE +bool trigger_enabled = true; +#else +bool trigger_enabled = false; +#endif + +#if CONFIG_EXAMPLE_ITWT_ANNOUNCED +bool flow_type_announced = true; +#else +bool flow_type_announced = false; +#endif + +esp_netif_t *netif_sta = NULL; +const int CONNECTED_BIT = BIT0; +const int DISCONNECTED_BIT = BIT1; +EventGroupHandle_t wifi_event_group; + +/******************************************************* + * Function Declarations + *******************************************************/ + +/******************************************************* + * Function Definitions + *******************************************************/ +static const char *itwt_probe_status_to_str(wifi_itwt_probe_status_t status) +{ + switch (status) { + case ITWT_PROBE_FAIL: return "itwt probe fail"; + case ITWT_PROBE_SUCCESS: return "itwt probe success"; + case ITWT_PROBE_TIMEOUT: return "itwt probe timeout"; + case ITWT_PROBE_STA_DISCONNECTED: return "Sta disconnected"; + default: return "Unknown status"; + } +} + +static void got_ip_handler(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + xEventGroupClearBits(wifi_event_group, DISCONNECTED_BIT); + xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); + + /* setup a trigger-based announce individual TWT agreement. */ + esp_err_t err = ESP_OK; + int flow_id = 0; + wifi_config_t sta_cfg = { 0, }; + esp_wifi_get_config(WIFI_IF_STA, &sta_cfg); + if (sta_cfg.sta.phymode == WIFI_PHY_MODE_HE20) { + err = esp_wifi_sta_itwt_setup(TWT_REQUEST, trigger_enabled, flow_type_announced ? 0 : 1, + CONFIG_EXAMPLE_ITWT_MIN_WAKE_DURA, CONFIG_EXAMPLE_ITWT_WAKE_INVL_EXPN, + CONFIG_EXAMPLE_ITWT_WAKE_INVL_MANT, &flow_id); + if (err != ESP_OK) { + ESP_LOGE(TAG, "itwt setup failed, err:0x%x", err); + } + + } else { + ESP_LOGE(TAG, "Must be in 11ax mode to support itwt"); + } +} + +static void connect_handler(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + ESP_LOGI(TAG, "sta connect to %s", DEFAULT_SSID); + esp_wifi_connect(); +} + +static void disconnect_handler(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + ESP_LOGI(TAG, "sta disconnect, reconnect..."); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + esp_wifi_connect(); +} + +static void itwt_setup_handler(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + wifi_event_sta_itwt_setup_t *setup = (wifi_event_sta_itwt_setup_t *) event_data; + if (setup->setup_cmd == TWT_ACCEPT) { + /* TWT Wake Interval = TWT Wake Interval Mantissa * (2 ^ TWT Wake Interval Exponent) */ + ESP_LOGI(TAG, "flow_id:%d, %s, %s, wake_dura:%d, wake_invl_e:%d, wake_invl_m:%d", setup->flow_id, + setup->trigger ? "trigger-enabled" : "non-trigger-enabled", setup->flow_type ? "unannounced" : "announced", + setup->min_wake_dura, setup->wake_invl_expn, setup->wake_invl_mant); + ESP_LOGI(TAG, "wake duration:%d us, service period:%d ms", setup->min_wake_dura << 8, setup->wake_invl_mant << setup->wake_invl_expn); + } else { + ESP_LOGE(TAG, "unexpected setup command:%d", setup->setup_cmd); + } +} + +static void itwt_teardown_handler(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + wifi_event_sta_itwt_teardown_t *teardown = (wifi_event_sta_itwt_teardown_t *) event_data; + ESP_LOGI(TAG, "flow_id %d%s", teardown->flow_id, (teardown->flow_id == 8) ? "(all twt)" : ""); +} + +static void itwt_suspend_handler(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + wifi_event_sta_itwt_suspend_t *suspend = (wifi_event_sta_itwt_suspend_t *) event_data; + ESP_LOGI(TAG, "status:%d, flow_id_bitmap:0x%x, actual_suspend_time_ms:[%lu %lu %lu %lu %lu %lu %lu %lu]", + suspend->status, suspend->flow_id_bitmap, + suspend->actual_suspend_time_ms[0], suspend->actual_suspend_time_ms[1], suspend->actual_suspend_time_ms[2], suspend->actual_suspend_time_ms[3], + suspend->actual_suspend_time_ms[4], suspend->actual_suspend_time_ms[5], suspend->actual_suspend_time_ms[6], suspend->actual_suspend_time_ms[7]); +} + +static void itwt_probe_handler(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + wifi_event_sta_itwt_probe_t *probe = (wifi_event_sta_itwt_probe_t *) event_data; + ESP_LOGI(TAG, "status:%s, reason:0x%x", itwt_probe_status_to_str(probe->status), probe->reason); +} + +static void wifi_itwt(void) +{ + ESP_ERROR_CHECK(esp_netif_init()); + wifi_event_group = xEventGroupCreate(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + netif_sta = esp_netif_create_default_wifi_sta(); + assert(netif_sta); + + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + + ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, + WIFI_EVENT_STA_START, + &connect_handler, + NULL, + NULL)); + ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, + WIFI_EVENT_STA_DISCONNECTED, + &disconnect_handler, + NULL, + NULL)); + ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, + IP_EVENT_STA_GOT_IP, + &got_ip_handler, + NULL, + NULL)); + /* itwt */ + ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, + WIFI_EVENT_ITWT_SETUP, + &itwt_setup_handler, + NULL, + NULL)); + ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, + WIFI_EVENT_ITWT_TEARDOWN, + &itwt_teardown_handler, + NULL, + NULL)); + ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, + WIFI_EVENT_ITWT_SUSPEND, + &itwt_suspend_handler, + NULL, + NULL)); + ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, + WIFI_EVENT_ITWT_PROBE, + &itwt_probe_handler, + NULL, + NULL)); + + wifi_config_t wifi_config = { + .sta = { + .ssid = DEFAULT_SSID, + .password = DEFAULT_PWD, + }, + }; + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); + + esp_wifi_set_bandwidth(WIFI_IF_STA, WIFI_BW_HT20); + esp_wifi_set_protocol(WIFI_IF_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N | WIFI_PROTOCOL_11AX); + esp_wifi_set_ps(WIFI_PS_MIN_MODEM); + + ESP_ERROR_CHECK(esp_wifi_start()); + +#if CONFIG_ENABLE_WIFI_RX_STATS +#if CONFIG_ENABLE_WIFI_RX_MU_STATS + esp_wifi_enable_rx_statistics(true, true); +#else + esp_wifi_enable_rx_statistics(true, false); +#endif +#endif +#if CONFIG_ENABLE_WIFI_TX_STATS + esp_wifi_enable_tx_statistics(ESP_WIFI_ACI_VO, true); //VO, mgmt + esp_wifi_enable_tx_statistics(ESP_WIFI_ACI_BE, true); //BE, data +#endif + +} + +void app_main(void) +{ + // Initialize NVS + esp_err_t ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + + // TODO: WIFI-5150 +#if CONFIG_PM_ENABLE + io_toggle_pmu_internal_signal_map_to_io_init(); + io_toggle_gpio_init(); + + sleep_clock_system_retention_init(); + sleep_clock_modem_retention_init(); + sleep_peripheral_retention_init(); + sleep_modem_wifi_modem_state_init(); + + // Configure dynamic frequency scaling: + // maximum and minimum frequencies are set in sdkconfig, + // automatic light sleep is enabled if tickless idle support is enabled. + esp_pm_config_esp32c6_t pm_config = { + .max_freq_mhz = CONFIG_EXAMPLE_MAX_CPU_FREQ_MHZ, + .min_freq_mhz = CONFIG_EXAMPLE_MIN_CPU_FREQ_MHZ, +#if CONFIG_FREERTOS_USE_TICKLESS_IDLE + .light_sleep_enable = true +#endif + }; + ESP_ERROR_CHECK( esp_pm_configure(&pm_config) ); + ESP_ERROR_CHECK( ret ); + +#else + printf("\n =================================================\n"); + printf(" | Test WiFi 6 itwt |\n"); + printf(" =================================================\n\n"); + + esp_console_repl_t *repl = NULL; + esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT(); + repl_config.prompt = "itwt>"; + + // init console REPL environment +#if CONFIG_ESP_CONSOLE_UART + esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &repl)); +#elif CONFIG_ESP_CONSOLE_USB_CDC + esp_console_dev_usb_cdc_config_t cdc_config = ESP_CONSOLE_DEV_CDC_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_console_new_repl_usb_cdc(&cdc_config, &repl_config, &repl)); +#elif CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG + esp_console_dev_usb_serial_jtag_config_t usbjtag_config = ESP_CONSOLE_DEV_USB_SERIAL_JTAG_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_console_new_repl_usb_serial_jtag(&usbjtag_config, &repl_config, &repl)); +#endif + + // start console REPL + ESP_ERROR_CHECK(esp_console_start_repl(repl)); +#endif + + //start wifi + wifi_itwt(); + // register commands + register_system(); + register_wifi_itwt(); + register_wifi_stats(); + +} diff --git a/examples/wifi/itwt/sdkconfig.defaults b/examples/wifi/itwt/sdkconfig.defaults new file mode 100644 index 0000000000..6c4793752f --- /dev/null +++ b/examples/wifi/itwt/sdkconfig.defaults @@ -0,0 +1,21 @@ +# Use lower CPU frequency +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80=y +# Enable support for power management +CONFIG_PM_ENABLE=y +# Enable tickless idle mode +CONFIG_FREERTOS_USE_TICKLESS_IDLE=y +# Put related source code in IRAM +CONFIG_PM_SLP_IRAM_OPT=y +CONFIG_PM_RTOS_IDLE_OPT=y +# Disable all GPIO at light sleep +CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL=y +CONFIG_PM_SLP_DISABLE_GPIO=y +# Enable wifi sleep iram optimization +CONFIG_ESP_WIFI_SLP_IRAM_OPT=y + +CONFIG_ESP_GRATUITOUS_ARP=n +CONFIG_LWIP_ESP_GRATUITOUS_ARP=n + +# CONFIG_LWIP_ESP_GRATUITOUS_ARP is not set +# CONFIG_ESP_GRATUITOUS_ARP is not set + diff --git a/examples/wifi/itwt/sdkconfig.defaults.esp32c6 b/examples/wifi/itwt/sdkconfig.defaults.esp32c6 new file mode 100644 index 0000000000..d2b6e22382 --- /dev/null +++ b/examples/wifi/itwt/sdkconfig.defaults.esp32c6 @@ -0,0 +1,19 @@ +# +# ESP32C6-Specific +# +CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=20 +CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=38 +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=35 +CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP32_WIFI_TX_BA_WIN=20 +CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP32_WIFI_RX_BA_WIN=20 +CONFIG_ESP32_WIFI_NVS_ENABLED=n + +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=30000 +CONFIG_LWIP_TCP_WND_DEFAULT=34000 +CONFIG_LWIP_TCP_RECVMBOX_SIZE=64 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=64 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=64 + + From 6e14adcb44ad9f5a0b7f448fa238bf496ec39a20 Mon Sep 17 00:00:00 2001 From: yuexia Date: Sat, 24 Dec 2022 00:14:20 +0800 Subject: [PATCH 4/6] rom: sync with the rebase --- components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld index 83c383a86d..f1a816d1e4 100644 --- a/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld @@ -24,7 +24,7 @@ RC_GetBlockAckTime = 0x40000be0; ebuf_list_remove = 0x40000be4; esf_buf_alloc = 0x40000be8; //esf_buf_alloc_dynamic = 0x40000bec; -esf_buf_recycle = 0x40000bf0; +//esf_buf_recycle = 0x40000bf0; GetAccess = 0x40000bf4; hal_mac_is_low_rate_enabled = 0x40000bf8; hal_mac_tx_get_blockack = 0x40000bfc; From bba409eec1d102b95f2f29a32a180f2867284c69 Mon Sep 17 00:00:00 2001 From: lvshisheng Date: Thu, 29 Dec 2022 12:58:02 +0800 Subject: [PATCH 5/6] wifi: update wifi libs to support wifi6 features and fix build error --- components/esp_hw_support/sleep_modes.c | 14 +++++++++- components/esp_wifi/Kconfig | 17 ++++++------ .../include/esp_private/esp_wifi_he_private.h | 1 - .../esp_private/esp_wifi_he_types_private.h | 2 -- .../esp_wifi/include/esp_private/wifi.h | 27 ------------------- .../esp_wifi/include/esp_wifi_he_types.h | 6 ++--- components/esp_wifi/include/esp_wifi_types.h | 1 + components/esp_wifi/lib | 2 +- .../common_components/iperf/CMakeLists.txt | 2 +- .../iperf/include/wifi_stats.h | 2 +- examples/common_components/iperf/iperf.c | 24 ++++++++--------- examples/common_components/iperf/wifi_cmd.c | 7 +++-- examples/common_components/iperf/wifi_stats.c | 14 +++++----- examples/wifi/.build-test-rules.yml | 6 +++++ examples/wifi/iperf/main/cmd_wifi.c | 7 +++-- examples/wifi/itwt/main/CMakeLists.txt | 2 +- examples/wifi/itwt/main/itwt.c | 11 +++++--- examples/wifi/itwt/sdkconfig.defaults | 1 - examples/wifi/itwt/sdkconfig.defaults.esp32c6 | 2 -- 19 files changed, 69 insertions(+), 79 deletions(-) diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index b51a2705ba..11eee77cb5 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -172,7 +172,9 @@ static sleep_config_t s_config = { /* Internal variable used to track if light sleep wakeup sources are to be expected when determining wakeup cause. */ +#if !CONFIG_IDF_TARGET_ESP32C6 // TODO: WIFI-5150 static bool s_light_sleep_wakeup = false; +#endif /* Updating RTC_MEMORY_CRC_REG register via set_rtc_memory_crc() is not thread-safe, so we need to disable interrupts before going to deep sleep. */ @@ -195,11 +197,13 @@ static uint32_t get_power_down_flags(void); static void ext0_wakeup_prepare(void); static void ext1_wakeup_prepare(void); #endif +#if !CONFIG_IDF_TARGET_ESP32C6 // TODO: WIFI-5150 static void timer_wakeup_prepare(void); +#endif #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 static void touch_wakeup_prepare(void); #endif -#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP +#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && !CONFIG_IDF_TARGET_ESP32C6 // TODO: WIFI-5150 static void gpio_deep_sleep_wakeup_prepare(void); #endif @@ -283,6 +287,7 @@ void esp_deep_sleep(uint64_t time_in_us) } // [refactor-todo] provide target logic for body of uart functions below +#if !CONFIG_IDF_TARGET_ESP32C6 // TODO: WIFI-5150 static void IRAM_ATTR flush_uarts(void) { for (int i = 0; i < SOC_UART_NUM; ++i) { @@ -327,6 +332,7 @@ static void IRAM_ATTR resume_uarts(void) uart_ll_force_xon(i); } } +#endif /** * These save-restore workaround should be moved to lower layer @@ -613,6 +619,7 @@ void IRAM_ATTR esp_deep_sleep_start(void) * Helper function which handles entry to and exit from light sleep * Placed into IRAM as flash may need some time to be powered on. */ +#if !CONFIG_IDF_TARGET_ESP32C6 // TODO: WIFI-5150 static esp_err_t esp_light_sleep_inner(uint32_t pd_flags, uint32_t flash_enable_time_us, rtc_vddsdio_config_t vddsdio_config) IRAM_ATTR __attribute__((noinline)); @@ -642,6 +649,7 @@ static esp_err_t esp_light_sleep_inner(uint32_t pd_flags, return reject ? ESP_ERR_SLEEP_REJECT : ESP_OK; #endif } +#endif /** * vddsdio is used for power supply of spi flash @@ -932,6 +940,7 @@ esp_err_t esp_sleep_enable_timer_wakeup(uint64_t time_in_us) return ESP_OK; } +#if !CONFIG_IDF_TARGET_ESP32C6 // TODO: WIFI-5150 static void timer_wakeup_prepare(void) { int64_t sleep_duration = (int64_t) s_config.sleep_duration - (int64_t) s_config.sleep_time_adjustment; @@ -942,6 +951,7 @@ static void timer_wakeup_prepare(void) int64_t ticks = rtc_time_us_to_slowclk(sleep_duration, s_config.rtc_clk_cal_period); rtc_hal_set_wakeup_timer(s_config.rtc_ticks_at_sleep_start + ticks); } +#endif #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 /* In deep sleep mode, only the sleep channel is supported, and other touch channels should be turned off. */ @@ -1131,6 +1141,7 @@ uint64_t esp_sleep_get_gpio_wakeup_status(void) return rtc_hal_gpio_get_wakeup_status(); } +#if !CONFIG_IDF_TARGET_ESP32C6 // TODO: WIFI-5150 static void gpio_deep_sleep_wakeup_prepare(void) { for (gpio_num_t gpio_idx = GPIO_NUM_0; gpio_idx < GPIO_NUM_MAX; gpio_idx++) { @@ -1149,6 +1160,7 @@ static void gpio_deep_sleep_wakeup_prepare(void) // Clear state from previous wakeup rtc_hal_gpio_clear_wakeup_status(); } +#endif esp_err_t esp_deep_sleep_enable_gpio_wakeup(uint64_t gpio_pin_mask, esp_deepsleep_gpio_wake_up_mode_t mode) { diff --git a/components/esp_wifi/Kconfig b/components/esp_wifi/Kconfig index bc54c2546e..a373287c11 100644 --- a/components/esp_wifi/Kconfig +++ b/components/esp_wifi/Kconfig @@ -402,26 +402,27 @@ menu "Wi-Fi" When using ESP mesh, this value should be set to a maximum of 6. - config ENABLE_WIFI_TX_STATS + config ESP_WIFI_ENABLE_WIFI_TX_STATS bool "Enable Wi-Fi transmission statistics" depends on SOC_WIFI_HE_SUPPORT default "y" help - Enable Wi-Fi transmission statistics. Total support 4 access category. Each access category will use 346 bytes memory. + Enable Wi-Fi transmission statistics. Total support 4 access category. Each access category + will use 346 bytes memory. - config ENABLE_WIFI_RX_STATS + config ESP_WIFI_ENABLE_WIFI_RX_STATS bool "Enable Wi-Fi reception statistics" depends on SOC_WIFI_HE_SUPPORT default "y" help - Enable Wi-Fi reception statistics. Total support 2 access category. Each access category will use 190 bytes memory. + Enable Wi-Fi reception statistics. Total support 2 access category. Each access category + will use 190 bytes memory. - config ENABLE_WIFI_RX_MU_STATS + config ESP_WIFI_ENABLE_WIFI_RX_MU_STATS bool "Enable Wi-Fi DL MU-MIMO and DL OFDMA reception statistics" - depends on SOC_WIFI_HE_SUPPORT - depends on ENABLE_WIFI_RX_STATS + depends on ESP_WIFI_ENABLE_WIFI_RX_STATS default "y" help Enable Wi-Fi DL MU-MIMO and DL OFDMA reception statistics. Will use 10932 bytes memory. -endmenu # Wi-Fi +endmenu # Wi-Fi diff --git a/components/esp_wifi/include/esp_private/esp_wifi_he_private.h b/components/esp_wifi/include/esp_private/esp_wifi_he_private.h index 7c046e78bb..36742242fd 100644 --- a/components/esp_wifi/include/esp_private/esp_wifi_he_private.h +++ b/components/esp_wifi/include/esp_private/esp_wifi_he_private.h @@ -189,4 +189,3 @@ esp_err_t esp_wifi_sta_reset_muedca_timer(uint8_t aci_bitmap); #ifdef __cplusplus } #endif - diff --git a/components/esp_wifi/include/esp_private/esp_wifi_he_types_private.h b/components/esp_wifi/include/esp_private/esp_wifi_he_types_private.h index e3c12749db..290b270cb7 100644 --- a/components/esp_wifi/include/esp_private/esp_wifi_he_types_private.h +++ b/components/esp_wifi/include/esp_private/esp_wifi_he_types_private.h @@ -10,7 +10,6 @@ #include #include "sys/queue.h" #include "esp_err.h" -#include "esp_interface.h" #include "esp_event_base.h" #ifdef __cplusplus @@ -315,4 +314,3 @@ typedef struct { #ifdef __cplusplus } #endif - diff --git a/components/esp_wifi/include/esp_private/wifi.h b/components/esp_wifi/include/esp_private/wifi.h index 25a7f1776d..2537b48f49 100644 --- a/components/esp_wifi/include/esp_private/wifi.h +++ b/components/esp_wifi/include/esp_private/wifi.h @@ -143,33 +143,6 @@ void esp_wifi_internal_free_rx_buffer(void* buffer); */ int esp_wifi_internal_tx(wifi_interface_t wifi_if, void *buffer, uint16_t len); -#if CONFIG_SOC_WIFI_HE_SUPPORT -/** - * @brief transmit eapol frames via wifi driver - * - * This API makes a copy of the input buffer and then forwards the buffer - * copy to WiFi driver. - * - * @param wifi_interface_t wifi_if : wifi interface id - * @param void *buffer : the buffer to be transmit - * @param uint16_t len : the length of buffer - * @param uint8_t msg_id : eapol message id - * - * @return - * - ESP_OK : Successfully transmit the buffer to wifi driver - * - ESP_ERR_NO_MEM: out of memory - * - ESP_ERR_WIFI_ARG: invalid argument - * - ESP_ERR_WIFI_IF : WiFi interface is invalid - * - ESP_ERR_WIFI_CONN : WiFi interface is not created, e.g. send the data to STA while WiFi mode is AP mode - * - ESP_ERR_WIFI_NOT_STARTED : WiFi is not started - * - ESP_ERR_WIFI_STATE : WiFi internal state is not ready, e.g. WiFi is not started - * - ESP_ERR_WIFI_NOT_ASSOC : WiFi is not associated - * - ESP_ERR_WIFI_TX_DISALLOW : WiFi TX is disallowed, e.g. WiFi hasn't pass the authentication - * - ESP_ERR_WIFI_POST : caller fails to post event to WiFi task - */ -int esp_wifi_eapol_tx(wifi_interface_t wifi_if, void *buffer, uint16_t len, uint8_t msg_id); -#endif - /** * @brief The net stack buffer reference counter callback function * diff --git a/components/esp_wifi/include/esp_wifi_he_types.h b/components/esp_wifi/include/esp_wifi_he_types.h index 7e34a4a34a..99fc8c1b58 100644 --- a/components/esp_wifi/include/esp_wifi_he_types.h +++ b/components/esp_wifi/include/esp_wifi_he_types.h @@ -8,6 +8,7 @@ #include #include +#include "esp_err.h" #ifdef __cplusplus extern "C" { @@ -112,8 +113,8 @@ typedef enum { } wifi_rx_bb_format_t; /** - * @brief RxControl Info - */ + * @brief RxControl Info + */ typedef struct { signed rssi : 8; /**< the RSSI of the reception frame */ unsigned rate : 5; /**< if cur_bb_format is RX_BB_FORMAT_11B, it's the transmission rate. otherwise it's Rate field of L-SIG */ @@ -222,4 +223,3 @@ typedef struct { #ifdef __cplusplus } #endif - diff --git a/components/esp_wifi/include/esp_wifi_types.h b/components/esp_wifi/include/esp_wifi_types.h index 3706175f14..ab5e65c78c 100644 --- a/components/esp_wifi/include/esp_wifi_types.h +++ b/components/esp_wifi/include/esp_wifi_types.h @@ -187,6 +187,7 @@ typedef enum { WIFI_ANT_MAX, /**< Invalid WiFi antenna */ } wifi_ant_t; +/** @brief Description of a WiFi AP HE Info */ typedef struct { uint8_t bss_color:6; /**< an unsigned integer whose value is the BSS Color of the BSS corresponding to the AP */ uint8_t partial_bss_color:1; /**< indicate if an AID assignment rule based on the BSS color */ diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index c0deded274..1eb9c86d74 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit c0deded2742ef619403eb3bda0c61e87fe5bcdf7 +Subproject commit 1eb9c86d74b7a0ea258e60bec5cec1cca2f6d248 diff --git a/examples/common_components/iperf/CMakeLists.txt b/examples/common_components/iperf/CMakeLists.txt index fa43ad42a0..3662ec032a 100644 --- a/examples/common_components/iperf/CMakeLists.txt +++ b/examples/common_components/iperf/CMakeLists.txt @@ -10,4 +10,4 @@ target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") if(CONFIG_SOC_WIFI_HE_SUPPORT) idf_component_optional_requires(PRIVATE esp_wifi console) -endif() \ No newline at end of file +endif() diff --git a/examples/common_components/iperf/include/wifi_stats.h b/examples/common_components/iperf/include/wifi_stats.h index 1908444509..64b5863a09 100644 --- a/examples/common_components/iperf/include/wifi_stats.h +++ b/examples/common_components/iperf/include/wifi_stats.h @@ -11,7 +11,7 @@ extern "C" { #endif -#if CONFIG_ENABLE_WIFI_TX_STATS || CONFIG_ENABLE_WIFI_RX_STATS +#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS || CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS int wifi_cmd_get_tx_statistics(int argc, char **argv); int wifi_cmd_clr_tx_statistics(int argc, char **argv); diff --git a/examples/common_components/iperf/iperf.c b/examples/common_components/iperf/iperf.c index e8987a819c..d2adf83276 100644 --- a/examples/common_components/iperf/iperf.c +++ b/examples/common_components/iperf/iperf.c @@ -279,17 +279,17 @@ static esp_err_t IRAM_ATTR iperf_run_tcp_server(void) timeout.tv_sec = IPERF_SOCKET_RX_TIMEOUT; setsockopt(client_socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); -#if CONFIG_ENABLE_WIFI_TX_STATS +#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS wifi_cmd_clr_tx_statistics(0, NULL); #endif -#if CONFIG_ENABLE_WIFI_RX_STATS +#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS wifi_cmd_clr_rx_statistics(0, NULL); #endif socket_recv(client_socket, listen_addr, IPERF_TRANS_TYPE_TCP); -#if CONFIG_ENABLE_WIFI_RX_STATS +#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS wifi_cmd_get_rx_statistics(0, NULL); #endif -#if CONFIG_ENABLE_WIFI_TX_STATS +#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS wifi_cmd_get_tx_statistics(0, NULL); #endif @@ -344,17 +344,17 @@ static esp_err_t iperf_run_tcp_client(void) } -#if CONFIG_ENABLE_WIFI_RX_STATS +#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS wifi_cmd_clr_rx_statistics(0, NULL); #endif -#if CONFIG_ENABLE_WIFI_TX_STATS +#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS wifi_cmd_clr_tx_statistics(0, NULL); #endif socket_send(client_socket, dest_addr, IPERF_TRANS_TYPE_TCP, s_iperf_ctrl.cfg.bw_lim); -#if CONFIG_ENABLE_WIFI_TX_STATS +#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS wifi_cmd_get_tx_statistics(0, NULL); #endif -#if CONFIG_ENABLE_WIFI_RX_STATS +#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS wifi_cmd_get_rx_statistics(0, NULL); #endif @@ -417,11 +417,11 @@ static esp_err_t IRAM_ATTR iperf_run_udp_server(void) timeout.tv_sec = IPERF_SOCKET_RX_TIMEOUT; setsockopt(listen_socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); -#if CONFIG_ENABLE_WIFI_RX_STATS +#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS wifi_cmd_clr_rx_statistics(0, NULL); #endif socket_recv(listen_socket, listen_addr, IPERF_TRANS_TYPE_UDP); -#if CONFIG_ENABLE_WIFI_RX_STATS +#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS wifi_cmd_get_rx_statistics(0, NULL); #endif exit: @@ -468,11 +468,11 @@ static esp_err_t iperf_run_udp_client(void) setsockopt(client_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); memcpy(&dest_addr, &dest_addr4, sizeof(dest_addr4)); } -#if CONFIG_ENABLE_WIFI_TX_STATS +#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS wifi_cmd_clr_tx_statistics(0, NULL); #endif socket_send(client_socket, dest_addr, IPERF_TRANS_TYPE_UDP, s_iperf_ctrl.cfg.bw_lim); -#if CONFIG_ENABLE_WIFI_TX_STATS +#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS wifi_cmd_get_tx_statistics(0, NULL); #endif exit: diff --git a/examples/common_components/iperf/wifi_cmd.c b/examples/common_components/iperf/wifi_cmd.c index 16afffd46b..1f1466c336 100644 --- a/examples/common_components/iperf/wifi_cmd.c +++ b/examples/common_components/iperf/wifi_cmd.c @@ -465,9 +465,9 @@ static int do_ping_cmd(int argc, char **argv) return 0; } -extern bool pm_is_waked(); -extern bool pm_is_sleeping(); -extern bool pm_is_dream(); +extern bool pm_is_waked(void); +extern bool pm_is_sleeping(void); +extern bool pm_is_dream(void); static int wifi_cmd_get_ps_state(int argc, char **argv) { ESP_LOGW(TAG, "ps: awake:%d, sleep:%d, dream:%d", pm_is_waked(), pm_is_sleeping(), pm_is_dream()); @@ -1076,4 +1076,3 @@ void register_wifi_cmd(void) } #endif /* CONFIG_SOC_WIFI_HE_SUPPORT */ - diff --git a/examples/common_components/iperf/wifi_stats.c b/examples/common_components/iperf/wifi_stats.c index 380e49940e..cbb1652a07 100644 --- a/examples/common_components/iperf/wifi_stats.c +++ b/examples/common_components/iperf/wifi_stats.c @@ -8,7 +8,7 @@ #include #include "esp_log.h" -#if CONFIG_ENABLE_WIFI_TX_STATS || CONFIG_ENABLE_WIFI_RX_STATS +#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS || CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS #include "esp_console.h" #include "argtable3/argtable3.h" @@ -39,7 +39,7 @@ static const char *TAG = "stats"; /******************************************************* * Variable Definitions *******************************************************/ -#if CONFIG_ENABLE_WIFI_RX_MU_STATS +#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_MU_STATS esp_test_rx_mu_statistics_t rx_mu_stats = { 0, }; //10932 bytes #endif @@ -466,7 +466,7 @@ int wifi_cmd_clr_rx_statistics(int argc, char **argv) ESP_LOGW(TAG, "Clear rx statistics"); esp_wifi_clr_rx_statistics(0); esp_wifi_clr_rx_statistics(7); -#if CONFIG_ENABLE_WIFI_RX_MU_STATS +#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_MU_STATS esp_test_clr_rx_error_occurs(); esp_wifi_clr_rx_mu_statistics(); #endif @@ -521,7 +521,7 @@ int wifi_cmd_get_rx_statistics(int argc, char **argv) ESP_LOGW(TAG, "(hw)isr:%d, nblks:%d", rx_stats.rx_isr, rx_stats.rx_nblks); /* hw rx statistics */ print_hw_rx_statistics(); -#if CONFIG_ENABLE_WIFI_RX_MU_STATS +#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_MU_STATS print_rx_mu_statistics(); #endif esp_test_get_rx_error_occurs(&rx_error_occurs); @@ -541,11 +541,11 @@ int wifi_cmd_get_rx_statistics(int argc, char **argv) return 0; } -#endif /* CONFIG_ENABLE_WIFI_TX_STATS || CONFIG_ENABLE_WIFI_RX_STATS */ +#endif /* CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS || CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS */ void register_wifi_stats(void) { -#if CONFIG_ENABLE_WIFI_TX_STATS +#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS /* get tx statistics */ const esp_console_cmd_t tx_stats_cmd = { .command = "tx", @@ -564,7 +564,7 @@ void register_wifi_stats(void) ESP_ERROR_CHECK(esp_console_cmd_register(&clr_cmd)); #endif -#if CONFIG_ENABLE_WIFI_RX_STATS +#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS /* get rx statistics */ const esp_console_cmd_t rx_stats_cmd = { .command = "rx", diff --git a/examples/wifi/.build-test-rules.yml b/examples/wifi/.build-test-rules.yml index f485b3d265..4191e328ca 100644 --- a/examples/wifi/.build-test-rules.yml +++ b/examples/wifi/.build-test-rules.yml @@ -31,3 +31,9 @@ examples/wifi/iperf: - if: IDF_TARGET != "esp32" temporary: true reason: lack of runners + +examples/wifi/itwt: + enable: + - if: IDF_TARGET == "esp32c6" + temporary: true + reason: the other targets are not supported yet diff --git a/examples/wifi/iperf/main/cmd_wifi.c b/examples/wifi/iperf/main/cmd_wifi.c index 6b45992cf1..ebae425db6 100644 --- a/examples/wifi/iperf/main/cmd_wifi.c +++ b/examples/wifi/iperf/main/cmd_wifi.c @@ -85,7 +85,7 @@ static void scan_done_handler(void *arg, esp_event_base_t event_base, if (esp_wifi_scan_get_ap_records(&sta_number, (wifi_ap_record_t *)ap_list_buffer) == ESP_OK) { for (i = 0; i < sta_number; i++) { #if CONFIG_SOC_WIFI_HE_SUPPORT - char ssid_rssi[45] = { 0, }; + char ssid_rssi[46] = { 0, }; sprintf(ssid_rssi, "[%s][rssi=%d]", ap_list_buffer[i].ssid, ap_list_buffer[i].rssi); if (ap_list_buffer[i].phy_11ax) { ESP_LOGW(TAG, @@ -186,9 +186,8 @@ void initialise_wifi(void) #endif #endif - -#if CONFIG_ENABLE_WIFI_RX_STATS -#if CONFIG_ENABLE_WIFI_RX_MU_STATS +#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS +#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_MU_STATS esp_wifi_enable_rx_statistics(true, true); #else esp_wifi_enable_rx_statistics(true, false); diff --git a/examples/wifi/itwt/main/CMakeLists.txt b/examples/wifi/itwt/main/CMakeLists.txt index 3a2fe809a1..ff877f0b9d 100644 --- a/examples/wifi/itwt/main/CMakeLists.txt +++ b/examples/wifi/itwt/main/CMakeLists.txt @@ -1,2 +1,2 @@ idf_component_register(SRCS "itwt.c" - INCLUDE_DIRS ".") \ No newline at end of file + INCLUDE_DIRS ".") diff --git a/examples/wifi/itwt/main/itwt.c b/examples/wifi/itwt/main/itwt.c index 5f35d8b568..ab6ee1d8e7 100644 --- a/examples/wifi/itwt/main/itwt.c +++ b/examples/wifi/itwt/main/itwt.c @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ /* itwt Example This example code is in the Public Domain (or CC0 licensed, at your option.) @@ -215,14 +220,14 @@ static void wifi_itwt(void) ESP_ERROR_CHECK(esp_wifi_start()); -#if CONFIG_ENABLE_WIFI_RX_STATS -#if CONFIG_ENABLE_WIFI_RX_MU_STATS +#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS +#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_MU_STATS esp_wifi_enable_rx_statistics(true, true); #else esp_wifi_enable_rx_statistics(true, false); #endif #endif -#if CONFIG_ENABLE_WIFI_TX_STATS +#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS esp_wifi_enable_tx_statistics(ESP_WIFI_ACI_VO, true); //VO, mgmt esp_wifi_enable_tx_statistics(ESP_WIFI_ACI_BE, true); //BE, data #endif diff --git a/examples/wifi/itwt/sdkconfig.defaults b/examples/wifi/itwt/sdkconfig.defaults index 6c4793752f..91254215ce 100644 --- a/examples/wifi/itwt/sdkconfig.defaults +++ b/examples/wifi/itwt/sdkconfig.defaults @@ -18,4 +18,3 @@ CONFIG_LWIP_ESP_GRATUITOUS_ARP=n # CONFIG_LWIP_ESP_GRATUITOUS_ARP is not set # CONFIG_ESP_GRATUITOUS_ARP is not set - diff --git a/examples/wifi/itwt/sdkconfig.defaults.esp32c6 b/examples/wifi/itwt/sdkconfig.defaults.esp32c6 index d2b6e22382..bfd90456d4 100644 --- a/examples/wifi/itwt/sdkconfig.defaults.esp32c6 +++ b/examples/wifi/itwt/sdkconfig.defaults.esp32c6 @@ -15,5 +15,3 @@ CONFIG_LWIP_TCP_WND_DEFAULT=34000 CONFIG_LWIP_TCP_RECVMBOX_SIZE=64 CONFIG_LWIP_UDP_RECVMBOX_SIZE=64 CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=64 - - From a5fdc53bb7a99ac5bec1ca793bf86fe3bf89a248 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Thu, 29 Dec 2022 12:29:10 +0800 Subject: [PATCH 6/6] clk: initialize wifi lp_clk in esp_perip_clk_init --- components/esp_system/port/soc/esp32c6/clk.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/components/esp_system/port/soc/esp32c6/clk.c b/components/esp_system/port/soc/esp32c6/clk.c index 22c30c6256..a6f725fa83 100644 --- a/components/esp_system/port/soc/esp32c6/clk.c +++ b/components/esp_system/port/soc/esp32c6/clk.c @@ -180,6 +180,23 @@ void rtc_clk_select_rtc_slow_clk(void) __attribute__((weak)) void esp_perip_clk_init(void) { modem_clock_domain_pmu_state_icg_map_init(); + + /* During system initialization, the low-power clock source of the modem + * (WiFi, BLE or Coexist) follows the configuration of the slow clock source + * of the system. If the WiFi, BLE or Coexist module needs a higher + * precision sleep clock (for example, the BLE needs to use the main XTAL + * oscillator (40 MHz) to provide the clock during the sleep process in some + * scenarios), the module needs to switch to the required clock source by + * itself. */ //TODO - WIFI-5233 + soc_rtc_slow_clk_src_t rtc_slow_clk_src = rtc_clk_slow_src_get(); + modem_clock_lpclk_src_t modem_lpclk_src = (modem_clock_lpclk_src_t) ( \ + (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_SLOW) ? MODEM_CLOCK_LPCLK_SRC_RC_SLOW \ + : (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) ? MODEM_CLOCK_LPCLK_SRC_XTAL32K \ + : (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) ? MODEM_CLOCK_LPCLK_SRC_RC32K \ + : (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) ? MODEM_CLOCK_LPCLK_SRC_EXT32K \ + : SOC_RTC_SLOW_CLK_SRC_RC_SLOW); + modem_clock_select_lp_clock_source(PERIPH_WIFI_MODULE, modem_lpclk_src, 0); + ESP_EARLY_LOGW(TAG, "esp_perip_clk_init() has not been implemented yet"); #if 0 // TODO: IDF-5658 uint32_t common_perip_clk, hwcrypto_perip_clk, wifi_bt_sdio_clk = 0;