drivers/net/dsa/dsa_loop.c

Source file repositories/reference/linux-study-clean/drivers/net/dsa/dsa_loop.c

File Facts

System
Linux kernel
Corpus path
drivers/net/dsa/dsa_loop.c
Extension
.c
Size
12295 bytes
Lines
517
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

const struct device_driver *drv)
{
	return drv == &dsa_loop_drv.mdiodrv.driver;
}

static void dsa_loop_phydevs_unregister(void)
{
	for (int i = 0; i < NUM_FIXED_PHYS; i++) {
		if (!IS_ERR(phydevs[i]))
			fixed_phy_unregister(phydevs[i]);
	}
}

static int __init dsa_loop_create_switch_mdiodev(void)
{
	static struct dsa_loop_pdata dsa_loop_pdata = {
		.cd = {
			.port_names[0] = "lan1",
			.port_names[1] = "lan2",
			.port_names[2] = "lan3",
			.port_names[3] = "lan4",
			.port_names[DSA_LOOP_CPU_PORT] = "cpu",
		},
		.name = "DSA mockup driver",
		.enabled_ports = 0x1f,
		.netdev = "eth0",
	};
	struct mii_bus *bus;
	int ret = -ENODEV;

	bus = mdio_find_bus("fixed-0");
	if (WARN_ON(!bus))
		return ret;

	switch_mdiodev = mdio_device_create(bus, 31);
	if (IS_ERR(switch_mdiodev))
		goto out;

	switch_mdiodev->bus_match = dsa_loop_bus_match;
	switch_mdiodev->dev.platform_data = &dsa_loop_pdata;

	ret = mdio_device_register(switch_mdiodev);
	if (ret)
		mdio_device_free(switch_mdiodev);
out:
	put_device(&bus->dev);
	return ret;
}

static int __init dsa_loop_init(void)
{
	unsigned int i;
	int ret;

	ret = dsa_loop_create_switch_mdiodev();
	if (ret)
		return ret;

	for (i = 0; i < NUM_FIXED_PHYS; i++)
		phydevs[i] = fixed_phy_register_100fd();

	ret = mdio_driver_register(&dsa_loop_drv);
	if (ret) {
		dsa_loop_phydevs_unregister();
		mdio_device_remove(switch_mdiodev);
		mdio_device_free(switch_mdiodev);
	}

	return ret;
}
module_init(dsa_loop_init);

static void __exit dsa_loop_exit(void)
{
	mdio_driver_unregister(&dsa_loop_drv);
	dsa_loop_phydevs_unregister();
	mdio_device_remove(switch_mdiodev);
	mdio_device_free(switch_mdiodev);
}
module_exit(dsa_loop_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Florian Fainelli");
MODULE_DESCRIPTION("DSA loopback driver");

Annotation

Implementation Notes