From 395ad3edc029bf4523ee7db60783389d1f12f375 Mon Sep 17 00:00:00 2001 From: xuxiao Date: Mon, 5 Jun 2023 20:06:52 +0800 Subject: [PATCH 1/2] feat(wifi): itwt support itwt wake duration unit --- components/esp_common/src/esp_err_to_name.c | 6 ++++++ .../esp_rom/esp32c6/ld/esp32c6.rom.pp.ld | 12 +++++------ components/esp_wifi/include/esp_wifi.h | 2 ++ .../esp_wifi/include/esp_wifi_he_types.h | 9 +++++--- components/esp_wifi/include/esp_wifi_types.h | 1 + components/esp_wifi/lib | 2 +- examples/common_components/iperf/wifi_twt.c | 19 ++++++++++++----- examples/wifi/itwt/main/Kconfig.projbuild | 16 +++++++++++++- examples/wifi/itwt/main/itwt.c | 21 ++++++++++++++----- 9 files changed, 67 insertions(+), 21 deletions(-) diff --git a/components/esp_common/src/esp_err_to_name.c b/components/esp_common/src/esp_err_to_name.c index d3efe88063..44da581452 100644 --- a/components/esp_common/src/esp_err_to_name.c +++ b/components/esp_common/src/esp_err_to_name.c @@ -401,6 +401,12 @@ static const esp_err_msg_t esp_err_msg_table[] = { ERR_TBL_IT(ESP_ERR_WIFI_TWT_SETUP_TIMEOUT), /* 12312 0x3018 Timeout of receiving twt setup response frame, timeout times can be set during twt setup */ +# endif +# ifdef ESP_ERR_WIFI_TWT_SETUP_TXFAIL + ERR_TBL_IT(ESP_ERR_WIFI_TWT_SETUP_TXFAIL), /* 12313 0x3019 TWT setup frame tx failed */ +# endif +# ifdef ESP_ERR_WIFI_TWT_SETUP_REJECT + ERR_TBL_IT(ESP_ERR_WIFI_TWT_SETUP_REJECT), /* 12314 0x301a The twt setup request was rejected by the AP */ # endif // components/wpa_supplicant/esp_supplicant/include/esp_wps.h # ifdef ESP_ERR_WIFI_REGISTRAR diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld index d9a21b624b..dd374cd2bd 100644 --- a/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld @@ -162,7 +162,7 @@ hal_mac_is_dma_enable = 0x40000e00; //wdevProcessRxSucDataAll = 0x40000e0c; wdev_csi_len_align = 0x40000e10; ppDequeueTxDone_Locked = 0x40000e14; -ppProcTxDone = 0x40000e18; +//ppProcTxDone = 0x40000e18; //pm_tx_data_done_process = 0x40000e1c; config_is_cache_tx_buf_enabled = 0x40000e20; ppMapWaitTxq = 0x40000e24; @@ -297,16 +297,16 @@ tsf_hal_unmap_tbtt_target_to_rx_frame = 0x40001024; //ppSelectTxFormat = 0x40001028; //ppCertSetRate = 0x4000102c; //ppHEAMPDU2Normal = 0x40001030; -ppCalTxHEAMPDULength = 0x40001034; -ppCalTxHESMPDULength = 0x40001038; +//ppCalTxHEAMPDULength = 0x40001034; +//ppCalTxHESMPDULength = 0x40001038; rcGetRate = 0x4000103c; rcGetDCMMaxRate = 0x40001040; //rcGetSMPDURate = 0x40001044; ppDirectRecycleAmpdu = 0x40001048; -ppCheckTxHEAMPDUlength = 0x4000104c; -rx11AXRate2AMPDULimit = 0x40001050; +//ppCheckTxHEAMPDUlength = 0x4000104c; +//rx11AXRate2AMPDULimit = 0x40001050; //ppRegressAmpdu = 0x40001054; -ppCalDeliNum = 0x40001058; +//ppCalDeliNum = 0x40001058; ppAdd2AMPDUTail = 0x4000105c; esp_test_disable_tx_statistics = 0x40001060; esp_test_enable_tx_statistics = 0x40001064; diff --git a/components/esp_wifi/include/esp_wifi.h b/components/esp_wifi/include/esp_wifi.h index fc68fc1f39..ae01e63375 100644 --- a/components/esp_wifi/include/esp_wifi.h +++ b/components/esp_wifi/include/esp_wifi.h @@ -85,6 +85,8 @@ extern "C" { #define ESP_ERR_WIFI_TWT_FULL (ESP_ERR_WIFI_BASE + 23) /*!< no available flow id */ #define ESP_ERR_WIFI_TWT_SETUP_TIMEOUT (ESP_ERR_WIFI_BASE + 24) /*!< Timeout of receiving twt setup response frame, timeout times can be set during twt setup */ +#define ESP_ERR_WIFI_TWT_SETUP_TXFAIL (ESP_ERR_WIFI_BASE + 25) /*!< TWT setup frame tx failed */ +#define ESP_ERR_WIFI_TWT_SETUP_REJECT (ESP_ERR_WIFI_BASE + 26) /*!< The twt setup request was rejected by the AP */ /** * @brief WiFi stack configuration parameters passed to esp_wifi_init call. diff --git a/components/esp_wifi/include/esp_wifi_he_types.h b/components/esp_wifi/include/esp_wifi_he_types.h index 7e92fdde44..f7c1b9a59e 100644 --- a/components/esp_wifi/include/esp_wifi_he_types.h +++ b/components/esp_wifi/include/esp_wifi_he_types.h @@ -103,7 +103,8 @@ typedef struct 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]. */ uint16_t wake_invl_expn :5; /**< TWT Wake Interval Exponent. The value range is [0, 31]. */ - uint16_t reserved :6; /**< bit: 10.15 reserved */ + uint16_t wake_duration_unit :1; /**< TWT Wake duration unit, 0: 256us 1: TU (TU = 1024us)*/ + uint16_t reserved :5; /**< bit: 11.15 reserved */ uint8_t 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]. */ uint16_t wake_invl_mant; /**< TWT Wake Interval Mantissa. The value range is [1, 65535]. */ uint16_t twt_id; /**< TWT connection id, the value range is [0, 32767]. */ @@ -204,8 +205,10 @@ typedef struct { /** Argument structure for WIFI_EVENT_TWT_SET_UP event */ typedef struct { - wifi_twt_setup_config_t config; /**< itwt setup config*/ - esp_err_t status; /**< 1: indicate tx success, others : indicate tx fail */ + wifi_twt_setup_config_t config; /**< itwt setup config, this value is determined by the AP */ + esp_err_t status; /**< itwt setup status, 1: indicate setup success, others : indicate setup fail */ + uint8_t reason; /**< itwt setup frame tx fail reason */ + uint64_t target_wake_time; /**< TWT SP start time */ } wifi_event_sta_itwt_setup_t; /** Argument structure for WIFI_EVENT_TWT_TEARDOWN event */ diff --git a/components/esp_wifi/include/esp_wifi_types.h b/components/esp_wifi/include/esp_wifi_types.h index 72ab60a249..213515eb21 100644 --- a/components/esp_wifi/include/esp_wifi_types.h +++ b/components/esp_wifi/include/esp_wifi_types.h @@ -969,6 +969,7 @@ typedef struct { uint8_t mac[6]; /**< MAC address of the station disconnects to soft-AP */ uint8_t aid; /**< the aid that soft-AP gave to the station disconnects to */ bool is_mesh_child; /**< flag to identify mesh child */ + uint8_t reason; /**< reason of disconnection */ } wifi_event_ap_stadisconnected_t; /** Argument structure for WIFI_EVENT_AP_PROBEREQRECVED event */ diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index 82dd9020a4..b9d885520d 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit 82dd9020a46f8603c60c33e5af87a80a256f4f8f +Subproject commit b9d885520d29081530681e45b256f63a09779efa diff --git a/examples/common_components/iperf/wifi_twt.c b/examples/common_components/iperf/wifi_twt.c index d026f419b3..157a88ef06 100644 --- a/examples/common_components/iperf/wifi_twt.c +++ b/examples/common_components/iperf/wifi_twt.c @@ -31,12 +31,13 @@ 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 *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 *wakeinvlexp; //setup + struct arg_int *wakeduraunit; //1-TU, 0-256us + struct arg_int *wakeinvlman; //setup + struct arg_int *minwakedur; //setup struct arg_int *flowid; struct arg_int *twtid; struct arg_int *setup_timeout_time_ms; @@ -91,6 +92,12 @@ static int wifi_cmd_itwt(int argc, char **argv) return 1; } } + if (itwt_args.wakeduraunit->count) { + if (itwt_args.wakeduraunit->ival[0] < 0 || itwt_args.wakeduraunit->ival[0] > 1) { + ESP_LOGE(TAG, "(itwt)expect [0, 1], wake duration unit: %d", itwt_args.wakeduraunit->ival[0]); + return 1; + } + } if (itwt_args.twtid->count) { if (itwt_args.twtid->ival[0] < 0 || itwt_args.twtid->ival[0] > 32767) { ESP_LOGE(TAG, "(itwt)expect [0, 32767], twt id: %d", itwt_args.twtid->ival[0]); @@ -109,6 +116,7 @@ static int wifi_cmd_itwt(int argc, char **argv) .twt_id = itwt_args.twtid->count ? itwt_args.twtid->ival[0] : 0, .flow_type = itwt_args.flowtype->count ? ((itwt_args.flowtype->ival[0] == 0) ? 0 : 1) : 0, .min_wake_dura = itwt_args.minwakedur->count ? itwt_args.minwakedur->ival[0] : 255, + .wake_duration_unit = itwt_args.wakeduraunit->count ? itwt_args.wakeduraunit->ival[0] : 0, .wake_invl_expn = itwt_args.wakeinvlexp->count ? itwt_args.wakeinvlexp->ival[0] : 10, .wake_invl_mant = itwt_args.wakeinvlman->count ? itwt_args.wakeinvlman->ival[0] : 512, .trigger = itwt_args.trigger->count ? (itwt_args.trigger->ival[0] ? 1 : 0) : 1, @@ -178,6 +186,7 @@ void register_wifi_itwt(void) itwt_args.flowtype = arg_int0("f", NULL, "", "flow type: 0-announced, 1-unannounced"); itwt_args.negtype = arg_int0("n", NULL, "", "negotiate type"); itwt_args.minwakedur = arg_int0("d", NULL, "", "Norminal Min. Wake Duration"); + itwt_args.wakeduraunit = arg_int0("u", NULL, "", "wake duration unit 0-256us, 1-TU (TU = 1024us)"); itwt_args.wakeinvlexp = arg_int0("e", NULL, "", "Wake Interval Exponent"); itwt_args.wakeinvlman = arg_int0("m", NULL, "", "Wake Interval Mantissa"); itwt_args.flowid = arg_int0("i", NULL, "", "Flow ID"); diff --git a/examples/wifi/itwt/main/Kconfig.projbuild b/examples/wifi/itwt/main/Kconfig.projbuild index ee3b29c9eb..9eb0e46e7b 100644 --- a/examples/wifi/itwt/main/Kconfig.projbuild +++ b/examples/wifi/itwt/main/Kconfig.projbuild @@ -44,11 +44,13 @@ menu "Example Configuration" default y help 0- a non-trigger-enabled TWT, 1-a trigger-enabled TWT + config EXAMPLE_ITWT_ANNOUNCED bool "announced" default y help 0- an unannounced TWT, 1-an announced TWT + config EXAMPLE_ITWT_MIN_WAKE_DURA int "itwt minimum wake duration" range 1 255 @@ -56,30 +58,42 @@ menu "Example Configuration" help Nominal Minimum Wake Duration, indicates the minimum amount of time, in unit of 256 us, that the TWT requesting STA expects that it needs to be awake. The value range is [1, 255]. + + config EXAMPLE_ITWT_WAKE_DURATION_UNIT + int "itwt wake duration unit" + range 0 1 + default 0 + help + TWT wake duration unit, 0: 256us 1: TU (TU = 1024us) + config EXAMPLE_ITWT_WAKE_INVL_EXPN int "itwt wake interval exponent" range 0 31 default 10 help TWT Wake Interval Exponent, in microseconds. The value range is [0, 31]. + config EXAMPLE_ITWT_WAKE_INVL_MANT int "itwt wake interval mantissa" range 1 65535 default 512 help TWT Wake Interval Mantissa, in microseconds. The value range is [1, 65535]. + config EXAMPLE_ITWT_ID int "itwt connection id" range 0 32767 default 0 help TWT Connection id. The value range is [0, 32767]. + config EXAMPLE_ITWT_SETUP_TIMEOUT_TIME_MS - int "itwt wake interval mantissa" + int "itwt setup timeout times" range 100 65535 default 5000 help TWT setup timeout time, in microseconds. The value range is [100, 65535]. + endmenu choice EXAMPLE_MAX_CPU_FREQ diff --git a/examples/wifi/itwt/main/itwt.c b/examples/wifi/itwt/main/itwt.c index bb4df81d11..7706afdb8b 100644 --- a/examples/wifi/itwt/main/itwt.c +++ b/examples/wifi/itwt/main/itwt.c @@ -46,6 +46,7 @@ static const char *TAG = "itwt"; /*set the ssid and password via "idf.py menuconfig"*/ #define DEFAULT_SSID CONFIG_EXAMPLE_WIFI_SSID #define DEFAULT_PWD CONFIG_EXAMPLE_WIFI_PASSWORD +#define ITWT_SETUP_SUCCESS 1 #if CONFIG_EXAMPLE_ITWT_TRIGGER_ENABLE uint8_t trigger_enabled = 1; @@ -123,6 +124,7 @@ static void got_ip_handler(void *arg, esp_event_base_t event_base, .twt_id = CONFIG_EXAMPLE_ITWT_ID, .flow_type = flow_type_announced ? 0 : 1, .min_wake_dura = CONFIG_EXAMPLE_ITWT_MIN_WAKE_DURA, + .wake_duration_unit = CONFIG_EXAMPLE_ITWT_WAKE_DURATION_UNIT, .wake_invl_expn = CONFIG_EXAMPLE_ITWT_WAKE_INVL_EXPN, .wake_invl_mant = CONFIG_EXAMPLE_ITWT_WAKE_INVL_MANT, .trigger = trigger_enabled, @@ -156,14 +158,23 @@ static void itwt_setup_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { wifi_event_sta_itwt_setup_t *setup = (wifi_event_sta_itwt_setup_t *) event_data; - if (setup->config.setup_cmd == TWT_ACCEPT) { + if (setup->status == ITWT_SETUP_SUCCESS) { /* TWT Wake Interval = TWT Wake Interval Mantissa * (2 ^ TWT Wake Interval Exponent) */ - ESP_LOGI(TAG, "twt_id:%d, flow_id:%d, %s, %s, wake_dura:%d, wake_invl_e:%d, wake_invl_m:%d", setup->config.twt_id, + ESP_LOGI(TAG, "twt_id:%d, flow_id:%d, %s, %s, wake_dura:%d, wake_dura_unit:%d, wake_invl_e:%d, wake_invl_m:%d", setup->config.twt_id, setup->config.flow_id, setup->config.trigger ? "trigger-enabled" : "non-trigger-enabled", setup->config.flow_type ? "unannounced" : "announced", - setup->config.min_wake_dura, setup->config.wake_invl_expn, setup->config.wake_invl_mant); - ESP_LOGI(TAG, "wake duration:%d us, service period:%d us", setup->config.min_wake_dura << 8, setup->config.wake_invl_mant << setup->config.wake_invl_expn); + setup->config.min_wake_dura, setup->config.wake_duration_unit, setup->config.wake_invl_expn, setup->config.wake_invl_mant); + ESP_LOGI(TAG, "target wake time:%lld, wake duration:%d us, service period:%d us", setup->target_wake_time, setup->config.min_wake_dura << (setup->config.wake_duration_unit == 1 ? 10 : 8), + setup->config.wake_invl_mant << setup->config.wake_invl_expn); } else { - ESP_LOGE(TAG, "twt_id:%d, unexpected setup command:%d", setup->config.twt_id, setup->config.setup_cmd); + if (setup->status == ESP_ERR_WIFI_TWT_SETUP_TIMEOUT) { + ESP_LOGE(TAG, "twt_id:%d, timeout of receiving twt setup response frame", setup->config.twt_id); + } else if (setup->status == ESP_ERR_WIFI_TWT_SETUP_TXFAIL) { + ESP_LOGE(TAG, "twt_id:%d, twt setup frame tx failed, reason: %d", setup->config.twt_id, setup->reason); + } else if (setup->status == ESP_ERR_WIFI_TWT_SETUP_REJECT) { + ESP_LOGE(TAG, "twt_id:%d, twt setup request was rejected, setup cmd: %d", setup->config.twt_id, setup->config.setup_cmd); + } else { + ESP_LOGE(TAG, "twt_id:%d, twt setup failed, status: %d", setup->config.twt_id, setup->status); + } } } From 6a5d4e40d2886b75a206f3b9329fbdec45e76004 Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Thu, 15 Jun 2023 10:46:01 +0800 Subject: [PATCH 2/2] Wi-Fi/power save: fix the some mac issues of wifi power save Some APs are configured to hide the SSID, the length field of the SSID element in the Beacon frame is set to 0. This can cause incorrect parsing of the Beacon by the Wi-Fi MAC hardware. Some APs send two beacon frames with different BSSID in a TBTT cycle. After correctly parsing the beacon of the associated AP, it continue to receive the other beacon frame, which will cause the MAC to remain in a wait RX/TXING state, blocking the Wi-Fi go to sleep. --- components/esp_rom/esp32c2/ld/esp32c2.rom.ld | 2 +- components/esp_rom/esp32c3/ld/esp32c3.rom.ld | 2 +- components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld | 2 +- components/esp_rom/esp32s3/ld/esp32s3.rom.ld | 2 +- components/esp_wifi/lib | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/components/esp_rom/esp32c2/ld/esp32c2.rom.ld b/components/esp_rom/esp32c2/ld/esp32c2.rom.ld index 02431363b0..4159da653d 100644 --- a/components/esp_rom/esp32c2/ld/esp32c2.rom.ld +++ b/components/esp_rom/esp32c2/ld/esp32c2.rom.ld @@ -1522,7 +1522,7 @@ hal_mac_is_low_rate_enabled = 0x40001af0; hal_mac_tx_get_blockack = 0x40001af4; hal_mac_tx_set_ppdu = 0x40001af8; ic_get_trc = 0x40001afc; -ic_mac_deinit = 0x40001b00; +/* ic_mac_deinit = 0x40001b00; */ ic_mac_init = 0x40001b04; ic_interface_enabled = 0x40001b08; is_lmac_idle = 0x40001b0c; diff --git a/components/esp_rom/esp32c3/ld/esp32c3.rom.ld b/components/esp_rom/esp32c3/ld/esp32c3.rom.ld index 70b1b78a92..c60e1d10e3 100644 --- a/components/esp_rom/esp32c3/ld/esp32c3.rom.ld +++ b/components/esp_rom/esp32c3/ld/esp32c3.rom.ld @@ -1589,7 +1589,7 @@ hal_mac_is_low_rate_enabled = 0x400015cc; hal_mac_tx_get_blockack = 0x400015d0; /* hal_mac_tx_set_ppdu = 0x400015d4;*/ ic_get_trc = 0x400015d8; -ic_mac_deinit = 0x400015dc; +/* ic_mac_deinit = 0x400015dc; */ ic_mac_init = 0x400015e0; ic_interface_enabled = 0x400015e4; is_lmac_idle = 0x400015e8; diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld index dd374cd2bd..1cf4abdb4a 100644 --- a/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld @@ -72,7 +72,7 @@ pm_is_waked = 0x40000c9c; /* pm_on_beacon_rx = 0x40000ca4; */ pm_on_data_rx = 0x40000ca8; //pm_on_tbtt = 0x40000cac; -pm_parse_beacon = 0x40000cb0; +/* pm_parse_beacon = 0x40000cb0; */ //pm_process_tim = 0x40000cb4; //pm_rx_beacon_process = 0x40000cb8; /* pm_rx_data_process = 0x40000cbc; */ diff --git a/components/esp_rom/esp32s3/ld/esp32s3.rom.ld b/components/esp_rom/esp32s3/ld/esp32s3.rom.ld index fd7acee91c..2e6e1a420a 100644 --- a/components/esp_rom/esp32s3/ld/esp32s3.rom.ld +++ b/components/esp_rom/esp32s3/ld/esp32s3.rom.ld @@ -1899,7 +1899,7 @@ hal_mac_is_low_rate_enabled = 0x400052a4; hal_mac_tx_get_blockack = 0x400052b0; /* hal_mac_tx_set_ppdu = 0x400052bc;*/ ic_get_trc = 0x400052c8; -ic_mac_deinit = 0x400052d4; +/* ic_mac_deinit = 0x400052d4; */ ic_mac_init = 0x400052e0; ic_interface_enabled = 0x400052ec; is_lmac_idle = 0x400052f8; diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index b9d885520d..e3e15870cb 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit b9d885520d29081530681e45b256f63a09779efa +Subproject commit e3e15870cb5d199a59867f66dd236e0d9ff5a127