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;
}
Esempio n. 2
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;
}