You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2023/01/07 05:46:43 UTC
[nuttx] branch master updated: xtensa/esp32: Optimize WLAN device buffer
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new eed2cce3f2 xtensa/esp32: Optimize WLAN device buffer
eed2cce3f2 is described below
commit eed2cce3f220b27d12d0484de9e17291030da135
Author: chenwen@espressif.com <ch...@espressif.com>
AuthorDate: Tue Dec 6 17:44:09 2022 +0800
xtensa/esp32: Optimize WLAN device buffer
---
arch/xtensa/src/esp32/Kconfig | 6 ++
arch/xtensa/src/esp32/esp32_wlan.c | 123 ++++++++++++++++++++++++++++++++-----
2 files changed, 115 insertions(+), 14 deletions(-)
diff --git a/arch/xtensa/src/esp32/Kconfig b/arch/xtensa/src/esp32/Kconfig
index 5cedaeb664..725f560a4b 100644
--- a/arch/xtensa/src/esp32/Kconfig
+++ b/arch/xtensa/src/esp32/Kconfig
@@ -2013,6 +2013,12 @@ choice EXAMPLE_POWER_SAVE_MODE
bool "maximum modem"
endchoice
+config ESP32_WIFI_WLAN_BUFFER_OPTIMIZATION
+ bool "Enable optimization of WLAN driver buffer"
+ default n
+ ---help---
+ Enable optimization of WLAN memory
+
endmenu # ESP32_WIFI
menu "BLE Configuration"
diff --git a/arch/xtensa/src/esp32/esp32_wlan.c b/arch/xtensa/src/esp32/esp32_wlan.c
index 5450b9147b..b6d9af714c 100644
--- a/arch/xtensa/src/esp32/esp32_wlan.c
+++ b/arch/xtensa/src/esp32/esp32_wlan.c
@@ -37,6 +37,7 @@
#include <nuttx/irq.h>
#include <nuttx/queue.h>
#include <nuttx/spinlock.h>
+#include <nuttx/kmalloc.h>
#include <nuttx/wdog.h>
#include <nuttx/wqueue.h>
#include <nuttx/net/netdev.h>
@@ -88,12 +89,27 @@
# endif
#endif
+#ifdef CONFIG_ESP32_WIFI_WLAN_BUFFER_OPTIMIZATION
+
+/* The smallest available heap is to ensure that Wi-Fi is not disconnected */
+
+# define MINIMUM_HEAP_SIZE (6000)
+#endif
+
/****************************************************************************
* Private Types
****************************************************************************/
/* WLAN packet buffer */
+#ifdef CONFIG_ESP32_WIFI_WLAN_BUFFER_OPTIMIZATION
+struct wlan_pktbuf
+{
+ sq_entry_t entry; /* Queue entry */
+ uint16_t len; /* Packet data length */
+ uint8_t buffer[0]; /* Packet data */
+};
+#else
struct wlan_pktbuf
{
sq_entry_t entry; /* Queue entry */
@@ -103,6 +119,7 @@ struct wlan_pktbuf
uint8_t buffer[WLAN_BUF_SIZE];
uint16_t len; /* Packet data length */
};
+#endif
/* WLAN operations */
@@ -152,7 +169,11 @@ struct wlan_priv_s
/* Packet buffer cache */
+#ifdef CONFIG_ESP32_WIFI_WLAN_BUFFER_OPTIMIZATION
+ struct wlan_pktbuf *pktbuf;
+#else
struct wlan_pktbuf pktbuf[WLAN_PKTBUF_NUM];
+#endif
/* RX packet queue */
@@ -264,6 +285,15 @@ static int wlan_ioctl(struct net_driver_s *dev, int cmd,
unsigned long arg);
#endif
+#ifdef CONFIG_NET_ICMPv6
+static void wlan_ipv6multicast(struct wlan_priv_s *priv);
+#endif
+
+static struct wlan_pktbuf *wlan_recvframe(FAR struct wlan_priv_s *priv);
+static struct wlan_pktbuf *wlan_txframe(FAR struct wlan_priv_s *priv);
+static inline void wlan_free_buffer(struct wlan_priv_s *priv,
+ uint8_t *buffer);
+
/****************************************************************************
* Private Functions
****************************************************************************/
@@ -294,9 +324,20 @@ static int wlan_ioctl(struct net_driver_s *dev, int cmd,
static inline void wlan_init_buffer(struct wlan_priv_s *priv)
{
- int i;
irqstate_t flags;
+#ifdef CONFIG_ESP32_WIFI_WLAN_BUFFER_OPTIMIZATION
+ flags = spin_lock_irqsave(&priv->lock);
+
+ priv->dev.d_buf = NULL;
+ priv->dev.d_len = 0;
+
+ sq_init(&priv->rxb);
+ sq_init(&priv->txb);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+#else
+ int i;
flags = spin_lock_irqsave(&priv->lock);
priv->dev.d_buf = NULL;
@@ -312,6 +353,40 @@ static inline void wlan_init_buffer(struct wlan_priv_s *priv)
}
spin_unlock_irqrestore(&priv->lock, flags);
+#endif
+}
+
+/****************************************************************************
+ * Function: wlan_deinit_buffer
+ *
+ * Description:
+ * De-initialize the buffer list
+ *
+ * Input Parameters:
+ * priv - Reference to the driver state structure
+ *
+ * Returned Value:
+ * None.
+ *
+ ****************************************************************************/
+
+static inline void wlan_deinit_buffer(struct wlan_priv_s *priv)
+{
+#ifdef CONFIG_ESP32_WIFI_WLAN_BUFFER_OPTIMIZATION
+ struct wlan_pktbuf *pktbuf;
+ while ((pktbuf = (struct wlan_pktbuf *)wlan_recvframe(priv)) != NULL)
+ {
+ wlan_free_buffer(priv, (void *)pktbuf->buffer);
+ }
+
+ while ((pktbuf = (struct wlan_pktbuf *)wlan_txframe(priv)) != NULL)
+ {
+ wlan_free_buffer(priv, (void *)pktbuf->buffer);
+ }
+
+ sq_init(&priv->rxb);
+ sq_init(&priv->txb);
+#endif
}
/****************************************************************************
@@ -330,11 +405,20 @@ static inline void wlan_init_buffer(struct wlan_priv_s *priv)
static inline struct wlan_pktbuf *wlan_alloc_buffer(struct wlan_priv_s *priv)
{
- sq_entry_t *entry;
- irqstate_t flags;
struct wlan_pktbuf *pktbuf = NULL;
- flags = spin_lock_irqsave(&priv->lock);
+#ifdef CONFIG_ESP32_WIFI_WLAN_BUFFER_OPTIMIZATION
+ struct mallinfo info = kmm_mallinfo();
+ if (info.fordblks < MINIMUM_HEAP_SIZE)
+ {
+ return NULL;
+ }
+
+ pktbuf = (struct wlan_pktbuf *)kmm_malloc(
+ sizeof(struct wlan_pktbuf) + WLAN_BUF_SIZE);
+#else
+ sq_entry_t *entry;
+ irqstate_t flags = spin_lock_irqsave(&priv->lock);
entry = sq_remfirst(&priv->freeb);
if (entry)
@@ -344,6 +428,7 @@ static inline struct wlan_pktbuf *wlan_alloc_buffer(struct wlan_priv_s *priv)
spin_unlock_irqrestore(&priv->lock, flags);
+#endif
return pktbuf;
}
@@ -366,14 +451,18 @@ static inline void wlan_free_buffer(struct wlan_priv_s *priv,
uint8_t *buffer)
{
struct wlan_pktbuf *pktbuf;
- irqstate_t flags;
- flags = spin_lock_irqsave(&priv->lock);
+#ifdef CONFIG_ESP32_WIFI_WLAN_BUFFER_OPTIMIZATION
+ pktbuf = container_of(buffer, struct wlan_pktbuf, buffer);
+ kmm_free(pktbuf);
+#else
+ irqstate_t flags = spin_lock_irqsave(&priv->lock);
pktbuf = container_of(buffer, struct wlan_pktbuf, buffer);
sq_addlast(&pktbuf->entry, &priv->freeb);
spin_unlock_irqrestore(&priv->lock, flags);
+#endif
}
/****************************************************************************
@@ -1069,14 +1158,6 @@ static int wlan_ifup(struct net_driver_s *dev)
return OK;
}
- ret = priv->ops->start();
- if (ret < 0)
- {
- net_unlock();
- nerr("ERROR: Failed to start Wi-Fi ret=%d\n", ret);
- return ret;
- }
-
#ifdef CONFIG_NET_ICMPv6
/* Set up IPv6 multicast address filtering */
@@ -1085,6 +1166,14 @@ static int wlan_ifup(struct net_driver_s *dev)
#endif
wlan_init_buffer(priv);
+ ret = priv->ops->start();
+ if (ret < 0)
+ {
+ wlan_deinit_buffer(priv);
+ net_unlock();
+ nerr("ERROR: Failed to start Wi-Fi ret=%d\n", ret);
+ return ret;
+ }
priv->ifup = true;
if (g_callback_register_ref == 0)
@@ -1097,6 +1186,12 @@ static int wlan_ifup(struct net_driver_s *dev)
}
++g_callback_register_ref;
+
+ /* We can make sure that the WLAN TX and RX are not doing, because
+ * the process is in "net_lock()"
+ */
+
+ wlan_deinit_buffer(priv);
net_unlock();
return OK;