Skip to content

Commit

Permalink
usbus/cdc_ecm: Make use of URBs for inbound frames
Browse files Browse the repository at this point in the history
  • Loading branch information
bergzand committed Feb 27, 2023
1 parent 7bfdd73 commit ba88608
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 23 deletions.
1 change: 1 addition & 0 deletions sys/Makefile.dep
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 11 additions & 2 deletions sys/include/usb/usbus/cdc/ecm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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;

/**
Expand Down
32 changes: 13 additions & 19 deletions sys/usb/usbus/cdc/ecm/cdc_ecm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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,
Expand All @@ -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);
Expand All @@ -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);
}
Expand Down
4 changes: 2 additions & 2 deletions sys/usb/usbus/cdc/ecm/cdc_ecm_netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
Expand Down

0 comments on commit ba88608

Please sign in to comment.