drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_tx.c
Source file repositories/reference/linux-study-clean/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_tx.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_tx.c- Extension
.c- Size
- 8376 bytes
- Lines
- 285
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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/skbuff.hmlxbf_gige.hmlxbf_gige_regs.h
Detected Declarations
function Copyrightfunction mlxbf_gige_tx_initfunction entriesfunction mlxbf_gige_handle_tx_completefunction mlxbf_gige_update_tx_wqe_nextfunction mlxbf_gige_start_xmit
Annotated Snippet
if (priv->tx_skb[i]) {
dma_unmap_single(priv->dev, *tx_wqe_addr,
priv->tx_skb[i]->len, DMA_TO_DEVICE);
dev_kfree_skb(priv->tx_skb[i]);
priv->tx_skb[i] = NULL;
}
tx_wqe_addr += 2;
}
size = MLXBF_GIGE_TX_WQE_SZ * priv->tx_q_entries;
dma_free_coherent(priv->dev, size,
priv->tx_wqe_base, priv->tx_wqe_base_dma);
dma_free_coherent(priv->dev, MLXBF_GIGE_TX_CC_SZ,
priv->tx_cc, priv->tx_cc_dma);
priv->tx_wqe_base = NULL;
priv->tx_wqe_base_dma = 0;
priv->tx_cc = NULL;
priv->tx_cc_dma = 0;
priv->tx_wqe_next = NULL;
writeq(0, priv->base + MLXBF_GIGE_TX_WQ_BASE);
writeq(0, priv->base + MLXBF_GIGE_TX_CI_UPDATE_ADDRESS);
}
/* Function that returns status of TX ring:
* 0: TX ring is full, i.e. there are no
* available un-used entries in TX ring.
* non-null: TX ring is not full, i.e. there are
* some available entries in TX ring.
* The non-null value is a measure of
* how many TX entries are available, but
* it is not the exact number of available
* entries (see below).
*
* The algorithm makes the assumption that if
* (prev_tx_ci == tx_pi) then the TX ring is empty.
* An empty ring actually has (tx_q_entries-1)
* entries, which allows the algorithm to differentiate
* the case of an empty ring vs. a full ring.
*/
static u16 mlxbf_gige_tx_buffs_avail(struct mlxbf_gige *priv)
{
unsigned long flags;
u16 avail;
spin_lock_irqsave(&priv->lock, flags);
if (priv->prev_tx_ci == priv->tx_pi)
avail = priv->tx_q_entries - 1;
else
avail = ((priv->tx_q_entries + priv->prev_tx_ci - priv->tx_pi)
% priv->tx_q_entries) - 1;
spin_unlock_irqrestore(&priv->lock, flags);
return avail;
}
bool mlxbf_gige_handle_tx_complete(struct mlxbf_gige *priv)
{
struct net_device_stats *stats;
u16 tx_wqe_index;
u64 *tx_wqe_addr;
u64 tx_status;
u16 tx_ci;
tx_status = readq(priv->base + MLXBF_GIGE_TX_STATUS);
if (tx_status & MLXBF_GIGE_TX_STATUS_DATA_FIFO_FULL)
priv->stats.tx_fifo_full++;
tx_ci = readq(priv->base + MLXBF_GIGE_TX_CONSUMER_INDEX);
stats = &priv->netdev->stats;
/* Transmit completion logic needs to loop until the completion
* index (in SW) equals TX consumer index (from HW). These
* parameters are unsigned 16-bit values and the wrap case needs
* to be supported, that is TX consumer index wrapped from 0xFFFF
* to 0 while TX completion index is still < 0xFFFF.
*/
for (; priv->prev_tx_ci != tx_ci; priv->prev_tx_ci++) {
tx_wqe_index = priv->prev_tx_ci % priv->tx_q_entries;
/* Each TX WQE is 16 bytes. The 8 MSB store the 2KB TX
* buffer address and the 8 LSB contain information
* about the TX WQE.
*/
tx_wqe_addr = priv->tx_wqe_base +
(tx_wqe_index * MLXBF_GIGE_TX_WQE_SZ_QWORDS);
stats->tx_packets++;
stats->tx_bytes += MLXBF_GIGE_TX_WQE_PKT_LEN(tx_wqe_addr);
Annotation
- Immediate include surface: `linux/skbuff.h`, `mlxbf_gige.h`, `mlxbf_gige_regs.h`.
- Detected declarations: `function Copyright`, `function mlxbf_gige_tx_init`, `function entries`, `function mlxbf_gige_handle_tx_complete`, `function mlxbf_gige_update_tx_wqe_next`, `function mlxbf_gige_start_xmit`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- 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.