drivers/net/ethernet/altera/altera_sgdma.c
Source file repositories/reference/linux-study-clean/drivers/net/ethernet/altera/altera_sgdma.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ethernet/altera/altera_sgdma.c- Extension
.c- Size
- 14861 bytes
- Lines
- 528
- Domain
- Driver Families
- Bucket
- drivers/net
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/list.haltera_utils.haltera_tse.haltera_sgdmahw.haltera_sgdma.h
Detected Declarations
function sgdma_initializefunction sgdma_uninitializefunction sgdma_resetfunction sgdma_enable_rxirqfunction sgdma_clear_txirqfunction sgdma_tx_bufferfunction sgdma_tx_completionsfunction sgdma_start_rxdmafunction sgdma_add_rx_descfunction sgdma_rx_statusfunction sgdma_setup_descripfunction sgdma_async_readfunction sgdma_async_writefunction sgdma_txphysaddrfunction sgdma_rxphysaddrfunction queue_txfunction queue_rxfunction dequeue_txfunction dequeue_rxfunction queue_rx_peekheadfunction sgdma_rxbusyfunction sgdma_txbusy
Annotated Snippet
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,
* then it's expected that the rxstatus from the
* descriptor is non-zero - meaning a valid packet
* with a nonzero length, or an error has been
* indicated. if not, then all we can do is signal
* an error and return no packet received. Most likely
* there is a system design error, or an error in the
* underlying kernel (cache or cache management problem)
*/
netdev_err(priv->dev,
"SGDMA RX Error Info: %x, %x, %x\n",
sts, csrrd8(desc, sgdma_descroffs(status)),
rxstatus);
}
} else if (sts == 0) {
sgdma_async_read(priv);
}
return rxstatus;
}
/* Private functions */
static void 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 */
u32 ctrl = csrrd8(ndesc, sgdma_descroffs(control));
ctrl &= ~SGDMA_CONTROL_HW_OWNED;
csrwr8(ctrl, ndesc, sgdma_descroffs(control));
ctrl = SGDMA_CONTROL_HW_OWNED;
ctrl |= generate_eop;
ctrl |= rfixed;
ctrl |= wfixed;
/* Channel is implicitly zero, initialized to 0 by default */
csrwr32(lower_32_bits(raddr), desc, sgdma_descroffs(raddr));
csrwr32(lower_32_bits(waddr), desc, sgdma_descroffs(waddr));
csrwr32(0, desc, sgdma_descroffs(pad1));
csrwr32(0, desc, sgdma_descroffs(pad2));
csrwr32(lower_32_bits(ndesc_phys), desc, sgdma_descroffs(next));
csrwr8(ctrl, desc, sgdma_descroffs(control));
csrwr8(0, desc, sgdma_descroffs(status));
csrwr8(0, desc, sgdma_descroffs(wburst));
csrwr8(0, desc, sgdma_descroffs(rburst));
csrwr16(length, desc, sgdma_descroffs(bytes));
csrwr16(0, desc, sgdma_descroffs(bytes_xferred));
}
/* If hardware is busy, don't restart async read.
* if status register is 0 - meaning initial state, restart async read,
* probably for the first time when populating a receive buffer.
* If read status indicate not busy and a status, restart the async
* DMA read.
*/
static int sgdma_async_read(struct altera_tse_private *priv)
{
struct sgdma_descrip __iomem *descbase =
(struct sgdma_descrip __iomem *)priv->rx_dma_desc;
struct sgdma_descrip __iomem *cdesc = &descbase[0];
struct sgdma_descrip __iomem *ndesc = &descbase[1];
Annotation
- Immediate include surface: `linux/list.h`, `altera_utils.h`, `altera_tse.h`, `altera_sgdmahw.h`, `altera_sgdma.h`.
- Detected declarations: `function sgdma_initialize`, `function sgdma_uninitialize`, `function sgdma_reset`, `function sgdma_enable_rxirq`, `function sgdma_clear_txirq`, `function sgdma_tx_buffer`, `function sgdma_tx_completions`, `function sgdma_start_rxdma`, `function sgdma_add_rx_desc`, `function sgdma_rx_status`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: source implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.