drivers/net/ethernet/ibm/emac/core.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/ibm/emac/core.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/ibm/emac/core.c
Extension
.c
Size
89423 bytes
Lines
3358
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 emac_netdev_ops = {
	.ndo_open		= emac_open,
	.ndo_stop		= emac_close,
	.ndo_get_stats		= emac_stats,
	.ndo_set_rx_mode	= emac_set_multicast_list,
	.ndo_eth_ioctl		= emac_ioctl,
	.ndo_tx_timeout		= emac_tx_timeout,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_set_mac_address	= emac_set_mac_address,
	.ndo_start_xmit		= emac_start_xmit,
};

static const struct net_device_ops emac_gige_netdev_ops = {
	.ndo_open		= emac_open,
	.ndo_stop		= emac_close,
	.ndo_get_stats		= emac_stats,
	.ndo_set_rx_mode	= emac_set_multicast_list,
	.ndo_eth_ioctl		= emac_ioctl,
	.ndo_tx_timeout		= emac_tx_timeout,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_set_mac_address	= emac_set_mac_address,
	.ndo_start_xmit		= emac_start_xmit_sg,
	.ndo_change_mtu		= emac_change_mtu,
};

static int emac_probe(struct platform_device *ofdev)
{
	struct net_device *ndev;
	struct emac_instance *dev;
	struct device_node *np = ofdev->dev.of_node;
	struct device_node **blist = NULL;
	int err, i;

	/* Skip unused/unwired EMACS.  We leave the check for an unused
	 * property here for now, but new flat device trees should set a
	 * status property to "disabled" instead.
	 */
	if (of_property_read_bool(np, "unused") || !of_device_is_available(np))
		return -ENODEV;

	/* Find ourselves in the bootlist if we are there */
	for (i = 0; i < EMAC_BOOT_LIST_SIZE; i++)
		if (emac_boot_list[i] == np)
			blist = &emac_boot_list[i];

	/* Allocate our net_device structure */
	err = -ENOMEM;
	ndev = devm_alloc_etherdev(&ofdev->dev, sizeof(struct emac_instance));
	if (!ndev)
		goto err_gone;

	dev = netdev_priv(ndev);
	dev->ndev = ndev;
	dev->ofdev = ofdev;
	dev->blist = blist;
	SET_NETDEV_DEV(ndev, &ofdev->dev);

	/* Initialize some embedded data structures */
	err = devm_mutex_init(&ofdev->dev, &dev->mdio_lock);
	if (err)
		goto err_gone;

	err = devm_mutex_init(&ofdev->dev, &dev->link_lock);
	if (err)
		goto err_gone;

	spin_lock_init(&dev->lock);
	INIT_WORK(&dev->reset_work, emac_reset_work);

	/* Init various config data based on device-tree */
	err = emac_init_config(dev);
	if (err)
		goto err_gone;

	/* Setup error IRQ handler */
	dev->emac_irq = platform_get_irq(ofdev, 0);
	if (dev->emac_irq < 0) {
		err = dev->emac_irq;
		goto err_gone;
	}

	err = devm_request_irq(&ofdev->dev, dev->emac_irq, emac_irq, 0, "EMAC",
			       dev);
	if (err) {
		dev_err_probe(&ofdev->dev, err, "failed to request IRQ %d",
			      dev->emac_irq);
		goto err_gone;
	}

	ndev->irq = dev->emac_irq;

Annotation

Implementation Notes