Commit 276a74d8 authored by David S. Miller's avatar David S. Miller

Merge branch 'phy-mmd-cleanup'

Russell King says:

====================
Clean up PHY MMD accessors

This series cleans up phylib's MMD accessors, so that we have a common
way of accessing the Clause 45 register set.

The current situation is far from ideal - we have phy_(read|write)_mmd()
which accesses Clause 45 registers over Clause 45 accesses, and we have
phy_(read|write)_mmd_indirect(), which accesses Clause 45 registers via
Clause 22 register 13/14.

Generic code uses the indirect methods to access standard Clause 45
features, and when we come to add Clause 45 PHY support to phylib, we
would need to make these conditional upon the PHY type, or duplicate
these functions.

An alternative solution is to merge these accessors together, and select
the appropriate access method depending upon the 802.3 clause that the
PHY conforms with.  The result is that we have a single set of
phy_(read|write)_mmd() accessors.

For cases which require special handling, we still allow PHY drivers to
override all MMD accesses - except rather than just overriding the
indirect accesses.  This keeps existing overrides working.

Combining the two also has another beneficial side effect - we get rid
of similar functions that take arguments in different orders.  The
old direct accessors took the phy structure, devad and register number,
whereas the indirect accessors took the phy structure, register number
and devad in that order.  Care must be taken when updating future
drivers that the argument order is correct, and the function name is
not merely replaced.

This patch set is against net-next.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 2d72d501 060fbc89
# Makefile for Linux PHY drivers and MDIO bus drivers # Makefile for Linux PHY drivers and MDIO bus drivers
libphy-y := phy.o phy_device.o mdio_bus.o mdio_device.o \ libphy-y := phy.o phy_device.o mdio_bus.o mdio_device.o \
mdio-boardinfo.o mdio-boardinfo.o phy-core.o
libphy-$(CONFIG_SWPHY) += swphy.o libphy-$(CONFIG_SWPHY) += swphy.o
libphy-$(CONFIG_LED_TRIGGER_PHY) += phy_led_triggers.o libphy-$(CONFIG_LED_TRIGGER_PHY) += phy_led_triggers.o
......
...@@ -201,8 +201,7 @@ int bcm_phy_set_eee(struct phy_device *phydev, bool enable) ...@@ -201,8 +201,7 @@ int bcm_phy_set_eee(struct phy_device *phydev, bool enable)
int val; int val;
/* Enable EEE at PHY level */ /* Enable EEE at PHY level */
val = phy_read_mmd_indirect(phydev, BRCM_CL45VEN_EEE_CONTROL, val = phy_read_mmd(phydev, MDIO_MMD_AN, BRCM_CL45VEN_EEE_CONTROL);
MDIO_MMD_AN);
if (val < 0) if (val < 0)
return val; return val;
...@@ -211,12 +210,10 @@ int bcm_phy_set_eee(struct phy_device *phydev, bool enable) ...@@ -211,12 +210,10 @@ int bcm_phy_set_eee(struct phy_device *phydev, bool enable)
else else
val &= ~(LPI_FEATURE_EN | LPI_FEATURE_EN_DIG1000X); val &= ~(LPI_FEATURE_EN | LPI_FEATURE_EN_DIG1000X);
phy_write_mmd_indirect(phydev, BRCM_CL45VEN_EEE_CONTROL, phy_write_mmd(phydev, MDIO_MMD_AN, BRCM_CL45VEN_EEE_CONTROL, (u32)val);
MDIO_MMD_AN, (u32)val);
/* Advertise EEE */ /* Advertise EEE */
val = phy_read_mmd_indirect(phydev, BCM_CL45VEN_EEE_ADV, val = phy_read_mmd(phydev, MDIO_MMD_AN, BCM_CL45VEN_EEE_ADV);
MDIO_MMD_AN);
if (val < 0) if (val < 0)
return val; return val;
...@@ -225,8 +222,7 @@ int bcm_phy_set_eee(struct phy_device *phydev, bool enable) ...@@ -225,8 +222,7 @@ int bcm_phy_set_eee(struct phy_device *phydev, bool enable)
else else
val &= ~(MDIO_EEE_100TX | MDIO_EEE_1000T); val &= ~(MDIO_EEE_100TX | MDIO_EEE_1000T);
phy_write_mmd_indirect(phydev, BCM_CL45VEN_EEE_ADV, phy_write_mmd(phydev, MDIO_MMD_AN, BCM_CL45VEN_EEE_ADV, (u32)val);
MDIO_MMD_AN, (u32)val);
return 0; return 0;
} }
......
...@@ -133,14 +133,14 @@ static int dp83867_config_port_mirroring(struct phy_device *phydev) ...@@ -133,14 +133,14 @@ static int dp83867_config_port_mirroring(struct phy_device *phydev)
(struct dp83867_private *)phydev->priv; (struct dp83867_private *)phydev->priv;
u16 val; u16 val;
val = phy_read_mmd_indirect(phydev, DP83867_CFG4, DP83867_DEVADDR); val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4);
if (dp83867->port_mirroring == DP83867_PORT_MIRROING_EN) if (dp83867->port_mirroring == DP83867_PORT_MIRROING_EN)
val |= DP83867_CFG4_PORT_MIRROR_EN; val |= DP83867_CFG4_PORT_MIRROR_EN;
else else
val &= ~DP83867_CFG4_PORT_MIRROR_EN; val &= ~DP83867_CFG4_PORT_MIRROR_EN;
phy_write_mmd_indirect(phydev, DP83867_CFG4, DP83867_DEVADDR, val); phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4, val);
return 0; return 0;
} }
...@@ -231,8 +231,7 @@ static int dp83867_config_init(struct phy_device *phydev) ...@@ -231,8 +231,7 @@ static int dp83867_config_init(struct phy_device *phydev)
* register's bit 11 (marked as RESERVED). * register's bit 11 (marked as RESERVED).
*/ */
bs = phy_read_mmd_indirect(phydev, DP83867_STRAP_STS1, bs = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_STRAP_STS1);
DP83867_DEVADDR);
if (bs & DP83867_STRAP_STS1_RESERVED) if (bs & DP83867_STRAP_STS1_RESERVED)
val &= ~DP83867_PHYCR_RESERVED_MASK; val &= ~DP83867_PHYCR_RESERVED_MASK;
...@@ -243,8 +242,7 @@ static int dp83867_config_init(struct phy_device *phydev) ...@@ -243,8 +242,7 @@ static int dp83867_config_init(struct phy_device *phydev)
if ((phydev->interface >= PHY_INTERFACE_MODE_RGMII_ID) && if ((phydev->interface >= PHY_INTERFACE_MODE_RGMII_ID) &&
(phydev->interface <= PHY_INTERFACE_MODE_RGMII_RXID)) { (phydev->interface <= PHY_INTERFACE_MODE_RGMII_RXID)) {
val = phy_read_mmd_indirect(phydev, DP83867_RGMIICTL, val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_RGMIICTL);
DP83867_DEVADDR);
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
val |= (DP83867_RGMII_TX_CLK_DELAY_EN | DP83867_RGMII_RX_CLK_DELAY_EN); val |= (DP83867_RGMII_TX_CLK_DELAY_EN | DP83867_RGMII_RX_CLK_DELAY_EN);
...@@ -255,25 +253,24 @@ static int dp83867_config_init(struct phy_device *phydev) ...@@ -255,25 +253,24 @@ static int dp83867_config_init(struct phy_device *phydev)
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
val |= DP83867_RGMII_RX_CLK_DELAY_EN; val |= DP83867_RGMII_RX_CLK_DELAY_EN;
phy_write_mmd_indirect(phydev, DP83867_RGMIICTL, phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RGMIICTL, val);
DP83867_DEVADDR, val);
delay = (dp83867->rx_id_delay | delay = (dp83867->rx_id_delay |
(dp83867->tx_id_delay << DP83867_RGMII_TX_CLK_DELAY_SHIFT)); (dp83867->tx_id_delay << DP83867_RGMII_TX_CLK_DELAY_SHIFT));
phy_write_mmd_indirect(phydev, DP83867_RGMIIDCTL, phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RGMIIDCTL,
DP83867_DEVADDR, delay); delay);
if (dp83867->io_impedance >= 0) { if (dp83867->io_impedance >= 0) {
val = phy_read_mmd_indirect(phydev, DP83867_IO_MUX_CFG, val = phy_read_mmd(phydev, DP83867_DEVADDR,
DP83867_DEVADDR); DP83867_IO_MUX_CFG);
val &= ~DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL; val &= ~DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL;
val |= dp83867->io_impedance & val |= dp83867->io_impedance &
DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL; DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL;
phy_write_mmd_indirect(phydev, DP83867_IO_MUX_CFG, phy_write_mmd(phydev, DP83867_DEVADDR,
DP83867_DEVADDR, val); DP83867_IO_MUX_CFG, val);
} }
} }
......
...@@ -166,13 +166,13 @@ static int xway_gphy_config_init(struct phy_device *phydev) ...@@ -166,13 +166,13 @@ static int xway_gphy_config_init(struct phy_device *phydev)
/* Clear all pending interrupts */ /* Clear all pending interrupts */
phy_read(phydev, XWAY_MDIO_ISTAT); phy_read(phydev, XWAY_MDIO_ISTAT);
phy_write_mmd_indirect(phydev, XWAY_MMD_LEDCH, MDIO_MMD_VEND2, phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDCH,
XWAY_MMD_LEDCH_NACS_NONE | XWAY_MMD_LEDCH_NACS_NONE |
XWAY_MMD_LEDCH_SBF_F02HZ | XWAY_MMD_LEDCH_SBF_F02HZ |
XWAY_MMD_LEDCH_FBF_F16HZ); XWAY_MMD_LEDCH_FBF_F16HZ);
phy_write_mmd_indirect(phydev, XWAY_MMD_LEDCL, MDIO_MMD_VEND2, phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDCL,
XWAY_MMD_LEDCH_CBLINK_NONE | XWAY_MMD_LEDCH_CBLINK_NONE |
XWAY_MMD_LEDCH_SCAN_NONE); XWAY_MMD_LEDCH_SCAN_NONE);
/** /**
* In most cases only one LED is connected to this phy, so * In most cases only one LED is connected to this phy, so
...@@ -183,12 +183,12 @@ static int xway_gphy_config_init(struct phy_device *phydev) ...@@ -183,12 +183,12 @@ static int xway_gphy_config_init(struct phy_device *phydev)
ledxh = XWAY_MMD_LEDxH_BLINKF_NONE | XWAY_MMD_LEDxH_CON_LINK10XX; ledxh = XWAY_MMD_LEDxH_BLINKF_NONE | XWAY_MMD_LEDxH_CON_LINK10XX;
ledxl = XWAY_MMD_LEDxL_PULSE_TXACT | XWAY_MMD_LEDxL_PULSE_RXACT | ledxl = XWAY_MMD_LEDxL_PULSE_TXACT | XWAY_MMD_LEDxL_PULSE_RXACT |
XWAY_MMD_LEDxL_BLINKS_NONE; XWAY_MMD_LEDxL_BLINKS_NONE;
phy_write_mmd_indirect(phydev, XWAY_MMD_LED0H, MDIO_MMD_VEND2, ledxh); phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED0H, ledxh);
phy_write_mmd_indirect(phydev, XWAY_MMD_LED0L, MDIO_MMD_VEND2, ledxl); phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED0L, ledxl);
phy_write_mmd_indirect(phydev, XWAY_MMD_LED1H, MDIO_MMD_VEND2, ledxh); phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED1H, ledxh);
phy_write_mmd_indirect(phydev, XWAY_MMD_LED1L, MDIO_MMD_VEND2, ledxl); phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED1L, ledxl);
phy_write_mmd_indirect(phydev, XWAY_MMD_LED2H, MDIO_MMD_VEND2, ledxh); phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED2H, ledxh);
phy_write_mmd_indirect(phydev, XWAY_MMD_LED2L, MDIO_MMD_VEND2, ledxl); phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED2L, ledxl);
return 0; return 0;
} }
......
...@@ -637,8 +637,7 @@ static int ksz8873mll_config_aneg(struct phy_device *phydev) ...@@ -637,8 +637,7 @@ static int ksz8873mll_config_aneg(struct phy_device *phydev)
* MMD extended PHY registers. * MMD extended PHY registers.
*/ */
static int static int
ksz9021_rd_mmd_phyreg(struct phy_device *phydev, int ptrad, int devnum, ksz9021_rd_mmd_phyreg(struct phy_device *phydev, int devad, u16 regnum)
int regnum)
{ {
return -1; return -1;
} }
...@@ -646,10 +645,10 @@ ksz9021_rd_mmd_phyreg(struct phy_device *phydev, int ptrad, int devnum, ...@@ -646,10 +645,10 @@ ksz9021_rd_mmd_phyreg(struct phy_device *phydev, int ptrad, int devnum,
/* This routine does nothing since the Micrel ksz9021 does not support /* This routine does nothing since the Micrel ksz9021 does not support
* standard IEEE MMD extended PHY registers. * standard IEEE MMD extended PHY registers.
*/ */
static void static int
ksz9021_wr_mmd_phyreg(struct phy_device *phydev, int ptrad, int devnum, ksz9021_wr_mmd_phyreg(struct phy_device *phydev, int devad, u16 regnum, u16 val)
int regnum, u32 val)
{ {
return -1;
} }
static int kszphy_get_sset_count(struct phy_device *phydev) static int kszphy_get_sset_count(struct phy_device *phydev)
...@@ -962,8 +961,8 @@ static struct phy_driver ksphy_driver[] = { ...@@ -962,8 +961,8 @@ static struct phy_driver ksphy_driver[] = {
.get_stats = kszphy_get_stats, .get_stats = kszphy_get_stats,
.suspend = genphy_suspend, .suspend = genphy_suspend,
.resume = genphy_resume, .resume = genphy_resume,
.read_mmd_indirect = ksz9021_rd_mmd_phyreg, .read_mmd = ksz9021_rd_mmd_phyreg,
.write_mmd_indirect = ksz9021_wr_mmd_phyreg, .write_mmd = ksz9021_wr_mmd_phyreg,
}, { }, {
.phy_id = PHY_ID_KSZ9031, .phy_id = PHY_ID_KSZ9031,
.phy_id_mask = MICREL_PHY_ID_MASK, .phy_id_mask = MICREL_PHY_ID_MASK,
......
...@@ -78,9 +78,8 @@ static int lan88xx_probe(struct phy_device *phydev) ...@@ -78,9 +78,8 @@ static int lan88xx_probe(struct phy_device *phydev)
priv->wolopts = 0; priv->wolopts = 0;
/* these values can be used to identify internal PHY */ /* these values can be used to identify internal PHY */
priv->chip_id = phy_read_mmd_indirect(phydev, LAN88XX_MMD3_CHIP_ID, 3); priv->chip_id = phy_read_mmd(phydev, 3, LAN88XX_MMD3_CHIP_ID);
priv->chip_rev = phy_read_mmd_indirect(phydev, LAN88XX_MMD3_CHIP_REV, priv->chip_rev = phy_read_mmd(phydev, 3, LAN88XX_MMD3_CHIP_REV);
3);
phydev->priv = priv; phydev->priv = priv;
......
/*
* Core PHY library, taken from phy.c
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#include <linux/export.h>
#include <linux/phy.h>
static void mmd_phy_indirect(struct mii_bus *bus, int phy_addr, int devad,
u16 regnum)
{
/* Write the desired MMD Devad */
bus->write(bus, phy_addr, MII_MMD_CTRL, devad);
/* Write the desired MMD register address */
bus->write(bus, phy_addr, MII_MMD_DATA, regnum);
/* Select the Function : DATA with no post increment */
bus->write(bus, phy_addr, MII_MMD_CTRL, devad | MII_MMD_CTRL_NOINCR);
}
/**
* 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();
*/
int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
{
int val;
if (regnum > (u16)~0 || devad > 32)
return -EINVAL;
if (phydev->drv->read_mmd) {
val = phydev->drv->read_mmd(phydev, devad, regnum);
} else if (phydev->is_c45) {
u32 addr = MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff);
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 = bus->read(bus, phy_addr, MII_MMD_DATA);
mutex_unlock(&bus->mdio_lock);
}
return val;
}
EXPORT_SYMBOL(phy_read_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;
if (regnum > (u16)~0 || devad > 32)
return -EINVAL;
if (phydev->drv->read_mmd) {
ret = phydev->drv->write_mmd(phydev, devad, regnum, val);
} 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);
} 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 */
bus->write(bus, phy_addr, MII_MMD_DATA, val);
mutex_unlock(&bus->mdio_lock);
ret = 0;
}
return ret;
}
EXPORT_SYMBOL(phy_write_mmd);
...@@ -1192,91 +1192,6 @@ void phy_mac_interrupt(struct phy_device *phydev, int new_link) ...@@ -1192,91 +1192,6 @@ void phy_mac_interrupt(struct phy_device *phydev, int new_link)
} }
EXPORT_SYMBOL(phy_mac_interrupt); EXPORT_SYMBOL(phy_mac_interrupt);
static inline void mmd_phy_indirect(struct mii_bus *bus, int prtad, int devad,
int addr)
{
/* Write the desired MMD Devad */
bus->write(bus, addr, MII_MMD_CTRL, devad);
/* Write the desired MMD register address */
bus->write(bus, addr, MII_MMD_DATA, prtad);
/* Select the Function : DATA with no post increment */
bus->write(bus, addr, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR));
}
/**
* phy_read_mmd_indirect - reads data from the MMD registers
* @phydev: The PHY device bus
* @prtad: MMD Address
* @devad: MMD DEVAD
*
* Description: it reads data from the MMD registers (clause 22 to access to
* clause 45) of the specified phy address.
* To read these register we have:
* 1) Write reg 13 // DEVAD
* 2) Write reg 14 // MMD Address
* 3) Write reg 13 // MMD Data Command for MMD DEVAD
* 3) Read reg 14 // Read MMD data
*/
int phy_read_mmd_indirect(struct phy_device *phydev, int prtad, int devad)
{
struct phy_driver *phydrv = phydev->drv;
int addr = phydev->mdio.addr;
int value = -1;
if (!phydrv->read_mmd_indirect) {
struct mii_bus *bus = phydev->mdio.bus;
mutex_lock(&bus->mdio_lock);
mmd_phy_indirect(bus, prtad, devad, addr);
/* Read the content of the MMD's selected register */
value = bus->read(bus, addr, MII_MMD_DATA);
mutex_unlock(&bus->mdio_lock);
} else {
value = phydrv->read_mmd_indirect(phydev, prtad, devad, addr);
}
return value;
}
EXPORT_SYMBOL(phy_read_mmd_indirect);
/**
* phy_write_mmd_indirect - writes data to the MMD registers
* @phydev: The PHY device
* @prtad: MMD Address
* @devad: MMD DEVAD
* @data: data to write in the MMD register
*
* Description: Write data from the MMD registers of the specified
* phy address.
* To write these register we have:
* 1) Write reg 13 // DEVAD
* 2) Write reg 14 // MMD Address
* 3) Write reg 13 // MMD Data Command for MMD DEVAD
* 3) Write reg 14 // Write MMD data
*/
void phy_write_mmd_indirect(struct phy_device *phydev, int prtad,
int devad, u32 data)
{
struct phy_driver *phydrv = phydev->drv;
int addr = phydev->mdio.addr;
if (!phydrv->write_mmd_indirect) {
struct mii_bus *bus = phydev->mdio.bus;
mutex_lock(&bus->mdio_lock);
mmd_phy_indirect(bus, prtad, devad, addr);
/* Write the data into MMD's selected register */
bus->write(bus, addr, MII_MMD_DATA, data);
mutex_unlock(&bus->mdio_lock);
} else {
phydrv->write_mmd_indirect(phydev, prtad, devad, addr, data);
}
}
EXPORT_SYMBOL(phy_write_mmd_indirect);
/** /**
* phy_init_eee - init and check the EEE feature * phy_init_eee - init and check the EEE feature
* @phydev: target phy_device struct * @phydev: target phy_device struct
...@@ -1312,8 +1227,7 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable) ...@@ -1312,8 +1227,7 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
return status; return status;
/* First check if the EEE ability is supported */ /* First check if the EEE ability is supported */
eee_cap = phy_read_mmd_indirect(phydev, MDIO_PCS_EEE_ABLE, eee_cap = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE);
MDIO_MMD_PCS);
if (eee_cap <= 0) if (eee_cap <= 0)
goto eee_exit_err; goto eee_exit_err;
...@@ -1324,13 +1238,11 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable) ...@@ -1324,13 +1238,11 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
/* Check which link settings negotiated and verify it in /* Check which link settings negotiated and verify it in
* the EEE advertising registers. * the EEE advertising registers.
*/ */
eee_lp = phy_read_mmd_indirect(phydev, MDIO_AN_EEE_LPABLE, eee_lp = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_LPABLE);
MDIO_MMD_AN);
if (eee_lp <= 0) if (eee_lp <= 0)
goto eee_exit_err; goto eee_exit_err;
eee_adv = phy_read_mmd_indirect(phydev, MDIO_AN_EEE_ADV, eee_adv = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV);
MDIO_MMD_AN);
if (eee_adv <= 0) if (eee_adv <= 0)
goto eee_exit_err; goto eee_exit_err;
...@@ -1343,14 +1255,12 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable) ...@@ -1343,14 +1255,12 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
/* Configure the PHY to stop receiving xMII /* Configure the PHY to stop receiving xMII
* clock while it is signaling LPI. * clock while it is signaling LPI.
*/ */
int val = phy_read_mmd_indirect(phydev, MDIO_CTRL1, int val = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1);
MDIO_MMD_PCS);
if (val < 0) if (val < 0)
return val; return val;
val |= MDIO_PCS_CTRL1_CLKSTOP_EN; val |= MDIO_PCS_CTRL1_CLKSTOP_EN;
phy_write_mmd_indirect(phydev, MDIO_CTRL1, phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1, val);
MDIO_MMD_PCS, val);
} }
return 0; /* EEE supported */ return 0; /* EEE supported */
...@@ -1372,7 +1282,7 @@ int phy_get_eee_err(struct phy_device *phydev) ...@@ -1372,7 +1282,7 @@ int phy_get_eee_err(struct phy_device *phydev)
if (!phydev->drv) if (!phydev->drv)
return -EIO; return -EIO;
return phy_read_mmd_indirect(phydev, MDIO_PCS_EEE_WK_ERR, MDIO_MMD_PCS); return phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_WK_ERR);
} }
EXPORT_SYMBOL(phy_get_eee_err); EXPORT_SYMBOL(phy_get_eee_err);
...@@ -1392,19 +1302,19 @@ int phy_ethtool_get_eee(struct phy_device *phydev, struct ethtool_eee *data) ...@@ -1392,19 +1302,19 @@ int phy_ethtool_get_eee(struct phy_device *phydev, struct ethtool_eee *data)
return -EIO; return -EIO;
/* Get Supported EEE */ /* Get Supported EEE */
val = phy_read_mmd_indirect(phydev, MDIO_PCS_EEE_ABLE, MDIO_MMD_PCS); val = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE);
if (val < 0) if (val < 0)
return val; return val;
data->supported = mmd_eee_cap_to_ethtool_sup_t(val); data->supported = mmd_eee_cap_to_ethtool_sup_t(val);
/* Get advertisement EEE */ /* Get advertisement EEE */
val = phy_read_mmd_indirect(phydev, MDIO_AN_EEE_ADV, MDIO_MMD_AN); val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV);
if (val < 0) if (val < 0)
return val; return val;
data->advertised = mmd_eee_adv_to_ethtool_adv_t(val); data->advertised = mmd_eee_adv_to_ethtool_adv_t(val);
/* Get LP advertisement EEE */ /* Get LP advertisement EEE */
val = phy_read_mmd_indirect(phydev, MDIO_AN_EEE_LPABLE, MDIO_MMD_AN); val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_LPABLE);
if (val < 0) if (val < 0)
return val; return val;
data->lp_advertised = mmd_eee_adv_to_ethtool_adv_t(val); data->lp_advertised = mmd_eee_adv_to_ethtool_adv_t(val);
...@@ -1430,7 +1340,7 @@ int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data) ...@@ -1430,7 +1340,7 @@ int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data)
/* Mask prohibited EEE modes */ /* Mask prohibited EEE modes */
val &= ~phydev->eee_broken_modes; val &= ~phydev->eee_broken_modes;
phy_write_mmd_indirect(phydev, MDIO_AN_EEE_ADV, MDIO_MMD_AN, val); phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val);
return 0; return 0;
} }
......
...@@ -1217,7 +1217,7 @@ static int genphy_config_eee_advert(struct phy_device *phydev) ...@@ -1217,7 +1217,7 @@ static int genphy_config_eee_advert(struct phy_device *phydev)
* supported by the phy. If we read 0, EEE is not advertised * supported by the phy. If we read 0, EEE is not advertised
* In both case, we don't need to continue * In both case, we don't need to continue
*/ */
adv = phy_read_mmd_indirect(phydev, MDIO_AN_EEE_ADV, MDIO_MMD_AN); adv = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV);
if (adv <= 0) if (adv <= 0)
return 0; return 0;
...@@ -1228,7 +1228,7 @@ static int genphy_config_eee_advert(struct phy_device *phydev) ...@@ -1228,7 +1228,7 @@ static int genphy_config_eee_advert(struct phy_device *phydev)
if (old_adv == adv) if (old_adv == adv)
return 0; return 0;
phy_write_mmd_indirect(phydev, MDIO_AN_EEE_ADV, MDIO_MMD_AN, adv); phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, adv);
return 1; return 1;
} }
......
...@@ -1952,10 +1952,10 @@ static int lan8835_fixup(struct phy_device *phydev) ...@@ -1952,10 +1952,10 @@ static int lan8835_fixup(struct phy_device *phydev)
struct lan78xx_net *dev = netdev_priv(phydev->attached_dev); struct lan78xx_net *dev = netdev_priv(phydev->attached_dev);
/* LED2/PME_N/IRQ_N/RGMII_ID pin to IRQ_N mode */ /* LED2/PME_N/IRQ_N/RGMII_ID pin to IRQ_N mode */
buf = phy_read_mmd_indirect(phydev, 0x8010, 3); buf = phy_read_mmd(phydev, MDIO_MMD_PCS, 0x8010);
buf &= ~0x1800; buf &= ~0x1800;
buf |= 0x0800; buf |= 0x0800;
phy_write_mmd_indirect(phydev, 0x8010, 3, buf); phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8010, buf);
/* RGMII MAC TXC Delay Enable */ /* RGMII MAC TXC Delay Enable */
ret = lan78xx_write_reg(dev, MAC_RGMII_ID, ret = lan78xx_write_reg(dev, MAC_RGMII_ID,
...@@ -1975,11 +1975,11 @@ static int ksz9031rnx_fixup(struct phy_device *phydev) ...@@ -1975,11 +1975,11 @@ static int ksz9031rnx_fixup(struct phy_device *phydev)
/* Micrel9301RNX PHY configuration */ /* Micrel9301RNX PHY configuration */
/* RGMII Control Signal Pad Skew */ /* RGMII Control Signal Pad Skew */
phy_write_mmd_indirect(phydev, 4, 2, 0x0077); phy_write_mmd(phydev, MDIO_MMD_WIS, 4, 0x0077);
/* RGMII RX Data Pad Skew */ /* RGMII RX Data Pad Skew */
phy_write_mmd_indirect(phydev, 5, 2, 0x7777); phy_write_mmd(phydev, MDIO_MMD_WIS, 5, 0x7777);
/* RGMII RX Clock Pad Skew */ /* RGMII RX Clock Pad Skew */
phy_write_mmd_indirect(phydev, 8, 2, 0x1FF); phy_write_mmd(phydev, MDIO_MMD_WIS, 8, 0x1FF);
dev->interface = PHY_INTERFACE_MODE_RGMII_RXID; dev->interface = PHY_INTERFACE_MODE_RGMII_RXID;
......
...@@ -587,23 +587,29 @@ struct phy_driver { ...@@ -587,23 +587,29 @@ struct phy_driver {
*/ */
void (*link_change_notify)(struct phy_device *dev); void (*link_change_notify)(struct phy_device *dev);
/* A function provided by a phy specific driver to override the /*
* the PHY driver framework support for reading a MMD register * Phy specific driver override for reading a MMD register.
* from the PHY. If not supported, return -1. This function is * This function is optional for PHY specific drivers. When
* optional for PHY specific drivers, if not provided then the * not provided, the default MMD read function will be used
* default MMD read function is used by the PHY framework. * by phy_read_mmd(), which will use either a direct read for
* Clause 45 PHYs or an indirect read for Clause 22 PHYs.
* devnum is the MMD device number within the PHY device,
* regnum is the register within the selected MMD device.
*/ */
int (*read_mmd_indirect)(struct phy_device *dev, int ptrad, int (*read_mmd)(struct phy_device *dev, int devnum, u16 regnum);
int devnum, int regnum);
/*
/* A function provided by a phy specific driver to override the * Phy specific driver override for writing a MMD register.
* the PHY driver framework support for writing a MMD register * This function is optional for PHY specific drivers. When
* from the PHY. This function is optional for PHY specific drivers, * not provided, the default MMD write function will be used
* if not provided then the default MMD read function is used by * by phy_write_mmd(), which will use either a direct write for
* the PHY framework. * Clause 45 PHYs, or an indirect write for Clause 22 PHYs.
* devnum is the MMD device number within the PHY device,
* regnum is the register within the selected MMD device.
* val is the value to be written.
*/ */
void (*write_mmd_indirect)(struct phy_device *dev, int ptrad, int (*write_mmd)(struct phy_device *dev, int devnum, u16 regnum,
int devnum, int regnum, u32 val); u16 val);
/* Get the size and type of the eeprom contained within a plug-in /* Get the size and type of the eeprom contained within a plug-in
* module */ * module */
...@@ -651,25 +657,7 @@ struct phy_fixup { ...@@ -651,25 +657,7 @@ struct phy_fixup {
* *
* Same rules as for phy_read(); * Same rules as for phy_read();
*/ */
static inline int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum) int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum);
{
if (!phydev->is_c45)
return -EOPNOTSUPP;
return mdiobus_read(phydev->mdio.bus, phydev->mdio.addr,
MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff));
}
/**
* phy_read_mmd_indirect - reads data from the MMD registers
* @phydev: The PHY device bus
* @prtad: MMD Address
* @addr: PHY address on the MII bus
*
* Description: it reads data from the MMD registers (clause 22 to access to
* clause 45) of the specified phy address.
*/
int phy_read_mmd_indirect(struct phy_device *phydev, int prtad, int devad);
/** /**
* phy_read - Convenience function for reading a given PHY register * phy_read - Convenience function for reading a given PHY register
...@@ -752,29 +740,7 @@ static inline bool phy_is_pseudo_fixed_link(struct phy_device *phydev) ...@@ -752,29 +740,7 @@ static inline bool phy_is_pseudo_fixed_link(struct phy_device *phydev)
* *
* Same rules as for phy_write(); * Same rules as for phy_write();
*/ */
static inline int phy_write_mmd(struct phy_device *phydev, int devad, int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val);
u32 regnum, u16 val)
{
if (!phydev->is_c45)
return -EOPNOTSUPP;
regnum = MII_ADDR_C45 | ((devad & 0x1f) << 16) | (regnum & 0xffff);
return mdiobus_write(phydev->mdio.bus, phydev->mdio.addr, regnum, val);
}
/**
* phy_write_mmd_indirect - writes data to the MMD registers
* @phydev: The PHY device
* @prtad: MMD Address
* @devad: MMD DEVAD
* @data: data to write in the MMD register
*
* Description: Write data from the MMD registers of the specified
* phy address.
*/
void phy_write_mmd_indirect(struct phy_device *phydev, int prtad,
int devad, u32 data);
struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id, struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id,
bool is_c45, bool is_c45,
......
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