static err_t liteeth_low_level_output(struct netif *netif, struct pbuf *p) { struct pbuf *q; txlen = 0; q = p; while(q) { memcpy(txbuffer, q->payload, q->len); txbuffer += q->len; txlen += q->len; if(q->tot_len != q->len) q = q->next; else q = NULL; } ethmac_sram_reader_slot_write(txslot); ethmac_sram_reader_length_write(txlen); while(!ethmac_sram_reader_ready_read()); ethmac_sram_reader_start_write(1); txslot = (txslot + 1) % 2; if(txslot) txbuffer = txbuffer1; else txbuffer = txbuffer0; return ERR_OK; }
static int misoc_net_transmit(FAR struct misoc_net_driver_s *priv) { /* Verify that the hardware is ready to send another packet. If we get * here, then we are committed to sending a packet; Higher level logic * must have assured that there is no transmission in progress. */ /* Increment statistics */ NETDEV_TXPACKETS(priv->misoc_net_dev); /* Send the packet: address=priv->misoc_net_dev.d_buf, * length=priv->misoc_net_dev.d_len * * NOTE: This memcpy could be avoided by setting tx_buf * to the d_buf pointer and setting d_buf to an alternate * buffer. Some additional buffer management logic would * be required. */ memcpy(priv->tx_buf, priv->misoc_net_dev.d_buf, priv->misoc_net_dev.d_len); /* Choose the slot on which we write */ ethmac_sram_reader_slot_write(priv->tx_slot); /* Write the len */ if (priv->misoc_net_dev.d_len < 60) { ethmac_sram_reader_length_write(60); } else { ethmac_sram_reader_length_write(priv->misoc_net_dev.d_len); } /* Trigger the writing */ ethmac_sram_reader_start_write(1); /* switch tx slot */ priv->tx_slot = (priv->tx_slot+1)%2; if (priv->tx_slot) { priv->tx_buf = priv->tx1_buf; } else { priv->tx_buf = priv->tx0_buf; } /* Enable Tx interrupts */ ethmac_sram_reader_ev_enable_write(1); /* Setup the TX timeout watchdog (perhaps restarting the timer) */ (void)wd_start(priv->misoc_net_txtimeout, MISOC_NET_TXTIMEOUT, misoc_net_txtimeout_expiry, 1, (wdparm_t)priv); return OK; }