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; }
err_t liteeth_init(struct netif *netif) { int i; netif->hwaddr_len = 6; for(i=0;i<netif->hwaddr_len;i++) netif->hwaddr[i] = macadr[i]; netif->name[0] = IFNAME0; netif->name[1] = IFNAME1; netif->output = etharp_output; netif->linkoutput = liteeth_low_level_output; netif->mtu = 1500; netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; ethmac_sram_reader_ev_pending_write(ETHMAC_EV_SRAM_READER); ethmac_sram_writer_ev_pending_write(ETHMAC_EV_SRAM_WRITER); rxbuffer0 = (char *)ETHMAC_RX0_BASE; rxbuffer1 = (char *)ETHMAC_RX1_BASE; txbuffer0 = (char *)ETHMAC_TX0_BASE; txbuffer1 = (char *)ETHMAC_TX1_BASE; txslot = 0; txbuffer = txbuffer0; return ERR_OK; }
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 liteeth_low_level_init(struct netif *netif) { int i; netif->hwaddr_len = 6; for(i=0;i<netif->hwaddr_len;i++) netif->hwaddr[i] = macadr[i]; netif->mtu = 1514; netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; ethmac_sram_reader_ev_pending_write(ETHMAC_EV_SRAM_READER); ethmac_sram_writer_ev_pending_write(ETHMAC_EV_SRAM_WRITER); rxbuffer0 = (char *)ETHMAC_RX0_BASE; rxbuffer1 = (char *)ETHMAC_RX1_BASE; txbuffer0 = (char *)ETHMAC_TX0_BASE; txbuffer1 = (char *)ETHMAC_TX1_BASE; rxslot = 0; txslot = 0; rxbuffer = rxbuffer0; txbuffer = txbuffer0; }
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); }
int misoc_net_initialize(int intf) { FAR struct misoc_net_driver_s *priv; /* Get the interface structure associated with this interface number. */ DEBUGASSERT(intf < CONFIG_MISOC_NET_NINTERFACES); priv = &g_misoc_net[intf]; /* Check if a Ethernet chip is recognized at its I/O base */ /* Attach the IRQ to the driver */ if (irq_attach(ETHMAC_INTERRUPT, misoc_net_interrupt, NULL)) { /* We could not attach the ISR to the interrupt */ return -EAGAIN; } /* clear pending int */ ethmac_sram_writer_ev_pending_write(1); ethmac_sram_reader_ev_pending_write(1); /* Initialize the driver structure */ memset(priv, 0, sizeof(struct misoc_net_driver_s)); priv->rx0_buf = (uint8_t *)ETHMAC_RX0_BASE; priv->rx1_buf = (uint8_t *)ETHMAC_RX1_BASE; priv->tx0_buf = (uint8_t *)ETHMAC_TX0_BASE; priv->tx1_buf = (uint8_t *)ETHMAC_TX1_BASE; priv->tx_buf = priv->tx0_buf; priv->tx_slot=0; priv->misoc_net_dev.d_buf = g_pktbuf; /* Single packet buffer */ priv->misoc_net_dev.d_ifup = misoc_net_ifup; /* I/F up (new IP address) callback */ priv->misoc_net_dev.d_ifdown = misoc_net_ifdown; /* I/F down callback */ priv->misoc_net_dev.d_txavail = misoc_net_txavail; /* New TX data callback */ #ifdef CONFIG_NET_IGMP priv->misoc_net_dev.d_addmac = misoc_net_addmac; /* Add multicast MAC address */ priv->misoc_net_dev.d_rmmac = misoc_net_rmmac; /* Remove multicast MAC address */ #endif priv->misoc_net_dev.d_private = (FAR void *)g_misoc_net; /* Used to recover private state from dev */ /* Create a watchdog for timing polling for and timing of transmissions */ priv->misoc_net_txpoll = wd_create(); /* Create periodic poll timer */ priv->misoc_net_txtimeout = wd_create(); /* Create TX timeout timer */ /* Put the interface in the down state. This usually amounts to resetting * the device and/or calling misoc_net_ifdown(). */ /* Read the MAC address from the hardware into * priv->misoc_net_dev.d_mac.ether.ether_addr_octet */ /* Register the device with the OS so that socket IOCTLs can be performed */ (void)netdev_register(&priv->misoc_net_dev, NET_LL_ETHERNET); return OK; }