if (priv->txdescphys)
dma_unmap_single(priv->device, priv->txdescphys,
priv->txdescmem, DMA_TO_DEVICE);
}
/* This function resets the SGDMA controller and clears the *descriptormemoryusedfortransmitsandreceives.
*/ void sgdma_reset(struct altera_tse_private *priv)
{ /* Initialize descriptor memory to 0 */
memset_io(priv->tx_dma_desc, 0, priv->txdescmem);
memset_io(priv->rx_dma_desc, 0, priv->rxdescmem);
if (rxstatus) {
csrwr8(0, desc, sgdma_descroffs(status));
rxbuffer = dequeue_rx(priv); if (rxbuffer == NULL)
netdev_info(priv->dev, "sgdma rx and rx queue empty!\n");
/* Clear control */
csrwr32(0, priv->rx_dma_csr, sgdma_csroffs(control)); /* clear status */
csrwr32(0xf, priv->rx_dma_csr, sgdma_csroffs(status));
/* kick the rx sgdma after reaping this descriptor */
sgdma_async_read(priv);
} else { /* If the SGDMA indicated an end of packet on recv, *thenit'sexpectedthattherxstatusfromthe *descriptorisnon-zero-meaningavalidpacket *withanonzerolength,oranerrorhasbeen *indicated.ifnot,thenallwecandoissignal *anerrorandreturnnopacketreceived.Mostlikely *thereisasystemdesignerror,oranerrorinthe *underlyingkernel(cacheorcachemanagementproblem)
*/
netdev_err(priv->dev, "SGDMA RX Error Info: %x, %x, %x\n",
sts, csrrd8(desc, sgdma_descroffs(status)),
rxstatus);
}
} elseif (sts == 0) {
sgdma_async_read(priv);
}
return rxstatus;
}
/* Private functions */ staticvoid sgdma_setup_descrip(struct sgdma_descrip __iomem *desc, struct sgdma_descrip __iomem *ndesc,
dma_addr_t ndesc_phys,
dma_addr_t raddr,
dma_addr_t waddr,
u16 length, int generate_eop, int rfixed, int wfixed)
{ /* Clear the next descriptor as not owned by hardware */
#define list_remove_head(list, entry, type, member) \ do { \
entry = NULL; \ if (!list_empty(list)) { \
entry = list_entry((list)->next, type, member); \
list_del_init(&entry->member); \
} \
} while (0)
#define list_peek_head(list, entry, type, member) \ do { \
entry = NULL; \ if (!list_empty(list)) { \
entry = list_entry((list)->next, type, member); \
} \
} while (0)
/* adds a tse_buffer to the tail of a tx buffer list. *assumesthecallerismanagingandholdingamutualexclusion *primitivetoavoidsimultaneouspushes/popstothelist.
*/ staticvoid
queue_tx(struct altera_tse_private *priv, struct tse_buffer *buffer)
{
list_add_tail(&buffer->lh, &priv->txlisthd);
}
/* adds a tse_buffer to the tail of a rx buffer list *assumesthecallerismanagingandholdingamutualexclusion *primitivetoavoidsimultaneouspushes/popstothelist.
*/ staticvoid
queue_rx(struct altera_tse_private *priv, struct tse_buffer *buffer)
{
list_add_tail(&buffer->lh, &priv->rxlisthd);
}
/* check and return rx sgdma status without polling
*/ staticint sgdma_rxbusy(struct altera_tse_private *priv)
{ return csrrd32(priv->rx_dma_csr, sgdma_csroffs(status))
& SGDMA_STSREG_BUSY;
}
/* waits for the tx sgdma to finish it's current operation, returns 0 *whenittransitionstononbusy,returns1iftheoperationtimesout
*/ staticint sgdma_txbusy(struct altera_tse_private *priv)
{ int delay = 0;
/* if DMA is busy, wait for current transaction to finish */ while ((csrrd32(priv->tx_dma_csr, sgdma_csroffs(status))
& SGDMA_STSREG_BUSY) && (delay++ < 100))
udelay(1);
if (csrrd32(priv->tx_dma_csr, sgdma_csroffs(status))
& SGDMA_STSREG_BUSY) {
netdev_err(priv->dev, "timeout waiting for tx dma\n"); return1;
} return0;
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.19 Sekunden
(vorverarbeitet am 2026-09-28)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.