drivers/net/ethernet/pensando/ionic/ionic_txrx.c
Source file repositories/reference/linux-study-clean/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ethernet/pensando/ionic/ionic_txrx.c- Extension
.c- Size
- 45653 bytes
- Lines
- 1848
- 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/ip.hlinux/ipv6.hlinux/if_vlan.hnet/ip6_checksum.hnet/netdev_queues.hnet/page_pool/helpers.hionic.hionic_lif.hionic_txrx.h
Detected Declarations
function ionic_txq_postfunction ionic_rxq_postfunction ionic_txq_poke_doorbellfunction ionic_rxq_poke_doorbellfunction ionic_rx_buf_pafunction __ionic_rx_put_buffunction ionic_rx_put_buffunction ionic_rx_put_buf_directfunction ionic_rx_add_skb_fragfunction ionic_xdp_tx_desc_cleanfunction ionic_xdp_post_framefunction ionic_xdp_xmitfunction ionic_xdp_rx_unlink_bufsfunction ionic_run_xdpfunction ionic_rx_cleanfunction __ionic_rx_servicefunction ionic_rx_servicefunction ionic_write_cmb_descfunction ionic_rx_fillfunction ionic_rx_emptyfunction ionic_dim_updatefunction ionic_tx_napifunction ionic_xdp_do_flushfunction ionic_rx_cq_servicefunction ionic_rx_napifunction ionic_txrx_napifunction ionic_tx_map_singlefunction ionic_tx_map_fragfunction ionic_tx_map_skbfunction ionic_tx_desc_unmap_bufsfunction ionic_tx_cleanfunction ionic_tx_servicefunction ionic_tx_cq_servicefunction ionic_tx_flushfunction ionic_tx_emptyfunction ionic_tx_tcp_inner_pseudo_csumfunction ionic_tx_tcp_pseudo_csumfunction ionic_tx_tso_postfunction ionic_tx_tsofunction ionic_tx_calc_csumfunction ionic_tx_calc_no_csumfunction ionic_tx_skb_fragsfunction ionic_txfunction ionic_tx_descs_neededfunction ionic_start_hwstamp_xmitfunction ionic_start_xmit
Annotated Snippet
if (act == XDP_TX) {
struct page *pg = skb_frag_page(frag);
dma_addr = page_pool_get_dma_addr(pg) +
skb_frag_off(frag);
dma_sync_single_for_device(q->dev, dma_addr,
skb_frag_size(frag),
DMA_TO_DEVICE);
} else {
dma_addr = ionic_tx_map_frag(q, frag, 0,
skb_frag_size(frag));
if (dma_addr == DMA_MAPPING_ERROR) {
ionic_tx_desc_unmap_bufs(q, desc_info);
return -EIO;
}
}
bi->dma_addr = dma_addr;
bi->len = skb_frag_size(frag);
bi->page = skb_frag_page(frag);
elem->addr = cpu_to_le64(bi->dma_addr);
elem->len = cpu_to_le16(bi->len);
elem++;
desc_info->nbufs++;
}
}
cmd = encode_txq_desc_cmd(IONIC_TXQ_DESC_OPCODE_CSUM_NONE,
0, (desc_info->nbufs - 1), buf_info->dma_addr);
desc->cmd = cpu_to_le64(cmd);
desc->len = cpu_to_le16(len);
desc->csum_start = 0;
desc->csum_offset = 0;
stats->xdp_frames++;
stats->pkts++;
stats->bytes += len;
ionic_txq_post(q, ring_doorbell);
return 0;
}
int ionic_xdp_xmit(struct net_device *netdev, int n,
struct xdp_frame **xdp_frames, u32 flags)
{
struct ionic_lif *lif = netdev_priv(netdev);
struct ionic_queue *txq;
struct netdev_queue *nq;
int nxmit;
int space;
int cpu;
int qi;
if (unlikely(!test_bit(IONIC_LIF_F_UP, lif->state)))
return -ENETDOWN;
if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK))
return -EINVAL;
/* AdminQ is assumed on cpu 0, while we attempt to affinitize the
* TxRx queue pairs 0..n-1 on cpus 1..n. We try to keep with that
* affinitization here, but of course irqbalance and friends might
* have juggled things anyway, so we have to check for the 0 case.
*/
cpu = smp_processor_id();
qi = cpu ? (cpu - 1) % lif->nxqs : cpu;
txq = &lif->txqcqs[qi]->q;
nq = netdev_get_tx_queue(netdev, txq->index);
__netif_tx_lock(nq, cpu);
txq_trans_cond_update(nq);
if (netif_tx_queue_stopped(nq) ||
!netif_txq_maybe_stop(q_to_ndq(netdev, txq),
ionic_q_space_avail(txq),
1, 1)) {
__netif_tx_unlock(nq);
return -EIO;
}
space = min_t(int, n, ionic_q_space_avail(txq));
for (nxmit = 0; nxmit < space ; nxmit++) {
if (ionic_xdp_post_frame(txq, xdp_frames[nxmit],
XDP_REDIRECT,
virt_to_page(xdp_frames[nxmit]->data),
0, false)) {
nxmit--;
break;
Annotation
- Immediate include surface: `linux/ip.h`, `linux/ipv6.h`, `linux/if_vlan.h`, `net/ip6_checksum.h`, `net/netdev_queues.h`, `net/page_pool/helpers.h`, `ionic.h`, `ionic_lif.h`.
- Detected declarations: `function ionic_txq_post`, `function ionic_rxq_post`, `function ionic_txq_poke_doorbell`, `function ionic_rxq_poke_doorbell`, `function ionic_rx_buf_pa`, `function __ionic_rx_put_buf`, `function ionic_rx_put_buf`, `function ionic_rx_put_buf_direct`, `function ionic_rx_add_skb_frag`, `function ionic_xdp_tx_desc_clean`.
- 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.