kernel: copy kernel 4.19 code to 5.4
[openwrt/staging/jogo.git] / target / linux / generic / backport-5.4 / 710-v5.3-net-phy-allow-Clause-45-access-via-mii-ioctl.patch
1 From eb5df3d026824832831376bbdf04e01a52776eea Mon Sep 17 00:00:00 2001
2 From: Russell King <rmk+kernel@armlinux.org.uk>
3 Date: Tue, 28 May 2019 10:57:29 +0100
4 Subject: [PATCH 608/660] net: phy: allow Clause 45 access via mii ioctl
5
6 Allow userspace to generate Clause 45 MII access cycles via phylib.
7 This is useful for tools such as mii-diag to be able to inspect Clause
8 45 PHYs.
9
10 Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
11 Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
12 Signed-off-by: David S. Miller <davem@davemloft.net>
13 Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
14 ---
15 drivers/net/phy/phy.c | 33 ++++++++++++++++++++++++---------
16 1 file changed, 24 insertions(+), 9 deletions(-)
17
18 --- a/drivers/net/phy/phy.c
19 +++ b/drivers/net/phy/phy.c
20 @@ -397,6 +397,7 @@ int phy_mii_ioctl(struct phy_device *phy
21 struct mii_ioctl_data *mii_data = if_mii(ifr);
22 u16 val = mii_data->val_in;
23 bool change_autoneg = false;
24 + int prtad, devad;
25
26 switch (cmd) {
27 case SIOCGMIIPHY:
28 @@ -404,14 +405,29 @@ int phy_mii_ioctl(struct phy_device *phy
29 /* fall through */
30
31 case SIOCGMIIREG:
32 - mii_data->val_out = mdiobus_read(phydev->mdio.bus,
33 - mii_data->phy_id,
34 - mii_data->reg_num);
35 + if (mdio_phy_id_is_c45(mii_data->phy_id)) {
36 + prtad = mdio_phy_id_prtad(mii_data->phy_id);
37 + devad = mdio_phy_id_devad(mii_data->phy_id);
38 + devad = MII_ADDR_C45 | devad << 16 | mii_data->reg_num;
39 + } else {
40 + prtad = mii_data->phy_id;
41 + devad = mii_data->reg_num;
42 + }
43 + mii_data->val_out = mdiobus_read(phydev->mdio.bus, prtad,
44 + devad);
45 return 0;
46
47 case SIOCSMIIREG:
48 - if (mii_data->phy_id == phydev->mdio.addr) {
49 - switch (mii_data->reg_num) {
50 + if (mdio_phy_id_is_c45(mii_data->phy_id)) {
51 + prtad = mdio_phy_id_prtad(mii_data->phy_id);
52 + devad = mdio_phy_id_devad(mii_data->phy_id);
53 + devad = MII_ADDR_C45 | devad << 16 | mii_data->reg_num;
54 + } else {
55 + prtad = mii_data->phy_id;
56 + devad = mii_data->reg_num;
57 + }
58 + if (prtad == phydev->mdio.addr) {
59 + switch (devad) {
60 case MII_BMCR:
61 if ((val & (BMCR_RESET | BMCR_ANENABLE)) == 0) {
62 if (phydev->autoneg == AUTONEG_ENABLE)
63 @@ -443,11 +459,10 @@ int phy_mii_ioctl(struct phy_device *phy
64 }
65 }
66
67 - mdiobus_write(phydev->mdio.bus, mii_data->phy_id,
68 - mii_data->reg_num, val);
69 + mdiobus_write(phydev->mdio.bus, prtad, devad, val);
70
71 - if (mii_data->phy_id == phydev->mdio.addr &&
72 - mii_data->reg_num == MII_BMCR &&
73 + if (prtad == phydev->mdio.addr &&
74 + devad == MII_BMCR &&
75 val & BMCR_RESET)
76 return phy_init_hw(phydev);
77