int ll_temac_recv_sdma(struct eth_device *dev) { int length, pb_idx; struct cdmac_bd *rx_dp = &cdmac_bd.rx[rx_idx]; struct ll_temac *ll_temac = dev->priv; phys_addr_t *ra = ll_temac->sdma_reg_addr; if (ll_temac_sdma_error(dev)) { if (ll_temac_reset_sdma(dev)) return -1; ll_temac_init_sdma(dev); } flush_cache((u32)rx_dp, sizeof(*rx_dp)); if (!(rx_dp->sca.stctrl & CDMAC_BD_STCTRL_COMPLETED)) return 0; if (rx_dp->sca.stctrl & (CDMAC_BD_STCTRL_SOP | CDMAC_BD_STCTRL_EOP)) { pb_idx = rx_idx; length = rx_dp->sca.app[4] & CDMAC_BD_APP4_RXBYTECNT_MASK; } else { pb_idx = -1; length = 0; printf("%s: Got part of package, unsupported (%x)\n", __func__, rx_dp->sca.stctrl); } /* flip the buffer */ flush_cache((u32)rx_dp->phys_buf_p, length); /* reset the current descriptor */ rx_dp->sca.stctrl = 0; rx_dp->sca.app[4] = 0; flush_cache((u32)rx_dp, sizeof(*rx_dp)); /* Find next empty buffer descriptor, preparation for next iteration */ rx_idx = (rx_idx + 1) % PKTBUFSRX; rx_dp = &cdmac_bd.rx[rx_idx]; flush_cache((u32)rx_dp, sizeof(*rx_dp)); /* DMA start by writing to respective TAILDESC_PTR */ ll_temac->out32(ra[RX_CURDESC_PTR], (int)&cdmac_bd.rx[rx_idx]); ll_temac->out32(ra[RX_TAILDESC_PTR], (int)&cdmac_bd.rx[rx_idx]); if (length > 0 && pb_idx != -1) NetReceive(NetRxPackets[pb_idx], length); return 0; }
int ll_temac_send_sdma(struct eth_device *dev, volatile void *packet, int length) { unsigned timeout = 50; /* 1usec * 50 = 50usec */ struct cdmac_bd *tx_dp = &cdmac_bd.tx[tx_idx]; struct ll_temac *ll_temac = dev->priv; phys_addr_t *ra = ll_temac->sdma_reg_addr; if (ll_temac_sdma_error(dev)) { if (ll_temac_reset_sdma(dev)) return -1; ll_temac_init_sdma(dev); } tx_dp->phys_buf_p = (u8 *)packet; tx_dp->buf_len = length; tx_dp->sca.stctrl = CDMAC_BD_STCTRL_SOP | CDMAC_BD_STCTRL_EOP | CDMAC_BD_STCTRL_STOP_ON_END; flush_cache((u32)packet, length); flush_cache((u32)tx_dp, sizeof(*tx_dp)); /* DMA start by writing to respective TAILDESC_PTR */ ll_temac->out32(ra[TX_CURDESC_PTR], (int)tx_dp); ll_temac->out32(ra[TX_TAILDESC_PTR], (int)tx_dp); /* Find next empty buffer descriptor, preparation for next iteration */ tx_idx = (tx_idx + 1) % TX_BUF_CNT; tx_dp = &cdmac_bd.tx[tx_idx]; do { flush_cache((u32)tx_dp, sizeof(*tx_dp)); udelay(1); } while (timeout-- && !(tx_dp->sca.stctrl & CDMAC_BD_STCTRL_COMPLETED)); if (!timeout) { printf("%s: Timeout\n", __func__); return -1; } return 0; }