cdcncm: switch net driver to netdev_lowerhalf
optimize the interaction flow associated with network drivers to reduce the amount of code and improve compatibility Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
This commit is contained in:
parent
4e79741e7d
commit
7aa3e2ebd6
@ -1389,6 +1389,15 @@ config CDCNCM_PRODUCTSTR
|
|||||||
default "CDC/NCM Ethernet"
|
default "CDC/NCM Ethernet"
|
||||||
|
|
||||||
endif # !CDCNCM_COMPOSITE
|
endif # !CDCNCM_COMPOSITE
|
||||||
|
|
||||||
|
config CDCNCM_QUOTA_TX
|
||||||
|
int "The drive holds the maximum quota of TX"
|
||||||
|
default 8
|
||||||
|
|
||||||
|
config CDCNCM_QUOTA_RX
|
||||||
|
int "The drive holds the maximum quota of RX"
|
||||||
|
default 8
|
||||||
|
|
||||||
endif # CDCNCM
|
endif # CDCNCM
|
||||||
|
|
||||||
config USBDEV_FS
|
config USBDEV_FS
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
|
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@ -37,24 +36,15 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#include <nuttx/arch.h>
|
|
||||||
#include <nuttx/irq.h>
|
|
||||||
#include <nuttx/kmalloc.h>
|
#include <nuttx/kmalloc.h>
|
||||||
#include <nuttx/net/ip.h>
|
#include <nuttx/net/netdev_lowerhalf.h>
|
||||||
#include <nuttx/net/netdev.h>
|
|
||||||
#include <nuttx/semaphore.h>
|
|
||||||
#include <nuttx/usb/cdc.h>
|
#include <nuttx/usb/cdc.h>
|
||||||
#include <nuttx/usb/cdcncm.h>
|
#include <nuttx/usb/cdcncm.h>
|
||||||
#include <nuttx/usb/usbdev.h>
|
#include <nuttx/usb/usbdev.h>
|
||||||
#include <nuttx/usb/usbdev_trace.h>
|
#include <nuttx/usb/usbdev_trace.h>
|
||||||
#include <nuttx/wqueue.h>
|
#include <nuttx/wqueue.h>
|
||||||
|
|
||||||
#ifdef CONFIG_NET_PKT
|
|
||||||
# include <nuttx/net/pkt.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_BOARD_USBDEV_SERIALSTR
|
#ifdef CONFIG_BOARD_USBDEV_SERIALSTR
|
||||||
# include <nuttx/board.h>
|
# include <nuttx/board.h>
|
||||||
#endif
|
#endif
|
||||||
@ -88,10 +78,6 @@
|
|||||||
#define CDCNCM_TXTIMEOUT (60*CLK_TCK)
|
#define CDCNCM_TXTIMEOUT (60*CLK_TCK)
|
||||||
#define CDCNCM_DGRAM_COMBINE_PERIOD 1
|
#define CDCNCM_DGRAM_COMBINE_PERIOD 1
|
||||||
|
|
||||||
/* This is a helper pointer for accessing the contents of Ethernet header */
|
|
||||||
|
|
||||||
#define BUF ((FAR struct eth_hdr_s *)self->dev.d_buf)
|
|
||||||
|
|
||||||
#define NTB_DEFAULT_IN_SIZE 16384
|
#define NTB_DEFAULT_IN_SIZE 16384
|
||||||
#define NTB_OUT_SIZE 16384
|
#define NTB_OUT_SIZE 16384
|
||||||
#define TX_MAX_NUM_DPE 32
|
#define TX_MAX_NUM_DPE 32
|
||||||
@ -304,9 +290,6 @@ struct cdcncm_driver_s
|
|||||||
FAR struct usbdev_ep_s *epbulkout; /* Bulk OUT endpoint */
|
FAR struct usbdev_ep_s *epbulkout; /* Bulk OUT endpoint */
|
||||||
uint8_t config; /* Selected configuration number */
|
uint8_t config; /* Selected configuration number */
|
||||||
|
|
||||||
uint16_t pktbuf[(CONFIG_NET_ETH_PKTSIZE +
|
|
||||||
CONFIG_NET_GUARDSIZE + 1) / 2];
|
|
||||||
|
|
||||||
FAR struct usbdev_req_s *rdreq; /* Single read request */
|
FAR struct usbdev_req_s *rdreq; /* Single read request */
|
||||||
bool rxpending; /* Packet available in rdreq */
|
bool rxpending; /* Packet available in rdreq */
|
||||||
|
|
||||||
@ -327,15 +310,14 @@ struct cdcncm_driver_s
|
|||||||
* to the work queue */
|
* to the work queue */
|
||||||
struct work_s notifywork; /* For deferring notify work
|
struct work_s notifywork; /* For deferring notify work
|
||||||
* to the work queue */
|
* to the work queue */
|
||||||
struct work_s pollwork; /* For deferring poll work to
|
|
||||||
* the work queue */
|
|
||||||
struct work_s delaywork; /* For deferring tx work
|
struct work_s delaywork; /* For deferring tx work
|
||||||
* to the work queue */
|
* to the work queue */
|
||||||
|
|
||||||
/* This holds the information visible to the NuttX network */
|
/* This holds the information visible to the NuttX network */
|
||||||
|
|
||||||
struct net_driver_s dev; /* Interface understood by the
|
struct netdev_lowerhalf_s dev; /* Interface understood by the
|
||||||
* network */
|
* network */
|
||||||
|
netpkt_queue_t rx_queue; /* RX packet queue */
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -344,14 +326,8 @@ struct cdcncm_driver_s
|
|||||||
|
|
||||||
/* Network Device ***********************************************************/
|
/* Network Device ***********************************************************/
|
||||||
|
|
||||||
/* Common TX logic */
|
|
||||||
|
|
||||||
static int cdcncm_transmit(FAR struct cdcncm_driver_s *priv);
|
|
||||||
static int cdcncm_txpoll(FAR struct net_driver_s *dev);
|
|
||||||
|
|
||||||
/* Interrupt handling */
|
/* Interrupt handling */
|
||||||
|
|
||||||
static void cdcncm_reply(FAR struct cdcncm_driver_s *priv);
|
|
||||||
static void cdcncm_receive(FAR struct cdcncm_driver_s *priv);
|
static void cdcncm_receive(FAR struct cdcncm_driver_s *priv);
|
||||||
static void cdcncm_txdone(FAR struct cdcncm_driver_s *priv);
|
static void cdcncm_txdone(FAR struct cdcncm_driver_s *priv);
|
||||||
|
|
||||||
@ -359,22 +335,21 @@ static void cdcncm_interrupt_work(FAR void *arg);
|
|||||||
|
|
||||||
/* NuttX callback functions */
|
/* NuttX callback functions */
|
||||||
|
|
||||||
static int cdcncm_ifup(FAR struct net_driver_s *dev);
|
static int cdcncm_ifup(FAR struct netdev_lowerhalf_s *dev);
|
||||||
static int cdcncm_ifdown(FAR struct net_driver_s *dev);
|
static int cdcncm_ifdown(FAR struct netdev_lowerhalf_s *dev);
|
||||||
|
static int cdcncm_send(struct netdev_lowerhalf_s *dev, netpkt_t *pkt);
|
||||||
static void cdcncm_txavail_work(FAR void *arg);
|
static FAR netpkt_t *cdcncm_recv(FAR struct netdev_lowerhalf_s *dev);
|
||||||
static int cdcncm_txavail(FAR struct net_driver_s *dev);
|
|
||||||
|
|
||||||
#if defined(CONFIG_NET_MCASTGROUP) || defined(CONFIG_NET_ICMPv6)
|
#if defined(CONFIG_NET_MCASTGROUP) || defined(CONFIG_NET_ICMPv6)
|
||||||
static int cdcncm_addmac(FAR struct net_driver_s *dev,
|
static int cdcncm_addmac(FAR struct netdev_lowerhalf_s *dev,
|
||||||
FAR const uint8_t *mac);
|
FAR const uint8_t *mac);
|
||||||
#ifdef CONFIG_NET_MCASTGROUP
|
#ifdef CONFIG_NET_MCASTGROUP
|
||||||
static int cdcncm_rmmac(FAR struct net_driver_s *dev,
|
static int cdcncm_rmmac(FAR struct netdev_lowerhalf_s *dev,
|
||||||
FAR const uint8_t *mac);
|
FAR const uint8_t *mac);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_NETDEV_IOCTL
|
#ifdef CONFIG_NETDEV_IOCTL
|
||||||
static int cdcncm_ioctl(FAR struct net_driver_s *dev, int cmd,
|
static int cdcncm_ioctl(FAR struct netdev_lowerhalf_s *dev, int cmd,
|
||||||
unsigned long arg);
|
unsigned long arg);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -475,6 +450,21 @@ static const struct usb_cdc_ncm_ntb_parameters_s g_ntbparameters =
|
|||||||
.ndpoutalignment = 4,
|
.ndpoutalignment = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct netdev_ops_s g_netops =
|
||||||
|
{
|
||||||
|
cdcncm_ifup, /* ifup */
|
||||||
|
cdcncm_ifdown, /* ifdown */
|
||||||
|
cdcncm_send, /* transmit */
|
||||||
|
cdcncm_recv, /* receive */
|
||||||
|
#ifdef CONFIG_NET_MCASTGROUP
|
||||||
|
cdcncm_addmac, /* addmac */
|
||||||
|
cdcncm_rmmac, /* rmmac */
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_NETDEV_IOCTL
|
||||||
|
cdcncm_ioctl, /* ioctl */
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Inline Functions
|
* Inline Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -558,22 +548,24 @@ void cdcncm_put(FAR uint8_t **address, size_t size, uint32_t value)
|
|||||||
* Name: cdcncm_transmit_format
|
* Name: cdcncm_transmit_format
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Format the data to be sent
|
* Format the data to be transmitted to the host in the format specified by
|
||||||
|
* the NCM protocol (Network Control Model) and the NCM NTB (Network
|
||||||
|
* Transfer Block) format.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* self - Reference to the driver state structure
|
* self - Reference to the driver state structure
|
||||||
|
* pkt - Reference to the packet to be transmitted
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
* Assumptions:
|
|
||||||
* The network is locked.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static void cdcncm_transmit_format(FAR struct cdcncm_driver_s *self)
|
static void cdcncm_transmit_format(FAR struct cdcncm_driver_s *self,
|
||||||
|
FAR netpkt_t *pkt)
|
||||||
{
|
{
|
||||||
FAR const struct ndp_parser_opts_s *opts = self->parseropts;
|
FAR const struct ndp_parser_opts_s *opts = self->parseropts;
|
||||||
|
unsigned int dglen = netpkt_getdatalen(&self->dev, pkt);
|
||||||
const int div = g_ntbparameters.ndpindivisor;
|
const int div = g_ntbparameters.ndpindivisor;
|
||||||
const int rem = g_ntbparameters.ndpinpayloadremainder;
|
const int rem = g_ntbparameters.ndpinpayloadremainder;
|
||||||
const int dgramidxlen = 2 * opts->dgramitemlen;
|
const int dgramidxlen = 2 * opts->dgramitemlen;
|
||||||
@ -612,12 +604,13 @@ static void cdcncm_transmit_format(FAR struct cdcncm_driver_s *self)
|
|||||||
tmp = self->wrreq->buf + ndpindex + opts->ndpsize +
|
tmp = self->wrreq->buf + ndpindex + opts->ndpsize +
|
||||||
self->dgramcount * dgramidxlen;
|
self->dgramcount * dgramidxlen;
|
||||||
cdcncm_put(&tmp, opts->dgramitemlen, self->dgramaddr - self->wrreq->buf);
|
cdcncm_put(&tmp, opts->dgramitemlen, self->dgramaddr - self->wrreq->buf);
|
||||||
cdcncm_put(&tmp, opts->dgramitemlen, self->dev.d_len);
|
cdcncm_put(&tmp, opts->dgramitemlen, dglen);
|
||||||
|
|
||||||
/* Fill IP packet: address=self->dev.d_buf, length=self->dev.d_len */
|
/* Fill IP packet */
|
||||||
|
|
||||||
memcpy(self->dgramaddr, self->dev.d_buf, self->dev.d_len);
|
netpkt_copyout(&self->dev, self->dgramaddr, pkt, dglen, 0);
|
||||||
self->dgramaddr += self->dev.d_len;
|
|
||||||
|
self->dgramaddr += dglen;
|
||||||
self->dgramaddr = (FAR uint8_t *)NCM_ALIGN((uintptr_t)self->dgramaddr,
|
self->dgramaddr = (FAR uint8_t *)NCM_ALIGN((uintptr_t)self->dgramaddr,
|
||||||
div) + rem;
|
div) + rem;
|
||||||
|
|
||||||
@ -657,8 +650,6 @@ static void cdcncm_transmit_work(FAR void *arg)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
net_lock();
|
|
||||||
|
|
||||||
ncblen = opts->nthsize;
|
ncblen = opts->nthsize;
|
||||||
ndpindex = NCM_ALIGN(ncblen, ndpalign);
|
ndpindex = NCM_ALIGN(ncblen, ndpalign);
|
||||||
|
|
||||||
@ -683,122 +674,6 @@ static void cdcncm_transmit_work(FAR void *arg)
|
|||||||
self->wrreq->len = totallen;
|
self->wrreq->len = totallen;
|
||||||
|
|
||||||
EP_SUBMIT(self->epbulkin, self->wrreq);
|
EP_SUBMIT(self->epbulkin, self->wrreq);
|
||||||
|
|
||||||
net_unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: cdcncm_transmit
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Start hardware transmission. Called either from the txdone interrupt
|
|
||||||
* handling or from watchdog based polling
|
|
||||||
*
|
|
||||||
* Input Parameters:
|
|
||||||
* priv - Reference to the driver state structure
|
|
||||||
*
|
|
||||||
* Returned Value:
|
|
||||||
* OK on success; a negated errno on failure
|
|
||||||
*
|
|
||||||
* Assumptions:
|
|
||||||
* The network is locked.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
static int cdcncm_transmit(FAR struct cdcncm_driver_s *self)
|
|
||||||
{
|
|
||||||
/* Increment statistics */
|
|
||||||
|
|
||||||
NETDEV_TXPACKETS(self->dev);
|
|
||||||
|
|
||||||
cdcncm_transmit_format(self);
|
|
||||||
|
|
||||||
if ((self->wrreq->buf + NTB_OUT_SIZE - self->dgramaddr <
|
|
||||||
self->dev.d_pktsize) || self->dgramcount >= TX_MAX_NUM_DPE)
|
|
||||||
{
|
|
||||||
work_cancel(ETHWORK, &self->delaywork);
|
|
||||||
cdcncm_transmit_work(self);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
work_queue(ETHWORK, &self->delaywork, cdcncm_transmit_work, self,
|
|
||||||
MSEC2TICK(CDCNCM_DGRAM_COMBINE_PERIOD));
|
|
||||||
}
|
|
||||||
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: cdcncm_txpoll
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* The transmitter is available, check if the network has any outgoing
|
|
||||||
* packets ready to send. This is a callback from devif_poll().
|
|
||||||
* devif_poll() may be called:
|
|
||||||
*
|
|
||||||
* 1. When the preceding TX packet send is complete,
|
|
||||||
* 2. When the preceding TX packet send times out and the interface is
|
|
||||||
* reset
|
|
||||||
* 3. During normal TX polling
|
|
||||||
*
|
|
||||||
* Input Parameters:
|
|
||||||
* dev - Reference to the NuttX driver state structure
|
|
||||||
*
|
|
||||||
* Returned Value:
|
|
||||||
* OK on success; a negated errno on failure
|
|
||||||
*
|
|
||||||
* Assumptions:
|
|
||||||
* The network is locked.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
static int cdcncm_txpoll(FAR struct net_driver_s *dev)
|
|
||||||
{
|
|
||||||
FAR struct cdcncm_driver_s *priv =
|
|
||||||
(FAR struct cdcncm_driver_s *)dev->d_private;
|
|
||||||
|
|
||||||
/* Send the packet */
|
|
||||||
|
|
||||||
cdcncm_transmit(priv);
|
|
||||||
|
|
||||||
/* Check if there is room in the device to hold another packet. If
|
|
||||||
* not, return a non-zero value to terminate the poll.
|
|
||||||
*/
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: cdcncm_reply
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* After a packet has been received and dispatched to the network, it
|
|
||||||
* may return return with an outgoing packet. This function checks for
|
|
||||||
* that case and performs the transmission if necessary.
|
|
||||||
*
|
|
||||||
* Input Parameters:
|
|
||||||
* priv - Reference to the driver state structure
|
|
||||||
*
|
|
||||||
* Returned Value:
|
|
||||||
* None
|
|
||||||
*
|
|
||||||
* Assumptions:
|
|
||||||
* The network is locked.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
static void cdcncm_reply(FAR struct cdcncm_driver_s *priv)
|
|
||||||
{
|
|
||||||
/* If the packet dispatch resulted in data that should be sent out on the
|
|
||||||
* network, the field d_len will set to a value > 0.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (priv->dev.d_len > 0)
|
|
||||||
{
|
|
||||||
/* And send the packet */
|
|
||||||
|
|
||||||
cdcncm_transmit(priv);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -813,77 +688,33 @@ static void cdcncm_reply(FAR struct cdcncm_driver_s *priv)
|
|||||||
* Returned Value:
|
* Returned Value:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
* Assumptions:
|
|
||||||
* The network is locked.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static void cdcncm_packet_handler(FAR struct cdcncm_driver_s *self)
|
static int cdcncm_packet_handler(FAR struct cdcncm_driver_s *self,
|
||||||
|
FAR uint8_t *dgram, uint32_t dglen)
|
||||||
{
|
{
|
||||||
/* Check for errors and update statistics */
|
FAR netpkt_t *pkt = netpkt_alloc(&self->dev, NETPKT_RX);
|
||||||
|
int ret = -ENOMEM;
|
||||||
|
|
||||||
#ifdef CONFIG_NET_PKT
|
if (pkt == NULL)
|
||||||
/* When packet sockets are enabled, feed the frame into the tap */
|
|
||||||
|
|
||||||
pkt_input(&self->dev);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* We only accept IP packets of the configured type and ARP packets */
|
|
||||||
|
|
||||||
#ifdef CONFIG_NET_IPv4
|
|
||||||
if (BUF->type == HTONS(ETHTYPE_IP))
|
|
||||||
{
|
{
|
||||||
ninfo("IPv4 frame\n");
|
return ret;
|
||||||
NETDEV_RXIPV4(&self->dev);
|
|
||||||
|
|
||||||
/* Receive an IPv4 packet from the network device */
|
|
||||||
|
|
||||||
ipv4_input(&self->dev);
|
|
||||||
|
|
||||||
/* Check for a reply to the IPv4 packet */
|
|
||||||
|
|
||||||
cdcncm_reply(self);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
#endif
|
ret = netpkt_copyin(&self->dev, pkt, dgram, dglen, 0);
|
||||||
#ifdef CONFIG_NET_IPv6
|
if (ret < 0)
|
||||||
if (BUF->type == HTONS(ETHTYPE_IP6))
|
|
||||||
{
|
{
|
||||||
ninfo("IPv6 frame\n");
|
netpkt_free(&self->dev, pkt, NETPKT_RX);
|
||||||
NETDEV_RXIPV6(&self->dev);
|
return ret;
|
||||||
|
|
||||||
/* Dispatch IPv6 packet to the network layer */
|
|
||||||
|
|
||||||
ipv6_input(&self->dev);
|
|
||||||
|
|
||||||
/* Check for a reply to the IPv6 packet */
|
|
||||||
|
|
||||||
cdcncm_reply(self);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
#endif
|
ret = netpkt_tryadd_queue(pkt, &self->rx_queue);
|
||||||
#ifdef CONFIG_NET_ARP
|
if (ret != 0)
|
||||||
if (BUF->type == HTONS(ETHTYPE_ARP))
|
|
||||||
{
|
{
|
||||||
/* Dispatch ARP packet to the network layer */
|
netpkt_free(&self->dev, pkt, NETPKT_RX);
|
||||||
|
|
||||||
arp_input(&self->dev);
|
|
||||||
NETDEV_RXARP(&self->dev);
|
|
||||||
|
|
||||||
/* If the above function invocation resulted in data that should be
|
|
||||||
* sent out on the network, d_len field will set to a value > 0.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (self->dev.d_len > 0)
|
|
||||||
{
|
|
||||||
cdcncm_transmit(self);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
NETDEV_RXDROPPED(&self->dev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -898,9 +729,6 @@ static void cdcncm_packet_handler(FAR struct cdcncm_driver_s *self)
|
|||||||
* Returned Value:
|
* Returned Value:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
* Assumptions:
|
|
||||||
* The network is locked.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static void cdcncm_receive(FAR struct cdcncm_driver_s *self)
|
static void cdcncm_receive(FAR struct cdcncm_driver_s *self)
|
||||||
@ -997,14 +825,11 @@ static void cdcncm_receive(FAR struct cdcncm_driver_s *self)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy the data data from the hardware to self->dev.d_buf. Set
|
|
||||||
* amount of data in self->dev.d_len
|
|
||||||
*/
|
|
||||||
|
|
||||||
memcpy(self->dev.d_buf, self->rdreq->buf + index, dglen);
|
|
||||||
self->dev.d_len = dglen;
|
|
||||||
dgramcounter++;
|
dgramcounter++;
|
||||||
cdcncm_packet_handler(self);
|
|
||||||
|
/* Copy the data from the hardware to self->rx_queue. */
|
||||||
|
|
||||||
|
cdcncm_packet_handler(self, self->rdreq->buf + index, dglen);
|
||||||
|
|
||||||
ndplen -= 2 * (opts->dgramitemlen);
|
ndplen -= 2 * (opts->dgramitemlen);
|
||||||
}
|
}
|
||||||
@ -1025,20 +850,13 @@ static void cdcncm_receive(FAR struct cdcncm_driver_s *self)
|
|||||||
* Returned Value:
|
* Returned Value:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
* Assumptions:
|
|
||||||
* The network is locked.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static void cdcncm_txdone(FAR struct cdcncm_driver_s *priv)
|
static void cdcncm_txdone(FAR struct cdcncm_driver_s *priv)
|
||||||
{
|
{
|
||||||
/* Check for errors and update statistics */
|
|
||||||
|
|
||||||
NETDEV_TXDONE(priv->dev);
|
|
||||||
|
|
||||||
/* In any event, poll the network for new TX data */
|
/* In any event, poll the network for new TX data */
|
||||||
|
|
||||||
devif_poll(&priv->dev, cdcncm_txpoll);
|
netdev_lower_txdone(&priv->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -1063,19 +881,12 @@ static void cdcncm_interrupt_work(FAR void *arg)
|
|||||||
FAR struct cdcncm_driver_s *self = (FAR struct cdcncm_driver_s *)arg;
|
FAR struct cdcncm_driver_s *self = (FAR struct cdcncm_driver_s *)arg;
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
|
|
||||||
/* Lock the network and serialize driver operations if necessary.
|
|
||||||
* NOTE: Serialization is only required in the case where the driver work
|
|
||||||
* is performed on an LP worker thread and where more than one LP worker
|
|
||||||
* thread has been configured.
|
|
||||||
*/
|
|
||||||
|
|
||||||
net_lock();
|
|
||||||
|
|
||||||
/* Check if we received an incoming packet, if so, call cdcncm_receive() */
|
/* Check if we received an incoming packet, if so, call cdcncm_receive() */
|
||||||
|
|
||||||
if (self->rxpending)
|
if (self->rxpending)
|
||||||
{
|
{
|
||||||
cdcncm_receive(self);
|
cdcncm_receive(self);
|
||||||
|
netdev_lower_rxready(&self->dev);
|
||||||
|
|
||||||
flags = enter_critical_section();
|
flags = enter_critical_section();
|
||||||
self->rxpending = false;
|
self->rxpending = false;
|
||||||
@ -1100,8 +911,6 @@ static void cdcncm_interrupt_work(FAR void *arg)
|
|||||||
{
|
{
|
||||||
leave_critical_section(flags);
|
leave_critical_section(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
net_unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -1122,21 +931,22 @@ static void cdcncm_interrupt_work(FAR void *arg)
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int cdcncm_ifup(FAR struct net_driver_s *dev)
|
static int cdcncm_ifup(FAR struct netdev_lowerhalf_s *dev)
|
||||||
{
|
{
|
||||||
FAR struct cdcncm_driver_s *priv =
|
FAR struct cdcncm_driver_s *priv =
|
||||||
(FAR struct cdcncm_driver_s *)dev->d_private;
|
container_of(dev, struct cdcncm_driver_s, dev);
|
||||||
|
|
||||||
#ifdef CONFIG_NET_IPv4
|
#ifdef CONFIG_NET_IPv4
|
||||||
ninfo("Bringing up: %u.%u.%u.%u\n",
|
ninfo("Bringing up: %u.%u.%u.%u\n",
|
||||||
ip4_addr1(dev->d_ipaddr), ip4_addr2(dev->d_ipaddr),
|
ip4_addr1(dev->netdev.d_ipaddr), ip4_addr2(dev->netdev.d_ipaddr),
|
||||||
ip4_addr3(dev->d_ipaddr), ip4_addr4(dev->d_ipaddr));
|
ip4_addr3(dev->netdev.d_ipaddr), ip4_addr4(dev->netdev.d_ipaddr));
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_NET_IPv6
|
#ifdef CONFIG_NET_IPv6
|
||||||
ninfo("Bringing up: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
|
ninfo("Bringing up: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
|
||||||
dev->d_ipv6addr[0], dev->d_ipv6addr[1], dev->d_ipv6addr[2],
|
dev->netdev.d_ipv6addr[0], dev->netdev.d_ipv6addr[1],
|
||||||
dev->d_ipv6addr[3], dev->d_ipv6addr[4], dev->d_ipv6addr[5],
|
dev->netdev.d_ipv6addr[2], dev->netdev.d_ipv6addr[3],
|
||||||
dev->d_ipv6addr[6], dev->d_ipv6addr[7]);
|
dev->netdev.d_ipv6addr[4], dev->netdev.d_ipv6addr[5],
|
||||||
|
dev->netdev.d_ipv6addr[6], dev->netdev.d_ipv6addr[7]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
priv->bifup = true;
|
priv->bifup = true;
|
||||||
@ -1160,10 +970,10 @@ static int cdcncm_ifup(FAR struct net_driver_s *dev)
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int cdcncm_ifdown(FAR struct net_driver_s *dev)
|
static int cdcncm_ifdown(FAR struct netdev_lowerhalf_s *dev)
|
||||||
{
|
{
|
||||||
FAR struct cdcncm_driver_s *priv =
|
FAR struct cdcncm_driver_s *priv =
|
||||||
(FAR struct cdcncm_driver_s *)dev->d_private;
|
container_of(dev, struct cdcncm_driver_s, dev);
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
|
|
||||||
/* Disable the Ethernet interrupt */
|
/* Disable the Ethernet interrupt */
|
||||||
@ -1179,87 +989,72 @@ static int cdcncm_ifdown(FAR struct net_driver_s *dev)
|
|||||||
|
|
||||||
priv->bifup = false;
|
priv->bifup = false;
|
||||||
leave_critical_section(flags);
|
leave_critical_section(flags);
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: cdcncm_txavail_work
|
* Name: cdcncm_send
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Perform an out-of-cycle poll on the worker thread.
|
* Transmit a packet through the USB interface
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* arg - Reference to the NuttX driver state structure (cast to void*)
|
* dev - Reference to the NuttX netdev lowerhalf driver structure
|
||||||
|
* pkt - The packet to be sent
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* None
|
* OK on success
|
||||||
*
|
|
||||||
* Assumptions:
|
|
||||||
* Runs on a work queue thread.
|
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static void cdcncm_txavail_work(FAR void *arg)
|
static int cdcncm_send(FAR struct netdev_lowerhalf_s *dev, FAR netpkt_t *pkt)
|
||||||
{
|
{
|
||||||
FAR struct cdcncm_driver_s *self = (FAR struct cdcncm_driver_s *)arg;
|
FAR struct cdcncm_driver_s *self;
|
||||||
|
|
||||||
/* Lock the network and serialize driver operations if necessary.
|
self = container_of(dev, struct cdcncm_driver_s, dev);
|
||||||
* NOTE: Serialization is only required in the case where the driver work
|
cdcncm_transmit_format(self, pkt);
|
||||||
* is performed on an LP worker thread and where more than one LP worker
|
netpkt_free(dev, pkt, NETPKT_TX);
|
||||||
* thread has been configured.
|
|
||||||
*/
|
|
||||||
|
|
||||||
net_lock();
|
if ((self->wrreq->buf + NTB_OUT_SIZE - self->dgramaddr <
|
||||||
|
self->dev.netdev.d_pktsize) || self->dgramcount >= TX_MAX_NUM_DPE)
|
||||||
/* Ignore the notification if the interface is not yet up */
|
|
||||||
|
|
||||||
if (self->bifup)
|
|
||||||
{
|
{
|
||||||
devif_poll(&self->dev, cdcncm_txpoll);
|
work_cancel(ETHWORK, &self->delaywork);
|
||||||
|
cdcncm_transmit_work(self);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
net_unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: cdcncm_txavail
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Driver callback invoked when new TX data is available. This is a
|
|
||||||
* stimulus perform an out-of-cycle poll and, thereby, reduce the TX
|
|
||||||
* latency.
|
|
||||||
*
|
|
||||||
* Input Parameters:
|
|
||||||
* dev - Reference to the NuttX driver state structure
|
|
||||||
*
|
|
||||||
* Returned Value:
|
|
||||||
* None
|
|
||||||
*
|
|
||||||
* Assumptions:
|
|
||||||
* The network is locked.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
static int cdcncm_txavail(FAR struct net_driver_s *dev)
|
|
||||||
{
|
|
||||||
FAR struct cdcncm_driver_s *priv =
|
|
||||||
(FAR struct cdcncm_driver_s *)dev->d_private;
|
|
||||||
|
|
||||||
/* Is our single work structure available? It may not be if there are
|
|
||||||
* pending interrupt actions and we will have to ignore the Tx
|
|
||||||
* availability action.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (work_available(&priv->pollwork))
|
|
||||||
{
|
{
|
||||||
/* Schedule to serialize the poll on the worker thread. */
|
work_queue(ETHWORK, &self->delaywork, cdcncm_transmit_work, self,
|
||||||
|
MSEC2TICK(CDCNCM_DGRAM_COMBINE_PERIOD));
|
||||||
work_queue(ETHWORK, &priv->pollwork, cdcncm_txavail_work, priv, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: cdcncm_recv
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Receive a packet from the USB interface
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - Reference to the NuttX netdev lowerhalf driver structure
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* The received packet, or NULL if no packet is available
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static FAR netpkt_t *cdcncm_recv(FAR struct netdev_lowerhalf_s *dev)
|
||||||
|
{
|
||||||
|
FAR struct cdcncm_driver_s *self;
|
||||||
|
FAR netpkt_t *pkt;
|
||||||
|
|
||||||
|
self = container_of(dev, struct cdcncm_driver_s, dev);
|
||||||
|
pkt = netpkt_remove_queue(&self->rx_queue);
|
||||||
|
return pkt;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: cdcncm_addmac
|
* Name: cdcncm_addmac
|
||||||
*
|
*
|
||||||
@ -1277,7 +1072,7 @@ static int cdcncm_txavail(FAR struct net_driver_s *dev)
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#if defined(CONFIG_NET_MCASTGROUP) || defined(CONFIG_NET_ICMPv6)
|
#if defined(CONFIG_NET_MCASTGROUP) || defined(CONFIG_NET_ICMPv6)
|
||||||
static int cdcncm_addmac(FAR struct net_driver_s *dev,
|
static int cdcncm_addmac(FAR struct netdev_lowerhalf_s *dev,
|
||||||
FAR const uint8_t *mac)
|
FAR const uint8_t *mac)
|
||||||
{
|
{
|
||||||
return OK;
|
return OK;
|
||||||
@ -1301,7 +1096,8 @@ static int cdcncm_addmac(FAR struct net_driver_s *dev,
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_NET_MCASTGROUP
|
#ifdef CONFIG_NET_MCASTGROUP
|
||||||
static int cdcncm_rmmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac)
|
static int cdcncm_rmmac(FAR struct netdev_lowerhalf_s *dev,
|
||||||
|
FAR const uint8_t *mac)
|
||||||
{
|
{
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@ -1327,7 +1123,7 @@ static int cdcncm_rmmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac)
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_NETDEV_IOCTL
|
#ifdef CONFIG_NETDEV_IOCTL
|
||||||
static int cdcncm_ioctl(FAR struct net_driver_s *dev, int cmd,
|
static int cdcncm_ioctl(FAR struct netdev_lowerhalf_s *dev, int cmd,
|
||||||
unsigned long arg)
|
unsigned long arg)
|
||||||
{
|
{
|
||||||
return -ENOTTY;
|
return -ENOTTY;
|
||||||
@ -1449,7 +1245,7 @@ static void cdcncm_resetconfig(FAR struct cdcncm_driver_s *self)
|
|||||||
|
|
||||||
/* Inform the networking layer that the link is down */
|
/* Inform the networking layer that the link is down */
|
||||||
|
|
||||||
self->dev.d_ifdown(&self->dev);
|
cdcncm_ifdown(&self->dev);
|
||||||
|
|
||||||
/* Disable endpoints. This should force completion of all pending
|
/* Disable endpoints. This should force completion of all pending
|
||||||
* transfers.
|
* transfers.
|
||||||
@ -1545,14 +1341,14 @@ static int cdcncm_setconfig(FAR struct cdcncm_driver_s *self, uint8_t config)
|
|||||||
|
|
||||||
/* Set client's MAC address */
|
/* Set client's MAC address */
|
||||||
|
|
||||||
memcpy(self->dev.d_mac.ether.ether_addr_octet,
|
memcpy(self->dev.netdev.d_mac.ether.ether_addr_octet,
|
||||||
"\x00\xe0\xde\xad\xbe\xef", IFHWADDRLEN);
|
"\x00\xe0\xde\xad\xbe\xef", IFHWADDRLEN);
|
||||||
|
|
||||||
/* Report link up to networking layer */
|
/* Report link up to networking layer */
|
||||||
|
|
||||||
if (self->dev.d_ifup(&self->dev) == OK)
|
if (cdcncm_ifup(&self->dev) == OK)
|
||||||
{
|
{
|
||||||
self->dev.d_flags |= IFF_UP;
|
self->dev.netdev.d_flags |= IFF_UP;
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
@ -1583,8 +1379,8 @@ static int ncm_notify(FAR struct cdcncm_driver_s *self)
|
|||||||
/* Notifying the host of the NIC modification status */
|
/* Notifying the host of the NIC modification status */
|
||||||
|
|
||||||
req->req = NCM_NETWORK_CONNECTION;
|
req->req = NCM_NETWORK_CONNECTION;
|
||||||
req->value[0] = LSBYTE(IFF_IS_RUNNING(self->dev.d_flags));
|
req->value[0] = LSBYTE(IFF_IS_RUNNING(self->dev.netdev.d_flags));
|
||||||
req->value[1] = MSBYTE(IFF_IS_RUNNING(self->dev.d_flags));
|
req->value[1] = MSBYTE(IFF_IS_RUNNING(self->dev.netdev.d_flags));
|
||||||
req->len[0] = 0;
|
req->len[0] = 0;
|
||||||
req->len[1] = 0;
|
req->len[1] = 0;
|
||||||
ret = sizeof(*req);
|
ret = sizeof(*req);
|
||||||
@ -1662,7 +1458,7 @@ static int cdcncm_setinterface(FAR struct cdcncm_driver_s *self,
|
|||||||
self->notify = NCM_NOTIFY_SPEED;
|
self->notify = NCM_NOTIFY_SPEED;
|
||||||
}
|
}
|
||||||
|
|
||||||
netdev_carrier_on(&self->dev);
|
netdev_lower_carrier_on(&self->dev);
|
||||||
work_queue(ETHWORK, &self->notifywork, ncm_do_notify, self,
|
work_queue(ETHWORK, &self->notifywork, ncm_do_notify, self,
|
||||||
MSEC2TICK(100));
|
MSEC2TICK(100));
|
||||||
}
|
}
|
||||||
@ -2246,7 +2042,6 @@ static int cdcncm_bind(FAR struct usbdevclass_driver_s *driver,
|
|||||||
}
|
}
|
||||||
|
|
||||||
self->txdone = false;
|
self->txdone = false;
|
||||||
self->dev.d_len = 0;
|
|
||||||
|
|
||||||
#ifndef CONFIG_CDCNCM_COMPOSITE
|
#ifndef CONFIG_CDCNCM_COMPOSITE
|
||||||
#ifdef CONFIG_USBDEV_SELFPOWERED
|
#ifdef CONFIG_USBDEV_SELFPOWERED
|
||||||
@ -2342,9 +2137,9 @@ static void cdcncm_unbind(FAR struct usbdevclass_driver_s *driver,
|
|||||||
self->epbulkin = NULL;
|
self->epbulkin = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear out all data in the buffer */
|
/* Clear out all data in the rx_queue */
|
||||||
|
|
||||||
self->dev.d_len = 0;
|
netpkt_free_queue(&self->rx_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cdcncm_setup(FAR struct usbdevclass_driver_s *driver,
|
static int cdcncm_setup(FAR struct usbdevclass_driver_s *driver,
|
||||||
@ -2514,18 +2309,9 @@ static int cdcncm_classobject(int minor,
|
|||||||
|
|
||||||
/* Network device initialization */
|
/* Network device initialization */
|
||||||
|
|
||||||
self->dev.d_buf = (FAR uint8_t *)self->pktbuf;
|
self->dev.ops = &g_netops;
|
||||||
self->dev.d_ifup = cdcncm_ifup; /* I/F up (new IP address) callback */
|
self->dev.quota[NETPKT_TX] = CONFIG_CDCNCM_QUOTA_TX;
|
||||||
self->dev.d_ifdown = cdcncm_ifdown; /* I/F down callback */
|
self->dev.quota[NETPKT_RX] = CONFIG_CDCNCM_QUOTA_RX;
|
||||||
self->dev.d_txavail = cdcncm_txavail; /* New TX data callback */
|
|
||||||
#ifdef CONFIG_NET_MCASTGROUP
|
|
||||||
self->dev.d_addmac = cdcncm_addmac; /* Add multicast MAC address */
|
|
||||||
self->dev.d_rmmac = cdcncm_rmmac; /* Remove multicast MAC address */
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_NETDEV_IOCTL
|
|
||||||
self->dev.d_ioctl = cdcncm_ioctl; /* Handle network IOCTL commands */
|
|
||||||
#endif
|
|
||||||
self->dev.d_private = self; /* Used to recover private state from dev */
|
|
||||||
|
|
||||||
/* USB device initialization */
|
/* USB device initialization */
|
||||||
|
|
||||||
@ -2545,19 +2331,19 @@ static int cdcncm_classobject(int minor,
|
|||||||
cdcncm_ifdown(&self->dev);
|
cdcncm_ifdown(&self->dev);
|
||||||
|
|
||||||
/* Read the MAC address from the hardware into
|
/* Read the MAC address from the hardware into
|
||||||
* priv->dev.d_mac.ether.ether_addr_octet
|
* priv->dev.netdev.d_mac.ether.ether_addr_octet
|
||||||
* Applies only if the Ethernet MAC has its own internal address.
|
* Applies only if the Ethernet MAC has its own internal address.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
memcpy(self->dev.d_mac.ether.ether_addr_octet,
|
memcpy(self->dev.netdev.d_mac.ether.ether_addr_octet,
|
||||||
"\x00\xe0\xde\xad\xbe\xef", IFHWADDRLEN);
|
"\x00\xe0\xde\xad\xbe\xef", IFHWADDRLEN);
|
||||||
|
|
||||||
/* Register the device with the OS so that socket IOCTLs can be performed */
|
/* Register the device with the OS so that socket IOCTLs can be performed */
|
||||||
|
|
||||||
ret = netdev_register(&self->dev, NET_LL_ETHERNET);
|
ret = netdev_lower_register(&self->dev, NET_LL_ETHERNET);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
nerr("netdev_register failed. ret: %d\n", ret);
|
nerr("netdev_lower_register failed. ret: %d\n", ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
*classdev = (FAR struct usbdevclass_driver_s *)self;
|
*classdev = (FAR struct usbdevclass_driver_s *)self;
|
||||||
@ -2592,10 +2378,10 @@ static void cdcncm_uninitialize(FAR struct usbdevclass_driver_s *classdev)
|
|||||||
|
|
||||||
/* Un-register the CDC/ECM netdev device */
|
/* Un-register the CDC/ECM netdev device */
|
||||||
|
|
||||||
ret = netdev_unregister(&self->dev);
|
ret = netdev_lower_unregister(&self->dev);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
nerr("ERROR: netdev_unregister failed. ret: %d\n", ret);
|
nerr("ERROR: netdev_lower_unregister failed. ret: %d\n", ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_CDCNCM_COMPOSITE
|
#ifndef CONFIG_CDCNCM_COMPOSITE
|
||||||
|
@ -81,6 +81,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct iob_s netpkt_t;
|
typedef struct iob_s netpkt_t;
|
||||||
|
typedef struct iob_queue_s netpkt_queue_t;
|
||||||
|
|
||||||
enum netpkt_type_e
|
enum netpkt_type_e
|
||||||
{
|
{
|
||||||
@ -510,4 +511,55 @@ bool netpkt_is_fragmented(FAR netpkt_t *pkt);
|
|||||||
int netpkt_to_iov(FAR struct netdev_lowerhalf_s *dev, FAR netpkt_t *pkt,
|
int netpkt_to_iov(FAR struct netdev_lowerhalf_s *dev, FAR netpkt_t *pkt,
|
||||||
FAR struct iovec *iov, int iovcnt);
|
FAR struct iovec *iov, int iovcnt);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: netpkt_tryadd_queue
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Add one net packet to the end of a queue without waiting for resources
|
||||||
|
* to become free.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* pkt - The packet to add
|
||||||
|
* queue - The queue to add the packet to
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* 0:Success; negated errno on failure
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#define netpkt_tryadd_queue(pkt, queue) iob_tryadd_queue(pkt, queue)
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: netpkt_remove_queue
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Remove one net packet from the head of a queue.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* queue - The queue to remove the packet from
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* The packet removed from the queue. NULL is returned if the queue is
|
||||||
|
* empty.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#define netpkt_remove_queue(queue) iob_remove_queue(queue)
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: netpkt_free_queue
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Free all net packets in a queue.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* queue - The queue to free
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#define netpkt_free_queue(queue) iob_free_queue(queue)
|
||||||
|
|
||||||
#endif /* __INCLUDE_NUTTX_NET_NETDEV_LOWERHALF_H */
|
#endif /* __INCLUDE_NUTTX_NET_NETDEV_LOWERHALF_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user