From ba88608749285d597ff9229a3b638e792f962705 Mon Sep 17 00:00:00 2001 From: Koen Zandberg Date: Sun, 31 Oct 2021 21:40:09 +0100 Subject: [PATCH] usbus/cdc_ecm: Make use of URBs for inbound frames --- sys/Makefile.dep | 1 + sys/include/usb/usbus/cdc/ecm.h | 13 +++++++++-- sys/usb/usbus/cdc/ecm/cdc_ecm.c | 32 +++++++++++--------------- sys/usb/usbus/cdc/ecm/cdc_ecm_netdev.c | 4 ++-- 4 files changed, 27 insertions(+), 23 deletions(-) diff --git a/sys/Makefile.dep b/sys/Makefile.dep index 0928893a5c63..1a781b7eba0a 100644 --- a/sys/Makefile.dep +++ b/sys/Makefile.dep @@ -831,6 +831,7 @@ ifneq (,$(filter usbus_cdc_ecm,$(USEMODULE))) USEMODULE += iolist USEMODULE += fmt USEMODULE += usbus + USEMODULE += usbus_urb USEMODULE += netdev_eth USEMODULE += luid endif diff --git a/sys/include/usb/usbus/cdc/ecm.h b/sys/include/usb/usbus/cdc/ecm.h index f117a32271d0..7ceb9293972c 100644 --- a/sys/include/usb/usbus/cdc/ecm.h +++ b/sys/include/usb/usbus/cdc/ecm.h @@ -29,6 +29,7 @@ #include "usb/descriptor.h" #include "usb/usbus.h" #include "usb/usbus/control.h" +#include "macros/math.h" #include "net/netdev.h" #include "mutex.h" @@ -77,6 +78,11 @@ extern "C" { */ #define USBUS_CDCECM_EP_DATA_SIZE 64 +/** + * @brief Full ethernet frame rounded up to a whole number of transfers + */ +#define USBUS_ETHERNET_FRAME_BUF MATH_ALIGN(ETHERNET_FRAME_LEN, USBUS_CDCECM_EP_DATA_SIZE) + /** * @brief notification state, used to track which information must be send to * the host @@ -108,14 +114,13 @@ typedef struct usbus_cdcecm_device { usbus_t *usbus; /**< Ptr to the USBUS context */ mutex_t out_lock; /**< mutex used for locking netif/USBUS send */ size_t tx_len; /**< Length of the current tx frame */ - size_t len; /**< Length of the current rx frame */ usbus_cdcecm_notif_t notif; /**< Startup message notification tracker */ unsigned active_iface; /**< Current active data interface */ /** * @brief Buffer for received frames from the host */ - usbdev_ep_buf_t data_out[ETHERNET_FRAME_LEN]; + usbdev_ep_buf_t data_out[USBUS_ETHERNET_FRAME_BUF]; /** * @brief Host in device out data buffer @@ -126,6 +131,10 @@ typedef struct usbus_cdcecm_device { * @brief Host out device in control buffer */ usbdev_ep_buf_t control_in[USBUS_CDCECM_EP_CTRL_SIZE]; + /** + * @brief Host out device in reception URB + */ + usbus_urb_t out_urb; } usbus_cdcecm_device_t; /** diff --git a/sys/usb/usbus/cdc/ecm/cdc_ecm.c b/sys/usb/usbus/cdc/ecm/cdc_ecm.c index d9504ba27a31..e9374add8017 100644 --- a/sys/usb/usbus/cdc/ecm/cdc_ecm.c +++ b/sys/usb/usbus/cdc/ecm/cdc_ecm.c @@ -162,6 +162,14 @@ static void _fill_ethernet(usbus_cdcecm_device_t *cdcecm) } +void _start_urb(usbus_cdcecm_device_t *cdcecm) +{ + usbus_urb_init(&cdcecm->out_urb, + cdcecm->data_out, + USBUS_ETHERNET_FRAME_BUF, 0); + usbus_urb_submit(cdcecm->usbus, cdcecm->ep_out, &cdcecm->out_urb); +} + void usbus_cdcecm_init(usbus_t *usbus, usbus_cdcecm_device_t *handler) { assert(usbus); @@ -251,9 +259,9 @@ static int _control_handler(usbus_t *usbus, usbus_handler_t *handler, setup->value); cdcecm->active_iface = (uint8_t)setup->value; if (cdcecm->active_iface == 1) { - usbdev_ep_xmit(cdcecm->ep_out->ep, cdcecm->data_out, - USBUS_CDCECM_EP_DATA_SIZE); _notify_link_up(cdcecm); + /* Start URB */ + _start_urb(cdcecm); } break; @@ -298,8 +306,8 @@ static void _handle_rx_flush_ev(event_t *ev) { usbus_cdcecm_device_t *cdcecm = container_of(ev, usbus_cdcecm_device_t, rx_flush); - cdcecm->len = 0; /* Flush packet */ - usbdev_ep_xmit(cdcecm->ep_out->ep, cdcecm->data_out, USBUS_CDCECM_EP_DATA_SIZE); + /* Start URB */ + _start_urb(cdcecm); } static void _transfer_handler(usbus_t *usbus, usbus_handler_t *handler, @@ -310,20 +318,7 @@ static void _transfer_handler(usbus_t *usbus, usbus_handler_t *handler, usbus_cdcecm_device_t *cdcecm = (usbus_cdcecm_device_t *)handler; if (ep == cdcecm->ep_out->ep) { /* Retrieve incoming data */ - if (cdcecm->notif == USBUS_CDCECM_NOTIF_NONE) { - _notify_link_up(cdcecm); - } - size_t len = 0; - usbdev_ep_get(ep, USBOPT_EP_AVAILABLE, &len, sizeof(size_t)); - cdcecm->len += len; - if (len == USBUS_CDCECM_EP_DATA_SIZE) { - /* ready next chunk */ - usbdev_ep_xmit(ep, cdcecm->data_out + cdcecm->len, - USBUS_CDCECM_EP_DATA_SIZE); - } - else { - netdev_trigger_event_isr(&cdcecm->netdev); - } + netdev_trigger_event_isr(&cdcecm->netdev); } else if (ep == cdcecm->ep_in->ep) { _handle_in_complete(usbus, handler); @@ -341,7 +336,6 @@ static void _handle_reset(usbus_t *usbus, usbus_handler_t *handler) DEBUG("CDC ECM: Reset\n"); _handle_in_complete(usbus, handler); cdcecm->notif = USBUS_CDCECM_NOTIF_NONE; - cdcecm->len = 0; /* Flush received data */ cdcecm->active_iface = 0; mutex_unlock(&cdcecm->out_lock); } diff --git a/sys/usb/usbus/cdc/ecm/cdc_ecm_netdev.c b/sys/usb/usbus/cdc/ecm/cdc_ecm_netdev.c index 906ab9f2d034..5cdfdc2c40c2 100644 --- a/sys/usb/usbus/cdc/ecm/cdc_ecm_netdev.c +++ b/sys/usb/usbus/cdc/ecm/cdc_ecm_netdev.c @@ -132,7 +132,7 @@ static int _recv(netdev_t *netdev, void *buf, size_t max_len, void *info) (void)info; usbus_cdcecm_device_t *cdcecm = _netdev_to_cdcecm(netdev); - size_t pktlen = cdcecm->len; + size_t pktlen = cdcecm->out_urb.transferred; if (max_len == 0 && buf == NULL) { return pktlen; @@ -198,7 +198,7 @@ static void _isr(netdev_t *dev) { usbus_cdcecm_device_t *cdcecm = _netdev_to_cdcecm(dev); - if (cdcecm->len) { + if (cdcecm->out_urb.transferred) { cdcecm->netdev.event_callback(&cdcecm->netdev, NETDEV_EVENT_RX_COMPLETE); }