drivers/net/ethernet/sunplus/spl2sw_int.c
Source file repositories/reference/linux-study-clean/drivers/net/ethernet/sunplus/spl2sw_int.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ethernet/sunplus/spl2sw_int.c- Extension
.c- Size
- 7396 bytes
- Lines
- 274
- 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/platform_device.hlinux/etherdevice.hlinux/netdevice.hlinux/bitfield.hlinux/spinlock.hlinux/of_mdio.hspl2sw_register.hspl2sw_define.hspl2sw_int.h
Detected Declarations
function spl2sw_rx_pollfunction spl2sw_tx_pollfunction spl2sw_ethernet_interrupt
Annotated Snippet
if (unlikely((cmd & RXD_ERR_CODE) || pkg_len < ETH_ZLEN + 4)) {
stats->rx_length_errors++;
stats->rx_dropped++;
goto spl2sw_rx_poll_rec_err;
}
dma_unmap_single(&comm->pdev->dev, sinfo->mapping,
comm->rx_desc_buff_size, DMA_FROM_DEVICE);
skb = sinfo->skb;
skb_put(skb, pkg_len - 4); /* Minus FCS */
skb->ip_summed = CHECKSUM_NONE;
skb->protocol = eth_type_trans(skb, comm->ndev[port]);
len = skb->len;
netif_receive_skb(skb);
stats->rx_packets++;
stats->rx_bytes += len;
/* Allocate a new skb for receiving. */
new_skb = netdev_alloc_skb(NULL, comm->rx_desc_buff_size);
if (unlikely(!new_skb)) {
desc->cmd2 = (rx_pos == comm->rx_desc_num[queue] - 1) ?
RXD_EOR : 0;
sinfo->skb = NULL;
sinfo->mapping = 0;
desc->addr1 = 0;
goto spl2sw_rx_poll_alloc_err;
}
sinfo->mapping = dma_map_single(&comm->pdev->dev, new_skb->data,
comm->rx_desc_buff_size,
DMA_FROM_DEVICE);
if (dma_mapping_error(&comm->pdev->dev, sinfo->mapping)) {
dev_kfree_skb_irq(new_skb);
desc->cmd2 = (rx_pos == comm->rx_desc_num[queue] - 1) ?
RXD_EOR : 0;
sinfo->skb = NULL;
sinfo->mapping = 0;
desc->addr1 = 0;
goto spl2sw_rx_poll_alloc_err;
}
sinfo->skb = new_skb;
desc->addr1 = sinfo->mapping;
spl2sw_rx_poll_rec_err:
desc->cmd2 = (rx_pos == comm->rx_desc_num[queue] - 1) ?
RXD_EOR | comm->rx_desc_buff_size :
comm->rx_desc_buff_size;
wmb(); /* Set RXD_OWN after other fields are effective. */
desc->cmd1 = RXD_OWN;
spl2sw_rx_poll_alloc_err:
/* Move rx_pos to next position */
rx_pos = ((rx_pos + 1) == comm->rx_desc_num[queue]) ? 0 : rx_pos + 1;
budget_left--;
/* If there are packets in high-priority queue,
* stop processing low-priority queue.
*/
if (queue == 1 && !(h_desc->cmd1 & RXD_OWN))
break;
}
comm->rx_pos[queue] = rx_pos;
/* Save pointer to last rx descriptor of high-priority queue. */
if (queue == 0)
h_desc = comm->rx_desc[queue] + rx_pos;
}
spin_lock_irqsave(&comm->int_mask_lock, flags);
mask = readl(comm->l2sw_reg_base + L2SW_SW_INT_MASK_0);
mask &= ~MAC_INT_RX;
writel(mask, comm->l2sw_reg_base + L2SW_SW_INT_MASK_0);
spin_unlock_irqrestore(&comm->int_mask_lock, flags);
napi_complete(napi);
return budget - budget_left;
}
int spl2sw_tx_poll(struct napi_struct *napi, int budget)
{
struct spl2sw_common *comm = container_of(napi, struct spl2sw_common, tx_napi);
struct spl2sw_skb_info *skbinfo;
struct net_device_stats *stats;
int budget_left = budget;
Annotation
- Immediate include surface: `linux/platform_device.h`, `linux/etherdevice.h`, `linux/netdevice.h`, `linux/bitfield.h`, `linux/spinlock.h`, `linux/of_mdio.h`, `spl2sw_register.h`, `spl2sw_define.h`.
- Detected declarations: `function spl2sw_rx_poll`, `function spl2sw_tx_poll`, `function spl2sw_ethernet_interrupt`.
- 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.