drivers/net/dsa/sja1105/sja1105_mdio.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/dsa/sja1105/sja1105_mdio.c
Extension
.c
Size
11711 bytes
Lines
508
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source 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

if (IS_ERR(pcs)) {
			rc = PTR_ERR(pcs);
			goto out_pcs_free;
		}

		priv->pcs[port] = pcs;
	}

	priv->mdio_pcs = bus;

	return 0;

out_pcs_free:
	for (port = 0; port < ds->num_ports; port++) {
		if (priv->pcs[port]) {
			xpcs_destroy_pcs(priv->pcs[port]);
			priv->pcs[port] = NULL;
		}
	}

	mdiobus_unregister(bus);
	mdiobus_free(bus);

	return rc;
}

static void sja1105_mdiobus_pcs_unregister(struct sja1105_private *priv)
{
	struct dsa_switch *ds = priv->ds;
	int port;

	if (!priv->mdio_pcs)
		return;

	for (port = 0; port < ds->num_ports; port++) {
		if (priv->pcs[port]) {
			xpcs_destroy_pcs(priv->pcs[port]);
			priv->pcs[port] = NULL;
		}
	}

	mdiobus_unregister(priv->mdio_pcs);
	mdiobus_free(priv->mdio_pcs);
	priv->mdio_pcs = NULL;
}

int sja1105_mdiobus_register(struct dsa_switch *ds)
{
	struct sja1105_private *priv = ds->priv;
	const struct sja1105_regs *regs = priv->info->regs;
	struct device_node *switch_node = ds->dev->of_node;
	struct device_node *mdio_node;
	int rc;

	rc = sja1105_mdiobus_pcs_register(priv);
	if (rc)
		return rc;

	mdio_node = of_get_available_child_by_name(switch_node, "mdios");
	if (!mdio_node)
		return 0;

	if (regs->mdio_100base_tx != SJA1105_RSV_ADDR) {
		rc = sja1105_mdiobus_base_tx_register(priv, mdio_node);
		if (rc)
			goto err_put_mdio_node;
	}

	if (regs->mdio_100base_t1 != SJA1105_RSV_ADDR) {
		rc = sja1105_mdiobus_base_t1_register(priv, mdio_node);
		if (rc)
			goto err_free_base_tx_mdiobus;
	}

	of_node_put(mdio_node);

	return 0;

err_free_base_tx_mdiobus:
	sja1105_mdiobus_base_tx_unregister(priv);
err_put_mdio_node:
	of_node_put(mdio_node);
	sja1105_mdiobus_pcs_unregister(priv);

	return rc;
}

void sja1105_mdiobus_unregister(struct dsa_switch *ds)
{
	struct sja1105_private *priv = ds->priv;

Annotation

Implementation Notes