drivers/net/ethernet/sfc/tx_common.c
Source file repositories/reference/linux-study-clean/drivers/net/ethernet/sfc/tx_common.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ethernet/sfc/tx_common.c- Extension
.c- Size
- 13785 bytes
- Lines
- 488
- 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
net_driver.hefx.hnic_common.htx_common.hnet/gso.h
Detected Declarations
function efx_tx_cb_page_countfunction efx_probe_tx_queuefunction efx_init_tx_queuefunction efx_fini_tx_queuefunction efx_remove_tx_queuefunction efx_dequeue_bufferfunction efx_dequeue_buffersfunction efx_xmit_done_check_emptyfunction efx_xmit_donefunction likelyfunction efx_enqueue_unwindfunction efx_tx_tso_header_lengthfunction efx_tx_map_datafunction efx_tx_max_skb_descsfunction efx_tx_tso_fallbackfunction skb_list_walk_safe
Annotated Snippet
if (unlikely(buffer->flags & EFX_TX_BUF_EFV)) {
EFX_WARN_ON_PARANOID(!efv_pkts_compl);
(*efv_pkts_compl)++;
} else {
EFX_WARN_ON_PARANOID(!pkts_compl || !bytes_compl);
(*pkts_compl)++;
(*bytes_compl) += skb->len;
}
if (tx_queue->timestamping &&
(tx_queue->completed_timestamp_major ||
tx_queue->completed_timestamp_minor)) {
struct skb_shared_hwtstamps hwtstamp;
hwtstamp.hwtstamp =
efx_ptp_nic_to_kernel_time(tx_queue);
skb_tstamp_tx(skb, &hwtstamp);
tx_queue->completed_timestamp_major = 0;
tx_queue->completed_timestamp_minor = 0;
}
dev_consume_skb_any((struct sk_buff *)buffer->skb);
netif_vdbg(tx_queue->efx, tx_done, tx_queue->efx->net_dev,
"TX queue %d transmission id %x complete\n",
tx_queue->queue, tx_queue->read_count);
} else if (buffer->flags & EFX_TX_BUF_XDP) {
xdp_return_frame_rx_napi(buffer->xdpf);
if (xdp_pkts)
(*xdp_pkts)++;
if (xdp_bytes)
(*xdp_bytes) += buffer->xdpf->len;
}
buffer->len = 0;
buffer->flags = 0;
}
/* Remove packets from the TX queue
*
* This removes packets from the TX queue, up to and including the
* specified index.
*/
static void efx_dequeue_buffers(struct efx_tx_queue *tx_queue,
unsigned int index,
unsigned int *pkts_compl,
unsigned int *bytes_compl,
unsigned int *efv_pkts_compl,
unsigned int *xdp_pkts,
unsigned int *xdp_bytes)
{
struct efx_nic *efx = tx_queue->efx;
unsigned int stop_index, read_ptr;
stop_index = (index + 1) & tx_queue->ptr_mask;
read_ptr = tx_queue->read_count & tx_queue->ptr_mask;
while (read_ptr != stop_index) {
struct efx_tx_buffer *buffer = &tx_queue->buffer[read_ptr];
if (!efx_tx_buffer_in_use(buffer)) {
netif_err(efx, tx_err, efx->net_dev,
"TX queue %d spurious TX completion id %d\n",
tx_queue->queue, read_ptr);
efx_schedule_reset(efx, RESET_TYPE_TX_SKIP);
return;
}
efx_dequeue_buffer(tx_queue, buffer, pkts_compl, bytes_compl,
efv_pkts_compl, xdp_pkts, xdp_bytes);
++tx_queue->read_count;
read_ptr = tx_queue->read_count & tx_queue->ptr_mask;
}
}
void efx_xmit_done_check_empty(struct efx_tx_queue *tx_queue)
{
if ((int)(tx_queue->read_count - tx_queue->old_write_count) >= 0) {
tx_queue->old_write_count = READ_ONCE(tx_queue->write_count);
if (tx_queue->read_count == tx_queue->old_write_count) {
/* Ensure that read_count is flushed. */
smp_mb();
tx_queue->empty_read_count =
tx_queue->read_count | EFX_EMPTY_COUNT_VALID;
}
}
}
int efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index)
{
Annotation
- Immediate include surface: `net_driver.h`, `efx.h`, `nic_common.h`, `tx_common.h`, `net/gso.h`.
- Detected declarations: `function efx_tx_cb_page_count`, `function efx_probe_tx_queue`, `function efx_init_tx_queue`, `function efx_fini_tx_queue`, `function efx_remove_tx_queue`, `function efx_dequeue_buffer`, `function efx_dequeue_buffers`, `function efx_xmit_done_check_empty`, `function efx_xmit_done`, `function likely`.
- 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.