Jelajahi Sumber

feature: support tx amsdu

ronghulin 5 tahun lalu
induk
melakukan
adfa43a3a4

+ 7 - 0
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

+ 14 - 0
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

+ 8 - 0
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,\

+ 1 - 1
components/esp_wifi/lib

@@ -1 +1 @@
-Subproject commit 8017558a14d29ce5f7fa8631afdecad3e86b2a93
+Subproject commit 22a92a009e4107341665ad307e4dd3c605ae31b3

+ 1 - 0
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 {

+ 1 - 0
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;
 };
 
 

+ 21 - 0
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)) {

+ 4 - 0
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,

+ 7 - 0
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,

+ 5 - 0
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);

+ 2 - 0
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);

+ 13 - 0
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;
 

+ 6 - 0
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);

+ 1 - 0
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;
 };
 
 /**

+ 9 - 0
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;