drivers/net/ethernet/mellanox/mlx4/en_tx.c
Source file repositories/reference/linux-study-clean/drivers/net/ethernet/mellanox/mlx4/en_tx.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ethernet/mellanox/mlx4/en_tx.c- Extension
.c- Size
- 33399 bytes
- Lines
- 1209
- 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.
- 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
asm/page.hlinux/mlx4/cq.hlinux/slab.hlinux/mlx4/qp.hlinux/skbuff.hlinux/if_vlan.hlinux/prefetch.hlinux/vmalloc.hlinux/tcp.hlinux/ip.hlinux/ipv6.hlinux/indirect_call_wrapper.hnet/ipv6.hnet/page_pool/helpers.hmlx4_en.h
Detected Declarations
function Copyrightfunction mlx4_en_destroy_tx_ringfunction mlx4_en_activate_tx_ringfunction mlx4_en_deactivate_tx_ringfunction mlx4_en_is_tx_ring_fullfunction mlx4_en_stamp_wqefunction mlx4_en_free_tx_descfunction mlx4_en_recycle_tx_descfunction mlx4_en_free_tx_buffunction mlx4_en_handle_err_cqefunction mlx4_en_process_tx_cqfunction mlx4_en_tx_irqfunction mlx4_en_poll_tx_cqfunction skb_copy_bitsfunction inline_sizefunction get_real_sizefunction build_inline_wqefunction mlx4_en_select_queuefunction mlx4_bf_copyfunction mlx4_en_xmit_doorbellfunction mlx4_en_tx_write_descfunction mlx4_en_build_dma_wqefunction mlx4_en_xmitfunction mlx4_en_init_tx_xdp_ring_descsfunction mlx4_en_xmit_frame
Annotated Snippet
if (!ring->bounce_buf) {
err = -ENOMEM;
goto err_info;
}
}
ring->buf_size = ALIGN(size * ring->sp_stride, MLX4_EN_PAGE_SIZE);
/* Allocate HW buffers on provided NUMA node */
set_dev_node(&mdev->dev->persist->pdev->dev, node);
err = mlx4_alloc_hwq_res(mdev->dev, &ring->sp_wqres, ring->buf_size);
set_dev_node(&mdev->dev->persist->pdev->dev, mdev->dev->numa_node);
if (err) {
en_err(priv, "Failed allocating hwq resources\n");
goto err_bounce;
}
ring->buf = ring->sp_wqres.buf.direct.buf;
en_dbg(DRV, priv, "Allocated TX ring (addr:%p) - buf:%p size:%d buf_size:%d dma:%llx\n",
ring, ring->buf, ring->size, ring->buf_size,
(unsigned long long) ring->sp_wqres.buf.direct.map);
err = mlx4_qp_reserve_range(mdev->dev, 1, 1, &ring->qpn,
MLX4_RESERVE_ETH_BF_QP,
MLX4_RES_USAGE_DRIVER);
if (err) {
en_err(priv, "failed reserving qp for TX ring\n");
goto err_hwq_res;
}
err = mlx4_qp_alloc(mdev->dev, ring->qpn, &ring->sp_qp);
if (err) {
en_err(priv, "Failed allocating qp %d\n", ring->qpn);
goto err_reserve;
}
ring->sp_qp.event = mlx4_en_sqp_event;
err = mlx4_bf_alloc(mdev->dev, &ring->bf, node);
if (err) {
en_dbg(DRV, priv, "working without blueflame (%d)\n", err);
ring->bf.uar = &mdev->priv_uar;
ring->bf.uar->map = mdev->uar_map;
ring->bf_enabled = false;
ring->bf_alloced = false;
priv->pflags &= ~MLX4_EN_PRIV_FLAGS_BLUEFLAME;
} else {
ring->bf_alloced = true;
ring->bf_enabled = !!(priv->pflags &
MLX4_EN_PRIV_FLAGS_BLUEFLAME);
}
ring->doorbell_address = ring->bf.uar->map + MLX4_SEND_DOORBELL;
ring->hwtstamp_tx_type = priv->hwtstamp_config.tx_type;
ring->queue_index = queue_index;
if (queue_index < priv->num_tx_rings_p_up)
cpumask_set_cpu(cpumask_local_spread(queue_index,
priv->mdev->dev->numa_node),
&ring->sp_affinity_mask);
*pring = ring;
return 0;
err_reserve:
mlx4_qp_release_range(mdev->dev, ring->qpn, 1);
err_hwq_res:
mlx4_free_hwq_res(mdev->dev, &ring->sp_wqres, ring->buf_size);
err_bounce:
kfree(ring->bounce_buf);
ring->bounce_buf = NULL;
err_info:
kvfree(ring->tx_info);
ring->tx_info = NULL;
err_ring:
kfree(ring);
*pring = NULL;
return err;
}
void mlx4_en_destroy_tx_ring(struct mlx4_en_priv *priv,
struct mlx4_en_tx_ring **pring)
{
struct mlx4_en_dev *mdev = priv->mdev;
struct mlx4_en_tx_ring *ring = *pring;
en_dbg(DRV, priv, "Destroying tx ring, qpn: %d\n", ring->qpn);
if (ring->bf_alloced)
mlx4_bf_free(mdev->dev, &ring->bf);
mlx4_qp_remove(mdev->dev, &ring->sp_qp);
mlx4_qp_free(mdev->dev, &ring->sp_qp);
Annotation
- Immediate include surface: `asm/page.h`, `linux/mlx4/cq.h`, `linux/slab.h`, `linux/mlx4/qp.h`, `linux/skbuff.h`, `linux/if_vlan.h`, `linux/prefetch.h`, `linux/vmalloc.h`.
- Detected declarations: `function Copyright`, `function mlx4_en_destroy_tx_ring`, `function mlx4_en_activate_tx_ring`, `function mlx4_en_deactivate_tx_ring`, `function mlx4_en_is_tx_ring_full`, `function mlx4_en_stamp_wqe`, `function mlx4_en_free_tx_desc`, `function mlx4_en_recycle_tx_desc`, `function mlx4_en_free_tx_buf`, `function mlx4_en_handle_err_cqe`.
- 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.