diff --git a/arch/risc-v/src/esp32c3/Kconfig b/arch/risc-v/src/esp32c3/Kconfig index 2e50ab919e..5251916dba 100644 --- a/arch/risc-v/src/esp32c3/Kconfig +++ b/arch/risc-v/src/esp32c3/Kconfig @@ -755,10 +755,6 @@ config ESP32C3_WIFI_RXBA_AMPDU_WZ int "Wi-Fi RX BA AMPDU windown size" default 6 -config ESP32C3_WLAN_PKTBUF_NUM - int "WLAN netcard packet buffer number per netcard" - default 16 - config ESP32C3_WIFI_CONNECT_TIMEOUT int "Connect timeout by second" default 10 diff --git a/arch/risc-v/src/esp32c3/esp32c3_wlan.c b/arch/risc-v/src/esp32c3/esp32c3_wlan.c index 7da216ca45..7161e16cf3 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_wlan.c +++ b/arch/risc-v/src/esp32c3/esp32c3_wlan.c @@ -72,41 +72,14 @@ * Total size : 1514 */ -#define WLAN_BUF_SIZE (CONFIG_NET_ETH_PKTSIZE) - -/* WLAN packet buffer number */ - -#define WLAN_PKTBUF_NUM (CONFIG_ESP32C3_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 (WLAN_PKTBUF_NUM) > (CONFIG_IOB_BUFSIZE + 1) -# define WLAN_RX_THRESHOLD (IOBBUF_SIZE - WLAN_BUF_SIZE + 1) -# else -# define WLAN_RX_THRESHOLD (WLAN_PKTBUF_NUM - 1) * WLAN_BUF_SIZE -# endif -#endif +#define WLAN_BUF_SIZE (CONFIG_NET_ETH_PKTSIZE + \ + CONFIG_NET_LL_GUARDSIZE + \ + CONFIG_NET_GUARDSIZE) /**************************************************************************** * Private Types ****************************************************************************/ -/* WLAN packet buffer */ - -struct wlan_pktbuf_s -{ - 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_s @@ -153,21 +126,17 @@ struct wlan_priv_s struct net_driver_s dev; - /* Packet buffer cache */ - - struct wlan_pktbuf_s pktbuf[WLAN_PKTBUF_NUM]; - /* RX packet queue */ - sq_queue_t rxb; + struct iob_queue_s rxb; /* TX ready packet queue */ - sq_queue_t txb; + struct iob_queue_s txb; - /* Free packet buffer queue */ + /* Flat buffer swap */ - sq_queue_t freeb; + uint8_t flatbuf[WLAN_BUF_SIZE]; }; /**************************************************************************** @@ -281,105 +250,6 @@ static void wlan_ipv6multicast(struct wlan_priv_s *priv); * 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) -{ - int i; - irqstate_t flags; - - flags = enter_critical_section(); - - 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); - } - - leave_critical_section(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 struct wlan_pktbuf_s *wlan_alloc_buffer( - struct wlan_priv_s *priv) -{ - sq_entry_t *entry; - irqstate_t flags; - struct wlan_pktbuf_s *pktbuf = NULL; - - flags = enter_critical_section(); - - entry = sq_remfirst(&priv->freeb); - if (entry != NULL) - { - pktbuf = container_of(entry, struct wlan_pktbuf_s, entry); - } - - leave_critical_section(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_s *pktbuf; - irqstate_t flags; - - flags = enter_critical_section(); - - pktbuf = container_of(buffer, struct wlan_pktbuf_s, buffer); - sq_addlast(&pktbuf->entry, &priv->freeb); - - leave_critical_section(flags); -} - /**************************************************************************** * Function: wlan_cache_txpkt_tail * @@ -396,109 +266,8 @@ static inline void wlan_free_buffer(struct wlan_priv_s *priv, static inline void wlan_cache_txpkt_tail(struct wlan_priv_s *priv) { - struct wlan_pktbuf_s *pktbuf; - irqstate_t flags; - struct net_driver_s *dev = &priv->dev; - - pktbuf = container_of(dev->d_buf, struct wlan_pktbuf_s, buffer); - pktbuf->len = dev->d_len; - - flags = enter_critical_section(); - sq_addlast(&pktbuf->entry, &priv->txb); - leave_critical_section(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_s *pktbuf) -{ - irqstate_t flags; - - flags = enter_critical_section(); - sq_addfirst(&pktbuf->entry, &priv->txb); - leave_critical_section(flags); -} - -/**************************************************************************** - * Function: wlan_recvframe - * - * Description: - * Try to receive RX packet from RX done packet queue. - * - * Input Parameters: - * priv - Reference to the driver state structure - * - * Returned Value: - * RX packet if success or NULl if no packet in queue. - * - ****************************************************************************/ - -static struct wlan_pktbuf_s *wlan_recvframe(struct wlan_priv_s *priv) -{ - irqstate_t flags; - sq_entry_t *entry; - struct wlan_pktbuf_s *pktbuf = NULL; - - flags = enter_critical_section(); - - entry = sq_remfirst(&priv->rxb); - if (entry != NULL) - { - pktbuf = container_of(entry, struct wlan_pktbuf_s, entry); - } - - leave_critical_section(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_s *wlan_txframe(struct wlan_priv_s *priv) -{ - irqstate_t flags; - sq_entry_t *entry; - struct wlan_pktbuf_s *pktbuf = NULL; - - flags = enter_critical_section(); - - entry = sq_remfirst(&priv->txb); - if (entry != NULL) - { - pktbuf = container_of(entry, struct wlan_pktbuf_s, entry); - } - - leave_critical_section(flags); - - return pktbuf; + iob_tryadd_queue(priv->dev.d_iob, &priv->txb); + netdev_iob_clear(&priv->dev); } /**************************************************************************** @@ -518,15 +287,19 @@ static struct wlan_pktbuf_s *wlan_txframe(struct wlan_priv_s *priv) static void wlan_transmit(struct wlan_priv_s *priv) { - struct wlan_pktbuf_s *pktbuf; + uint16_t llhdrlen = NET_LL_HDRLEN(&priv->dev); + unsigned int offset = CONFIG_NET_LL_GUARDSIZE - llhdrlen; + struct iob_s *iob; int ret; - while ((pktbuf = wlan_txframe(priv)) != NULL) + while ((iob = iob_peek_queue(&priv->txb)) != NULL) { - ret = priv->ops->send(pktbuf->buffer, pktbuf->len); + 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); if (ret == -ENOMEM) { - wlan_add_txpkt_head(priv, pktbuf); wd_start(&priv->txtimeout, WLAN_TXTOUT, wlan_txtimeout_expiry, (uint32_t)priv); break; @@ -538,7 +311,11 @@ static void wlan_transmit(struct wlan_priv_s *priv) nwarn("WARN: Failed to send pkt, ret: %d\n", ret); } - wlan_free_buffer(priv, pktbuf->buffer); + iob_remove_queue(&priv->txb); + + /* And free the I/O buffer chain */ + + iob_free_chain(iob); } } } @@ -586,7 +363,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 wlan_pktbuf_s *pktbuf; + struct iob_s *iob = NULL; irqstate_t flags; int ret = 0; @@ -603,25 +380,43 @@ static int wlan_rx_done(struct wlan_priv_s *priv, void *buffer, goto out; } - pktbuf = wlan_alloc_buffer(priv); - if (pktbuf == NULL) + if (len > iob_navail(false) * CONFIG_IOB_BUFSIZE) { ret = -ENOBUFS; goto out; } - memcpy(pktbuf->buffer, buffer, len); - pktbuf->len = len; + iob = iob_tryalloc(false); + if (iob == NULL) + { + ret = -ENOBUFS; + goto out; + } + + ret = iob_trycopyin(iob, buffer, len, 0, false); + if (ret != len) + { + ret = -ENOBUFS; + goto out; + } + + iob_reserve(iob, CONFIG_NET_LL_GUARDSIZE); + + flags = enter_critical_section(); + ret = iob_tryadd_queue(iob, &priv->rxb); + leave_critical_section(flags); + + if (ret < 0) + { + ret = -ENOBUFS; + goto out; + } if (eb != NULL) { esp_wifi_free_eb(eb); } - flags = enter_critical_section(); - sq_addlast(&pktbuf->entry, &priv->rxb); - leave_critical_section(flags); - if (work_available(&priv->rxwork)) { work_queue(WLAN_WORK, &priv->rxwork, wlan_rxpoll, priv, 0); @@ -630,11 +425,18 @@ static int wlan_rx_done(struct wlan_priv_s *priv, void *buffer, return 0; out: + if (iob != NULL) + { + iob_free_chain(iob); + } + if (eb != NULL) { esp_wifi_free_eb(eb); } + wlan_txavail(&priv->dev); + return ret; } @@ -655,32 +457,25 @@ out: static void wlan_rxpoll(void *arg) { - struct wlan_pktbuf_s *pktbuf; - struct eth_hdr_s *eth_hdr; struct wlan_priv_s *priv = (struct wlan_priv_s *)arg; struct net_driver_s *dev = &priv->dev; -#ifdef WLAN_RX_THRESHOLD - uint32_t rbytes = 0; -#endif + struct eth_hdr_s *eth_hdr; + struct iob_s *iob; /* Try to send all cached TX packets for TX ack and so on */ wlan_transmit(priv); - /* Loop while while wlan_recvframe() successfully retrieves valid + /* Loop while while iob_remove_queue() successfully retrieves valid * Ethernet frames. */ net_lock(); - while ((pktbuf = wlan_recvframe(priv)) != NULL) + while ((iob = iob_remove_queue(&priv->rxb)) != NULL) { - dev->d_buf = pktbuf->buffer; - dev->d_len = pktbuf->len; - -#ifdef WLAN_RX_THRESHOLD - rbytes += pktbuf->len; -#endif + dev->d_iob = iob; + dev->d_len = iob->io_pktlen; #ifdef CONFIG_NET_PKT @@ -691,27 +486,9 @@ static void wlan_rxpoll(void *arg) pkt_input(&priv->dev); #endif - /* 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; + eth_hdr = (struct eth_hdr_s *) + &dev->d_iob->io_data[CONFIG_NET_LL_GUARDSIZE - + NET_LL_HDRLEN(dev)]; /* We only accept IP packets of the configured type and ARP packets */ @@ -786,34 +563,7 @@ static void wlan_rxpoll(void *arg) ninfo("INFO: Dropped, Unknown type: %04x\n", eth_hdr->type); } - /* 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 + netdev_iob_release(&priv->dev); } /* Try to send all cached TX packets */ @@ -845,27 +595,16 @@ static void wlan_rxpoll(void *arg) static int wlan_txpoll(struct net_driver_s *dev) { - struct wlan_pktbuf_s *pktbuf; - struct wlan_priv_s *priv = (struct wlan_priv_s *)dev->d_private; - - DEBUGASSERT(dev->d_buf != NULL); + struct wlan_priv_s *priv = dev->d_private; wlan_cache_txpkt_tail(priv); - - pktbuf = wlan_alloc_buffer(priv); - if (pktbuf == NULL) - { - return -ENOMEM; - } - - dev->d_buf = pktbuf->buffer; - dev->d_len = WLAN_BUF_SIZE; + wlan_transmit(priv); /* If zero is returned, the polling will continue until * all connections have been examined. */ - return OK; + return 1; } /**************************************************************************** @@ -890,36 +629,10 @@ 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_s *pktbuf; - uint8_t *txbuf; - int ret; - - pktbuf = wlan_alloc_buffer(priv); - if (pktbuf == NULL) - { - return ; - } - - dev->d_buf = pktbuf->buffer; - dev->d_len = WLAN_BUF_SIZE; /* Try to let TCP/IP to send all packets to netcard driver */ - do - { - txbuf = dev->d_buf; - ret = devif_poll(dev, wlan_txpoll); - } - while ((ret == 0) && - (dev->d_buf != txbuf)); - - if (dev->d_buf != NULL) - { - wlan_free_buffer(priv, dev->d_buf); - - dev->d_buf = NULL; - dev->d_len = 0; - } + while (devif_poll(dev, wlan_txpoll)); /* Try to send all cached TX packets */ @@ -1088,7 +801,11 @@ static int wlan_ifup(struct net_driver_s *dev) wlan_ipv6multicast(priv); #endif - wlan_init_buffer(priv); + 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) @@ -1141,6 +858,9 @@ 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) { diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/configs/wapi/defconfig b/boards/risc-v/esp32c3/esp32c3-devkit/configs/wapi/defconfig index fb48072532..16fb59816f 100644 --- a/boards/risc-v/esp32c3/esp32c3-devkit/configs/wapi/defconfig +++ b/boards/risc-v/esp32c3/esp32c3-devkit/configs/wapi/defconfig @@ -29,19 +29,24 @@ CONFIG_HAVE_CXXINITIALIZE=y CONFIG_IDLETHREAD_STACKSIZE=3072 CONFIG_INIT_ENTRYPOINT="nsh_main" CONFIG_INTELHEX_BINARY=y -CONFIG_LIBC_FLOATINGPOINT=y +CONFIG_IOB_NBUFFERS=124 +CONFIG_IOB_THROTTLE=24 CONFIG_LIBC_MAX_EXITFUNS=1 CONFIG_NAME_MAX=48 CONFIG_NETDB_DNSCLIENT=y CONFIG_NETDEV_LATEINIT=y CONFIG_NETDEV_PHY_IOCTL=y CONFIG_NETDEV_WIRELESS_IOCTL=y +CONFIG_NETUTILS_IPERF=y CONFIG_NET_BROADCAST=y CONFIG_NET_ETH_PKTSIZE=1514 CONFIG_NET_ICMP=y CONFIG_NET_ICMP_SOCKET=y CONFIG_NET_TCP=y +CONFIG_NET_TCP_DELAYED_ACK=y +CONFIG_NET_TCP_WRITE_BUFFERS=y CONFIG_NET_UDP=y +CONFIG_NET_UDP_WRITE_BUFFERS=y CONFIG_NSH_ARCHINIT=y CONFIG_NSH_BUILTIN_APPS=y CONFIG_NSH_FILEIOSIZE=512