drivers/net/ethernet/sfc/falcon/efx.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/sfc/falcon/efx.c
Extension
.c
Size
82570 bytes
Lines
3205
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 ef4_netdev_ops = {
	.ndo_open		= ef4_net_open,
	.ndo_stop		= ef4_net_stop,
	.ndo_get_stats64	= ef4_net_stats,
	.ndo_tx_timeout		= ef4_watchdog,
	.ndo_start_xmit		= ef4_hard_start_xmit,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_eth_ioctl		= ef4_ioctl,
	.ndo_change_mtu		= ef4_change_mtu,
	.ndo_set_mac_address	= ef4_set_mac_address,
	.ndo_set_rx_mode	= ef4_set_rx_mode,
	.ndo_set_features	= ef4_set_features,
	.ndo_setup_tc		= ef4_setup_tc,
#ifdef CONFIG_RFS_ACCEL
	.ndo_rx_flow_steer	= ef4_filter_rfs,
#endif
};

static void ef4_update_name(struct ef4_nic *efx)
{
	strcpy(efx->name, efx->net_dev->name);
	ef4_mtd_rename(efx);
	ef4_set_channel_names(efx);
}

static int ef4_netdev_event(struct notifier_block *this,
			    unsigned long event, void *ptr)
{
	struct net_device *net_dev = netdev_notifier_info_to_dev(ptr);

	if ((net_dev->netdev_ops == &ef4_netdev_ops) &&
	    event == NETDEV_CHANGENAME)
		ef4_update_name(netdev_priv(net_dev));

	return NOTIFY_DONE;
}

static struct notifier_block ef4_netdev_notifier = {
	.notifier_call = ef4_netdev_event,
};

static ssize_t
phy_type_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct ef4_nic *efx = dev_get_drvdata(dev);
	return sprintf(buf, "%d\n", efx->phy_type);
}
static DEVICE_ATTR_RO(phy_type);

static int ef4_register_netdev(struct ef4_nic *efx)
{
	struct net_device *net_dev = efx->net_dev;
	struct ef4_channel *channel;
	int rc;

	net_dev->watchdog_timeo = 5 * HZ;
	net_dev->irq = efx->pci_dev->irq;
	net_dev->netdev_ops = &ef4_netdev_ops;
	net_dev->ethtool_ops = &ef4_ethtool_ops;
	netif_set_tso_max_segs(net_dev, EF4_TSO_MAX_SEGS);
	net_dev->min_mtu = EF4_MIN_MTU;
	net_dev->max_mtu = EF4_MAX_MTU;

	rtnl_lock();

	/* Enable resets to be scheduled and check whether any were
	 * already requested.  If so, the NIC is probably hosed so we
	 * abort.
	 */
	efx->state = STATE_READY;
	smp_mb(); /* ensure we change state before checking reset_pending */
	if (efx->reset_pending) {
		netif_err(efx, probe, efx->net_dev,
			  "aborting probe due to scheduled reset\n");
		rc = -EIO;
		goto fail_locked;
	}

	rc = dev_alloc_name(net_dev, net_dev->name);
	if (rc < 0)
		goto fail_locked;
	ef4_update_name(efx);

	/* Always start with carrier off; PHY events will detect the link */
	netif_carrier_off(net_dev);

	rc = register_netdevice(net_dev);
	if (rc)
		goto fail_locked;

Annotation

Implementation Notes