diff options
author | Russell King <linux@armlinux.org.uk> | 2019-11-27 11:45:25 +0000 |
---|---|---|
committer | Jonas Gorski <jonas.gorski@gmail.com> | 2020-01-21 22:32:48 +0100 |
commit | 1c16b574c4f77a30a0268acee30be96ae0dc5948 (patch) | |
tree | 716fd94ee81e332ba19e1af7bf98371120ea1856 /target/linux/generic/backport-4.19/705-v5.1-net-phy-provide-full-set-of-accessor-functions-to-MM.patch | |
parent | a07638eb24b8310a35ea6c3b09f6db59bb31cd68 (diff) | |
download | upstream-1c16b574c4f77a30a0268acee30be96ae0dc5948.tar.gz upstream-1c16b574c4f77a30a0268acee30be96ae0dc5948.tar.bz2 upstream-1c16b574c4f77a30a0268acee30be96ae0dc5948.zip |
kernel: add backported phy/phylink/sfp patches
Backport the phy/phylink/sfp patches currently queued in netdev or in
mainline necessary to support GPON popular modules, specifically to
support Huawei and Nokia GPON modules.
Signed-off-by: Russell King <linux@armlinux.org.uk>
[jonas.gorski: include kernel version in file names, refresh patches]
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Diffstat (limited to 'target/linux/generic/backport-4.19/705-v5.1-net-phy-provide-full-set-of-accessor-functions-to-MM.patch')
-rw-r--r-- | target/linux/generic/backport-4.19/705-v5.1-net-phy-provide-full-set-of-accessor-functions-to-MM.patch | 375 |
1 files changed, 375 insertions, 0 deletions
diff --git a/target/linux/generic/backport-4.19/705-v5.1-net-phy-provide-full-set-of-accessor-functions-to-MM.patch b/target/linux/generic/backport-4.19/705-v5.1-net-phy-provide-full-set-of-accessor-functions-to-MM.patch new file mode 100644 index 0000000000..9a587ad3a6 --- /dev/null +++ b/target/linux/generic/backport-4.19/705-v5.1-net-phy-provide-full-set-of-accessor-functions-to-MM.patch @@ -0,0 +1,375 @@ +From 80758d9542205cd2e9fa730067bc3888d4f5a096 Mon Sep 17 00:00:00 2001 +From: Nikita Yushchenko <nikita.yoush@cogentembedded.com> +Date: Wed, 6 Feb 2019 07:36:40 +0100 +Subject: [PATCH 603/660] net: phy: provide full set of accessor functions to + MMD registers + +This adds full set of locked and unlocked accessor functions to read and +write PHY MMD registers and/or bitfields. + +Set of functions exactly matches what is already available for PHY +legacy registers. + +Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com> +Signed-off-by: Andrew Lunn <andrew@lunn.ch> +Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> +--- + drivers/net/phy/phy-core.c | 116 ++++++++++++++++++++++++++++---- + include/linux/phy.h | 134 ++++++++++++++++++++++++++++++------- + 2 files changed, 214 insertions(+), 36 deletions(-) + +--- a/drivers/net/phy/phy-core.c ++++ b/drivers/net/phy/phy-core.c +@@ -247,15 +247,15 @@ static void mmd_phy_indirect(struct mii_ + } + + /** +- * phy_read_mmd - Convenience function for reading a register ++ * __phy_read_mmd - Convenience function for reading a register + * from an MMD on a given PHY. + * @phydev: The phy_device struct + * @devad: The MMD to read from (0..31) + * @regnum: The register on the MMD to read (0..65535) + * +- * Same rules as for phy_read(); ++ * Same rules as for __phy_read(); + */ +-int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum) ++int __phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum) + { + int val; + +@@ -267,33 +267,52 @@ int phy_read_mmd(struct phy_device *phyd + } else if (phydev->is_c45) { + u32 addr = MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff); + +- val = mdiobus_read(phydev->mdio.bus, phydev->mdio.addr, addr); ++ val = __mdiobus_read(phydev->mdio.bus, phydev->mdio.addr, addr); + } else { + struct mii_bus *bus = phydev->mdio.bus; + int phy_addr = phydev->mdio.addr; + +- mutex_lock(&bus->mdio_lock); + mmd_phy_indirect(bus, phy_addr, devad, regnum); + + /* Read the content of the MMD's selected register */ + val = __mdiobus_read(bus, phy_addr, MII_MMD_DATA); +- mutex_unlock(&bus->mdio_lock); + } + return val; + } ++EXPORT_SYMBOL(__phy_read_mmd); ++ ++/** ++ * phy_read_mmd - Convenience function for reading a register ++ * from an MMD on a given PHY. ++ * @phydev: The phy_device struct ++ * @devad: The MMD to read from ++ * @regnum: The register on the MMD to read ++ * ++ * Same rules as for phy_read(); ++ */ ++int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum) ++{ ++ int ret; ++ ++ mutex_lock(&phydev->mdio.bus->mdio_lock); ++ ret = __phy_read_mmd(phydev, devad, regnum); ++ mutex_unlock(&phydev->mdio.bus->mdio_lock); ++ ++ return ret; ++} + EXPORT_SYMBOL(phy_read_mmd); + + /** +- * phy_write_mmd - Convenience function for writing a register ++ * __phy_write_mmd - Convenience function for writing a register + * on an MMD on a given PHY. + * @phydev: The phy_device struct + * @devad: The MMD to read from + * @regnum: The register on the MMD to read + * @val: value to write to @regnum + * +- * Same rules as for phy_write(); ++ * Same rules as for __phy_write(); + */ +-int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val) ++int __phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val) + { + int ret; + +@@ -305,23 +324,43 @@ int phy_write_mmd(struct phy_device *phy + } else if (phydev->is_c45) { + u32 addr = MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff); + +- ret = mdiobus_write(phydev->mdio.bus, phydev->mdio.addr, +- addr, val); ++ ret = __mdiobus_write(phydev->mdio.bus, phydev->mdio.addr, ++ addr, val); + } else { + struct mii_bus *bus = phydev->mdio.bus; + int phy_addr = phydev->mdio.addr; + +- mutex_lock(&bus->mdio_lock); + mmd_phy_indirect(bus, phy_addr, devad, regnum); + + /* Write the data into MMD's selected register */ + __mdiobus_write(bus, phy_addr, MII_MMD_DATA, val); +- mutex_unlock(&bus->mdio_lock); + + ret = 0; + } + return ret; + } ++EXPORT_SYMBOL(__phy_write_mmd); ++ ++/** ++ * phy_write_mmd - Convenience function for writing a register ++ * on an MMD on a given PHY. ++ * @phydev: The phy_device struct ++ * @devad: The MMD to read from ++ * @regnum: The register on the MMD to read ++ * @val: value to write to @regnum ++ * ++ * Same rules as for phy_write(); ++ */ ++int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val) ++{ ++ int ret; ++ ++ mutex_lock(&phydev->mdio.bus->mdio_lock); ++ ret = __phy_write_mmd(phydev, devad, regnum, val); ++ mutex_unlock(&phydev->mdio.bus->mdio_lock); ++ ++ return ret; ++} + EXPORT_SYMBOL(phy_write_mmd); + + /** +@@ -371,6 +410,57 @@ int phy_modify(struct phy_device *phydev + } + EXPORT_SYMBOL_GPL(phy_modify); + ++/** ++ * __phy_modify_mmd - Convenience function for modifying a register on MMD ++ * @phydev: the phy_device struct ++ * @devad: the MMD containing register to modify ++ * @regnum: register number to modify ++ * @mask: bit mask of bits to clear ++ * @set: new value of bits set in mask to write to @regnum ++ * ++ * Unlocked helper function which allows a MMD register to be modified as ++ * new register value = (old register value & ~mask) | set ++ */ ++int __phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum, ++ u16 mask, u16 set) ++{ ++ int ret; ++ ++ ret = __phy_read_mmd(phydev, devad, regnum); ++ if (ret < 0) ++ return ret; ++ ++ ret = __phy_write_mmd(phydev, devad, regnum, (ret & ~mask) | set); ++ ++ return ret < 0 ? ret : 0; ++} ++EXPORT_SYMBOL_GPL(__phy_modify_mmd); ++ ++/** ++ * phy_modify_mmd - Convenience function for modifying a register on MMD ++ * @phydev: the phy_device struct ++ * @devad: the MMD containing register to modify ++ * @regnum: register number to modify ++ * @mask: bit mask of bits to clear ++ * @set: new value of bits set in mask to write to @regnum ++ * ++ * NOTE: MUST NOT be called from interrupt context, ++ * because the bus read/write functions may wait for an interrupt ++ * to conclude the operation. ++ */ ++int phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum, ++ u16 mask, u16 set) ++{ ++ int ret; ++ ++ mutex_lock(&phydev->mdio.bus->mdio_lock); ++ ret = __phy_modify_mmd(phydev, devad, regnum, mask, set); ++ mutex_unlock(&phydev->mdio.bus->mdio_lock); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(phy_modify_mmd); ++ + static int __phy_read_page(struct phy_device *phydev) + { + return phydev->drv->read_page(phydev); +--- a/include/linux/phy.h ++++ b/include/linux/phy.h +@@ -695,17 +695,6 @@ size_t phy_speeds(unsigned int *speeds, + void phy_resolve_aneg_linkmode(struct phy_device *phydev); + + /** +- * phy_read_mmd - Convenience function for reading a register +- * from an MMD on a given PHY. +- * @phydev: The phy_device struct +- * @devad: The MMD to read from +- * @regnum: The register on the MMD to read +- * +- * Same rules as for phy_read(); +- */ +-int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum); +- +-/** + * phy_read - Convenience function for reading a given PHY register + * @phydev: the phy_device struct + * @regnum: register number to read +@@ -760,9 +749,60 @@ static inline int __phy_write(struct phy + val); + } + ++/** ++ * phy_read_mmd - Convenience function for reading a register ++ * from an MMD on a given PHY. ++ * @phydev: The phy_device struct ++ * @devad: The MMD to read from ++ * @regnum: The register on the MMD to read ++ * ++ * Same rules as for phy_read(); ++ */ ++int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum); ++ ++/** ++ * __phy_read_mmd - Convenience function for reading a register ++ * from an MMD on a given PHY. ++ * @phydev: The phy_device struct ++ * @devad: The MMD to read from ++ * @regnum: The register on the MMD to read ++ * ++ * Same rules as for __phy_read(); ++ */ ++int __phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum); ++ ++/** ++ * phy_write_mmd - Convenience function for writing a register ++ * on an MMD on a given PHY. ++ * @phydev: The phy_device struct ++ * @devad: The MMD to write to ++ * @regnum: The register on the MMD to read ++ * @val: value to write to @regnum ++ * ++ * Same rules as for phy_write(); ++ */ ++int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val); ++ ++/** ++ * __phy_write_mmd - Convenience function for writing a register ++ * on an MMD on a given PHY. ++ * @phydev: The phy_device struct ++ * @devad: The MMD to write to ++ * @regnum: The register on the MMD to read ++ * @val: value to write to @regnum ++ * ++ * Same rules as for __phy_write(); ++ */ ++int __phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val); ++ + int __phy_modify(struct phy_device *phydev, u32 regnum, u16 mask, u16 set); + int phy_modify(struct phy_device *phydev, u32 regnum, u16 mask, u16 set); + ++int __phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum, ++ u16 mask, u16 set); ++int phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum, ++ u16 mask, u16 set); ++ + /** + * __phy_set_bits - Convenience function for setting bits in a PHY register + * @phydev: the phy_device struct +@@ -813,6 +853,66 @@ static inline int phy_clear_bits(struct + } + + /** ++ * __phy_set_bits_mmd - Convenience function for setting bits in a register ++ * on MMD ++ * @phydev: the phy_device struct ++ * @devad: the MMD containing register to modify ++ * @regnum: register number to modify ++ * @val: bits to set ++ * ++ * The caller must have taken the MDIO bus lock. ++ */ ++static inline int __phy_set_bits_mmd(struct phy_device *phydev, int devad, ++ u32 regnum, u16 val) ++{ ++ return __phy_modify_mmd(phydev, devad, regnum, 0, val); ++} ++ ++/** ++ * __phy_clear_bits_mmd - Convenience function for clearing bits in a register ++ * on MMD ++ * @phydev: the phy_device struct ++ * @devad: the MMD containing register to modify ++ * @regnum: register number to modify ++ * @val: bits to clear ++ * ++ * The caller must have taken the MDIO bus lock. ++ */ ++static inline int __phy_clear_bits_mmd(struct phy_device *phydev, int devad, ++ u32 regnum, u16 val) ++{ ++ return __phy_modify_mmd(phydev, devad, regnum, val, 0); ++} ++ ++/** ++ * phy_set_bits_mmd - Convenience function for setting bits in a register ++ * on MMD ++ * @phydev: the phy_device struct ++ * @devad: the MMD containing register to modify ++ * @regnum: register number to modify ++ * @val: bits to set ++ */ ++static inline int phy_set_bits_mmd(struct phy_device *phydev, int devad, ++ u32 regnum, u16 val) ++{ ++ return phy_modify_mmd(phydev, devad, regnum, 0, val); ++} ++ ++/** ++ * phy_clear_bits_mmd - Convenience function for clearing bits in a register ++ * on MMD ++ * @phydev: the phy_device struct ++ * @devad: the MMD containing register to modify ++ * @regnum: register number to modify ++ * @val: bits to clear ++ */ ++static inline int phy_clear_bits_mmd(struct phy_device *phydev, int devad, ++ u32 regnum, u16 val) ++{ ++ return phy_modify_mmd(phydev, devad, regnum, val, 0); ++} ++ ++/** + * phy_interrupt_is_valid - Convenience function for testing a given PHY irq + * @phydev: the phy_device struct + * +@@ -888,18 +988,6 @@ static inline bool phy_is_pseudo_fixed_l + return phydev->is_pseudo_fixed_link; + } + +-/** +- * phy_write_mmd - Convenience function for writing a register +- * on an MMD on a given PHY. +- * @phydev: The phy_device struct +- * @devad: The MMD to read from +- * @regnum: The register on the MMD to read +- * @val: value to write to @regnum +- * +- * Same rules as for phy_write(); +- */ +-int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val); +- + int phy_save_page(struct phy_device *phydev); + int phy_select_page(struct phy_device *phydev, int page); + int phy_restore_page(struct phy_device *phydev, int oldpage, int ret); |