drivers/net/ethernet/meta/fbnic/fbnic_netdev.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
Extension
.c
Size
23388 bytes
Lines
887
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct net_device_ops fbnic_netdev_ops = {
	.ndo_open		= fbnic_open,
	.ndo_stop		= fbnic_stop,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_start_xmit		= fbnic_xmit_frame,
	.ndo_features_check	= fbnic_features_check,
	.ndo_set_mac_address	= fbnic_set_mac,
	.ndo_change_mtu		= fbnic_change_mtu,
	.ndo_set_rx_mode_async	= fbnic_set_rx_mode,
	.ndo_get_stats64	= fbnic_get_stats64,
	.ndo_bpf		= fbnic_bpf,
	.ndo_hwtstamp_get	= fbnic_hwtstamp_get,
	.ndo_hwtstamp_set	= fbnic_hwtstamp_set,
};

static void fbnic_get_queue_stats_rx(struct net_device *dev, int idx,
				     struct netdev_queue_stats_rx *rx)
{
	u64 bytes, packets, alloc_fail, alloc_fail_bdq;
	struct fbnic_net *fbn = netdev_priv(dev);
	struct fbnic_ring *rxr = fbn->rx[idx];
	struct fbnic_dev *fbd = fbn->fbd;
	struct fbnic_queue_stats *stats;
	u64 csum_complete, csum_none;
	struct fbnic_q_triad *qt;
	unsigned int start;

	if (!rxr)
		return;

	/* fbn->rx points to completion queues */
	qt = container_of(rxr, struct fbnic_q_triad, cmpl);

	stats = &rxr->stats;
	do {
		start = u64_stats_fetch_begin(&stats->syncp);
		bytes = stats->bytes;
		packets = stats->packets;
		alloc_fail = stats->rx.alloc_failed;
		csum_complete = stats->rx.csum_complete;
		csum_none = stats->rx.csum_none;
	} while (u64_stats_fetch_retry(&stats->syncp, start));

	stats = &qt->sub0.stats;
	do {
		start = u64_stats_fetch_begin(&stats->syncp);
		alloc_fail_bdq = stats->bdq.alloc_failed;
	} while (u64_stats_fetch_retry(&stats->syncp, start));
	alloc_fail += alloc_fail_bdq;

	stats = &qt->sub1.stats;
	do {
		start = u64_stats_fetch_begin(&stats->syncp);
		alloc_fail_bdq = stats->bdq.alloc_failed;
	} while (u64_stats_fetch_retry(&stats->syncp, start));
	alloc_fail += alloc_fail_bdq;

	rx->bytes = bytes;
	rx->packets = packets;
	rx->alloc_fail = alloc_fail;
	rx->csum_complete = csum_complete;
	rx->csum_none = csum_none;

	fbnic_get_hw_q_stats(fbd, fbd->hw_stats.hw_q);

	spin_lock(&fbd->hw_stats.lock);
	rx->hw_drop_overruns = fbd->hw_stats.hw_q[idx].rde_pkt_cq_drop.value +
			       fbd->hw_stats.hw_q[idx].rde_pkt_bdq_drop.value;
	rx->hw_drops = fbd->hw_stats.hw_q[idx].rde_pkt_err.value +
		       rx->hw_drop_overruns;
	spin_unlock(&fbd->hw_stats.lock);
}

static void fbnic_get_queue_stats_tx(struct net_device *dev, int idx,
				     struct netdev_queue_stats_tx *tx)
{
	struct fbnic_net *fbn = netdev_priv(dev);
	struct fbnic_ring *txr = fbn->tx[idx];
	struct fbnic_queue_stats *stats;
	u64 stop, wake, csum, lso;
	struct fbnic_ring *xdpr;
	unsigned int start;
	u64 bytes, packets;

	if (!txr)
		return;

	stats = &txr->stats;
	do {
		start = u64_stats_fetch_begin(&stats->syncp);

Annotation

Implementation Notes