drivers/net/ethernet/sfc/tx.c
Source file repositories/reference/linux-study-clean/drivers/net/ethernet/sfc/tx.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ethernet/sfc/tx.c- Extension
.c- Size
- 17264 bytes
- Lines
- 601
- 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/pci.hlinux/tcp.hlinux/ip.hlinux/in.hlinux/ipv6.hlinux/slab.hnet/ipv6.hlinux/if_ether.hlinux/highmem.hlinux/cache.hnet_driver.hefx.hio.hnic.htx.htx_common.hworkarounds.hef10_regs.h
Detected Declarations
struct efx_short_copy_bufferfunction efx_tx_maybe_stop_queuefunction efx_enqueue_skb_copyfunction efx_memcpy_toio_alignedfunction efx_memcpy_toio_aligned_cbfunction efx_flush_copy_bufferfunction efx_skb_copy_bits_to_piofunction efx_enqueue_skb_piofunction efx_tx_may_piofunction efx_tx_send_pendingfunction efx_for_each_channel_tx_queuefunction netif_tx_lockfunction efx_tx_may_piofunction efx_xdp_tx_buffersfunction efx_hard_start_xmitfunction unlikelyfunction efx_xmit_done_singlefunction efx_init_tx_queue_core_txq
Annotated Snippet
struct efx_short_copy_buffer {
int used;
u8 buf[L1_CACHE_BYTES];
};
/* Copy to PIO, respecting that writes to PIO buffers must be dword aligned.
* Advances piobuf pointer. Leaves additional data in the copy buffer.
*/
static void efx_memcpy_toio_aligned(struct efx_nic *efx, u8 __iomem **piobuf,
u8 *data, int len,
struct efx_short_copy_buffer *copy_buf)
{
int block_len = len & ~(sizeof(copy_buf->buf) - 1);
__iowrite64_copy(*piobuf, data, block_len >> 3);
*piobuf += block_len;
len -= block_len;
if (len) {
data += block_len;
BUG_ON(copy_buf->used);
BUG_ON(len > sizeof(copy_buf->buf));
memcpy(copy_buf->buf, data, len);
copy_buf->used = len;
}
}
/* Copy to PIO, respecting dword alignment, popping data from copy buffer first.
* Advances piobuf pointer. Leaves additional data in the copy buffer.
*/
static void efx_memcpy_toio_aligned_cb(struct efx_nic *efx, u8 __iomem **piobuf,
u8 *data, int len,
struct efx_short_copy_buffer *copy_buf)
{
if (copy_buf->used) {
/* if the copy buffer is partially full, fill it up and write */
int copy_to_buf =
min_t(int, sizeof(copy_buf->buf) - copy_buf->used, len);
memcpy(copy_buf->buf + copy_buf->used, data, copy_to_buf);
copy_buf->used += copy_to_buf;
/* if we didn't fill it up then we're done for now */
if (copy_buf->used < sizeof(copy_buf->buf))
return;
__iowrite64_copy(*piobuf, copy_buf->buf,
sizeof(copy_buf->buf) >> 3);
*piobuf += sizeof(copy_buf->buf);
data += copy_to_buf;
len -= copy_to_buf;
copy_buf->used = 0;
}
efx_memcpy_toio_aligned(efx, piobuf, data, len, copy_buf);
}
static void efx_flush_copy_buffer(struct efx_nic *efx, u8 __iomem *piobuf,
struct efx_short_copy_buffer *copy_buf)
{
/* if there's anything in it, write the whole buffer, including junk */
if (copy_buf->used)
__iowrite64_copy(piobuf, copy_buf->buf,
sizeof(copy_buf->buf) >> 3);
}
/* Traverse skb structure and copy fragments in to PIO buffer.
* Advances piobuf pointer.
*/
static void efx_skb_copy_bits_to_pio(struct efx_nic *efx, struct sk_buff *skb,
u8 __iomem **piobuf,
struct efx_short_copy_buffer *copy_buf)
{
int i;
efx_memcpy_toio_aligned(efx, piobuf, skb->data, skb_headlen(skb),
copy_buf);
for (i = 0; i < skb_shinfo(skb)->nr_frags; ++i) {
skb_frag_t *f = &skb_shinfo(skb)->frags[i];
u8 *vaddr;
vaddr = kmap_local_page(skb_frag_page(f));
efx_memcpy_toio_aligned_cb(efx, piobuf, vaddr + skb_frag_off(f),
skb_frag_size(f), copy_buf);
kunmap_local(vaddr);
}
EFX_WARN_ON_ONCE_PARANOID(skb_shinfo(skb)->frag_list);
Annotation
- Immediate include surface: `linux/pci.h`, `linux/tcp.h`, `linux/ip.h`, `linux/in.h`, `linux/ipv6.h`, `linux/slab.h`, `net/ipv6.h`, `linux/if_ether.h`.
- Detected declarations: `struct efx_short_copy_buffer`, `function efx_tx_maybe_stop_queue`, `function efx_enqueue_skb_copy`, `function efx_memcpy_toio_aligned`, `function efx_memcpy_toio_aligned_cb`, `function efx_flush_copy_buffer`, `function efx_skb_copy_bits_to_pio`, `function efx_enqueue_skb_pio`, `function efx_tx_may_pio`, `function efx_tx_send_pending`.
- 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.