static int vnet_txavail(struct net_driver_s *dev) { FAR struct vnet_driver_s *vnet = (FAR struct vnet_driver_s *)dev->d_private; irqstate_t flags; /* Disable interrupts because this function may be called from interrupt * level processing. */ flags = enter_critical_section(); /* Ignore the notification if the interface is not yet up */ if (vnet->sk_bifup) { /* Check if there is room in the hardware to hold another outgoing packet. */ if (vnet_is_txbuff_full(vnet->vnet)) { #ifdef CONFIG_DEBUG cprintf("VNET: TX buffer is full\n"); #endif goto out; } /* If so, then poll the network for new XMIT data */ (void)devif_poll(&vnet->sk_dev, vnet_txpoll); } out: leave_critical_section(flags); return OK; }
static void vnet_polltimer(int argc, uint32_t arg, ...) { FAR struct vnet_driver_s *vnet = (FAR struct vnet_driver_s *)arg; /* Check if there is room in the send another TX packet. We cannot perform * the TX poll if he are unable to accept another packet for transmission. */ if (vnet_is_txbuff_full(vnet->vnet)) { #ifdef CONFIG_DEBUG cprintf("VNET: TX buffer is full\n"); #endif return; } /* If so, update TCP timing states and poll the network for new XMIT data. * Hmmm.. might be bug here. Does this mean if there is a transmit in * progress, we will missing TCP time state updates? */ (void)devif_timer(&vnet->sk_dev, vnet_txpoll); /* Setup the watchdog poll timer again */ (void)wd_start(vnet->sk_txpoll, VNET_WDDELAY, vnet_polltimer, 1, (wdparm_t)arg); }
static int vnet_uiptxpoll(struct uip_driver_s *dev) { FAR struct vnet_driver_s *vnet = (FAR struct vnet_driver_s *)dev->d_private; /* If the polling resulted in data that should be sent out on the network, * the field d_len is set to a value > 0. */ if (vnet->sk_dev.d_len > 0) { uip_arp_out(&vnet->sk_dev); vnet_transmit(vnet); /* Check if there is room in the device to hold another packet. If not, * return a non-zero value to terminate the poll. */ if (vnet_is_txbuff_full(vnet->vnet)) return 1; } /* If zero is returned, the polling will continue until all connections have * been examined. */ return 0; }
static int vnet_txpoll(struct net_driver_s *dev) { FAR struct vnet_driver_s *vnet = (FAR struct vnet_driver_s *)dev->d_private; /* If the polling resulted in data that should be sent out on the network, * the field d_len is set to a value > 0. */ if (vnet->sk_dev.d_len > 0) { /* Look up the destination MAC address and add it to the Ethernet * header. */ #ifdef CONFIG_NET_IPv4 #ifdef CONFIG_NET_IPv6 if (IFF_IS_IPv4(vnet->sk_dev.d_flags)) #endif { arp_out(&vnet->sk_dev); } #endif /* CONFIG_NET_IPv4 */ #ifdef CONFIG_NET_IPv6 #ifdef CONFIG_NET_IPv4 else #endif { neighbor_out(&vnet->sk_dev); } #endif /* CONFIG_NET_IPv6 */ /* Send the packet */ vnet_transmit(vnet); /* Check if there is room in the device to hold another packet. If not, * return a non-zero value to terminate the poll. */ if (vnet_is_txbuff_full(vnet->vnet)) { return 1; } } /* If zero is returned, the polling will continue until all connections have * been examined. */ return 0; }