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;