mvebu: add linux 4.9 support
[openwrt/openwrt.git] / target / linux / mvebu / patches-4.9 / 402-net-phy-make-phy_-read-write-_mmd-generic-MMD-access.patch
1 From: Russell King <rmk+kernel@armlinux.org.uk>
2 Date: Wed, 4 Jan 2017 19:20:21 +0000
3 Subject: [PATCH] net: phy: make phy_(read|write)_mmd() generic MMD
4 accessors
5
6 Make phy_(read|write)_mmd() generic 802.3 clause 45 register accessors
7 for both Clause 22 and Clause 45 PHYs, using either the direct register
8 reading for Clause 45, or the indirect method for Clause 22 PHYs.
9 Allow this behaviour to be overriden by PHY drivers where necessary.
10
11 Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
12 ---
13
14 --- a/drivers/net/phy/phy-core.c
15 +++ b/drivers/net/phy/phy-core.c
16 @@ -69,11 +69,18 @@ EXPORT_SYMBOL(phy_read_mmd_indirect);
17 */
18 int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
19 {
20 - if (!phydev->is_c45)
21 - return -EOPNOTSUPP;
22 + if (regnum > (u16)~0 || devad > 32)
23 + return -EINVAL;
24
25 - return mdiobus_read(phydev->mdio.bus, phydev->mdio.addr,
26 - MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff));
27 + if (phydev->drv->read_mmd)
28 + return phydev->drv->read_mmd(phydev, devad, regnum);
29 +
30 + if (phydev->is_c45) {
31 + u32 addr = MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff);
32 + return mdiobus_read(phydev->mdio.bus, phydev->mdio.addr, addr);
33 + }
34 +
35 + return phy_read_mmd_indirect(phydev, regnum, devad);
36 }
37 EXPORT_SYMBOL(phy_read_mmd);
38
39 @@ -125,11 +132,21 @@ EXPORT_SYMBOL(phy_write_mmd_indirect);
40 */
41 int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
42 {
43 - if (!phydev->is_c45)
44 - return -EOPNOTSUPP;
45 + if (regnum > (u16)~0 || devad > 32)
46 + return -EINVAL;
47 +
48 + if (phydev->drv->read_mmd)
49 + return phydev->drv->write_mmd(phydev, devad, regnum, val);
50 +
51 + if (phydev->is_c45) {
52 + u32 addr = MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff);
53 +
54 + return mdiobus_write(phydev->mdio.bus, phydev->mdio.addr,
55 + addr, val);
56 + }
57
58 - regnum = MII_ADDR_C45 | ((devad & 0x1f) << 16) | (regnum & 0xffff);
59 + phy_write_mmd_indirect(phydev, regnum, devad, val);
60
61 - return mdiobus_write(phydev->mdio.bus, phydev->mdio.addr, regnum, val);
62 + return 0;
63 }
64 EXPORT_SYMBOL(phy_write_mmd);
65 --- a/include/linux/phy.h
66 +++ b/include/linux/phy.h
67 @@ -570,6 +570,30 @@ struct phy_driver {
68 */
69 void (*link_change_notify)(struct phy_device *dev);
70
71 + /*
72 + * Phy specific driver override for reading a MMD register.
73 + * This function is optional for PHY specific drivers. When
74 + * not provided, the default MMD read function will be used
75 + * by phy_read_mmd(), which will use either a direct read for
76 + * Clause 45 PHYs or an indirect read for Clause 22 PHYs.
77 + * devnum is the MMD device number within the PHY device,
78 + * regnum is the register within the selected MMD device.
79 + */
80 + int (*read_mmd)(struct phy_device *dev, int devnum, u16 regnum);
81 +
82 + /*
83 + * Phy specific driver override for writing a MMD register.
84 + * This function is optional for PHY specific drivers. When
85 + * not provided, the default MMD write function will be used
86 + * by phy_write_mmd(), which will use either a direct write for
87 + * Clause 45 PHYs, or an indirect write for Clause 22 PHYs.
88 + * devnum is the MMD device number within the PHY device,
89 + * regnum is the register within the selected MMD device.
90 + * val is the value to be written.
91 + */
92 + int (*write_mmd)(struct phy_device *dev, int devnum, u16 regnum,
93 + u16 val);
94 +
95 /* A function provided by a phy specific driver to override the
96 * the PHY driver framework support for reading a MMD register
97 * from the PHY. If not supported, return -1. This function is