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/kmalloc.h>
|
||||||
#include <nuttx/wqueue.h>
|
#include <nuttx/wqueue.h>
|
||||||
#include <nuttx/net/net.h>
|
#include <nuttx/net/net.h>
|
||||||
#include <nuttx/net/netdev.h>
|
#include <nuttx/net/netdev_lowerhalf.h>
|
||||||
#include <nuttx/net/pkt.h>
|
#include <nuttx/net/pkt.h>
|
||||||
|
|
||||||
#include "sim_internal.h"
|
#include "sim_internal.h"
|
||||||
|
|
||||||
#if CONFIG_IOB_BUFSIZE >= (MAX_NETDEV_PKTSIZE + \
|
#define SIM_NETDEV_BUFSIZE (MAX_NETDEV_PKTSIZE + CONFIG_NET_GUARDSIZE)
|
||||||
CONFIG_NET_GUARDSIZE + CONFIG_NET_LL_GUARDSIZE)
|
|
||||||
# define SIM_NETDEV_IOB_OFFLOAD
|
/* 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
|
#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
|
* 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
|
* 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 */
|
/* 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
|
* 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;
|
unsigned int len = netpkt_getdatalen(dev, pkt);
|
||||||
#ifdef SIM_NETDEV_IOB_OFFLOAD
|
|
||||||
uint8_t *buf = NETLLBUF;
|
|
||||||
#else
|
|
||||||
uint8_t *buf = dev->d_buf;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
UNUSED(devidx);
|
if (netpkt_is_fragmented(pkt))
|
||||||
|
|
||||||
#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)
|
|
||||||
{
|
{
|
||||||
/* Send the packet */
|
netpkt_copyout(dev, DEVBUF(dev), pkt, len, 0);
|
||||||
|
sim_netdev_send(DEVIDX(dev), DEVBUF(dev), len);
|
||||||
NETDEV_TXPACKETS(dev);
|
|
||||||
netdriver_send(dev);
|
|
||||||
NETDEV_TXDONE(dev);
|
|
||||||
}
|
}
|
||||||
|
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;
|
netpkt_t *pkt = NULL;
|
||||||
struct eth_hdr_s *eth;
|
unsigned int len;
|
||||||
int devidx = (intptr_t)dev->d_private;
|
|
||||||
|
|
||||||
UNUSED(devidx);
|
if (sim_netdev_avail(DEVIDX(dev)))
|
||||||
|
|
||||||
net_lock();
|
|
||||||
|
|
||||||
/* Retrieve all the queued RX frames from the network device
|
|
||||||
* to prevent RX data stream congestion.
|
|
||||||
*/
|
|
||||||
|
|
||||||
while (sim_netdev_avail(devidx))
|
|
||||||
{
|
{
|
||||||
#ifdef SIM_NETDEV_IOB_OFFLOAD
|
pkt = netpkt_alloc(dev, NETPKT_RX);
|
||||||
if (netdev_iob_prepare(dev, false, 0) != OK)
|
if (pkt == NULL)
|
||||||
{
|
{
|
||||||
netdriver_txdone_interrupt(dev);
|
return NULL;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* sim_netdev_read will return 0 on a timeout event and > 0
|
/* sim_netdev_read will return 0 on a timeout event and > 0
|
||||||
* on a data received event
|
* on a data received event
|
||||||
*/
|
*/
|
||||||
|
|
||||||
dev->d_len = sim_netdev_read(devidx,
|
#ifdef SIM_NETDEV_RECV_OFFLOAD
|
||||||
(unsigned char *)dev->d_buf,
|
len = sim_netdev_read(DEVIDX(dev), netpkt_getbase(pkt),
|
||||||
dev->d_pktsize);
|
SIM_NETDEV_BUFSIZE);
|
||||||
if (dev->d_len > 0)
|
#else
|
||||||
|
len = sim_netdev_read(DEVIDX(dev), DEVBUF(dev), SIM_NETDEV_BUFSIZE);
|
||||||
|
#endif
|
||||||
|
if (len == 0)
|
||||||
{
|
{
|
||||||
NETDEV_RXPACKETS(dev);
|
netpkt_free(dev, pkt, NETPKT_RX);
|
||||||
|
return NULL;
|
||||||
#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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SIM_NETDEV_IOB_OFFLOAD
|
#ifdef SIM_NETDEV_RECV_OFFLOAD
|
||||||
netdev_iob_release(dev);
|
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
|
#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
|
#ifdef CONFIG_NET_IPv4
|
||||||
sim_netdev_ifup(devidx, &dev->d_ipaddr);
|
sim_netdev_ifup(DEVIDX(dev), &dev->netdev.d_ipaddr);
|
||||||
#else /* CONFIG_NET_IPv6 */
|
#else /* CONFIG_NET_IPv6 */
|
||||||
sim_netdev_ifup(devidx, &dev->d_ipv6addr);
|
sim_netdev_ifup(DEVIDX(dev), &dev->netdev.d_ipv6addr);
|
||||||
#endif /* CONFIG_NET_IPv4 */
|
#endif /* CONFIG_NET_IPv4 */
|
||||||
netdev_carrier_on(dev);
|
netdev_lower_carrier_on(dev);
|
||||||
return OK;
|
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;
|
netdev_lower_carrier_off(dev);
|
||||||
|
sim_netdev_ifdown(DEVIDX(dev));
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void netdriver_txdone_interrupt(void *priv)
|
static void netdriver_txdone_interrupt(void *priv)
|
||||||
{
|
{
|
||||||
struct net_driver_s *dev = (struct net_driver_s *)priv;
|
struct netdev_lowerhalf_s *dev = (struct netdev_lowerhalf_s *)priv;
|
||||||
int devidx = (intptr_t)dev->d_private;
|
netdev_lower_txdone(dev);
|
||||||
if (work_available(&g_avail_work[devidx]))
|
|
||||||
{
|
|
||||||
work_queue(LPWORK, &g_avail_work[devidx], netdriver_txavail_work,
|
|
||||||
dev, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void netdriver_rxready_interrupt(void *priv)
|
static void netdriver_rxready_interrupt(void *priv)
|
||||||
{
|
{
|
||||||
struct net_driver_s *dev = (struct net_driver_s *)priv;
|
struct netdev_lowerhalf_s *dev = (struct netdev_lowerhalf_s *)priv;
|
||||||
int devidx = (intptr_t)dev->d_private;
|
netdev_lower_rxready(dev);
|
||||||
if (work_available(&g_recv_work[devidx]))
|
|
||||||
{
|
|
||||||
work_queue(LPWORK, &g_recv_work[devidx], netdriver_recv_work, dev, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -356,42 +218,30 @@ static void netdriver_rxready_interrupt(void *priv)
|
|||||||
|
|
||||||
int sim_netdriver_init(void)
|
int sim_netdriver_init(void)
|
||||||
{
|
{
|
||||||
struct net_driver_s *dev;
|
struct netdev_lowerhalf_s *dev;
|
||||||
int devidx;
|
int devidx;
|
||||||
|
|
||||||
for (devidx = 0; devidx < CONFIG_SIM_NETDEV_NUMBER; devidx++)
|
for (devidx = 0; devidx < CONFIG_SIM_NETDEV_NUMBER; devidx++)
|
||||||
{
|
{
|
||||||
dev = &g_sim_dev[devidx];
|
dev = &g_sim_dev[devidx].dev;
|
||||||
|
|
||||||
/* Internal initialization */
|
/* Internal initialization */
|
||||||
|
|
||||||
sim_netdev_init(devidx, dev,
|
sim_netdev_init(devidx, dev,
|
||||||
netdriver_txdone_interrupt,
|
netdriver_txdone_interrupt,
|
||||||
netdriver_rxready_interrupt);
|
netdriver_rxready_interrupt);
|
||||||
|
|
||||||
/* Allocate packet buffer */
|
/* 1TX + 1RX is enough for sim. */
|
||||||
|
|
||||||
#ifndef SIM_NETDEV_IOB_OFFLOAD
|
dev->quota[NETPKT_TX] = 1;
|
||||||
dev->d_buf = kmm_malloc(dev->d_pktsize != 0 ?
|
dev->quota[NETPKT_RX] = 1;
|
||||||
dev->d_pktsize :
|
dev->ops = &g_ops;
|
||||||
(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;
|
|
||||||
|
|
||||||
/* Register the device with the OS so that socket IOCTLs can be
|
/* Register the device with the OS so that socket IOCTLs can be
|
||||||
* performed
|
* performed
|
||||||
*/
|
*/
|
||||||
|
|
||||||
netdev_register(dev, NET_LL_ETHERNET);
|
netdev_lower_register(dev, NET_LL_ETHERNET);
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
@ -399,13 +249,13 @@ int sim_netdriver_init(void)
|
|||||||
|
|
||||||
void sim_netdriver_setmacaddr(int devidx, unsigned char *macaddr)
|
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);
|
IFHWADDRLEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sim_netdriver_setmtu(int devidx, int mtu)
|
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)
|
void sim_netdriver_loop(void)
|
||||||
@ -413,10 +263,9 @@ void sim_netdriver_loop(void)
|
|||||||
int devidx;
|
int devidx;
|
||||||
for (devidx = 0; devidx < CONFIG_SIM_NETDEV_NUMBER; 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,
|
netdev_lower_rxready(&g_sim_dev[devidx].dev);
|
||||||
&g_sim_dev[devidx], 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -633,6 +633,46 @@ int netdev_lower_unregister(FAR struct netdev_lowerhalf_s *dev)
|
|||||||
return OK;
|
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
|
* 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));
|
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
|
* 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);
|
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);
|
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
|
* 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,
|
int netpkt_copyout(FAR struct netdev_lowerhalf_s *dev, FAR uint8_t *dest,
|
||||||
FAR const netpkt_t *pkt, unsigned int len, int offset);
|
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
|
* 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,
|
unsigned int netpkt_getdatalen(FAR struct netdev_lowerhalf_s *dev,
|
||||||
FAR netpkt_t *pkt);
|
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 */
|
#endif /* __INCLUDE_NUTTX_NET_NETDEV_LOWERHALF_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user