mirror of
https://github.com/apache/nuttx.git
synced 2026-08-10 06:55:13 +00:00
esp32s3/wifi: Fix bug related to IOB off-loading with SMP
For now, IOB off-loading in the wireless driver was removed because it is not compatible with SMP-enabled devices, which is valid for ESP32-S3. The performance gain by keeping the IOB off-loading in the wireless drivers is not exceeded by keeping the flat buffer approach and enabling `CONFIG_SMP=y`.
This commit is contained in:
parent
e913828955
commit
f594859d99
2 changed files with 351 additions and 90 deletions
|
|
@ -1544,6 +1544,10 @@ config ESP32S3_WIFI_RXBA_AMPDU_WZ
|
|||
int "Wi-Fi RX BA AMPDU windown size"
|
||||
default 6
|
||||
|
||||
config ESP32S3_WLAN_PKTBUF_NUM
|
||||
int "WLAN netcard packet buffer number per netcard"
|
||||
default 16
|
||||
|
||||
config ESP_WIFI_GCMP_SUPPORT
|
||||
bool "WiFi GCMP Support(GCMP128 and GCMP256)"
|
||||
default n
|
||||
|
|
@ -2398,7 +2402,7 @@ config ESP32S3_KERNEL_IMAGE_SIZE
|
|||
|
||||
config ESP32S3_KERNEL_RAM_SIZE
|
||||
hex "Kernel Allocated RAM"
|
||||
default 0x29000
|
||||
default 0x30000
|
||||
range 0x10000 0x54700
|
||||
depends on ESP32S3_APP_FORMAT_LEGACY
|
||||
---help---
|
||||
|
|
|
|||
|
|
@ -75,14 +75,39 @@
|
|||
* Total size : 1514
|
||||
*/
|
||||
|
||||
#define WLAN_BUF_SIZE (CONFIG_NET_ETH_PKTSIZE + \
|
||||
CONFIG_NET_LL_GUARDSIZE + \
|
||||
CONFIG_NET_GUARDSIZE)
|
||||
#define WLAN_BUF_SIZE (CONFIG_NET_ETH_PKTSIZE)
|
||||
|
||||
/* WLAN packet buffer number */
|
||||
|
||||
#define WLAN_PKTBUF_NUM (CONFIG_ESP32S3_WLAN_PKTBUF_NUM)
|
||||
|
||||
/* Receive threshold which allows the receive function to trigger a scheduler
|
||||
* to activate the application if possible.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_MM_IOB
|
||||
# define IOBBUF_SIZE (CONFIG_IOB_NBUFFERS * CONFIG_IOB_BUFSIZE)
|
||||
# if (IOBBUF_SIZE) > (WLAN_BUF_SIZE + 1)
|
||||
# define WLAN_RX_THRESHOLD (IOBBUF_SIZE - WLAN_BUF_SIZE + 1)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* WLAN packet buffer */
|
||||
|
||||
struct wlan_pktbuf
|
||||
{
|
||||
sq_entry_t entry; /* Queue entry */
|
||||
|
||||
/* Packet data buffer */
|
||||
|
||||
uint8_t buffer[WLAN_BUF_SIZE];
|
||||
uint16_t len; /* Packet data length */
|
||||
};
|
||||
|
||||
/* WLAN operations */
|
||||
|
||||
struct wlan_ops
|
||||
|
|
@ -129,17 +154,23 @@ struct wlan_priv_s
|
|||
|
||||
struct net_driver_s dev;
|
||||
|
||||
/* Packet buffer cache */
|
||||
|
||||
struct wlan_pktbuf pktbuf[WLAN_PKTBUF_NUM];
|
||||
|
||||
/* RX packet queue */
|
||||
|
||||
struct iob_queue_s rxb;
|
||||
sq_queue_t rxb;
|
||||
|
||||
/* TX ready packet queue */
|
||||
|
||||
struct iob_queue_s txb;
|
||||
sq_queue_t txb;
|
||||
|
||||
/* Flat buffer swap */
|
||||
/* Free packet buffer queue */
|
||||
|
||||
uint8_t flatbuf[WLAN_BUF_SIZE];
|
||||
sq_queue_t freeb;
|
||||
|
||||
/* Device specific lock */
|
||||
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
|
@ -204,8 +235,10 @@ static const struct wlan_ops g_softap_ops =
|
|||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* Common TX logic */
|
||||
/* Common TX/RX logic */
|
||||
|
||||
static struct wlan_pktbuf *wlan_recvframe(struct wlan_priv_s *priv);
|
||||
static struct wlan_pktbuf *wlan_txframe(struct wlan_priv_s *priv);
|
||||
static void wlan_transmit(struct wlan_priv_s *priv);
|
||||
static void wlan_rxpoll(void *arg);
|
||||
static int wlan_txpoll(struct net_driver_s *dev);
|
||||
|
|
@ -251,6 +284,102 @@ static int wlan_ioctl(struct net_driver_s *dev, int cmd,
|
|||
* mutex/semaphore instead of disable interrupt, if necessary.
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
* Function: wlan_init_buffer
|
||||
*
|
||||
* Description:
|
||||
* Initialize the free buffer list
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void wlan_init_buffer(struct wlan_priv_s *priv)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
||||
int i;
|
||||
flags = spin_lock_irqsave(&priv->lock);
|
||||
|
||||
priv->dev.d_buf = NULL;
|
||||
priv->dev.d_len = 0;
|
||||
|
||||
sq_init(&priv->freeb);
|
||||
sq_init(&priv->rxb);
|
||||
sq_init(&priv->txb);
|
||||
|
||||
for (i = 0; i < WLAN_PKTBUF_NUM; i++)
|
||||
{
|
||||
sq_addlast(&priv->pktbuf[i].entry, &priv->freeb);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: wlan_alloc_buffer
|
||||
*
|
||||
* Description:
|
||||
* Allocate one buffer from the free buffer queue
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* Pointer to the allocated buffer on success; NULL on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline struct wlan_pktbuf *wlan_alloc_buffer(struct wlan_priv_s *priv)
|
||||
{
|
||||
struct wlan_pktbuf *pktbuf = NULL;
|
||||
|
||||
sq_entry_t *entry;
|
||||
irqstate_t flags = spin_lock_irqsave(&priv->lock);
|
||||
|
||||
entry = sq_remfirst(&priv->freeb);
|
||||
if (entry)
|
||||
{
|
||||
pktbuf = container_of(entry, struct wlan_pktbuf, entry);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
return pktbuf;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: wlan_free_buffer
|
||||
*
|
||||
* Description:
|
||||
* Insert a free Rx buffer into the free queue
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
* buffer - A pointer to the packet buffer to be freed
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void wlan_free_buffer(struct wlan_priv_s *priv,
|
||||
uint8_t *buffer)
|
||||
{
|
||||
struct wlan_pktbuf *pktbuf;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: wlan_cache_txpkt_tail
|
||||
*
|
||||
|
|
@ -267,12 +396,43 @@ static int wlan_ioctl(struct net_driver_s *dev, int cmd,
|
|||
|
||||
static inline void wlan_cache_txpkt_tail(struct wlan_priv_s *priv)
|
||||
{
|
||||
if (priv->dev.d_iob)
|
||||
{
|
||||
iob_tryadd_queue(priv->dev.d_iob, &priv->txb);
|
||||
}
|
||||
struct wlan_pktbuf *pktbuf;
|
||||
irqstate_t flags;
|
||||
struct net_driver_s *dev = &priv->dev;
|
||||
|
||||
netdev_iob_clear(&priv->dev);
|
||||
pktbuf = container_of(dev->d_buf, struct wlan_pktbuf, buffer);
|
||||
pktbuf->len = dev->d_len;
|
||||
|
||||
flags = spin_lock_irqsave(&priv->lock);
|
||||
sq_addlast(&pktbuf->entry, &priv->txb);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
dev->d_buf = NULL;
|
||||
dev->d_len = 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: wlan_add_txpkt_head
|
||||
*
|
||||
* Description:
|
||||
* Add packet into head of TX ready queue.
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void wlan_add_txpkt_head(struct wlan_priv_s *priv,
|
||||
struct wlan_pktbuf *pktbuf)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
||||
flags = spin_lock_irqsave(&priv->lock);
|
||||
sq_addfirst(&pktbuf->entry, &priv->txb);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -289,13 +449,56 @@ static inline void wlan_cache_txpkt_tail(struct wlan_priv_s *priv)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static struct iob_s *wlan_recvframe(struct wlan_priv_s *priv)
|
||||
static struct wlan_pktbuf *wlan_recvframe(struct wlan_priv_s *priv)
|
||||
{
|
||||
struct iob_s *iob;
|
||||
irqstate_t flags;
|
||||
sq_entry_t *entry;
|
||||
struct wlan_pktbuf *pktbuf = NULL;
|
||||
|
||||
iob = iob_remove_queue(&priv->rxb);
|
||||
flags = spin_lock_irqsave(&priv->lock);
|
||||
|
||||
return iob;
|
||||
entry = sq_remfirst(&priv->rxb);
|
||||
if (entry)
|
||||
{
|
||||
pktbuf = container_of(entry, struct wlan_pktbuf, entry);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
return pktbuf;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: wlan_txframe
|
||||
*
|
||||
* Description:
|
||||
* Try to receive TX buffer from TX ready buffer queue.
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* TX packets buffer if success or NULL if no packet in queue.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static struct wlan_pktbuf *wlan_txframe(struct wlan_priv_s *priv)
|
||||
{
|
||||
irqstate_t flags;
|
||||
sq_entry_t *entry;
|
||||
struct wlan_pktbuf *pktbuf = NULL;
|
||||
|
||||
flags = spin_lock_irqsave(&priv->lock);
|
||||
|
||||
entry = sq_remfirst(&priv->txb);
|
||||
if (entry)
|
||||
{
|
||||
pktbuf = container_of(entry, struct wlan_pktbuf, entry);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
return pktbuf;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -315,19 +518,15 @@ static struct iob_s *wlan_recvframe(struct wlan_priv_s *priv)
|
|||
|
||||
static void wlan_transmit(struct wlan_priv_s *priv)
|
||||
{
|
||||
uint16_t llhdrlen = NET_LL_HDRLEN(&priv->dev);
|
||||
unsigned int offset = CONFIG_NET_LL_GUARDSIZE - llhdrlen;
|
||||
struct iob_s *iob;
|
||||
struct wlan_pktbuf *pktbuf;
|
||||
int ret;
|
||||
|
||||
while ((iob = iob_peek_queue(&priv->txb)) != NULL)
|
||||
while ((pktbuf = wlan_txframe(priv)))
|
||||
{
|
||||
iob_copyout(priv->flatbuf + llhdrlen, iob, iob->io_pktlen, 0);
|
||||
memcpy(priv->flatbuf, iob->io_data + offset, llhdrlen);
|
||||
|
||||
ret = priv->ops->send(priv->flatbuf, iob->io_pktlen + llhdrlen);
|
||||
ret = priv->ops->send(pktbuf->buffer, pktbuf->len);
|
||||
if (ret == -ENOMEM)
|
||||
{
|
||||
wlan_add_txpkt_head(priv, pktbuf);
|
||||
wd_start(&priv->txtimeout, WLAN_TXTOUT,
|
||||
wlan_txtimeout_expiry, (uint32_t)priv);
|
||||
break;
|
||||
|
|
@ -339,11 +538,7 @@ static void wlan_transmit(struct wlan_priv_s *priv)
|
|||
nwarn("WARN: Failed to send pkt, ret: %d\n", ret);
|
||||
}
|
||||
|
||||
iob_remove_queue(&priv->txb);
|
||||
|
||||
/* And free the I/O buffer chain */
|
||||
|
||||
iob_free_chain(iob);
|
||||
wlan_free_buffer(priv, pktbuf->buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -391,8 +586,7 @@ static void wlan_tx_done(struct wlan_priv_s *priv)
|
|||
static int wlan_rx_done(struct wlan_priv_s *priv, void *buffer,
|
||||
uint16_t len, void *eb)
|
||||
{
|
||||
struct net_driver_s *dev = &priv->dev;
|
||||
struct iob_s *iob = NULL;
|
||||
struct wlan_pktbuf *pktbuf;
|
||||
irqstate_t flags;
|
||||
int ret = 0;
|
||||
|
||||
|
|
@ -409,56 +603,37 @@ static int wlan_rx_done(struct wlan_priv_s *priv, void *buffer,
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (len > iob_navail(false) * CONFIG_IOB_BUFSIZE)
|
||||
pktbuf = wlan_alloc_buffer(priv);
|
||||
if (!pktbuf)
|
||||
{
|
||||
ret = -ENOBUFS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
iob = iob_tryalloc(false);
|
||||
if (iob == NULL)
|
||||
{
|
||||
ret = -ENOBUFS;
|
||||
goto out;
|
||||
}
|
||||
memcpy(pktbuf->buffer, buffer, len);
|
||||
pktbuf->len = len;
|
||||
|
||||
iob_reserve(iob, CONFIG_NET_LL_GUARDSIZE - NET_LL_HDRLEN(dev));
|
||||
|
||||
ret = iob_trycopyin(iob, buffer, len, 0, false);
|
||||
if (ret != len)
|
||||
{
|
||||
ret = -ENOBUFS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
flags = spin_lock_irqsave(&priv->lock);
|
||||
ret = iob_tryadd_queue(iob, &priv->rxb);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
ret = -ENOBUFS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
|
||||
if (eb != NULL)
|
||||
if (eb)
|
||||
{
|
||||
esp_wifi_free_eb(eb);
|
||||
}
|
||||
|
||||
if (ret != OK && iob != NULL)
|
||||
{
|
||||
iob_free_chain(iob);
|
||||
}
|
||||
flags = spin_lock_irqsave(&priv->lock);
|
||||
sq_addlast(&pktbuf->entry, &priv->rxb);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
if (work_available(&priv->rxwork))
|
||||
{
|
||||
work_queue(WLAN_WORK, &priv->rxwork, wlan_rxpoll, priv, 0);
|
||||
}
|
||||
|
||||
wlan_txavail(&priv->dev);
|
||||
return 0;
|
||||
|
||||
out:
|
||||
if (eb)
|
||||
{
|
||||
esp_wifi_free_eb(eb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -480,27 +655,32 @@ out:
|
|||
|
||||
static void wlan_rxpoll(void *arg)
|
||||
{
|
||||
struct wlan_pktbuf *pktbuf;
|
||||
struct eth_hdr_s *eth_hdr;
|
||||
struct wlan_priv_s *priv = (struct wlan_priv_s *)arg;
|
||||
struct net_driver_s *dev = &priv->dev;
|
||||
struct eth_hdr_s *eth_hdr;
|
||||
struct iob_s *iob;
|
||||
#ifdef WLAN_RX_THRESHOLD
|
||||
uint32_t rbytes = 0;
|
||||
#endif
|
||||
|
||||
/* Try to send all cached TX packets for TX ack and so on */
|
||||
|
||||
wlan_transmit(priv);
|
||||
|
||||
/* Loop while while iob_remove_queue() successfully retrieves valid
|
||||
/* Loop while while wlan_recvframe() successfully retrieves valid
|
||||
* Ethernet frames.
|
||||
*/
|
||||
|
||||
net_lock();
|
||||
|
||||
while ((iob = wlan_recvframe(priv)) != NULL)
|
||||
while ((pktbuf = wlan_recvframe(priv)) != NULL)
|
||||
{
|
||||
dev->d_iob = iob;
|
||||
dev->d_len = iob->io_pktlen;
|
||||
dev->d_buf = pktbuf->buffer;
|
||||
dev->d_len = pktbuf->len;
|
||||
|
||||
iob_reserve(iob, CONFIG_NET_LL_GUARDSIZE);
|
||||
#ifdef WLAN_RX_THRESHOLD
|
||||
rbytes += pktbuf->len;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_PKT
|
||||
|
||||
|
|
@ -511,9 +691,27 @@ static void wlan_rxpoll(void *arg)
|
|||
pkt_input(&priv->dev);
|
||||
#endif
|
||||
|
||||
eth_hdr = (struct eth_hdr_s *)
|
||||
&dev->d_iob->io_data[CONFIG_NET_LL_GUARDSIZE -
|
||||
NET_LL_HDRLEN(dev)];
|
||||
/* Check if the packet is a valid size for the network
|
||||
* buffer configuration (this should not happen)
|
||||
*/
|
||||
|
||||
if (dev->d_len > WLAN_BUF_SIZE)
|
||||
{
|
||||
nwarn("WARNING: DROPPED Too big: %d\n", dev->d_len);
|
||||
|
||||
/* Free dropped packet buffer */
|
||||
|
||||
if (dev->d_buf)
|
||||
{
|
||||
wlan_free_buffer(priv, dev->d_buf);
|
||||
dev->d_buf = NULL;
|
||||
dev->d_len = 0;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
eth_hdr = (struct eth_hdr_s *)dev->d_buf;
|
||||
|
||||
/* We only accept IP packets of the configured type and ARP packets */
|
||||
|
||||
|
|
@ -588,7 +786,33 @@ static void wlan_rxpoll(void *arg)
|
|||
ninfo("INFO: Dropped, Unknown type: %04x\n", eth_hdr->type);
|
||||
}
|
||||
|
||||
netdev_iob_release(&priv->dev);
|
||||
/* We are finished with the RX buffer. NOTE: If the buffer is
|
||||
* re-used for transmission, the dev->d_buf field will have been
|
||||
* nullified.
|
||||
*/
|
||||
|
||||
if (dev->d_buf)
|
||||
{
|
||||
/* Free the receive packet buffer */
|
||||
|
||||
wlan_free_buffer(priv, dev->d_buf);
|
||||
dev->d_buf = NULL;
|
||||
dev->d_len = 0;
|
||||
}
|
||||
|
||||
#ifdef WLAN_RX_THRESHOLD
|
||||
/* If received total bytes is larger than receive threshold,
|
||||
* then do "unlock" to try to active applicantion to receive
|
||||
* data from low-level buffer of IP stack.
|
||||
*/
|
||||
|
||||
if (rbytes >= WLAN_RX_THRESHOLD)
|
||||
{
|
||||
net_unlock();
|
||||
rbytes = 0;
|
||||
net_lock();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Try to send all cached TX packets */
|
||||
|
|
@ -620,10 +844,25 @@ static void wlan_rxpoll(void *arg)
|
|||
|
||||
static int wlan_txpoll(struct net_driver_s *dev)
|
||||
{
|
||||
struct wlan_priv_s *priv = dev->d_private;
|
||||
struct wlan_pktbuf *pktbuf;
|
||||
struct wlan_priv_s *priv = (struct wlan_priv_s *)dev->d_private;
|
||||
|
||||
DEBUGASSERT(dev->d_buf != NULL);
|
||||
|
||||
wlan_cache_txpkt_tail(priv);
|
||||
wlan_transmit(priv);
|
||||
|
||||
pktbuf = wlan_alloc_buffer(priv);
|
||||
if (!pktbuf)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dev->d_buf = pktbuf->buffer;
|
||||
dev->d_len = WLAN_BUF_SIZE;
|
||||
|
||||
/* If zero is returned, the polling will continue until
|
||||
* all connections have been examined.
|
||||
*/
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
@ -650,10 +889,36 @@ static int wlan_txpoll(struct net_driver_s *dev)
|
|||
static void wlan_dopoll(struct wlan_priv_s *priv)
|
||||
{
|
||||
struct net_driver_s *dev = &priv->dev;
|
||||
struct wlan_pktbuf *pktbuf;
|
||||
uint8_t *txbuf;
|
||||
int ret;
|
||||
|
||||
pktbuf = wlan_alloc_buffer(priv);
|
||||
if (!pktbuf)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
dev->d_buf = pktbuf->buffer;
|
||||
dev->d_len = WLAN_BUF_SIZE;
|
||||
|
||||
/* Try to let TCP/IP to send all packets to netcard driver */
|
||||
|
||||
while (devif_poll(dev, wlan_txpoll));
|
||||
do
|
||||
{
|
||||
txbuf = dev->d_buf;
|
||||
ret = devif_poll(dev, wlan_txpoll);
|
||||
}
|
||||
while ((ret == 0) &&
|
||||
(dev->d_buf != txbuf));
|
||||
|
||||
if (dev->d_buf)
|
||||
{
|
||||
wlan_free_buffer(priv, dev->d_buf);
|
||||
|
||||
dev->d_buf = NULL;
|
||||
dev->d_len = 0;
|
||||
}
|
||||
|
||||
/* Try to send all cached TX packets */
|
||||
|
||||
|
|
@ -807,6 +1072,7 @@ static int wlan_ifup(struct net_driver_s *dev)
|
|||
return OK;
|
||||
}
|
||||
|
||||
wlan_init_buffer(priv);
|
||||
ret = priv->ops->start();
|
||||
if (ret < 0)
|
||||
{
|
||||
|
|
@ -815,12 +1081,6 @@ static int wlan_ifup(struct net_driver_s *dev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
IOB_QINIT(&priv->rxb);
|
||||
IOB_QINIT(&priv->txb);
|
||||
|
||||
priv->dev.d_buf = NULL;
|
||||
priv->dev.d_len = 0;
|
||||
|
||||
priv->ifup = true;
|
||||
if (g_callback_register_ref == 0)
|
||||
{
|
||||
|
|
@ -872,9 +1132,6 @@ static int wlan_ifdown(struct net_driver_s *dev)
|
|||
|
||||
priv->ifup = false;
|
||||
|
||||
iob_free_queue(&priv->rxb);
|
||||
iob_free_queue(&priv->txb);
|
||||
|
||||
ret = priv->ops->stop();
|
||||
if (ret < 0)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue