drivers/net/ethernet/xscale/ixp4xx_eth.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/xscale/ixp4xx_eth.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/xscale/ixp4xx_eth.c
Extension
.c
Size
41615 bytes
Lines
1624
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 ixp4xx_netdev_ops = {
	.ndo_open = eth_open,
	.ndo_stop = eth_close,
	.ndo_change_mtu = ixp4xx_eth_change_mtu,
	.ndo_start_xmit = eth_xmit,
	.ndo_set_rx_mode = eth_set_mcast_list,
	.ndo_eth_ioctl = phy_do_ioctl_running,
	.ndo_set_mac_address = eth_mac_addr,
	.ndo_validate_addr = eth_validate_addr,
	.ndo_hwtstamp_get = ixp4xx_hwtstamp_get,
	.ndo_hwtstamp_set = ixp4xx_hwtstamp_set,
};

static struct eth_plat_info *ixp4xx_of_get_platdata(struct device *dev)
{
	struct device_node *np = dev->of_node;
	struct of_phandle_args queue_spec;
	struct of_phandle_args npe_spec;
	struct device_node *mdio_np;
	struct eth_plat_info *plat;
	u8 mac[ETH_ALEN];
	int ret;

	plat = devm_kzalloc(dev, sizeof(*plat), GFP_KERNEL);
	if (!plat)
		return NULL;

	ret = of_parse_phandle_with_fixed_args(np, "intel,npe-handle", 1, 0,
					       &npe_spec);
	if (ret) {
		dev_err(dev, "no NPE engine specified\n");
		return NULL;
	}
	/* NPE ID 0x00, 0x10, 0x20... */
	plat->npe = (npe_spec.args[0] << 4);

	/* Check if this device has an MDIO bus */
	mdio_np = of_get_child_by_name(np, "mdio");
	if (mdio_np) {
		plat->has_mdio = true;
		mdio_bus_np = mdio_np;
		/* DO NOT put the mdio_np, it will be used */
	}

	/* Get the rx queue as a resource from queue manager */
	ret = of_parse_phandle_with_fixed_args(np, "queue-rx", 1, 0,
					       &queue_spec);
	if (ret) {
		dev_err(dev, "no rx queue phandle\n");
		return NULL;
	}
	plat->rxq = queue_spec.args[0];

	/* Get the txready queue as resource from queue manager */
	ret = of_parse_phandle_with_fixed_args(np, "queue-txready", 1, 0,
					       &queue_spec);
	if (ret) {
		dev_err(dev, "no txready queue phandle\n");
		return NULL;
	}
	plat->txreadyq = queue_spec.args[0];

	ret = of_get_mac_address(np, mac);
	if (!ret) {
		dev_info(dev, "Setting macaddr from DT %pM\n", mac);
		memcpy(plat->hwaddr, mac, ETH_ALEN);
	}

	return plat;
}

static int ixp4xx_eth_probe(struct platform_device *pdev)
{
	struct phy_device *phydev = NULL;
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	struct eth_plat_info *plat;
	struct net_device *ndev;
	struct port *port;
	int err;

	plat = ixp4xx_of_get_platdata(dev);
	if (!plat)
		return -ENODEV;

	if (!(ndev = devm_alloc_etherdev(dev, sizeof(struct port))))
		return -ENOMEM;

	SET_NETDEV_DEV(ndev, dev);
	port = netdev_priv(ndev);

Annotation

Implementation Notes