drivers/net/pcs/pcs-xpcs.c

Source file repositories/reference/linux-study-clean/drivers/net/pcs/pcs-xpcs.c

File Facts

System
Linux kernel
Corpus path
drivers/net/pcs/pcs-xpcs.c
Extension
.c
Size
43261 bytes
Lines
1729
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 dw_xpcs_compat {
	phy_interface_t interface;
	const int *supported;
	int an_mode;
	int (*pma_config)(struct dw_xpcs *xpcs);
};

struct dw_xpcs_desc {
	u32 id;
	u32 mask;
	const struct dw_xpcs_compat *compat;
};

static const struct dw_xpcs_compat *
xpcs_find_compat(struct dw_xpcs *xpcs, phy_interface_t interface)
{
	const struct dw_xpcs_compat *compat;

	for (compat = xpcs->desc->compat; compat->supported; compat++)
		if (compat->interface == interface)
			return compat;

	return NULL;
}

struct phylink_pcs *xpcs_to_phylink_pcs(struct dw_xpcs *xpcs)
{
	return &xpcs->pcs;
}
EXPORT_SYMBOL_GPL(xpcs_to_phylink_pcs);

int xpcs_get_an_mode(struct dw_xpcs *xpcs, phy_interface_t interface)
{
	const struct dw_xpcs_compat *compat;

	compat = xpcs_find_compat(xpcs, interface);
	if (!compat)
		return -ENODEV;

	return compat->an_mode;
}
EXPORT_SYMBOL_GPL(xpcs_get_an_mode);

static bool __xpcs_linkmode_supported(const struct dw_xpcs_compat *compat,
				      enum ethtool_link_mode_bit_indices linkmode)
{
	int i;

	for (i = 0; compat->supported[i] != __ETHTOOL_LINK_MODE_MASK_NBITS; i++)
		if (compat->supported[i] == linkmode)
			return true;

	return false;
}

#define xpcs_linkmode_supported(compat, mode) \
	__xpcs_linkmode_supported(compat, ETHTOOL_LINK_MODE_ ## mode ## _BIT)

int xpcs_read(struct dw_xpcs *xpcs, int dev, u32 reg)
{
	return mdiodev_c45_read(xpcs->mdiodev, dev, reg);
}

int xpcs_write(struct dw_xpcs *xpcs, int dev, u32 reg, u16 val)
{
	return mdiodev_c45_write(xpcs->mdiodev, dev, reg, val);
}

int xpcs_modify(struct dw_xpcs *xpcs, int dev, u32 reg, u16 mask, u16 set)
{
	return mdiodev_c45_modify(xpcs->mdiodev, dev, reg, mask, set);
}

static int xpcs_modify_changed(struct dw_xpcs *xpcs, int dev, u32 reg,
			       u16 mask, u16 set)
{
	return mdiodev_c45_modify_changed(xpcs->mdiodev, dev, reg, mask, set);
}

static int xpcs_read_vendor(struct dw_xpcs *xpcs, int dev, u32 reg)
{
	return xpcs_read(xpcs, dev, DW_VENDOR | reg);
}

static int xpcs_write_vendor(struct dw_xpcs *xpcs, int dev, int reg,
			     u16 val)
{
	return xpcs_write(xpcs, dev, DW_VENDOR | reg, val);
}

Annotation

Implementation Notes