drivers/net/dsa/mv88e6xxx/pcs-6352.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/dsa/mv88e6xxx/pcs-6352.c
Extension
.c
Size
9325 bytes
Lines
389
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 marvell_c22_pcs {
	struct mdio_device mdio;
	struct phylink_pcs phylink_pcs;
	unsigned int irq;
	char name[64];
	bool (*link_check)(struct marvell_c22_pcs *mpcs);
	struct mv88e6xxx_port *port;
};

static struct marvell_c22_pcs *pcs_to_marvell_c22_pcs(struct phylink_pcs *pcs)
{
	return container_of(pcs, struct marvell_c22_pcs, phylink_pcs);
}

static int marvell_c22_pcs_set_fiber_page(struct marvell_c22_pcs *mpcs)
{
	u16 page;
	int err;

	mutex_lock(&mpcs->mdio.bus->mdio_lock);

	err = __mdiodev_read(&mpcs->mdio, MII_MARVELL_PHY_PAGE);
	if (err < 0) {
		dev_err(mpcs->mdio.dev.parent,
			"%s: can't read Serdes page register: %pe\n",
			mpcs->name, ERR_PTR(err));
		return err;
	}

	page = err;

	err = __mdiodev_write(&mpcs->mdio, MII_MARVELL_PHY_PAGE,
			      MII_MARVELL_FIBER_PAGE);
	if (err) {
		dev_err(mpcs->mdio.dev.parent,
			"%s: can't set Serdes page register: %pe\n",
			mpcs->name, ERR_PTR(err));
		return err;
	}

	return page;
}

static int marvell_c22_pcs_restore_page(struct marvell_c22_pcs *mpcs,
					int oldpage, int ret)
{
	int err;

	if (oldpage >= 0) {
		err = __mdiodev_write(&mpcs->mdio, MII_MARVELL_PHY_PAGE,
				      oldpage);
		if (err)
			dev_err(mpcs->mdio.dev.parent,
				"%s: can't restore Serdes page register: %pe\n",
				mpcs->name, ERR_PTR(err));
		if (!err || ret < 0)
			err = ret;
	} else {
		err = oldpage;
	}
	mutex_unlock(&mpcs->mdio.bus->mdio_lock);

	return err;
}

static irqreturn_t marvell_c22_pcs_handle_irq(int irq, void *dev_id)
{
	struct marvell_c22_pcs *mpcs = dev_id;
	irqreturn_t status = IRQ_NONE;
	int err, oldpage;

	oldpage = marvell_c22_pcs_set_fiber_page(mpcs);
	if (oldpage < 0)
		goto fail;

	err = __mdiodev_read(&mpcs->mdio, MII_M1011_IEVENT);
	if (err >= 0 && err & MII_M1011_IEVENT_LINK_CHANGE) {
		phylink_pcs_change(&mpcs->phylink_pcs, true);
		status = IRQ_HANDLED;
	}

fail:
	marvell_c22_pcs_restore_page(mpcs, oldpage, 0);

	return status;
}

static int marvell_c22_pcs_modify(struct marvell_c22_pcs *mpcs, u8 reg,
				  u16 mask, u16 val)
{

Annotation

Implementation Notes