drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c
Source file repositories/reference/linux-study-clean/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c- Extension
.c- Size
- 16991 bytes
- Lines
- 552
- 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.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/unaligned.hmcp251xfd.hmcp251xfd-ram.h
Detected Declarations
function mcp251xfd_cmd_prepare_write_regfunction mcp251xfd_ring_init_teffunction mcp251xfd_tx_ring_init_tx_objfunction mcp251xfd_ring_init_txfunction mcp251xfd_ring_init_rxfunction mcp251xfd_for_each_rx_ringfunction RXOVIEfunction mcp251xfd_ring_initfunction mcp251xfd_for_each_rx_ringfunction mcp251xfd_ring_freefunction mcp251xfd_rx_irq_timerfunction mcp251xfd_tx_irq_timerfunction mcp251xfd_ring_alloc
Annotated Snippet
if (rx_ring->nr == 0 && priv->rx_obj_num_coalesce_irq) {
netdev_dbg(priv->ndev,
"FIFO setup: RX-%u: FIFO %u/0x%03x: %2u*%u bytes = %4u bytes (coalesce)\n",
rx_ring->nr, rx_ring->fifo_nr,
mcp251xfd_get_rx_obj_addr(rx_ring, 0),
priv->rx_obj_num_coalesce_irq, rx_ring->obj_size,
priv->rx_obj_num_coalesce_irq * rx_ring->obj_size);
if (priv->rx_obj_num_coalesce_irq == MCP251XFD_FIFO_DEPTH)
continue;
netdev_dbg(priv->ndev,
" 0x%03x: %2u*%u bytes = %4u bytes\n",
mcp251xfd_get_rx_obj_addr(rx_ring,
priv->rx_obj_num_coalesce_irq),
rx_ring->obj_num - priv->rx_obj_num_coalesce_irq,
rx_ring->obj_size,
(rx_ring->obj_num - priv->rx_obj_num_coalesce_irq) *
rx_ring->obj_size);
} else {
netdev_dbg(priv->ndev,
"FIFO setup: RX-%u: FIFO %u/0x%03x: %2u*%u bytes = %4u bytes\n",
rx_ring->nr, rx_ring->fifo_nr,
mcp251xfd_get_rx_obj_addr(rx_ring, 0),
rx_ring->obj_num, rx_ring->obj_size,
rx_ring->obj_num * rx_ring->obj_size);
}
}
netdev_dbg(priv->ndev,
"FIFO setup: TX: FIFO %u/0x%03x: %2u*%u bytes = %4u bytes\n",
priv->tx->fifo_nr,
mcp251xfd_get_tx_obj_addr(priv->tx, 0),
priv->tx->obj_num, priv->tx->obj_size,
priv->tx->obj_num * priv->tx->obj_size);
netdev_dbg(priv->ndev,
"FIFO setup: free: %4d bytes\n",
MCP251XFD_RAM_SIZE - (base - MCP251XFD_RAM_START));
ram_used = base - MCP251XFD_RAM_START;
if (ram_used > MCP251XFD_RAM_SIZE) {
netdev_err(priv->ndev,
"Error during ring configuration, using more RAM (%u bytes) than available (%u bytes).\n",
ram_used, MCP251XFD_RAM_SIZE);
err = -ENOMEM;
}
if (priv->tx_obj_num_coalesce_irq &&
priv->tx_obj_num_coalesce_irq * 2 != priv->tx->obj_num) {
netdev_err(priv->ndev,
"Error during ring configuration, number of TEF coalescing buffers (%u) must be half of TEF buffers (%u).\n",
priv->tx_obj_num_coalesce_irq, priv->tx->obj_num);
err = -EINVAL;
}
return err;
}
void mcp251xfd_ring_free(struct mcp251xfd_priv *priv)
{
int i;
for (i = ARRAY_SIZE(priv->rx) - 1; i >= 0; i--) {
kfree(priv->rx[i]);
priv->rx[i] = NULL;
}
}
static enum hrtimer_restart mcp251xfd_rx_irq_timer(struct hrtimer *t)
{
struct mcp251xfd_priv *priv = container_of(t, struct mcp251xfd_priv,
rx_irq_timer);
struct mcp251xfd_rx_ring *ring = priv->rx[0];
if (test_bit(MCP251XFD_FLAGS_DOWN, priv->flags))
return HRTIMER_NORESTART;
spi_async(priv->spi, &ring->irq_enable_msg);
return HRTIMER_NORESTART;
}
static enum hrtimer_restart mcp251xfd_tx_irq_timer(struct hrtimer *t)
{
struct mcp251xfd_priv *priv = container_of(t, struct mcp251xfd_priv,
tx_irq_timer);
struct mcp251xfd_tef_ring *ring = priv->tef;
if (test_bit(MCP251XFD_FLAGS_DOWN, priv->flags))
Annotation
- Immediate include surface: `linux/unaligned.h`, `mcp251xfd.h`, `mcp251xfd-ram.h`.
- Detected declarations: `function mcp251xfd_cmd_prepare_write_reg`, `function mcp251xfd_ring_init_tef`, `function mcp251xfd_tx_ring_init_tx_obj`, `function mcp251xfd_ring_init_tx`, `function mcp251xfd_ring_init_rx`, `function mcp251xfd_for_each_rx_ring`, `function RXOVIE`, `function mcp251xfd_ring_init`, `function mcp251xfd_for_each_rx_ring`, `function mcp251xfd_ring_free`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: source implementation candidate.
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.