net/netdev: Use upper half of netdev to simplify sim driver
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
This commit is contained in:
parent
72b77d36e2
commit
f21742899f
@ -66,288 +66,150 @@
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/net/net.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
#include <nuttx/net/netdev_lowerhalf.h>
|
||||
#include <nuttx/net/pkt.h>
|
||||
|
||||
#include "sim_internal.h"
|
||||
|
||||
#if CONFIG_IOB_BUFSIZE >= (MAX_NETDEV_PKTSIZE + \
|
||||
CONFIG_NET_GUARDSIZE + CONFIG_NET_LL_GUARDSIZE)
|
||||
# define SIM_NETDEV_IOB_OFFLOAD
|
||||
#define SIM_NETDEV_BUFSIZE (MAX_NETDEV_PKTSIZE + CONFIG_NET_GUARDSIZE)
|
||||
|
||||
/* We don't know packet length before receiving, so we can only offload it
|
||||
* when netpkt's buffer is long enough.
|
||||
*/
|
||||
|
||||
#if NETPKT_BUFLEN >= SIM_NETDEV_BUFSIZE
|
||||
# define SIM_NETDEV_RECV_OFFLOAD
|
||||
#endif
|
||||
|
||||
/* Get index / buffer from dev pointer. */
|
||||
|
||||
#define DEVIDX(p) ((struct sim_netdev_s *)(p) - g_sim_dev)
|
||||
#define DEVBUF(p) (((struct sim_netdev_s *)(p))->buf)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct sim_netdev_s
|
||||
{
|
||||
struct netdev_lowerhalf_s dev;
|
||||
uint8_t buf[SIM_NETDEV_BUFSIZE]; /* Used when packet buffer is fragmented */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static void netdriver_txdone_interrupt(void *priv);
|
||||
static int netdriver_send(struct netdev_lowerhalf_s *dev, netpkt_t *pkt);
|
||||
static netpkt_t *netdriver_recv(struct netdev_lowerhalf_s *dev);
|
||||
static int netdriver_ifup(struct netdev_lowerhalf_s *dev);
|
||||
static int netdriver_ifdown(struct netdev_lowerhalf_s *dev);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* Net driver worker */
|
||||
|
||||
static struct work_s g_avail_work[CONFIG_SIM_NETDEV_NUMBER];
|
||||
static struct work_s g_recv_work[CONFIG_SIM_NETDEV_NUMBER];
|
||||
|
||||
/* Ethernet peripheral state */
|
||||
|
||||
static struct net_driver_s g_sim_dev[CONFIG_SIM_NETDEV_NUMBER];
|
||||
static struct sim_netdev_s g_sim_dev[CONFIG_SIM_NETDEV_NUMBER];
|
||||
static const struct netdev_ops_s g_ops =
|
||||
{
|
||||
netdriver_ifup, /* ifup */
|
||||
netdriver_ifdown, /* ifdown */
|
||||
netdriver_send, /* transmit */
|
||||
netdriver_recv /* receive */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static void netdriver_send(struct net_driver_s *dev)
|
||||
static int netdriver_send(struct netdev_lowerhalf_s *dev, netpkt_t *pkt)
|
||||
{
|
||||
int devidx = (intptr_t)dev->d_private;
|
||||
#ifdef SIM_NETDEV_IOB_OFFLOAD
|
||||
uint8_t *buf = NETLLBUF;
|
||||
#else
|
||||
uint8_t *buf = dev->d_buf;
|
||||
#endif
|
||||
unsigned int len = netpkt_getdatalen(dev, pkt);
|
||||
|
||||
UNUSED(devidx);
|
||||
|
||||
#ifdef CONFIG_NET_PKT
|
||||
/* When packet sockets are enabled, feed the tx frame into it */
|
||||
|
||||
pkt_input(dev);
|
||||
#endif
|
||||
|
||||
sim_netdev_send(devidx, buf, dev->d_len);
|
||||
}
|
||||
|
||||
static void netdriver_reply(struct net_driver_s *dev)
|
||||
{
|
||||
/* If the receiving resulted in data that should be sent out on
|
||||
* the network, the field d_len is set to a value > 0.
|
||||
*/
|
||||
|
||||
if (dev->d_len > 0)
|
||||
if (netpkt_is_fragmented(pkt))
|
||||
{
|
||||
/* Send the packet */
|
||||
|
||||
NETDEV_TXPACKETS(dev);
|
||||
netdriver_send(dev);
|
||||
NETDEV_TXDONE(dev);
|
||||
netpkt_copyout(dev, DEVBUF(dev), pkt, len, 0);
|
||||
sim_netdev_send(DEVIDX(dev), DEVBUF(dev), len);
|
||||
}
|
||||
else
|
||||
{
|
||||
sim_netdev_send(DEVIDX(dev), netpkt_getdata(dev, pkt), len);
|
||||
}
|
||||
|
||||
netpkt_free(dev, pkt, NETPKT_TX);
|
||||
return OK;
|
||||
}
|
||||
|
||||
static void netdriver_recv_work(void *arg)
|
||||
static netpkt_t *netdriver_recv(struct netdev_lowerhalf_s *dev)
|
||||
{
|
||||
struct net_driver_s *dev = arg;
|
||||
struct eth_hdr_s *eth;
|
||||
int devidx = (intptr_t)dev->d_private;
|
||||
netpkt_t *pkt = NULL;
|
||||
unsigned int len;
|
||||
|
||||
UNUSED(devidx);
|
||||
|
||||
net_lock();
|
||||
|
||||
/* Retrieve all the queued RX frames from the network device
|
||||
* to prevent RX data stream congestion.
|
||||
*/
|
||||
|
||||
while (sim_netdev_avail(devidx))
|
||||
if (sim_netdev_avail(DEVIDX(dev)))
|
||||
{
|
||||
#ifdef SIM_NETDEV_IOB_OFFLOAD
|
||||
if (netdev_iob_prepare(dev, false, 0) != OK)
|
||||
pkt = netpkt_alloc(dev, NETPKT_RX);
|
||||
if (pkt == NULL)
|
||||
{
|
||||
netdriver_txdone_interrupt(dev);
|
||||
break;
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* sim_netdev_read will return 0 on a timeout event and > 0
|
||||
* on a data received event
|
||||
*/
|
||||
|
||||
dev->d_len = sim_netdev_read(devidx,
|
||||
(unsigned char *)dev->d_buf,
|
||||
dev->d_pktsize);
|
||||
if (dev->d_len > 0)
|
||||
#ifdef SIM_NETDEV_RECV_OFFLOAD
|
||||
len = sim_netdev_read(DEVIDX(dev), netpkt_getbase(pkt),
|
||||
SIM_NETDEV_BUFSIZE);
|
||||
#else
|
||||
len = sim_netdev_read(DEVIDX(dev), DEVBUF(dev), SIM_NETDEV_BUFSIZE);
|
||||
#endif
|
||||
if (len == 0)
|
||||
{
|
||||
NETDEV_RXPACKETS(dev);
|
||||
|
||||
#ifdef SIM_NETDEV_IOB_OFFLOAD
|
||||
iob_update_pktlen(dev->d_iob, dev->d_len - NET_LL_HDRLEN(dev));
|
||||
#endif
|
||||
|
||||
/* Data received event. Check for valid Ethernet header with
|
||||
* destination == our MAC address
|
||||
*/
|
||||
|
||||
eth = (struct eth_hdr_s *)dev->d_buf;
|
||||
if (dev->d_len > ETH_HDRLEN)
|
||||
{
|
||||
#ifdef CONFIG_NET_PKT
|
||||
/* When packet sockets are enabled, feed the frame into
|
||||
* the packet tap.
|
||||
*/
|
||||
|
||||
pkt_input(dev);
|
||||
#endif /* CONFIG_NET_PKT */
|
||||
|
||||
/* We only accept IP packets of the configured type
|
||||
* and ARP packets
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_NET_IPv4
|
||||
if (eth->type == HTONS(ETHTYPE_IP))
|
||||
{
|
||||
ninfo("IPv4 frame\n");
|
||||
NETDEV_RXIPV4(dev);
|
||||
|
||||
/* Receive an IPv4 packet from the network device */
|
||||
|
||||
ipv4_input(dev);
|
||||
|
||||
/* Check for a reply to the IPv4 packet */
|
||||
|
||||
netdriver_reply(dev);
|
||||
}
|
||||
else
|
||||
#endif /* CONFIG_NET_IPv4 */
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
if (eth->type == HTONS(ETHTYPE_IP6))
|
||||
{
|
||||
ninfo("IPv6 frame\n");
|
||||
NETDEV_RXIPV6(dev);
|
||||
|
||||
/* Give the IPv6 packet to the network layer */
|
||||
|
||||
ipv6_input(dev);
|
||||
|
||||
/* Check for a reply to the IPv6 packet */
|
||||
|
||||
netdriver_reply(dev);
|
||||
}
|
||||
else
|
||||
#endif/* CONFIG_NET_IPv6 */
|
||||
#ifdef CONFIG_NET_ARP
|
||||
if (eth->type == HTONS(ETHTYPE_ARP))
|
||||
{
|
||||
ninfo("ARP frame\n");
|
||||
NETDEV_RXARP(dev);
|
||||
|
||||
arp_input(dev);
|
||||
|
||||
/* If the above function invocation resulted in data that
|
||||
* should be sent out on the network, the global variable
|
||||
* d_len is set to a value > 0.
|
||||
*/
|
||||
|
||||
if (dev->d_len > 0)
|
||||
{
|
||||
netdriver_send(dev);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
NETDEV_RXDROPPED(dev);
|
||||
nwarn("WARNING: Unsupported Ethernet type %u\n",
|
||||
eth->type);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NETDEV_RXERRORS(dev);
|
||||
}
|
||||
netpkt_free(dev, pkt, NETPKT_RX);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef SIM_NETDEV_IOB_OFFLOAD
|
||||
netdev_iob_release(dev);
|
||||
#ifdef SIM_NETDEV_RECV_OFFLOAD
|
||||
netpkt_reset_reserved(dev, pkt, 0); /* No overhead before data. */
|
||||
netpkt_setdatalen(dev, pkt, len);
|
||||
#else
|
||||
netpkt_copyin(dev, pkt, DEVBUF(dev), len, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
net_unlock();
|
||||
return pkt;
|
||||
}
|
||||
|
||||
static int netdriver_txpoll(struct net_driver_s *dev)
|
||||
static int netdriver_ifup(struct netdev_lowerhalf_s *dev)
|
||||
{
|
||||
/* Send the packet */
|
||||
|
||||
NETDEV_TXPACKETS(dev);
|
||||
netdriver_send(dev);
|
||||
NETDEV_TXDONE(dev);
|
||||
|
||||
/* If zero is returned, the polling will continue until all connections
|
||||
* have been examined.
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int netdriver_ifup(struct net_driver_s *dev)
|
||||
{
|
||||
int devidx = (intptr_t)dev->d_private;
|
||||
|
||||
UNUSED(devidx);
|
||||
#ifdef CONFIG_NET_IPv4
|
||||
sim_netdev_ifup(devidx, &dev->d_ipaddr);
|
||||
sim_netdev_ifup(DEVIDX(dev), &dev->netdev.d_ipaddr);
|
||||
#else /* CONFIG_NET_IPv6 */
|
||||
sim_netdev_ifup(devidx, &dev->d_ipv6addr);
|
||||
sim_netdev_ifup(DEVIDX(dev), &dev->netdev.d_ipv6addr);
|
||||
#endif /* CONFIG_NET_IPv4 */
|
||||
netdev_carrier_on(dev);
|
||||
netdev_lower_carrier_on(dev);
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int netdriver_ifdown(struct net_driver_s *dev)
|
||||
static int netdriver_ifdown(struct netdev_lowerhalf_s *dev)
|
||||
{
|
||||
int devidx = (intptr_t)dev->d_private;
|
||||
|
||||
UNUSED(devidx);
|
||||
netdev_carrier_off(dev);
|
||||
sim_netdev_ifdown(devidx);
|
||||
return OK;
|
||||
}
|
||||
|
||||
static void netdriver_txavail_work(void *arg)
|
||||
{
|
||||
struct net_driver_s *dev = arg;
|
||||
|
||||
net_lock();
|
||||
if (IFF_IS_UP(dev->d_flags))
|
||||
{
|
||||
devif_poll(dev, netdriver_txpoll);
|
||||
}
|
||||
|
||||
net_unlock();
|
||||
}
|
||||
|
||||
static int netdriver_txavail(struct net_driver_s *dev)
|
||||
{
|
||||
int devidx = (intptr_t)dev->d_private;
|
||||
if (work_available(&g_avail_work[devidx]))
|
||||
{
|
||||
work_queue(LPWORK, &g_avail_work[devidx], netdriver_txavail_work,
|
||||
dev, 0);
|
||||
}
|
||||
|
||||
netdev_lower_carrier_off(dev);
|
||||
sim_netdev_ifdown(DEVIDX(dev));
|
||||
return OK;
|
||||
}
|
||||
|
||||
static void netdriver_txdone_interrupt(void *priv)
|
||||
{
|
||||
struct net_driver_s *dev = (struct net_driver_s *)priv;
|
||||
int devidx = (intptr_t)dev->d_private;
|
||||
if (work_available(&g_avail_work[devidx]))
|
||||
{
|
||||
work_queue(LPWORK, &g_avail_work[devidx], netdriver_txavail_work,
|
||||
dev, 0);
|
||||
}
|
||||
struct netdev_lowerhalf_s *dev = (struct netdev_lowerhalf_s *)priv;
|
||||
netdev_lower_txdone(dev);
|
||||
}
|
||||
|
||||
static void netdriver_rxready_interrupt(void *priv)
|
||||
{
|
||||
struct net_driver_s *dev = (struct net_driver_s *)priv;
|
||||
int devidx = (intptr_t)dev->d_private;
|
||||
if (work_available(&g_recv_work[devidx]))
|
||||
{
|
||||
work_queue(LPWORK, &g_recv_work[devidx], netdriver_recv_work, dev, 0);
|
||||
}
|
||||
struct netdev_lowerhalf_s *dev = (struct netdev_lowerhalf_s *)priv;
|
||||
netdev_lower_rxready(dev);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -356,42 +218,30 @@ static void netdriver_rxready_interrupt(void *priv)
|
||||
|
||||
int sim_netdriver_init(void)
|
||||
{
|
||||
struct net_driver_s *dev;
|
||||
struct netdev_lowerhalf_s *dev;
|
||||
int devidx;
|
||||
|
||||
for (devidx = 0; devidx < CONFIG_SIM_NETDEV_NUMBER; devidx++)
|
||||
{
|
||||
dev = &g_sim_dev[devidx];
|
||||
dev = &g_sim_dev[devidx].dev;
|
||||
|
||||
/* Internal initialization */
|
||||
|
||||
sim_netdev_init(devidx, dev,
|
||||
netdriver_txdone_interrupt,
|
||||
netdriver_rxready_interrupt);
|
||||
netdriver_txdone_interrupt,
|
||||
netdriver_rxready_interrupt);
|
||||
|
||||
/* Allocate packet buffer */
|
||||
/* 1TX + 1RX is enough for sim. */
|
||||
|
||||
#ifndef SIM_NETDEV_IOB_OFFLOAD
|
||||
dev->d_buf = kmm_malloc(dev->d_pktsize != 0 ?
|
||||
dev->d_pktsize :
|
||||
(MAX_NETDEV_PKTSIZE +
|
||||
CONFIG_NET_GUARDSIZE));
|
||||
if (dev->d_buf == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
#endif
|
||||
|
||||
dev->d_ifup = netdriver_ifup;
|
||||
dev->d_ifdown = netdriver_ifdown;
|
||||
dev->d_txavail = netdriver_txavail;
|
||||
dev->d_private = (void *)(intptr_t)devidx;
|
||||
dev->quota[NETPKT_TX] = 1;
|
||||
dev->quota[NETPKT_RX] = 1;
|
||||
dev->ops = &g_ops;
|
||||
|
||||
/* Register the device with the OS so that socket IOCTLs can be
|
||||
* performed
|
||||
*/
|
||||
|
||||
netdev_register(dev, NET_LL_ETHERNET);
|
||||
netdev_lower_register(dev, NET_LL_ETHERNET);
|
||||
}
|
||||
|
||||
return OK;
|
||||
@ -399,13 +249,13 @@ int sim_netdriver_init(void)
|
||||
|
||||
void sim_netdriver_setmacaddr(int devidx, unsigned char *macaddr)
|
||||
{
|
||||
memcpy(g_sim_dev[devidx].d_mac.ether.ether_addr_octet, macaddr,
|
||||
memcpy(g_sim_dev[devidx].dev.netdev.d_mac.ether.ether_addr_octet, macaddr,
|
||||
IFHWADDRLEN);
|
||||
}
|
||||
|
||||
void sim_netdriver_setmtu(int devidx, int mtu)
|
||||
{
|
||||
g_sim_dev[devidx].d_pktsize = mtu + ETH_HDRLEN;
|
||||
g_sim_dev[devidx].dev.netdev.d_pktsize = mtu + ETH_HDRLEN;
|
||||
}
|
||||
|
||||
void sim_netdriver_loop(void)
|
||||
@ -413,10 +263,9 @@ void sim_netdriver_loop(void)
|
||||
int devidx;
|
||||
for (devidx = 0; devidx < CONFIG_SIM_NETDEV_NUMBER; devidx++)
|
||||
{
|
||||
if (work_available(&g_recv_work[devidx]) && sim_netdev_avail(devidx))
|
||||
if (sim_netdev_avail(devidx))
|
||||
{
|
||||
work_queue(LPWORK, &g_recv_work[devidx], netdriver_recv_work,
|
||||
&g_sim_dev[devidx], 0);
|
||||
netdev_lower_rxready(&g_sim_dev[devidx].dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -633,6 +633,46 @@ int netdev_lower_unregister(FAR struct netdev_lowerhalf_s *dev)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netdev_lower_carrier_on
|
||||
*
|
||||
* Description:
|
||||
* Notifies the networking layer about an available carrier.
|
||||
* (e.g. a cable was plugged in)
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - The lower half device driver structure
|
||||
*
|
||||
* Returned Value:
|
||||
* 0:Success; negated errno on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int netdev_lower_carrier_on(FAR struct netdev_lowerhalf_s *dev)
|
||||
{
|
||||
return netdev_carrier_on(&dev->netdev);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netdev_lower_carrier_off
|
||||
*
|
||||
* Description:
|
||||
* Notifies the networking layer about an disappeared carrier.
|
||||
* (e.g. a cable was unplugged)
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - The lower half device driver structure
|
||||
*
|
||||
* Returned Value:
|
||||
* 0:Success; negated errno on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int netdev_lower_carrier_off(FAR struct netdev_lowerhalf_s *dev)
|
||||
{
|
||||
return netdev_carrier_off(&dev->netdev);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netdev_lower_rxready
|
||||
*
|
||||
@ -779,6 +819,54 @@ int netpkt_copyout(FAR struct netdev_lowerhalf_s *dev, FAR uint8_t *dest,
|
||||
return iob_copyout(dest, pkt, len, offset - NET_LL_HDRLEN(&dev->netdev));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netpkt_getdata/getbase
|
||||
*
|
||||
* Description:
|
||||
* Get the pointer of data/base in a netpkt, used when NETPKT_BUFLEN is
|
||||
* big enough to fit a full packet in.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - The lower half device driver structure
|
||||
* pkt - The net packet
|
||||
*
|
||||
* Returned Value:
|
||||
* Pointer data/base, NULL on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR uint8_t *netpkt_getdata(FAR struct netdev_lowerhalf_s *dev,
|
||||
FAR netpkt_t *pkt)
|
||||
{
|
||||
return IOB_DATA(pkt) - NET_LL_HDRLEN(&dev->netdev);
|
||||
}
|
||||
|
||||
FAR uint8_t *netpkt_getbase(FAR netpkt_t *pkt)
|
||||
{
|
||||
return pkt->io_data;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netpkt_setdatalen
|
||||
*
|
||||
* Description:
|
||||
* Set the length of data in netpkt, used when data is written into
|
||||
* netpkt by data/base pointer, no need to set this length after
|
||||
* copyin.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - The lower half device driver structure
|
||||
* pkt - The net packet
|
||||
* len - The length of data in netpkt
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void netpkt_setdatalen(FAR struct netdev_lowerhalf_s *dev,
|
||||
FAR netpkt_t *pkt, unsigned int len)
|
||||
{
|
||||
iob_update_pktlen(pkt, len - NET_LL_HDRLEN(&dev->netdev));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netpkt_getdatalen
|
||||
*
|
||||
@ -799,3 +887,39 @@ unsigned int netpkt_getdatalen(FAR struct netdev_lowerhalf_s *dev,
|
||||
{
|
||||
return pkt->io_pktlen + NET_LL_HDRLEN(&dev->netdev);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netpkt_reset_reserved
|
||||
*
|
||||
* Description:
|
||||
* Reset the reserved length (the starting point of data) of netpkt
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - The lower half device driver structure
|
||||
* pkt - The net packet
|
||||
* len - The reserved length
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void netpkt_reset_reserved(FAR struct netdev_lowerhalf_s *dev,
|
||||
FAR netpkt_t *pkt, unsigned int len)
|
||||
{
|
||||
iob_reserve(pkt, len + NET_LL_HDRLEN(&dev->netdev));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netpkt_is_fragmented
|
||||
*
|
||||
* Description:
|
||||
* Returns whether the netpkt is fragmented into different blocks.
|
||||
* In other words, NETPKT_BUFLEN < reserved + total data
|
||||
*
|
||||
* Input Parameters:
|
||||
* pkt - The net packet
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
bool netpkt_is_fragmented(FAR netpkt_t *pkt)
|
||||
{
|
||||
return pkt->io_flink != NULL;
|
||||
}
|
||||
|
@ -174,6 +174,40 @@ int netdev_lower_register(FAR struct netdev_lowerhalf_s *dev,
|
||||
|
||||
int netdev_lower_unregister(FAR struct netdev_lowerhalf_s *dev);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netdev_lower_carrier_on
|
||||
*
|
||||
* Description:
|
||||
* Notifies the networking layer about an available carrier.
|
||||
* (e.g. a cable was plugged in)
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - The lower half device driver structure
|
||||
*
|
||||
* Returned Value:
|
||||
* 0:Success; negated errno on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int netdev_lower_carrier_on(FAR struct netdev_lowerhalf_s *dev);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netdev_lower_carrier_off
|
||||
*
|
||||
* Description:
|
||||
* Notifies the networking layer about an disappeared carrier.
|
||||
* (e.g. a cable was unplugged)
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - The lower half device driver structure
|
||||
*
|
||||
* Returned Value:
|
||||
* 0:Success; negated errno on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int netdev_lower_carrier_off(FAR struct netdev_lowerhalf_s *dev);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netdev_lower_rxready
|
||||
*
|
||||
@ -278,6 +312,44 @@ int netpkt_copyin(FAR struct netdev_lowerhalf_s *dev, FAR netpkt_t *pkt,
|
||||
int netpkt_copyout(FAR struct netdev_lowerhalf_s *dev, FAR uint8_t *dest,
|
||||
FAR const netpkt_t *pkt, unsigned int len, int offset);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netpkt_getdata/getbase
|
||||
*
|
||||
* Description:
|
||||
* Get the pointer of data/base in a netpkt, used when NETPKT_BUFLEN is
|
||||
* big enough to fit a full packet in.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - The lower half device driver structure
|
||||
* pkt - The net packet
|
||||
*
|
||||
* Returned Value:
|
||||
* Pointer data/base, NULL on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR uint8_t *netpkt_getdata(FAR struct netdev_lowerhalf_s *dev,
|
||||
FAR netpkt_t *pkt);
|
||||
FAR uint8_t *netpkt_getbase(FAR netpkt_t *pkt);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netpkt_setdatalen
|
||||
*
|
||||
* Description:
|
||||
* Set the length of data in netpkt, used when data is written into
|
||||
* netpkt by data/base pointer, no need to set this length after
|
||||
* copyin.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - The lower half device driver structure
|
||||
* pkt - The net packet
|
||||
* len - The length of data in netpkt
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void netpkt_setdatalen(FAR struct netdev_lowerhalf_s *dev,
|
||||
FAR netpkt_t *pkt, unsigned int len);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netpkt_getdatalen
|
||||
*
|
||||
@ -296,4 +368,34 @@ int netpkt_copyout(FAR struct netdev_lowerhalf_s *dev, FAR uint8_t *dest,
|
||||
unsigned int netpkt_getdatalen(FAR struct netdev_lowerhalf_s *dev,
|
||||
FAR netpkt_t *pkt);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netpkt_reset_reserved
|
||||
*
|
||||
* Description:
|
||||
* Reset the reserved length (the starting point of data) of netpkt
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - The lower half device driver structure
|
||||
* pkt - The net packet
|
||||
* len - The reserved length
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void netpkt_reset_reserved(FAR struct netdev_lowerhalf_s *dev,
|
||||
FAR netpkt_t *pkt, unsigned int len);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netpkt_is_fragmented
|
||||
*
|
||||
* Description:
|
||||
* Returns whether the netpkt is fragmented into different blocks.
|
||||
* In other words, NETPKT_BUFLEN < reserved + total data
|
||||
*
|
||||
* Input Parameters:
|
||||
* pkt - The net packet
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
bool netpkt_is_fragmented(FAR netpkt_t *pkt);
|
||||
|
||||
#endif /* __INCLUDE_NUTTX_NET_NETDEV_LOWERHALF_H */
|
||||
|
Loading…
Reference in New Issue
Block a user