drivers/net/phy/phy_package.c

Source file repositories/reference/linux-study-clean/drivers/net/phy/phy_package.c

File Facts

System
Linux kernel
Corpus path
drivers/net/phy/phy_package.c
Extension
.c
Size
11893 bytes
Lines
420
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 phy_package_shared {
	u8 base_addr;
	/* With PHY package defined in DT this points to the PHY package node */
	struct device_node *np;
	refcount_t refcnt;
	unsigned long flags;
	size_t priv_size;

	/* private data pointer */
	/* note that this pointer is shared between different phydevs and
	 * the user has to take care of appropriate locking. It is allocated
	 * and freed automatically by phy_package_join() and
	 * phy_package_leave().
	 */
	void *priv;
};

struct device_node *phy_package_get_node(struct phy_device *phydev)
{
	return phydev->shared->np;
}
EXPORT_SYMBOL_GPL(phy_package_get_node);

void *phy_package_get_priv(struct phy_device *phydev)
{
	return phydev->shared->priv;
}
EXPORT_SYMBOL_GPL(phy_package_get_priv);

static int phy_package_address(struct phy_device *phydev,
			       unsigned int addr_offset)
{
	struct phy_package_shared *shared = phydev->shared;
	u8 base_addr = shared->base_addr;

	if (addr_offset >= PHY_MAX_ADDR - base_addr)
		return -EIO;

	/* we know that addr will be in the range 0..31 and thus the
	 * implicit cast to a signed int is not a problem.
	 */
	return base_addr + addr_offset;
}

int __phy_package_read(struct phy_device *phydev, unsigned int addr_offset,
		       u32 regnum)
{
	int addr = phy_package_address(phydev, addr_offset);

	if (addr < 0)
		return addr;

	return __mdiobus_read(phydev->mdio.bus, addr, regnum);
}
EXPORT_SYMBOL_GPL(__phy_package_read);

int __phy_package_write(struct phy_device *phydev, unsigned int addr_offset,
			u32 regnum, u16 val)
{
	int addr = phy_package_address(phydev, addr_offset);

	if (addr < 0)
		return addr;

	return __mdiobus_write(phydev->mdio.bus, addr, regnum, val);
}
EXPORT_SYMBOL_GPL(__phy_package_write);

/**
 * __phy_package_read_mmd - read MMD reg relative to PHY package base addr
 * @phydev: The phy_device struct
 * @addr_offset: The offset to be added to PHY package base_addr
 * @devad: The MMD to read from
 * @regnum: The register on the MMD to read
 *
 * Convenience helper for reading a register of an MMD on a given PHY
 * using the PHY package base address. The base address is added to
 * the addr_offset value.
 *
 * Same calling rules as for __phy_read();
 *
 * NOTE: It's assumed that the entire PHY package is either C22 or C45.
 */
int __phy_package_read_mmd(struct phy_device *phydev,
			   unsigned int addr_offset, int devad,
			   u32 regnum)
{
	int addr = phy_package_address(phydev, addr_offset);

	if (addr < 0)

Annotation

Implementation Notes