esp32c6: support wifi 6

This commit is contained in:
yuexia 2022-12-20 22:07:09 +08:00 committed by lvshisheng
parent 58b7fc1d8b
commit 032ebd76cb
24 changed files with 3164 additions and 91 deletions

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -0,0 +1,192 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#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

View File

@ -0,0 +1,318 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#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

View File

@ -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
*

View File

@ -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;

View File

@ -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

View File

@ -0,0 +1,155 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#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

View File

@ -0,0 +1,225 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#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

View File

@ -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 */

View File

@ -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

View File

@ -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
/*
----------------------------------

View File

@ -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

View File

@ -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 */

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -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);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,585 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <string.h>
#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
}

View File

@ -0,0 +1,180 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <string.h>
#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", "<setup>", "twt setup/teardown an individual flow id");
itwt_args.teardown = arg_int0(NULL, "teardown", "<setup>", "twt setup/teardown an individual flow id");
itwt_args.suspend = arg_int0(NULL, "suspend", "<setup>", "twt setup/teardown an individual flow id");
itwt_args.trigger = arg_int0("t", NULL, "<trigger>", "trigger");
itwt_args.flowtype = arg_int0("f", NULL, "<flow_type>", "flow type: 0-announced, 1-unannounced");
itwt_args.negtype = arg_int0("n", NULL, "<neg_type>", "negotiate type");
itwt_args.minwakedur = arg_int0("d", NULL, "<minwakedur>", "Norminal Min. Wake Duration");
itwt_args.wakeinvlexp = arg_int0("e", NULL, "<wakeinvlexp>", "Wake Interval Exponent");
itwt_args.wakeinvlman = arg_int0("m", NULL, "<wakeinvlman>", "Wake Interval Mantissa");
itwt_args.flowid = arg_int0("i", NULL, "<flow_id>", "Flow ID");
itwt_args.suspend_time_ms = arg_int0("s", NULL, "<suspend_time_ms>", "time of suspending iTWT agreements, unit ms");
itwt_args.all_twt = arg_int0("a", NULL, "<all_twt>", "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 */

View File

@ -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>", "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();
}

View File

@ -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