Skip to content

Commit d63710f

Browse files
Ansueldavem330
authored andcommitted
net: phy: add support for PHY package MMD read/write
Some PHY in PHY package may require to read/write MMD regs to correctly configure the PHY package. Add support for these additional required function in both lock and no lock variant. It's assumed that the entire PHY package is either C22 or C45. We use C22 or C45 way of writing/reading to mmd regs based on the passed phydev whether it's C22 or C45. Signed-off-by: Christian Marangi <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 028672b commit d63710f

File tree

2 files changed

+156
-0
lines changed

2 files changed

+156
-0
lines changed

drivers/net/phy/phy-core.c

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,146 @@ int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
650650
}
651651
EXPORT_SYMBOL(phy_write_mmd);
652652

653+
/**
654+
* __phy_package_read_mmd - read MMD reg relative to PHY package base addr
655+
* @phydev: The phy_device struct
656+
* @addr_offset: The offset to be added to PHY package base_addr
657+
* @devad: The MMD to read from
658+
* @regnum: The register on the MMD to read
659+
*
660+
* Convenience helper for reading a register of an MMD on a given PHY
661+
* using the PHY package base address. The base address is added to
662+
* the addr_offset value.
663+
*
664+
* Same calling rules as for __phy_read();
665+
*
666+
* NOTE: It's assumed that the entire PHY package is either C22 or C45.
667+
*/
668+
int __phy_package_read_mmd(struct phy_device *phydev,
669+
unsigned int addr_offset, int devad,
670+
u32 regnum)
671+
{
672+
int addr = phy_package_address(phydev, addr_offset);
673+
674+
if (addr < 0)
675+
return addr;
676+
677+
if (regnum > (u16)~0 || devad > 32)
678+
return -EINVAL;
679+
680+
return mmd_phy_read(phydev->mdio.bus, addr, phydev->is_c45, devad,
681+
regnum);
682+
}
683+
EXPORT_SYMBOL(__phy_package_read_mmd);
684+
685+
/**
686+
* phy_package_read_mmd - read MMD reg relative to PHY package base addr
687+
* @phydev: The phy_device struct
688+
* @addr_offset: The offset to be added to PHY package base_addr
689+
* @devad: The MMD to read from
690+
* @regnum: The register on the MMD to read
691+
*
692+
* Convenience helper for reading a register of an MMD on a given PHY
693+
* using the PHY package base address. The base address is added to
694+
* the addr_offset value.
695+
*
696+
* Same calling rules as for phy_read();
697+
*
698+
* NOTE: It's assumed that the entire PHY package is either C22 or C45.
699+
*/
700+
int phy_package_read_mmd(struct phy_device *phydev,
701+
unsigned int addr_offset, int devad,
702+
u32 regnum)
703+
{
704+
int addr = phy_package_address(phydev, addr_offset);
705+
int val;
706+
707+
if (addr < 0)
708+
return addr;
709+
710+
if (regnum > (u16)~0 || devad > 32)
711+
return -EINVAL;
712+
713+
phy_lock_mdio_bus(phydev);
714+
val = mmd_phy_read(phydev->mdio.bus, addr, phydev->is_c45, devad,
715+
regnum);
716+
phy_unlock_mdio_bus(phydev);
717+
718+
return val;
719+
}
720+
EXPORT_SYMBOL(phy_package_read_mmd);
721+
722+
/**
723+
* __phy_package_write_mmd - write MMD reg relative to PHY package base addr
724+
* @phydev: The phy_device struct
725+
* @addr_offset: The offset to be added to PHY package base_addr
726+
* @devad: The MMD to write to
727+
* @regnum: The register on the MMD to write
728+
* @val: value to write to @regnum
729+
*
730+
* Convenience helper for writing a register of an MMD on a given PHY
731+
* using the PHY package base address. The base address is added to
732+
* the addr_offset value.
733+
*
734+
* Same calling rules as for __phy_write();
735+
*
736+
* NOTE: It's assumed that the entire PHY package is either C22 or C45.
737+
*/
738+
int __phy_package_write_mmd(struct phy_device *phydev,
739+
unsigned int addr_offset, int devad,
740+
u32 regnum, u16 val)
741+
{
742+
int addr = phy_package_address(phydev, addr_offset);
743+
744+
if (addr < 0)
745+
return addr;
746+
747+
if (regnum > (u16)~0 || devad > 32)
748+
return -EINVAL;
749+
750+
return mmd_phy_write(phydev->mdio.bus, addr, phydev->is_c45, devad,
751+
regnum, val);
752+
}
753+
EXPORT_SYMBOL(__phy_package_write_mmd);
754+
755+
/**
756+
* phy_package_write_mmd - write MMD reg relative to PHY package base addr
757+
* @phydev: The phy_device struct
758+
* @addr_offset: The offset to be added to PHY package base_addr
759+
* @devad: The MMD to write to
760+
* @regnum: The register on the MMD to write
761+
* @val: value to write to @regnum
762+
*
763+
* Convenience helper for writing a register of an MMD on a given PHY
764+
* using the PHY package base address. The base address is added to
765+
* the addr_offset value.
766+
*
767+
* Same calling rules as for phy_write();
768+
*
769+
* NOTE: It's assumed that the entire PHY package is either C22 or C45.
770+
*/
771+
int phy_package_write_mmd(struct phy_device *phydev,
772+
unsigned int addr_offset, int devad,
773+
u32 regnum, u16 val)
774+
{
775+
int addr = phy_package_address(phydev, addr_offset);
776+
int ret;
777+
778+
if (addr < 0)
779+
return addr;
780+
781+
if (regnum > (u16)~0 || devad > 32)
782+
return -EINVAL;
783+
784+
phy_lock_mdio_bus(phydev);
785+
ret = mmd_phy_write(phydev->mdio.bus, addr, phydev->is_c45, devad,
786+
regnum, val);
787+
phy_unlock_mdio_bus(phydev);
788+
789+
return ret;
790+
}
791+
EXPORT_SYMBOL(phy_package_write_mmd);
792+
653793
/**
654794
* phy_modify_changed - Function for modifying a PHY register
655795
* @phydev: the phy_device struct

include/linux/phy.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2064,6 +2064,22 @@ static inline int __phy_package_write(struct phy_device *phydev,
20642064
return __mdiobus_write(phydev->mdio.bus, addr, regnum, val);
20652065
}
20662066

2067+
int __phy_package_read_mmd(struct phy_device *phydev,
2068+
unsigned int addr_offset, int devad,
2069+
u32 regnum);
2070+
2071+
int phy_package_read_mmd(struct phy_device *phydev,
2072+
unsigned int addr_offset, int devad,
2073+
u32 regnum);
2074+
2075+
int __phy_package_write_mmd(struct phy_device *phydev,
2076+
unsigned int addr_offset, int devad,
2077+
u32 regnum, u16 val);
2078+
2079+
int phy_package_write_mmd(struct phy_device *phydev,
2080+
unsigned int addr_offset, int devad,
2081+
u32 regnum, u16 val);
2082+
20672083
static inline bool __phy_package_set_once(struct phy_device *phydev,
20682084
unsigned int b)
20692085
{

0 commit comments

Comments
 (0)