diff --git a/components/esp_wifi/Kconfig b/components/esp_wifi/Kconfig index a9ae9b409f..f0ab1bb459 100644 --- a/components/esp_wifi/Kconfig +++ b/components/esp_wifi/Kconfig @@ -163,6 +163,13 @@ menu "Wi-Fi" the default and minimum value should be 16 to achieve better throughput and compatibility with both stations and APs. + config ESP32_WIFI_AMSDU_TX_ENABLED + bool "WiFi AMSDU TX" + depends on (ESP32_SPIRAM_SUPPORT || ESP32S2_SPIRAM_SUPPORT || ESP32S3_SPIRAM_SUPPORT) + default n + help + Select this option to enable AMSDU TX feature + config ESP32_WIFI_NVS_ENABLED bool "WiFi NVS flash" default y diff --git a/components/esp_wifi/include/esp_private/wifi.h b/components/esp_wifi/include/esp_private/wifi.h index 2e9d0efbe1..d2c8e2972f 100644 --- a/components/esp_wifi/include/esp_private/wifi.h +++ b/components/esp_wifi/include/esp_private/wifi.h @@ -512,6 +512,20 @@ typedef void (* wifi_tx_done_cb_t)(uint8_t ifidx, uint8_t *data, uint16_t *data_ */ esp_err_t esp_wifi_set_tx_done_cb(wifi_tx_done_cb_t cb); +/** + * @brief Set device spp amsdu attributes + * + * @param ifx: WiFi interface + * @param spp_cap: spp amsdu capable + * @param spp_req: spp amsdu require + * + * @return + * - ESP_OK: succeed + * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init + * - ESP_ERR_WIFI_IF : invalid WiFi interface + */ +esp_err_t esp_wifi_internal_set_spp_amsdu(wifi_interface_t ifidx, bool spp_cap, bool spp_req); + #ifdef __cplusplus } #endif diff --git a/components/esp_wifi/include/esp_wifi.h b/components/esp_wifi/include/esp_wifi.h index 0741fa261c..a893ce0453 100644 --- a/components/esp_wifi/include/esp_wifi.h +++ b/components/esp_wifi/include/esp_wifi.h @@ -107,6 +107,7 @@ typedef struct { int csi_enable; /**< WiFi channel state information enable flag */ int ampdu_rx_enable; /**< WiFi AMPDU RX feature enable flag */ int ampdu_tx_enable; /**< WiFi AMPDU TX feature enable flag */ + int amsdu_tx_enable; /**< WiFi AMSDU TX feature enable flag */ int nvs_enable; /**< WiFi NVS flash enable flag */ int nano_enable; /**< Nano option for printf/scan family enable flag */ int rx_ba_win; /**< WiFi Block Ack RX window size */ @@ -153,6 +154,12 @@ typedef struct { #define WIFI_AMPDU_TX_ENABLED 0 #endif +#if CONFIG_ESP32_WIFI_AMSDU_TX_ENABLED +#define WIFI_AMSDU_TX_ENABLED 1 +#else +#define WIFI_AMSDU_TX_ENABLED 0 +#endif + #if CONFIG_ESP32_WIFI_NVS_ENABLED #define WIFI_NVS_ENABLED 1 #else @@ -210,6 +217,7 @@ extern uint64_t g_wifi_feature_caps; .csi_enable = WIFI_CSI_ENABLED,\ .ampdu_rx_enable = WIFI_AMPDU_RX_ENABLED,\ .ampdu_tx_enable = WIFI_AMPDU_TX_ENABLED,\ + .amsdu_tx_enable = WIFI_AMSDU_TX_ENABLED,\ .nvs_enable = WIFI_NVS_ENABLED,\ .nano_enable = WIFI_NANO_FORMAT_ENABLED,\ .rx_ba_win = WIFI_DEFAULT_RX_BA_WIN,\ diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index 8017558a14..22a92a009e 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit 8017558a14d29ce5f7fa8631afdecad3e86b2a93 +Subproject commit 22a92a009e4107341665ad307e4dd3c605ae31b3 diff --git a/components/wpa_supplicant/src/ap/wpa_auth.h b/components/wpa_supplicant/src/ap/wpa_auth.h index c666c85edb..4979ec6bae 100644 --- a/components/wpa_supplicant/src/ap/wpa_auth.h +++ b/components/wpa_supplicant/src/ap/wpa_auth.h @@ -162,6 +162,7 @@ struct wpa_auth_config { #endif /* CONFIG_IEEE80211R */ int disable_gtk; int ap_mlme; + struct rsn_sppamsdu_sup spp_sup; }; typedef enum { diff --git a/components/wpa_supplicant/src/ap/wpa_auth_i.h b/components/wpa_supplicant/src/ap/wpa_auth_i.h index 6a55cdee53..7dc19dc66d 100644 --- a/components/wpa_supplicant/src/ap/wpa_auth_i.h +++ b/components/wpa_supplicant/src/ap/wpa_auth_i.h @@ -118,6 +118,7 @@ struct wpa_state_machine { int pending_1_of_4_timeout; u32 index; ETSTimer resend_eapol; + struct rsn_sppamsdu_sup spp_sup; }; diff --git a/components/wpa_supplicant/src/ap/wpa_auth_ie.c b/components/wpa_supplicant/src/ap/wpa_auth_ie.c index a546123c61..046ecf3588 100644 --- a/components/wpa_supplicant/src/ap/wpa_auth_ie.c +++ b/components/wpa_supplicant/src/ap/wpa_auth_ie.c @@ -222,6 +222,15 @@ int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len, /* 4 PTKSA replay counters when using WMM */ capab |= (RSN_NUM_REPLAY_COUNTERS_16 << 2); } + + if (conf->spp_sup.capable) { + capab |= WPA_CAPABILITY_SPP_CAPABLE; + } + + if (conf->spp_sup.require) { + capab |= WPA_CAPABILITY_SPP_REQUIRED; + } + #ifdef CONFIG_IEEE80211W if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) { capab |= WPA_CAPABILITY_MFPC; @@ -487,6 +496,18 @@ int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth, return WPA_INVALID_PAIRWISE; } + if (data.capabilities & WPA_CAPABILITY_SPP_CAPABLE) { + sm->spp_sup.capable = SPP_AMSDU_CAP_ENABLE; + } else { + sm->spp_sup.capable = SPP_AMSDU_CAP_DISABLE; + } + + if (data.capabilities & WPA_CAPABILITY_SPP_REQUIRED) { + sm->spp_sup.require = SPP_AMSDU_REQ_ENABLE; + } else { + sm->spp_sup.require = SPP_AMSDU_REQ_DISABLE; + } + #ifdef CONFIG_IEEE80211W if (wpa_auth->conf.ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED) { if (!(data.capabilities & WPA_CAPABILITY_MFPC)) { diff --git a/components/wpa_supplicant/src/common/eapol_common.h b/components/wpa_supplicant/src/common/eapol_common.h index 6a40ac33b3..9e488aacbe 100644 --- a/components/wpa_supplicant/src/common/eapol_common.h +++ b/components/wpa_supplicant/src/common/eapol_common.h @@ -26,6 +26,10 @@ struct ieee802_1x_hdr { #define EAPOL_VERSION 2 +#define SPP_AMSDU_CAP_ENABLE 1 +#define SPP_AMSDU_REQ_ENABLE 1 +#define SPP_AMSDU_CAP_DISABLE 0 +#define SPP_AMSDU_REQ_DISABLE 0 enum { IEEE802_1X_TYPE_EAP_PACKET = 0, IEEE802_1X_TYPE_EAPOL_START = 1, diff --git a/components/wpa_supplicant/src/common/wpa_common.h b/components/wpa_supplicant/src/common/wpa_common.h index f88e8a6fac..05f707aff4 100644 --- a/components/wpa_supplicant/src/common/wpa_common.h +++ b/components/wpa_supplicant/src/common/wpa_common.h @@ -110,6 +110,8 @@ #define WPA_CAPABILITY_MFPR BIT(6) #define WPA_CAPABILITY_MFPC BIT(7) #define WPA_CAPABILITY_PEERKEY_ENABLED BIT(9) +#define WPA_CAPABILITY_SPP_CAPABLE BIT(10) +#define WPA_CAPABILITY_SPP_REQUIRED BIT(11) /* IEEE 802.11r */ @@ -303,6 +305,11 @@ struct wpa_ie_data { int mgmt_group_cipher; }; +struct rsn_sppamsdu_sup { + bool capable; + bool require; +}; + const char * wpa_cipher_txt(int cipher); int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len, diff --git a/components/wpa_supplicant/src/esp_supplicant/esp_hostap.c b/components/wpa_supplicant/src/esp_supplicant/esp_hostap.c index 11a0564a6c..19a88d529d 100644 --- a/components/wpa_supplicant/src/esp_supplicant/esp_hostap.c +++ b/components/wpa_supplicant/src/esp_supplicant/esp_hostap.c @@ -32,6 +32,7 @@ void *hostap_init(void) struct hostapd_data *hapd = NULL; struct wpa_auth_config *auth_conf; u8 mac[6]; + u16 spp_attrubute = 0; hapd = (struct hostapd_data *)os_zalloc(sizeof(struct hostapd_data)); @@ -70,6 +71,10 @@ void *hostap_init(void) auth_conf->wpa_key_mgmt = WPA_KEY_MGMT_PSK; auth_conf->eapol_version = EAPOL_VERSION; + spp_attrubute = esp_wifi_get_spp_attrubute_internal(WIFI_IF_AP); + auth_conf->spp_sup.capable = ((spp_attrubute & WPA_CAPABILITY_SPP_CAPABLE) ? SPP_AMSDU_CAP_ENABLE : SPP_AMSDU_CAP_DISABLE); + auth_conf->spp_sup.require = ((spp_attrubute & WPA_CAPABILITY_SPP_REQUIRED) ? SPP_AMSDU_CAP_ENABLE : SPP_AMSDU_REQ_DISABLE); + memcpy(hapd->conf->ssid.ssid, ssid->ssid, ssid->len); hapd->conf->ssid.ssid_len = ssid->len; hapd->conf->ssid.wpa_passphrase = (char *)os_zalloc(64); diff --git a/components/wpa_supplicant/src/esp_supplicant/esp_wifi_driver.h b/components/wpa_supplicant/src/esp_supplicant/esp_wifi_driver.h index 7320647f0d..ccac01a238 100644 --- a/components/wpa_supplicant/src/esp_supplicant/esp_wifi_driver.h +++ b/components/wpa_supplicant/src/esp_supplicant/esp_wifi_driver.h @@ -126,6 +126,7 @@ struct wpa_funcs { bool (*wpa_ap_remove)(void *sm); uint8_t *(*wpa_ap_get_wpa_ie)(uint8_t *len); bool (*wpa_ap_rx_eapol)(void *hapd_data, void *sm, u8 *data, size_t data_len); + void (*wpa_ap_get_peer_spp_msg)(void *sm, bool *spp_cap, bool *spp_req); char *(*wpa_config_parse_string)(const char *value, size_t *len); int (*wpa_parse_wpa_ie)(const u8 *wpa_ie, size_t wpa_ie_len, wifi_wpa_ie_t *data); int (*wpa_config_bss)(u8 *bssid); @@ -207,6 +208,7 @@ struct wifi_appie *esp_wifi_get_appie_internal(uint8_t type); void *esp_wifi_get_hostap_private_internal(void); //1 uint8_t *esp_wifi_sta_get_prof_password_internal(void); void esp_wifi_deauthenticate_internal(u8 reason_code); +uint16_t esp_wifi_get_spp_attrubute_internal(uint8_t ifx); bool esp_wifi_sta_is_running_internal(void); bool esp_wifi_auth_done_internal(void); int esp_wifi_set_ap_key_internal(int alg, const u8 *addr, int idx, u8 *key, size_t key_len); diff --git a/components/wpa_supplicant/src/esp_supplicant/esp_wpa_main.c b/components/wpa_supplicant/src/esp_supplicant/esp_wpa_main.c index 2f130abe3b..4843813dbe 100644 --- a/components/wpa_supplicant/src/esp_supplicant/esp_wpa_main.c +++ b/components/wpa_supplicant/src/esp_supplicant/esp_wpa_main.c @@ -149,6 +149,18 @@ bool wpa_ap_rx_eapol(void *hapd_data, void *sm_data, u8 *data, size_t data_len) return true; } +void wpa_ap_get_peer_spp_msg(void *sm_data, bool *spp_cap, bool *spp_req) +{ + struct wpa_state_machine *sm = (struct wpa_state_machine *)sm_data; + + if (!sm) { + return; + } + + *spp_cap = sm->spp_sup.capable; + *spp_req = sm->spp_sup.require; +} + bool wpa_deattach(void) { esp_wifi_sta_wpa2_ent_disable(); @@ -230,6 +242,7 @@ int esp_supplicant_init(void) wpa_cb->wpa_ap_remove = wpa_ap_remove; wpa_cb->wpa_ap_get_wpa_ie = wpa_ap_get_wpa_ie; wpa_cb->wpa_ap_rx_eapol = wpa_ap_rx_eapol; + wpa_cb->wpa_ap_get_peer_spp_msg = wpa_ap_get_peer_spp_msg; wpa_cb->wpa_ap_init = hostap_init; wpa_cb->wpa_ap_deinit = hostap_deinit; diff --git a/components/wpa_supplicant/src/rsn_supp/wpa.c b/components/wpa_supplicant/src/rsn_supp/wpa.c index 77c0f403c6..2c467a4029 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa.c +++ b/components/wpa_supplicant/src/rsn_supp/wpa.c @@ -2063,6 +2063,7 @@ bool wpa_sm_init(char * payload, WPA_SEND_FUNC snd_func, WPA_NEG_COMPLETE wpa_neg_complete) { struct wpa_sm *sm = &gWpaSm; + u16 spp_attrubute = 0; sm->eapol_version = 0x1; /* DEFAULT_EAPOL_VERSION */ sm->sendto = snd_func; @@ -2073,6 +2074,11 @@ bool wpa_sm_init(char * payload, WPA_SEND_FUNC snd_func, sm->wpa_neg_complete = wpa_neg_complete; sm->key_entry_valid = 0; sm->key_install = false; + + spp_attrubute = esp_wifi_get_spp_attrubute_internal(ESP_IF_WIFI_STA); + sm->spp_sup.capable = ((spp_attrubute & WPA_CAPABILITY_SPP_CAPABLE) ? SPP_AMSDU_CAP_ENABLE : SPP_AMSDU_CAP_DISABLE); + sm->spp_sup.require = ((spp_attrubute & WPA_CAPABILITY_SPP_REQUIRED) ? SPP_AMSDU_CAP_ENABLE : SPP_AMSDU_REQ_DISABLE); + wpa_sm_set_state(WPA_INACTIVE); sm->pmksa = pmksa_cache_init(wpa_sm_pmksa_free_cb, sm, sm); diff --git a/components/wpa_supplicant/src/rsn_supp/wpa_i.h b/components/wpa_supplicant/src/rsn_supp/wpa_i.h index e7f29abe93..8e39d7bb22 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa_i.h +++ b/components/wpa_supplicant/src/rsn_supp/wpa_i.h @@ -91,6 +91,7 @@ struct wpa_sm { bool ap_notify_completed_rsne; wifi_pmf_config_t pmf_cfg; u8 eapol1_count; + struct rsn_sppamsdu_sup spp_sup; }; /** diff --git a/components/wpa_supplicant/src/rsn_supp/wpa_ie.c b/components/wpa_supplicant/src/rsn_supp/wpa_ie.c index 76ba0ebb93..50c05cffe8 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa_ie.c +++ b/components/wpa_supplicant/src/rsn_supp/wpa_ie.c @@ -225,6 +225,15 @@ static int wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len, } } #endif /* CONFIG_IEEE80211W */ + + if (sm->spp_sup.capable) { + capab |= WPA_CAPABILITY_SPP_CAPABLE; + } + + if (sm->spp_sup.require) { + capab |= WPA_CAPABILITY_SPP_REQUIRED; + } + WPA_PUT_LE16(pos, capab); pos += 2;