drivers/net/dsa/lantiq/mxl-gsw1xx.c

Source file repositories/reference/linux-study-clean/drivers/net/dsa/lantiq/mxl-gsw1xx.c

File Facts

System
Linux kernel
Corpus path
drivers/net/dsa/lantiq/mxl-gsw1xx.c
Extension
.c
Size
26530 bytes
Lines
941
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

struct gsw1xx_priv {
	struct mdio_device	*mdio_dev;
	int			smdio_badr;
	struct			regmap *sgmii;
	struct			regmap *gpio;
	struct			regmap *clk;
	struct			regmap *shell;
	struct			phylink_pcs pcs;
	struct delayed_work	clear_raneg;
	phy_interface_t		tbi_interface;
	struct gswip_priv	gswip;
};

static int gsw1xx_config_smdio_badr(struct gsw1xx_priv *priv,
				    unsigned int reg)
{
	struct mii_bus *bus = priv->mdio_dev->bus;
	int sw_addr = priv->mdio_dev->addr;
	int smdio_badr = priv->smdio_badr;
	int res;

	if (smdio_badr == GSW1XX_SMDIO_BADR_UNKNOWN ||
	    reg - smdio_badr >= GSW1XX_SMDIO_BADR ||
	    smdio_badr > reg) {
		/* Configure the Switch Base Address */
		smdio_badr = reg & ~GENMASK(3, 0);
		res = __mdiobus_write(bus, sw_addr, GSW1XX_SMDIO_BADR, smdio_badr);
		if (res < 0) {
			dev_err(&priv->mdio_dev->dev,
				"%s: Error %d, configuring switch base\n",
				__func__, res);
			return res;
		}
		priv->smdio_badr = smdio_badr;
	}

	return smdio_badr;
}

static int gsw1xx_regmap_read(void *context, unsigned int reg,
			      unsigned int *val)
{
	struct gsw1xx_priv *priv = context;
	struct mii_bus *bus = priv->mdio_dev->bus;
	int sw_addr = priv->mdio_dev->addr;
	int smdio_badr;
	int res;

	smdio_badr = gsw1xx_config_smdio_badr(priv, reg);
	if (smdio_badr < 0)
		return smdio_badr;

	res = __mdiobus_read(bus, sw_addr, reg - smdio_badr);
	if (res < 0) {
		dev_err(&priv->mdio_dev->dev, "%s: Error %d reading 0x%x\n",
			__func__, res, reg);
		return res;
	}

	*val = res;

	return 0;
}

static int gsw1xx_regmap_write(void *context, unsigned int reg,
			       unsigned int val)
{
	struct gsw1xx_priv *priv = context;
	struct mii_bus *bus = priv->mdio_dev->bus;
	int sw_addr = priv->mdio_dev->addr;
	int smdio_badr;
	int res;

	smdio_badr = gsw1xx_config_smdio_badr(priv, reg);
	if (smdio_badr < 0)
		return smdio_badr;

	res = __mdiobus_write(bus, sw_addr, reg - smdio_badr, val);
	if (res < 0)
		dev_err(&priv->mdio_dev->dev,
			"%s: Error %d, writing 0x%x:0x%x\n", __func__, res, reg,
			val);

	return res;
}

static const struct regmap_bus gsw1xx_regmap_bus = {
	.reg_write = gsw1xx_regmap_write,
	.reg_read = gsw1xx_regmap_read,
};

Annotation

Implementation Notes