drivers/net/ethernet/cirrus/ep93xx_eth.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/cirrus/ep93xx_eth.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/cirrus/ep93xx_eth.c
Extension
.c
Size
20736 bytes
Lines
877
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 ep93xx_netdev_ops = {
	.ndo_open		= ep93xx_open,
	.ndo_stop		= ep93xx_close,
	.ndo_start_xmit		= ep93xx_xmit,
	.ndo_eth_ioctl		= ep93xx_ioctl,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_set_mac_address	= eth_mac_addr,
};

static void ep93xx_eth_remove(struct platform_device *pdev)
{
	struct net_device *dev;
	struct ep93xx_priv *ep;
	struct resource *mem;

	dev = platform_get_drvdata(pdev);
	if (dev == NULL)
		return;

	ep = netdev_priv(dev);

	/* @@@ Force down.  */
	unregister_netdev(dev);
	ep93xx_free_buffers(ep);

	if (ep->base_addr != NULL)
		iounmap(ep->base_addr);

	if (ep->res != NULL) {
		mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
		release_mem_region(mem->start, resource_size(mem));
	}

	free_netdev(dev);
}

static int ep93xx_eth_probe(struct platform_device *pdev)
{
	struct net_device *dev;
	struct ep93xx_priv *ep;
	struct resource *mem;
	void __iomem *base_addr;
	struct device_node *np;
	u8 addr[ETH_ALEN];
	u32 phy_id;
	int irq;
	int err;

	if (pdev == NULL)
		return -ENODEV;

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	irq = platform_get_irq(pdev, 0);
	if (!mem || irq < 0)
		return -ENXIO;

	base_addr = ioremap(mem->start, resource_size(mem));
	if (!base_addr)
		return dev_err_probe(&pdev->dev, -EIO, "Failed to ioremap ethernet registers\n");

	np = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0);
	if (!np)
		return dev_err_probe(&pdev->dev, -ENODEV, "Please provide \"phy-handle\"\n");

	err = of_property_read_u32(np, "reg", &phy_id);
	of_node_put(np);
	if (err)
		return dev_err_probe(&pdev->dev, -ENOENT, "Failed to locate \"phy_id\"\n");

	dev = alloc_etherdev(sizeof(struct ep93xx_priv));
	if (dev == NULL) {
		err = -ENOMEM;
		goto err_out;
	}

	memcpy_fromio(addr, base_addr + 0x50, ETH_ALEN);
	eth_hw_addr_set(dev, addr);
	dev->ethtool_ops = &ep93xx_ethtool_ops;
	dev->netdev_ops = &ep93xx_netdev_ops;
	dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;

	ep = netdev_priv(dev);
	ep->dev = dev;
	SET_NETDEV_DEV(dev, &pdev->dev);
	netif_napi_add(dev, &ep->napi, ep93xx_poll);

	platform_set_drvdata(pdev, dev);

	ep->res = request_mem_region(mem->start, resource_size(mem),
				     dev_name(&pdev->dev));

Annotation

Implementation Notes