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; }
static int bcmf_txpoll(FAR struct net_driver_s *dev) { FAR struct bcmf_dev_s *priv = (FAR struct bcmf_dev_s *)dev->d_private; wlinfo("Entry\n"); /* 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 (priv->bc_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(priv->bc_dev.d_flags)) #endif { arp_out(&priv->bc_dev); } #endif /* CONFIG_NET_IPv4 */ #ifdef CONFIG_NET_IPv6 #ifdef CONFIG_NET_IPv4 else #endif { neighbor_out(&priv->bc_dev); } #endif /* CONFIG_NET_IPv6 */ /* Send the packet */ bcmf_transmit(priv, priv->cur_tx_frame); /* Check if there is room in the device to hold another packet. If not, * return a non-zero value to terminate the poll. */ // TODO priv->cur_tx_frame = NULL; return 1; } /* If zero is returned, the polling will continue until all connections have * been examined. */ return 0; }
static void emac_receive(FAR struct emac_driver_s *priv) { do { /* Check for errors and update statistics */ /* Check if the packet is a valid size for the uIP buffer configuration */ /* Copy the data data from the hardware to priv->d_dev.d_buf. Set * amount of data in priv->d_dev.d_len */ /* We only accept IP packets of the configured type and ARP packets */ #ifdef CONFIG_NET_IPv6 if (BUF->type == HTONS(ETHTYPE_IP6)) #else if (BUF->type == HTONS(ETHTYPE_IP)) #endif { arp_ipin(&priv->d_dev); devif_input(&priv->d_dev); /* If the above function invocation resulted in data that should be * sent out on the network, the field d_len will set to a value > 0. */ if (priv->d_dev.d_len > 0) { arp_out(&priv->d_dev); emac_transmit(priv); } } else if (BUF->type == htons(ETHTYPE_ARP)) { arp_arpin(&priv->d_dev); /* If the above function invocation resulted in data that should be * sent out on the network, the field d_len will set to a value > 0. */ if (priv->d_dev.d_len > 0) { emac_transmit(priv); } } } while (true); /* While there are more packets to be processed */ }
static int sim_txpoll(struct net_driver_s *dev) { /* 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 (g_sim_dev.d_len > 0) { arp_out(&g_sim_dev); netdev_send(g_sim_dev.d_buf, g_sim_dev.d_len); } /* If zero is returned, the polling will continue until all connections have * been examined. */ return 0; }
static int sim_txpoll(struct net_driver_s *dev) { /* 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 (g_sim_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(&g_sim_dev)) #endif { arp_out(&g_sim_dev); } #endif /* CONFIG_NET_IPv4 */ #ifdef CONFIG_NET_IPv6 #ifdef CONFIG_NET_IPv4 else #endif { neighbor_out(&g_sim_dev); } #endif /* CONFIG_NET_IPv6 */ /* Send the packet */ netdev_send(g_sim_dev.d_buf, g_sim_dev.d_len); } /* If zero is returned, the polling will continue until all connections have * been examined. */ return 0; }
static int emac_txpoll(struct net_driver_s *dev) { FAR struct emac_driver_s *priv = (FAR struct emac_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 (priv->d_dev.d_len > 0) { arp_out(&priv->d_dev); emac_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. */ } /* If zero is returned, the polling will continue until all connections have * been examined. */ return 0; }
static void emac_receive(FAR struct emac_driver_s *priv) { do { /* Check for errors and update statistics */ /* Check if the packet is a valid size for the network buffer configuration */ /* Copy the data data from the hardware to priv->d_dev.d_buf. Set * amount of data in priv->d_dev.d_len */ #ifdef CONFIG_NET_PKT /* When packet sockets are enabled, feed the frame into the packet tap */ pkt_input(&priv->d_dev); #endif /* We only accept IP packets of the configured type and ARP packets */ #ifdef CONFIG_NET_IPv4 if (BUF->type == HTONS(ETHTYPE_IP)) { nllvdbg("IPv4 frame\n"); /* Handle ARP on input then give the IPv4 packet to the network * layer */ arp_ipin(&priv->d_dev); ipv4_input(&priv->d_dev); /* If the above function invocation resulted in data that should be * sent out on the network, the field d_len will set to a value > 0. */ if (priv->d_dev.d_len > 0) { /* Update the Ethernet header with the correct MAC address */ #ifdef CONFIG_NET_IPv6 if (IFF_IS_IPv4(priv->d_dev.d_flags)) #endif { arp_out(&priv->d_dev); } #ifdef CONFIG_NET_IPv6 else { neighbor_out(&priv->d_dev); } #endif /* And send the packet */ emac_transmit(priv); } } else #endif #ifdef CONFIG_NET_IPv6 if (BUF->type == HTONS(ETHTYPE_IP6)) { nllvdbg("Iv6 frame\n"); /* Give the IPv6 packet to the network layer */ ipv6_input(&priv->d_dev); /* If the above function invocation resulted in data that should be * sent out on the network, the field d_len will set to a value > 0. */ if (priv->d_dev.d_len > 0) { /* Update the Ethernet header with the correct MAC address */ #ifdef CONFIG_NET_IPv4 if (IFF_IS_IPv4(priv->d_dev.d_flags)) { arp_out(&priv->d_dev); } else #endif #ifdef CONFIG_NET_IPv6 { neighbor_out(&priv->d_dev); } #endif /* And send the packet */ emac_transmit(priv); } } else #endif #ifdef CONFIG_NET_ARP if (BUF->type == htons(ETHTYPE_ARP)) { arp_arpin(&priv->d_dev); /* If the above function invocation resulted in data that should be * sent out on the network, the field d_len will set to a value > 0. */ if (priv->d_dev.d_len > 0) { emac_transmit(priv); } } #endif } while (true); /* While there are more packets to be processed */ }
static void e1000_receive(struct e1000_dev *e1000) { int head = e1000->rx_ring.head; unsigned char *cp = (unsigned char *) (e1000->rx_ring.buf + head * CONFIG_E1000_BUFF_SIZE); int cnt; while (e1000->rx_ring.desc[head].desc_status) { /* Check for errors and update statistics */ /* Here we do not handle packets that exceed packet-buffer size */ if ((e1000->rx_ring.desc[head].desc_status & 3) == 1) { cprintf("NIC READ: Oversized packet\n"); goto next; } /* Check if the packet is a valid size for the uIP buffer configuration */ /* get the number of actual data-bytes in this packet */ cnt = e1000->rx_ring.desc[head].packet_length; if (cnt > CONFIG_NET_ETH_MTU || cnt < 14) { cprintf("NIC READ: invalid package size\n"); goto next; } /* Copy the data data from the hardware to e1000->netdev.d_buf. Set * amount of data in e1000->netdev.d_len */ /* now we try to copy these data-bytes to the UIP buffer */ memcpy(e1000->netdev.d_buf, cp, cnt); e1000->netdev.d_len = cnt; #ifdef CONFIG_NET_PKT /* When packet sockets are enabled, feed the frame into the packet tap */ pkt_input(&e1000->netdev); #endif /* We only accept IP packets of the configured type and ARP packets */ #ifdef CONFIG_NET_IPv4 if (BUF->type == HTONS(ETHTYPE_IP)) { nllvdbg("IPv4 frame\n"); /* Handle ARP on input then give the IPv4 packet to the network * layer */ arp_ipin(&e1000->netdev); ipv4_input(&e1000->netdev); /* If the above function invocation resulted in data that should be * sent out on the network, the field d_len will set to a value > 0. */ if (e1000->netdev.d_len > 0) { /* Update the Ethernet header with the correct MAC address */ #ifdef CONFIG_NET_IPv6 if (IFF_IS_IPv4(e1000->netdev.d_flags)) #endif { arp_out(&e1000->netdev); } #ifdef CONFIG_NET_IPv6 else { neighbor_out(&e1000->netdev); } #endif /* And send the packet */ e1000_transmit(e1000); } } else #endif #ifdef CONFIG_NET_IPv6 if (BUF->type == HTONS(ETHTYPE_IP6)) { nllvdbg("Iv6 frame\n"); /* Give the IPv6 packet to the network layer */ ipv6_input(&e1000->netdev); /* If the above function invocation resulted in data that should be * sent out on the network, the field d_len will set to a value > 0. */ if (e1000->netdev.d_len > 0) { /* Update the Ethernet header with the correct MAC address */ #ifdef CONFIG_NET_IPv4 if (IFF_IS_IPv4(e1000->netdev.d_flags)) { arp_out(&e1000->netdev); } else #endif #ifdef CONFIG_NET_IPv6 { neighbor_out(&e1000->netdev); } #endif /* And send the packet */ e1000_transmit(e1000); } } else #endif #ifdef CONFIG_NET_ARP if (BUF->type == htons(ETHTYPE_ARP)) { arp_arpin(&e1000->netdev); /* If the above function invocation resulted in data that should be * sent out on the network, the field d_len will set to a value > 0. */ if (e1000->netdev.d_len > 0) { e1000_transmit(e1000); } #endif } next: e1000->rx_ring.desc[head].desc_status = 0; e1000->rx_ring.head = (head + 1) % CONFIG_E1000_N_RX_DESC; e1000->rx_ring.free++; head = e1000->rx_ring.head; cp = (unsigned char *)(e1000->rx_ring.buf + head * CONFIG_E1000_BUFF_SIZE); } }
static void bcmf_receive(FAR struct bcmf_dev_s *priv) { struct bcmf_frame_s *frame; // wlinfo("Entry\n"); do { /* Request frame buffer from bus interface */ frame = bcmf_bdc_rx_frame(priv); if (frame == NULL) { /* No more frame to process */ break; } if (!priv->bc_bifup) { /* Interface down, drop frame */ priv->bus->free_frame(priv, frame); continue; } priv->bc_dev.d_buf = frame->data; priv->bc_dev.d_len = frame->len - (uint32_t)(frame->data - frame->base); wlinfo("Got frame %p %d\n", frame, priv->bc_dev.d_len); #ifdef CONFIG_NET_PKT /* When packet sockets are enabled, feed the frame into the packet tap */ pkt_input(&priv->bc_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"); NETDEV_RXIPV4(&priv->bc_dev); /* Handle ARP on input then give the IPv4 packet to the network * layer */ arp_ipin(&priv->bc_dev); ipv4_input(&priv->bc_dev); /* If the above function invocation resulted in data that should be * sent out on the network, the field d_len will set to a value > 0. */ if (priv->bc_dev.d_len > 0) { /* Update the Ethernet header with the correct MAC address */ #ifdef CONFIG_NET_IPv6 if (IFF_IS_IPv4(priv->bc_dev.d_flags)) #endif { arp_out(&priv->bc_dev); } #ifdef CONFIG_NET_IPv6 else { neighbor_out(&kel->bc_dev); } #endif /* And send the packet */ bcmf_transmit(priv, frame); } else { /* Release RX frame buffer */ priv->bus->free_frame(priv, frame); } } else #endif #ifdef CONFIG_NET_IPv6 if (BUF->type == HTONS(ETHTYPE_IP6)) { ninfo("Iv6 frame\n"); NETDEV_RXIPV6(&priv->bc_dev); /* Give the IPv6 packet to the network layer */ ipv6_input(&priv->bc_dev); /* If the above function invocation resulted in data that should be * sent out on the network, the field d_len will set to a value > 0. */ if (priv->bc_dev.d_len > 0) { /* Update the Ethernet header with the correct MAC address */ #ifdef CONFIG_NET_IPv4 if (IFF_IS_IPv4(priv->bc_dev.d_flags)) { arp_out(&priv->bc_dev); } else #endif #ifdef CONFIG_NET_IPv6 { neighbor_out(&priv->bc_dev); } #endif /* And send the packet */ bcmf_transmit(priv, frame); } else { /* Release RX frame buffer */ priv->bus->free_frame(priv, frame); } } else #endif #ifdef CONFIG_NET_ARP if (BUF->type == htons(ETHTYPE_ARP)) { arp_arpin(&priv->bc_dev); NETDEV_RXARP(&priv->bc_dev); /* If the above function invocation resulted in data that should be * sent out on the network, the field d_len will set to a value > 0. */ if (priv->bc_dev.d_len > 0) { bcmf_transmit(priv, frame); } else { /* Release RX frame buffer */ priv->bus->free_frame(priv, frame); } } else #endif { wlerr("ERROR: RX dropped\n"); NETDEV_RXDROPPED(&priv->bc_dev); priv->bus->free_frame(priv, frame); } } while (1); /* While there are more packets to be processed */ }
void netdriver_loop(void) { FAR struct eth_hdr_s *eth; /* Check for new frames. If so, then poll the network for new XMIT data */ net_lock(); (void)devif_poll(&g_sim_dev, sim_txpoll); net_unlock(); /* netdev_read will return 0 on a timeout event and >0 on a data received event */ g_sim_dev.d_len = netdev_read((FAR unsigned char *)g_sim_dev.d_buf, CONFIG_NET_ETH_MTU); /* Disable preemption through to the following so that it behaves a little more * like an interrupt (otherwise, the following logic gets pre-empted an behaves * oddly. */ sched_lock(); if (g_sim_dev.d_len > 0) { /* Data received event. Check for valid Ethernet header with destination == our * MAC address */ eth = BUF; if (g_sim_dev.d_len > ETH_HDRLEN) { int is_ours; /* Figure out if this ethernet frame is addressed to us. This affects * what we're willing to receive. Note that in promiscuous mode, the * up_comparemac will always return 0. */ is_ours = (up_comparemac(eth->dest, &g_sim_dev.d_mac.ether) == 0); #ifdef CONFIG_NET_PKT /* When packet sockets are enabled, feed the frame into the packet * tap. */ if (is_ours) { pkt_input(&g_sim_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) && is_ours) { ninfo("IPv4 frame\n"); /* Handle ARP on input then give the IPv4 packet to the network * layer */ arp_ipin(&g_sim_dev); ipv4_input(&g_sim_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 (g_sim_dev.d_len > 0) { /* Update the Ethernet header with the correct MAC address */ #ifdef CONFIG_NET_IPv6 if (IFF_IS_IPv4(g_sim_dev.d_flags)) #endif { arp_out(&g_sim_dev); } #ifdef CONFIG_NET_IPv6 else { neighbor_out(&g_sim_dev); } #endif /* And send the packet */ netdev_send(g_sim_dev.d_buf, g_sim_dev.d_len); } } else #endif /* CONFIG_NET_IPv4 */ #ifdef CONFIG_NET_IPv6 if (eth->type == HTONS(ETHTYPE_IP6) && is_ours) { ninfo("Iv6 frame\n"); /* Give the IPv6 packet to the network layer */ ipv6_input(&g_sim_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 (g_sim_dev.d_len > 0) { /* Update the Ethernet header with the correct MAC address */ #ifdef CONFIG_NET_IPv4 if (IFF_IS_IPv4(g_sim_dev.d_flags)) { arp_out(&g_sim_dev); } else #endif #ifdef CONFIG_NET_IPv6 { neighbor_out(&g_sim_dev); } #endif /* CONFIG_NET_IPv6 */ /* And send the packet */ netdev_send(g_sim_dev.d_buf, g_sim_dev.d_len); } } else #endif/* CONFIG_NET_IPv6 */ #ifdef CONFIG_NET_ARP if (eth->type == htons(ETHTYPE_ARP)) { arp_arpin(&g_sim_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 (g_sim_dev.d_len > 0) { netdev_send(g_sim_dev.d_buf, g_sim_dev.d_len); } } else #endif { nwarn("WARNING: Unsupported Ethernet type %u\n", eth->type); } } } /* Otherwise, it must be a timeout event */ else if (timer_expired(&g_periodic_timer)) { timer_reset(&g_periodic_timer); devif_timer(&g_sim_dev, sim_txpoll); } sched_unlock(); }
static void misoc_net_receive(FAR struct misoc_net_driver_s *priv) { uint8_t rxslot; uint32_t rxlen; do { /* Check for errors and update statistics */ /* Check if the packet is a valid size for the network buffer * configuration. */ /* Find rx slot */ rxslot = ethmac_sram_writer_slot_read(); /* Get rx len */ rxlen = ethmac_sram_writer_length_read(); /* Copy the data data from the hardware to priv->misoc_net_dev.d_buf. Set * amount of data in priv->misoc_net_dev.d_len * * NOTE: These memcpy's could be avoided by simply setting the d_buf * pointer to the rx*_buf containing the received data. Some additional * buffer management logic would also be required. */ misoc_flush_dcache(); if (rxslot) { memcpy(priv->misoc_net_dev.d_buf, priv->rx1_buf, rxlen); } else { memcpy(priv->misoc_net_dev.d_buf, priv->rx0_buf, rxlen); } /* Clear event pending */ ethmac_sram_writer_ev_pending_write(1); priv->misoc_net_dev.d_len = rxlen; #ifdef CONFIG_NET_PKT /* When packet sockets are enabled, feed the frame into the packet tap */ pkt_input(&priv->misoc_net_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"); NETDEV_RXIPV4(&priv->misoc_net_dev); /* Handle ARP on input then give the IPv4 packet to the network * layer */ arp_ipin(&priv->misoc_net_dev); ipv4_input(&priv->misoc_net_dev); /* If the above function invocation resulted in data that should be * sent out on the network, the field d_len will set to a value > 0. */ if (priv->misoc_net_dev.d_len > 0) { /* Update the Ethernet header with the correct MAC address */ #ifdef CONFIG_NET_IPv6 if (IFF_IS_IPv4(priv->misoc_net_dev.d_flags)) #endif { arp_out(&priv->misoc_net_dev); } #ifdef CONFIG_NET_IPv6 else { neighbor_out(&kel->misoc_net_dev); } #endif /* And send the packet */ misoc_net_transmit(priv); } } else #endif #ifdef CONFIG_NET_IPv6 if (BUF->type == HTONS(ETHTYPE_IP6)) { ninfo("Iv6 frame\n"); NETDEV_RXIPV6(&priv->misoc_net_dev); /* Give the IPv6 packet to the network layer */ ipv6_input(&priv->misoc_net_dev); /* If the above function invocation resulted in data that should be * sent out on the network, the field d_len will set to a value > 0. */ if (priv->misoc_net_dev.d_len > 0) { /* Update the Ethernet header with the correct MAC address */ #ifdef CONFIG_NET_IPv4 if (IFF_IS_IPv4(priv->misoc_net_dev.d_flags)) { arp_out(&priv->misoc_net_dev); } else #endif #ifdef CONFIG_NET_IPv6 { neighbor_out(&priv->misoc_net_dev); } #endif /* And send the packet */ misoc_net_transmit(priv); } } else #endif #ifdef CONFIG_NET_ARP if (BUF->type == htons(ETHTYPE_ARP)) { arp_arpin(&priv->misoc_net_dev); NETDEV_RXARP(&priv->misoc_net_dev); /* If the above function invocation resulted in data that should be * sent out on the network, the field d_len will set to a value > 0. */ if (priv->misoc_net_dev.d_len > 0) { misoc_net_transmit(priv); } } #endif else { NETDEV_RXDROPPED(&priv->misoc_net_dev); } } while (ethmac_sram_writer_ev_pending_read() & ETHMAC_EV_SRAM_WRITER); }
void netdriver_loop(void) { /* netdev_read will return 0 on a timeout event and >0 on a data received event */ g_sim_dev.d_len = netdev_read((unsigned char*)g_sim_dev.d_buf, CONFIG_NET_ETH_MTU); /* Disable preemption through to the following so that it behaves a little more * like an interrupt (otherwise, the following logic gets pre-empted an behaves * oddly. */ sched_lock(); if (g_sim_dev.d_len > 0) { /* Data received event. Check for valid Ethernet header with destination == our * MAC address */ if (g_sim_dev.d_len > ETH_HDRLEN && up_comparemac(BUF->ether_dhost, &g_sim_dev.d_mac) == 0) { /* We only accept IP packets of the configured type and ARP packets */ #ifdef CONFIG_NET_IPv6 if (BUF->ether_type == htons(ETHTYPE_IP6)) #else if (BUF->ether_type == htons(ETHTYPE_IP)) #endif { arp_ipin(&g_sim_dev); devif_input(&g_sim_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 (g_sim_dev.d_len > 0) { arp_out(&g_sim_dev); netdev_send(g_sim_dev.d_buf, g_sim_dev.d_len); } } else if (BUF->ether_type == htons(ETHTYPE_ARP)) { arp_arpin(&g_sim_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 (g_sim_dev.d_len > 0) { netdev_send(g_sim_dev.d_buf, g_sim_dev.d_len); } } } } /* Otherwise, it must be a timeout event */ else if (timer_expired(&g_periodic_timer)) { timer_reset(&g_periodic_timer); devif_timer(&g_sim_dev, sim_txpoll, 1); } sched_unlock(); }
void rtos_vnet_recv(struct rgmp_vnet *rgmp_vnet, char *data, int len) { struct vnet_driver_s *vnet = rgmp_vnet->priv; do { /* Check if the packet is a valid size for the network buffer * configuration. */ if (len > CONFIG_NET_ETH_MTU || len < 14) { #ifdef CONFIG_DEBUG cprintf("VNET: receive invalid packet of size %d\n", len); #endif return; } /* Copy the data data from the hardware to vnet->sk_dev.d_buf. Set * amount of data in vnet->sk_dev.d_len */ memcpy(vnet->sk_dev.d_buf, data, len); vnet->sk_dev.d_len = len; #ifdef CONFIG_NET_PKT /* When packet sockets are enabled, feed the frame into the packet tap */ pkt_input(&vnet->sk_dev); #endif /* We only accept IP packets of the configured type and ARP packets */ #ifdef CONFIG_NET_IPv4 if (BUF->type == HTONS(ETHTYPE_IP)) { nllvdbg("IPv4 frame\n"); /* Handle ARP on input then give the IPv4 packet to the network * layer */ arp_ipin(&vnet->sk_dev); ipv4_input(&vnet->sk_dev); /* If the above function invocation resulted in data that should be * sent out on the network, the field d_len will set to a value > 0. */ if (vnet->sk_dev.d_len > 0) { /* Update the Ethernet header with the correct MAC address */ #ifdef CONFIG_NET_IPv6 if (IFF_IS_IPv4(vnet->sk_dev.d_flags)) #endif { arp_out(&vnet->sk_dev); } #ifdef CONFIG_NET_IPv6 else { neighbor_out(&vnet->sk_dev); } #endif /* And send the packet */ vnet_transmit(vnet); } } else #endif #ifdef CONFIG_NET_IPv6 if (BUF->type == HTONS(ETHTYPE_IP6)) { nllvdbg("Iv6 frame\n"); /* Give the IPv6 packet to the network layer */ ipv6_input(&vnet->sk_dev); /* If the above function invocation resulted in data that should be * sent out on the network, the field d_len will set to a value > 0. */ if (vnet->sk_dev.d_len > 0) { /* Update the Ethernet header with the correct MAC address */ #ifdef CONFIG_NET_IPv4 if (IFF_IS_IPv4(vnet->sk_dev.d_flags)) { arp_out(&vnet->sk_dev); } else #endif #ifdef CONFIG_NET_IPv6 { neighbor_out(&vnet->sk_dev); } #endif /* And send the packet */ vnet_transmit(vnet); } } else #endif #ifdef CONFIG_NET_ARP if (BUF->type == htons(ETHTYPE_ARP)) { arp_arpin(&vnet->sk_dev); /* If the above function invocation resulted in data that should * be sent out on the network, the field d_len will set to a * value > 0. */ if (vnet->sk_dev.d_len > 0) { vnet_transmit(vnet); } } #endif } while (0); /* While there are more packets to be processed */ }
static void e1000_receive(struct e1000_dev *e1000) { int head = e1000->rx_ring.head; unsigned char *cp = (unsigned char *) (e1000->rx_ring.buf + head * CONFIG_E1000_BUFF_SIZE); int cnt; while (e1000->rx_ring.desc[head].desc_status) { /* Check for errors and update statistics */ /* Here we do not handle packets that exceed packet-buffer size */ if ((e1000->rx_ring.desc[head].desc_status & 3) == 1) { cprintf("NIC READ: Oversized packet\n"); goto next; } /* Check if the packet is a valid size for the uIP buffer configuration */ /* get the number of actual data-bytes in this packet */ cnt = e1000->rx_ring.desc[head].packet_length; if (cnt > CONFIG_NET_BUFSIZE || cnt < 14) { cprintf("NIC READ: invalid package size\n"); goto next; } /* Copy the data data from the hardware to e1000->uip_dev.d_buf. Set * amount of data in e1000->uip_dev.d_len */ /* now we try to copy these data-bytes to the UIP buffer */ memcpy(e1000->uip_dev.d_buf, cp, cnt); e1000->uip_dev.d_len = cnt; /* We only accept IP packets of the configured type and ARP packets */ #ifdef CONFIG_NET_IPv6 if (BUF->type == HTONS(UIP_ETHTYPE_IP6)) #else { if (BUF->type == HTONS(UIP_ETHTYPE_IP)) #endif { arp_ipin(&e1000->uip_dev); uip_input(&e1000->uip_dev); /* If the above function invocation resulted in data that should be * sent out on the network, the field d_len will set to a value > 0. */ if (e1000->uip_dev.d_len > 0) { arp_out(&e1000->uip_dev); e1000_transmit(e1000); } } else if (BUF->type == htons(UIP_ETHTYPE_ARP)) { arp_arpin(&e1000->uip_dev); /* If the above function invocation resulted in data that should be * sent out on the network, the field d_len will set to a value > 0. */ if (e1000->uip_dev.d_len > 0) { e1000_transmit(e1000); } } } next: e1000->rx_ring.desc[head].desc_status = 0; e1000->rx_ring.head = (head + 1) % CONFIG_E1000_N_RX_DESC; e1000->rx_ring.free++; head = e1000->rx_ring.head; cp = (unsigned char *)(e1000->rx_ring.buf + head * CONFIG_E1000_BUFF_SIZE); } }