drivers/net/dsa/mv88e6xxx/pcs-639x.c

Source file repositories/reference/linux-study-clean/drivers/net/dsa/mv88e6xxx/pcs-639x.c

File Facts

System
Linux kernel
Corpus path
drivers/net/dsa/mv88e6xxx/pcs-639x.c
Extension
.c
Size
24287 bytes
Lines
971
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 mv88e639x_pcs {
	struct mdio_device mdio;
	struct phylink_pcs sgmii_pcs;
	struct phylink_pcs xg_pcs;
	bool erratum_3_14;
	bool supports_5g;
	phy_interface_t interface;
	unsigned int irq;
	char name[64];
	irqreturn_t (*handle_irq)(struct mv88e639x_pcs *mpcs);
};

static int mv88e639x_read(struct mv88e639x_pcs *mpcs, u16 regnum, u16 *val)
{
	int err;

	err = mdiodev_c45_read(&mpcs->mdio, MDIO_MMD_PHYXS, regnum);
	if (err < 0)
		return err;

	*val = err;

	return 0;
}

static int mv88e639x_write(struct mv88e639x_pcs *mpcs, u16 regnum, u16 val)
{
	return mdiodev_c45_write(&mpcs->mdio, MDIO_MMD_PHYXS, regnum, val);
}

static int mv88e639x_modify(struct mv88e639x_pcs *mpcs, u16 regnum, u16 mask,
			    u16 val)
{
	return mdiodev_c45_modify(&mpcs->mdio, MDIO_MMD_PHYXS, regnum, mask,
				  val);
}

static int mv88e639x_modify_changed(struct mv88e639x_pcs *mpcs, u16 regnum,
				    u16 mask, u16 set)
{
	return mdiodev_c45_modify_changed(&mpcs->mdio, MDIO_MMD_PHYXS, regnum,
					  mask, set);
}

static struct mv88e639x_pcs *
mv88e639x_pcs_alloc(struct device *dev, struct mii_bus *bus, unsigned int addr,
		    int port)
{
	struct mv88e639x_pcs *mpcs;

	mpcs = kzalloc_obj(*mpcs);
	if (!mpcs)
		return NULL;

	mpcs->mdio.dev.parent = dev;
	mpcs->mdio.bus = bus;
	mpcs->mdio.addr = addr;

	snprintf(mpcs->name, sizeof(mpcs->name),
		 "mv88e6xxx-%s-serdes-%d", dev_name(dev), port);

	return mpcs;
}

static irqreturn_t mv88e639x_pcs_handle_irq(int irq, void *dev_id)
{
	struct mv88e639x_pcs *mpcs = dev_id;
	irqreturn_t (*handler)(struct mv88e639x_pcs *);

	handler = READ_ONCE(mpcs->handle_irq);
	if (!handler)
		return IRQ_NONE;

	return handler(mpcs);
}

static int mv88e639x_pcs_setup_irq(struct mv88e639x_pcs *mpcs,
				   struct mv88e6xxx_chip *chip, int port)
{
	unsigned int irq;

	irq = mv88e6xxx_serdes_irq_mapping(chip, port);
	if (!irq) {
		/* Use polling mode */
		mpcs->sgmii_pcs.poll = true;
		mpcs->xg_pcs.poll = true;
		return 0;
	}

	mpcs->irq = irq;

Annotation

Implementation Notes