static int altera_tse_free_pkt(struct udevice *dev, uchar *packet, int length) { struct altera_tse_priv *priv = dev_get_priv(dev); struct alt_sgdma_descriptor *rx_desc = priv->rx_desc; unsigned long rx_buf = (unsigned long)priv->rx_buf; alt_sgdma_wait_transfer(priv->sgdma_rx); invalidate_dcache_range(rx_buf, rx_buf + PKTSIZE_ALIGN); alt_sgdma_construct_descriptor( rx_desc, rx_desc + 1, NULL, /* read addr */ priv->rx_buf, /* write addr */ 0, /* length or EOP */ 0, /* gen eop */ 0, /* read fixed */ 0 /* write fixed or sop */ ); /* setup the sgdma */ alt_sgdma_start_transfer(priv->sgdma_rx, rx_desc); debug("recv setup\n"); return 0; }
static int altera_tse_send(struct udevice *dev, void *packet, int length) { struct altera_tse_priv *priv = dev_get_priv(dev); struct alt_sgdma_descriptor *tx_desc = priv->tx_desc; unsigned long tx_buf = (unsigned long)packet; flush_dcache_range(tx_buf, tx_buf + length); alt_sgdma_construct_descriptor( tx_desc, tx_desc + 1, packet, /* read addr */ NULL, /* write addr */ length, /* length or EOP ,will change for each tx */ 1, /* gen eop */ 0, /* read fixed */ 1 /* write fixed or sop */ ); /* send the packet */ alt_sgdma_start_transfer(priv->sgdma_tx, tx_desc); alt_sgdma_wait_transfer(priv->sgdma_tx); debug("sent %d bytes\n", tx_desc->actual_bytes_transferred); return tx_desc->actual_bytes_transferred; }
static void altera_tse_stop_sgdma(struct udevice *dev) { struct altera_tse_priv *priv = dev_get_priv(dev); struct alt_sgdma_registers *rx_sgdma = priv->sgdma_rx; struct alt_sgdma_registers *tx_sgdma = priv->sgdma_tx; struct alt_sgdma_descriptor *rx_desc = priv->rx_desc; int ret; /* clear rx desc & wait for sgdma to complete */ rx_desc->descriptor_control = 0; writel(0, &rx_sgdma->control); ret = alt_sgdma_wait_transfer(rx_sgdma); if (ret == -ETIMEDOUT) writel(ALT_SGDMA_CONTROL_SOFTWARERESET_MSK, &rx_sgdma->control); writel(0, &tx_sgdma->control); ret = alt_sgdma_wait_transfer(tx_sgdma); if (ret == -ETIMEDOUT) writel(ALT_SGDMA_CONTROL_SOFTWARERESET_MSK, &tx_sgdma->control); }
static void altera_tse_stop(struct udevice *dev) { struct altera_tse_priv *priv = dev_get_priv(dev); struct alt_tse_mac *mac_dev = priv->mac_dev; struct alt_sgdma_registers *rx_sgdma = priv->sgdma_rx; struct alt_sgdma_registers *tx_sgdma = priv->sgdma_tx; struct alt_sgdma_descriptor *rx_desc = priv->rx_desc; unsigned int status; int ret; ulong ctime; /* clear rx desc & wait for sgdma to complete */ rx_desc->descriptor_control = 0; writel(0, &rx_sgdma->control); ret = alt_sgdma_wait_transfer(rx_sgdma); if (ret == -ETIMEDOUT) writel(ALT_SGDMA_CONTROL_SOFTWARERESET_MSK, &rx_sgdma->control); writel(0, &tx_sgdma->control); ret = alt_sgdma_wait_transfer(tx_sgdma); if (ret == -ETIMEDOUT) writel(ALT_SGDMA_CONTROL_SOFTWARERESET_MSK, &tx_sgdma->control); /* reset the mac */ writel(ALTERA_TSE_CMD_SW_RESET_MSK, &mac_dev->command_config); ctime = get_timer(0); while (1) { status = readl(&mac_dev->command_config); if (!(status & ALTERA_TSE_CMD_SW_RESET_MSK)) break; if (get_timer(ctime) > ALT_TSE_SW_RESET_TIMEOUT) { debug("Reset mac timeout\n"); break; } } }
static int altera_tse_recv_sgdma(struct udevice *dev, int flags, uchar **packetp) { struct altera_tse_priv *priv = dev_get_priv(dev); struct alt_sgdma_descriptor *rx_desc = priv->rx_desc; int packet_length; if (rx_desc->descriptor_status & ALT_SGDMA_DESCRIPTOR_STATUS_TERMINATED_BY_EOP_MSK) { alt_sgdma_wait_transfer(priv->sgdma_rx); packet_length = rx_desc->actual_bytes_transferred; debug("recv %d bytes\n", packet_length); *packetp = priv->rx_buf; return packet_length; } return -EAGAIN; }