static void misoc_net_interrupt_work(FAR void *arg) { FAR struct misoc_net_driver_s *priv = (FAR struct misoc_net_driver_s *)arg; /* Process pending Ethernet interrupts */ net_lock(); /* Check if we received an incoming packet, if so, call misoc_net_receive() */ if (ethmac_sram_writer_ev_pending_read() & ETHMAC_EV_SRAM_WRITER) { misoc_net_receive(priv); } /* Check if a packet transmission just completed. If so, call misoc_net_txdone. * This may disable further Tx interrupts if there are no pending * transmissions. */ if (ethmac_sram_reader_ev_pending_read() & ETHMAC_EV_SRAM_READER) { misoc_net_txdone(priv); ethmac_sram_reader_ev_pending_write(1); } net_unlock(); /* Re-enable Ethernet interrupts */ up_enable_irq(ETHMAC_INTERRUPT); }
static struct pbuf *liteeth_low_level_input(struct netif *netif) { unsigned int rxslot; unsigned int rxlen; char *rxbuffer; struct pbuf *p, *q; p = NULL; if(ethmac_sram_writer_ev_pending_read() & ETHMAC_EV_SRAM_WRITER) { rxslot = ethmac_sram_writer_slot_read(); rxlen = ethmac_sram_writer_length_read(); /* dest MAC + source MAC + 802.1Q + ethertype + payload (MTU) */ if(rxlen <= (netif->mtu + 18)) { if(rxslot) rxbuffer = rxbuffer1; else rxbuffer = rxbuffer0; p = pbuf_alloc(PBUF_RAW, rxlen, PBUF_POOL); q = p; while(q) { memcpy(q->payload, rxbuffer, q->len); rxbuffer += q->len; if(q->tot_len != q->len) q = q->next; else q = NULL; } } ethmac_sram_writer_ev_pending_write(ETHMAC_EV_SRAM_WRITER); } return p; }
static void lwip_service(void) { sys_check_timeouts(); if(ethmac_sram_writer_ev_pending_read() & ETHMAC_EV_SRAM_WRITER) { liteeth_input(&netif); ethmac_sram_writer_ev_pending_write(ETHMAC_EV_SRAM_WRITER); } }
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); }