Commit cdea04c2 authored by Russell King's avatar Russell King Committed by David S. Miller

net: phy: allow Clause 45 access via mii ioctl

Allow userspace to generate Clause 45 MII access cycles via phylib.
This is useful for tools such as mii-diag to be able to inspect Clause
45 PHYs.
Reviewed-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Signed-off-by: default avatarRussell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7b3b0e89
...@@ -409,6 +409,7 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd) ...@@ -409,6 +409,7 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd)
struct mii_ioctl_data *mii_data = if_mii(ifr); struct mii_ioctl_data *mii_data = if_mii(ifr);
u16 val = mii_data->val_in; u16 val = mii_data->val_in;
bool change_autoneg = false; bool change_autoneg = false;
int prtad, devad;
switch (cmd) { switch (cmd) {
case SIOCGMIIPHY: case SIOCGMIIPHY:
...@@ -416,14 +417,29 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd) ...@@ -416,14 +417,29 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd)
/* fall through */ /* fall through */
case SIOCGMIIREG: case SIOCGMIIREG:
mii_data->val_out = mdiobus_read(phydev->mdio.bus, if (mdio_phy_id_is_c45(mii_data->phy_id)) {
mii_data->phy_id, prtad = mdio_phy_id_prtad(mii_data->phy_id);
mii_data->reg_num); devad = mdio_phy_id_devad(mii_data->phy_id);
devad = MII_ADDR_C45 | devad << 16 | mii_data->reg_num;
} else {
prtad = mii_data->phy_id;
devad = mii_data->reg_num;
}
mii_data->val_out = mdiobus_read(phydev->mdio.bus, prtad,
devad);
return 0; return 0;
case SIOCSMIIREG: case SIOCSMIIREG:
if (mii_data->phy_id == phydev->mdio.addr) { if (mdio_phy_id_is_c45(mii_data->phy_id)) {
switch (mii_data->reg_num) { prtad = mdio_phy_id_prtad(mii_data->phy_id);
devad = mdio_phy_id_devad(mii_data->phy_id);
devad = MII_ADDR_C45 | devad << 16 | mii_data->reg_num;
} else {
prtad = mii_data->phy_id;
devad = mii_data->reg_num;
}
if (prtad == phydev->mdio.addr) {
switch (devad) {
case MII_BMCR: case MII_BMCR:
if ((val & (BMCR_RESET | BMCR_ANENABLE)) == 0) { if ((val & (BMCR_RESET | BMCR_ANENABLE)) == 0) {
if (phydev->autoneg == AUTONEG_ENABLE) if (phydev->autoneg == AUTONEG_ENABLE)
...@@ -456,11 +472,10 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd) ...@@ -456,11 +472,10 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd)
} }
} }
mdiobus_write(phydev->mdio.bus, mii_data->phy_id, mdiobus_write(phydev->mdio.bus, prtad, devad, val);
mii_data->reg_num, val);
if (mii_data->phy_id == phydev->mdio.addr && if (prtad == phydev->mdio.addr &&
mii_data->reg_num == MII_BMCR && devad == MII_BMCR &&
val & BMCR_RESET) val & BMCR_RESET)
return phy_init_hw(phydev); return phy_init_hw(phydev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment