mirror of
https://github.com/apache/nuttx.git
synced 2026-06-02 01:21:26 +08:00
xtensa/esp32: Optimize WLAN device buffer
This commit is contained in:
committed by
Xiang Xiao
parent
933d1a0a80
commit
eed2cce3f2
@@ -2013,6 +2013,12 @@ choice EXAMPLE_POWER_SAVE_MODE
|
|||||||
bool "maximum modem"
|
bool "maximum modem"
|
||||||
endchoice
|
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
|
endmenu # ESP32_WIFI
|
||||||
|
|
||||||
menu "BLE Configuration"
|
menu "BLE Configuration"
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
#include <nuttx/irq.h>
|
#include <nuttx/irq.h>
|
||||||
#include <nuttx/queue.h>
|
#include <nuttx/queue.h>
|
||||||
#include <nuttx/spinlock.h>
|
#include <nuttx/spinlock.h>
|
||||||
|
#include <nuttx/kmalloc.h>
|
||||||
#include <nuttx/wdog.h>
|
#include <nuttx/wdog.h>
|
||||||
#include <nuttx/wqueue.h>
|
#include <nuttx/wqueue.h>
|
||||||
#include <nuttx/net/netdev.h>
|
#include <nuttx/net/netdev.h>
|
||||||
@@ -88,12 +89,27 @@
|
|||||||
# endif
|
# endif
|
||||||
#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
|
* Private Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/* WLAN packet buffer */
|
/* 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
|
struct wlan_pktbuf
|
||||||
{
|
{
|
||||||
sq_entry_t entry; /* Queue entry */
|
sq_entry_t entry; /* Queue entry */
|
||||||
@@ -103,6 +119,7 @@ struct wlan_pktbuf
|
|||||||
uint8_t buffer[WLAN_BUF_SIZE];
|
uint8_t buffer[WLAN_BUF_SIZE];
|
||||||
uint16_t len; /* Packet data length */
|
uint16_t len; /* Packet data length */
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
/* WLAN operations */
|
/* WLAN operations */
|
||||||
|
|
||||||
@@ -152,7 +169,11 @@ struct wlan_priv_s
|
|||||||
|
|
||||||
/* Packet buffer cache */
|
/* Packet buffer cache */
|
||||||
|
|
||||||
|
#ifdef CONFIG_ESP32_WIFI_WLAN_BUFFER_OPTIMIZATION
|
||||||
|
struct wlan_pktbuf *pktbuf;
|
||||||
|
#else
|
||||||
struct wlan_pktbuf pktbuf[WLAN_PKTBUF_NUM];
|
struct wlan_pktbuf pktbuf[WLAN_PKTBUF_NUM];
|
||||||
|
#endif
|
||||||
|
|
||||||
/* RX packet queue */
|
/* RX packet queue */
|
||||||
|
|
||||||
@@ -264,6 +285,15 @@ static int wlan_ioctl(struct net_driver_s *dev, int cmd,
|
|||||||
unsigned long arg);
|
unsigned long arg);
|
||||||
#endif
|
#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
|
* 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)
|
static inline void wlan_init_buffer(struct wlan_priv_s *priv)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
irqstate_t flags;
|
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);
|
flags = spin_lock_irqsave(&priv->lock);
|
||||||
|
|
||||||
priv->dev.d_buf = NULL;
|
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);
|
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)
|
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;
|
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);
|
entry = sq_remfirst(&priv->freeb);
|
||||||
if (entry)
|
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);
|
spin_unlock_irqrestore(&priv->lock, flags);
|
||||||
|
|
||||||
|
#endif
|
||||||
return pktbuf;
|
return pktbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -366,14 +451,18 @@ static inline void wlan_free_buffer(struct wlan_priv_s *priv,
|
|||||||
uint8_t *buffer)
|
uint8_t *buffer)
|
||||||
{
|
{
|
||||||
struct wlan_pktbuf *pktbuf;
|
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);
|
pktbuf = container_of(buffer, struct wlan_pktbuf, buffer);
|
||||||
sq_addlast(&pktbuf->entry, &priv->freeb);
|
sq_addlast(&pktbuf->entry, &priv->freeb);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&priv->lock, flags);
|
spin_unlock_irqrestore(&priv->lock, flags);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -1069,14 +1158,6 @@ static int wlan_ifup(struct net_driver_s *dev)
|
|||||||
return OK;
|
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
|
#ifdef CONFIG_NET_ICMPv6
|
||||||
|
|
||||||
/* Set up IPv6 multicast address filtering */
|
/* Set up IPv6 multicast address filtering */
|
||||||
@@ -1085,6 +1166,14 @@ static int wlan_ifup(struct net_driver_s *dev)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
wlan_init_buffer(priv);
|
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;
|
priv->ifup = true;
|
||||||
if (g_callback_register_ref == 0)
|
if (g_callback_register_ref == 0)
|
||||||
@@ -1097,6 +1186,12 @@ static int wlan_ifup(struct net_driver_s *dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
++g_callback_register_ref;
|
++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();
|
net_unlock();
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
|
|||||||
Reference in New Issue
Block a user