sim/netdev: retrieve all the queued RX frames from the network device on every poll.

As a result, the RX throughput is increased significantly w/o harming the TX throughput.
This commit is contained in:
Alexander Lunev 2022-01-22 02:57:45 +03:00 committed by Xiang Xiao
parent 021363f1db
commit f73abc76d5

View File

@ -120,99 +120,107 @@ static void netdriver_recv_work(FAR void *arg)
net_lock();
/* netdev_read will return 0 on a timeout event and > 0
* on a data received event
/* Retrieve all the queued RX frames from the network device
* to prevent RX data stream congestion.
*/
dev->d_len = netdev_read((FAR unsigned char *)dev->d_buf,
dev->d_pktsize);
if (dev->d_len > 0)
while (netdev_avail())
{
NETDEV_RXPACKETS(dev);
/* Data received event. Check for valid Ethernet header with
* destination == our MAC address
/* netdev_read will return 0 on a timeout event and > 0
* on a data received event
*/
eth = (FAR struct eth_hdr_s *)dev->d_buf;
if (dev->d_len > ETH_HDRLEN)
dev->d_len = netdev_read((FAR unsigned char *)dev->d_buf,
dev->d_pktsize);
if (dev->d_len > 0)
{
#ifdef CONFIG_NET_PKT
/* When packet sockets are enabled, feed the frame into the packet
* tap.
NETDEV_RXPACKETS(dev);
/* Data received event. Check for valid Ethernet header with
* destination == our MAC address
*/
pkt_input(dev);
eth = (FAR 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
*/
/* 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);
if (eth->type == HTONS(ETHTYPE_IP))
{
ninfo("IPv4 frame\n");
NETDEV_RXIPV4(dev);
/* Handle ARP on input then give the IPv4 packet to the network
* layer
*/
/* Handle ARP on input then give the IPv4 packet to
* the network layer
*/
arp_ipin(dev);
ipv4_input(dev);
arp_ipin(dev);
ipv4_input(dev);
/* Check for a reply to the IPv4 packet */
/* Check for a reply to the IPv4 packet */
netdriver_reply(dev);
}
else
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);
if (eth->type == HTONS(ETHTYPE_IP6))
{
ninfo("IPv6 frame\n");
NETDEV_RXIPV6(dev);
/* Give the IPv6 packet to the network layer */
/* Give the IPv6 packet to the network layer */
ipv6_input(dev);
ipv6_input(dev);
/* Check for a reply to the IPv6 packet */
/* Check for a reply to the IPv6 packet */
netdriver_reply(dev);
}
else
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_arpin(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)
if (eth->type == HTONS(ETHTYPE_ARP))
{
netdev_send(dev->d_buf, dev->d_len);
ninfo("ARP frame\n");
NETDEV_RXARP(dev);
arp_arpin(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)
{
netdev_send(dev->d_buf, dev->d_len);
}
}
else
#endif
{
NETDEV_RXDROPPED(dev);
nwarn("WARNING: Unsupported Ethernet type %u\n",
eth->type);
}
}
else
#endif
{
NETDEV_RXDROPPED(dev);
nwarn("WARNING: Unsupported Ethernet type %u\n", eth->type);
NETDEV_RXERRORS(dev);
}
}
else
{
NETDEV_RXERRORS(dev);
}
}
net_unlock();