drivers/net/ethernet/sfc/efx.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/sfc/efx.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/sfc/efx.c
Extension
.c
Size
37668 bytes
Lines
1464
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 efx_netdev_ops = {
	.ndo_open		= efx_net_open,
	.ndo_stop		= efx_net_stop,
	.ndo_get_stats64	= efx_net_stats,
	.ndo_tx_timeout		= efx_watchdog,
	.ndo_start_xmit		= efx_hard_start_xmit,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_change_mtu		= efx_change_mtu,
	.ndo_set_mac_address	= efx_set_mac_address,
	.ndo_set_rx_mode	= efx_set_rx_mode,
	.ndo_set_features	= efx_set_features,
	.ndo_features_check	= efx_features_check,
	.ndo_vlan_rx_add_vid	= efx_vlan_rx_add_vid,
	.ndo_vlan_rx_kill_vid	= efx_vlan_rx_kill_vid,
	.ndo_hwtstamp_set	= efx_hwtstamp_set,
	.ndo_hwtstamp_get	= efx_hwtstamp_get,
#ifdef CONFIG_SFC_SRIOV
	.ndo_set_vf_mac		= efx_sriov_set_vf_mac,
	.ndo_set_vf_vlan	= efx_sriov_set_vf_vlan,
	.ndo_set_vf_spoofchk	= efx_sriov_set_vf_spoofchk,
	.ndo_get_vf_config	= efx_sriov_get_vf_config,
	.ndo_set_vf_link_state  = efx_sriov_set_vf_link_state,
#endif
	.ndo_get_phys_port_id   = efx_get_phys_port_id,
	.ndo_get_phys_port_name	= efx_get_phys_port_name,
#ifdef CONFIG_RFS_ACCEL
	.ndo_rx_flow_steer	= efx_filter_rfs,
#endif
	.ndo_xdp_xmit		= efx_xdp_xmit,
	.ndo_bpf		= efx_xdp
};

static void efx_get_queue_stats_rx(struct net_device *net_dev, int idx,
				   struct netdev_queue_stats_rx *stats)
{
	struct efx_nic *efx = efx_netdev_priv(net_dev);
	struct efx_rx_queue *rx_queue;
	struct efx_channel *channel;

	channel = efx_get_channel(efx, idx);
	rx_queue = efx_channel_get_rx_queue(channel);
	/* Count only packets since last time datapath was started */
	stats->packets = rx_queue->rx_packets - rx_queue->old_rx_packets;
	stats->bytes = rx_queue->rx_bytes - rx_queue->old_rx_bytes;
	stats->hw_drops = efx_get_queue_stat_rx_hw_drops(channel) -
			  channel->old_n_rx_hw_drops;
	stats->hw_drop_overruns = channel->n_rx_nodesc_trunc -
				  channel->old_n_rx_hw_drop_overruns;
}

static void efx_get_queue_stats_tx(struct net_device *net_dev, int idx,
				   struct netdev_queue_stats_tx *stats)
{
	struct efx_nic *efx = efx_netdev_priv(net_dev);
	struct efx_tx_queue *tx_queue;
	struct efx_channel *channel;

	channel = efx_get_tx_channel(efx, idx);
	stats->packets = 0;
	stats->bytes = 0;
	stats->hw_gso_packets = 0;
	stats->hw_gso_wire_packets = 0;
	efx_for_each_channel_tx_queue(tx_queue, channel) {
		stats->packets += tx_queue->complete_packets -
				  tx_queue->old_complete_packets;
		stats->bytes += tx_queue->complete_bytes -
				tx_queue->old_complete_bytes;
		/* Note that, unlike stats->packets and stats->bytes,
		 * these count TXes enqueued, rather than completed,
		 * which may not be what users expect.
		 */
		stats->hw_gso_packets += tx_queue->tso_bursts -
					 tx_queue->old_tso_bursts;
		stats->hw_gso_wire_packets += tx_queue->tso_packets -
					      tx_queue->old_tso_packets;
	}
}

static void efx_get_base_stats(struct net_device *net_dev,
			       struct netdev_queue_stats_rx *rx,
			       struct netdev_queue_stats_tx *tx)
{
	struct efx_nic *efx = efx_netdev_priv(net_dev);
	struct efx_tx_queue *tx_queue;
	struct efx_rx_queue *rx_queue;
	struct efx_channel *channel;

	rx->packets = 0;
	rx->bytes = 0;
	rx->hw_drops = 0;

Annotation

Implementation Notes