drivers/net/ethernet/marvell/pxa168_eth.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/marvell/pxa168_eth.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/marvell/pxa168_eth.c
Extension
.c
Size
41263 bytes
Lines
1591
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 pxa168_eth_netdev_ops = {
	.ndo_open		= pxa168_eth_open,
	.ndo_stop		= pxa168_eth_stop,
	.ndo_start_xmit		= pxa168_eth_start_xmit,
	.ndo_set_rx_mode	= pxa168_eth_set_rx_mode,
	.ndo_set_mac_address	= pxa168_eth_set_mac_address,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_eth_ioctl		= phy_do_ioctl,
	.ndo_change_mtu		= pxa168_eth_change_mtu,
	.ndo_tx_timeout		= pxa168_eth_tx_timeout,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller    = pxa168_eth_netpoll,
#endif
};

static int pxa168_eth_probe(struct platform_device *pdev)
{
	struct pxa168_eth_private *pep = NULL;
	struct net_device *dev = NULL;
	struct clk *clk;
	struct device_node *np;
	int err;

	printk(KERN_NOTICE "PXA168 10/100 Ethernet Driver\n");

	clk = devm_clk_get_enabled(&pdev->dev, NULL);
	if (IS_ERR(clk)) {
		dev_err(&pdev->dev, "Fast Ethernet failed to get and enable clock\n");
		return -ENODEV;
	}

	dev = alloc_etherdev(sizeof(struct pxa168_eth_private));
	if (!dev)
		return -ENOMEM;

	platform_set_drvdata(pdev, dev);
	pep = netdev_priv(dev);
	pep->dev = dev;
	pep->clk = clk;

	pep->base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(pep->base)) {
		err = PTR_ERR(pep->base);
		goto err_netdev;
	}

	err = platform_get_irq(pdev, 0);
	if (err == -EPROBE_DEFER)
		goto err_netdev;
	BUG_ON(dev->irq < 0);
	dev->irq = err;
	dev->netdev_ops = &pxa168_eth_netdev_ops;
	dev->watchdog_timeo = 2 * HZ;
	dev->base_addr = 0;
	dev->ethtool_ops = &pxa168_ethtool_ops;

	/* MTU range: 68 - 9500 */
	dev->min_mtu = ETH_MIN_MTU;
	dev->max_mtu = 9500;

	INIT_WORK(&pep->tx_timeout_task, pxa168_eth_tx_timeout_task);

	err = of_get_ethdev_address(pdev->dev.of_node, dev);
	if (err) {
		u8 addr[ETH_ALEN];

		/* try reading the mac address, if set by the bootloader */
		pxa168_eth_get_mac_address(dev, addr);
		if (is_valid_ether_addr(addr)) {
			eth_hw_addr_set(dev, addr);
		} else {
			dev_info(&pdev->dev, "Using random mac address\n");
			eth_hw_addr_random(dev);
		}
	}

	pep->rx_ring_size = NUM_RX_DESCS;
	pep->tx_ring_size = NUM_TX_DESCS;

	pep->pd = dev_get_platdata(&pdev->dev);
	if (pep->pd) {
		if (pep->pd->rx_queue_size)
			pep->rx_ring_size = pep->pd->rx_queue_size;

		if (pep->pd->tx_queue_size)
			pep->tx_ring_size = pep->pd->tx_queue_size;

		pep->port_num = pep->pd->port_number;
		pep->phy_addr = pep->pd->phy_addr;
		pep->phy_speed = pep->pd->speed;

Annotation

Implementation Notes