* [PATCH 0/9] net: phy: PHY reset consolidation
@ 2013-12-06 0:55 Florian Fainelli
2013-12-06 0:55 ` [PATCH 1/9] net: phy: report link partner features through ethtool Florian Fainelli
` (8 more replies)
0 siblings, 9 replies; 12+ messages in thread
From: Florian Fainelli @ 2013-12-06 0:55 UTC (permalink / raw)
To: netdev
Cc: davem, sebastian.hesselbarth, sergei.shtylyov, afleming, kyle,
Florian Fainelli
Hi all,
Over the past few months there have been various attempts at doing
"wild" PHY resets eventually bypassing the PHY state machine and causing
various sort of issues whenever auto-negotiation as not enabled.
This patchset resumes the work Kyle Moffett started here:
https://lkml.org/lkml/2011/10/20/301
Once Sebastian's phy_resume/suspend patchet is in, we can also make sure
we consolidate PHY resets after resuming from S2/S3 suspend modes.
Florian Fainelli (9):
net: phy: report link partner features through ethtool
net: phy: use phy_init_hw instead of open-coding it
net: greth: use phy_read_status()
net: bfin_mac: do not reset PHY after phy_start()
net: phy: consolidate PHY reset in phy_init_hw()
net: mv643xx_eth: use phy_init_hw to reset PHY
net: pxa168_eth: use phy_init_hw for PHY reset
net: tc35815: use phy_init_hw for PHY reset
net: sh_eth: do not issue a wild PHY reset through BMCR
Documentation/networking/phy.txt | 3 +-
drivers/net/ethernet/adi/bfin_mac.c | 1 -
drivers/net/ethernet/aeroflex/greth.c | 2 +-
drivers/net/ethernet/marvell/mv643xx_eth.c | 21 +---------
drivers/net/ethernet/marvell/pxa168_eth.c | 19 +--------
drivers/net/ethernet/renesas/sh_eth.c | 5 ++-
drivers/net/ethernet/toshiba/tc35815.c | 15 ++------
drivers/net/phy/phy.c | 11 +++---
drivers/net/phy/phy_device.c | 62 +++++++++++++++++++++++++++++-
include/linux/phy.h | 5 ++-
10 files changed, 82 insertions(+), 62 deletions(-)
--
1.8.3.2
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 1/9] net: phy: report link partner features through ethtool
2013-12-06 0:55 [PATCH 0/9] net: phy: PHY reset consolidation Florian Fainelli
@ 2013-12-06 0:55 ` Florian Fainelli
2013-12-06 0:55 ` [PATCH 2/9] net: phy: use phy_init_hw instead of open-coding it Florian Fainelli
` (7 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Florian Fainelli @ 2013-12-06 0:55 UTC (permalink / raw)
To: netdev
Cc: davem, sebastian.hesselbarth, sergei.shtylyov, afleming, kyle,
Florian Fainelli
The PHY library already reads the MII_STAT1000 and MII_LPA registers in
genphy_read_status(), so extend it to also populate the PHY device link
partner advertised features such that we can feed this back into ethtool
when asked for it in phy_ethtool_gset().
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/phy/phy.c | 1 +
drivers/net/phy/phy_device.c | 6 ++++++
include/linux/phy.h | 5 +++--
3 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 36c6994..05cb8fe 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -289,6 +289,7 @@ int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd)
cmd->supported = phydev->supported;
cmd->advertising = phydev->advertising;
+ cmd->lp_advertising = phydev->lp_advertising;
ethtool_cmd_speed_set(cmd, phydev->speed);
cmd->duplex = phydev->duplex;
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index d6447b3..6db3659 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -839,6 +839,8 @@ int genphy_read_status(struct phy_device *phydev)
if (err)
return err;
+ phydev->lp_advertising = 0;
+
if (AUTONEG_ENABLE == phydev->autoneg) {
if (phydev->supported & (SUPPORTED_1000baseT_Half
| SUPPORTED_1000baseT_Full)) {
@@ -852,6 +854,8 @@ int genphy_read_status(struct phy_device *phydev)
if (adv < 0)
return adv;
+ phydev->lp_advertising =
+ mii_stat1000_to_ethtool_lpa_t(lpagb);
lpagb &= adv << 2;
}
@@ -860,6 +864,8 @@ int genphy_read_status(struct phy_device *phydev)
if (lpa < 0)
return lpa;
+ phydev->lp_advertising |= mii_lpa_to_ethtool_lpa_t(lpa);
+
adv = phy_read(phydev, MII_ADVERTISE);
if (adv < 0)
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 48a4dc3..cc2c8bb 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -278,8 +278,8 @@ struct phy_c45_device_ids {
* adjust_state: Callback for the enet driver to respond to
* changes in the state machine.
*
- * speed, duplex, pause, supported, advertising, and
- * autoneg are used like in mii_if_info
+ * speed, duplex, pause, supported, advertising, lp_advertising,
+ * and autoneg are used like in mii_if_info
*
* interrupts currently only supports enabled or disabled,
* but could be changed in the future to support enabling
@@ -331,6 +331,7 @@ struct phy_device {
/* See mii.h for more info */
u32 supported;
u32 advertising;
+ u32 lp_advertising;
int autoneg;
--
1.8.3.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 2/9] net: phy: use phy_init_hw instead of open-coding it
2013-12-06 0:55 [PATCH 0/9] net: phy: PHY reset consolidation Florian Fainelli
2013-12-06 0:55 ` [PATCH 1/9] net: phy: report link partner features through ethtool Florian Fainelli
@ 2013-12-06 0:55 ` Florian Fainelli
2013-12-06 0:55 ` [PATCH 3/9] net: greth: use phy_read_status() Florian Fainelli
` (6 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Florian Fainelli @ 2013-12-06 0:55 UTC (permalink / raw)
To: netdev
Cc: davem, sebastian.hesselbarth, sergei.shtylyov, afleming, kyle,
Florian Fainelli
Use phy_init_hw() instead of open-coding it in phy_mii_ioctl(), this
improves consistenty and makes sure that we will not duplicate the same
routine somewhere else.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/phy/phy.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 05cb8fe..5d7101b 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -361,11 +361,8 @@ int phy_mii_ioctl(struct phy_device *phydev,
mii_data->reg_num, val);
if (mii_data->reg_num == MII_BMCR &&
- val & BMCR_RESET &&
- phydev->drv->config_init) {
- phy_scan_fixups(phydev);
- phydev->drv->config_init(phydev);
- }
+ val & BMCR_RESET)
+ phy_init_hw(phydev);
break;
case SIOCSHWTSTAMP:
--
1.8.3.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 3/9] net: greth: use phy_read_status()
2013-12-06 0:55 [PATCH 0/9] net: phy: PHY reset consolidation Florian Fainelli
2013-12-06 0:55 ` [PATCH 1/9] net: phy: report link partner features through ethtool Florian Fainelli
2013-12-06 0:55 ` [PATCH 2/9] net: phy: use phy_init_hw instead of open-coding it Florian Fainelli
@ 2013-12-06 0:55 ` Florian Fainelli
2013-12-06 0:55 ` [PATCH 4/9] net: bfin_mac: do not reset PHY after phy_start() Florian Fainelli
` (5 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Florian Fainelli @ 2013-12-06 0:55 UTC (permalink / raw)
To: netdev
Cc: davem, sebastian.hesselbarth, sergei.shtylyov, afleming, kyle,
Florian Fainelli
In case the greth driver is bound to anything but the Generic PHY
driver or the PHY has a special read_status callback implemented,
unexpected things will happen. Make sure we that we use
phy_read_status() which does the proper abstraction of calling the
driver specific read_status() callback for a given PHY.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/ethernet/aeroflex/greth.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/aeroflex/greth.c b/drivers/net/ethernet/aeroflex/greth.c
index e066945..b20cbf0 100644
--- a/drivers/net/ethernet/aeroflex/greth.c
+++ b/drivers/net/ethernet/aeroflex/greth.c
@@ -1361,7 +1361,7 @@ static int greth_mdio_init(struct greth_private *greth)
timeout = jiffies + 6*HZ;
while (!phy_aneg_done(greth->phy) && time_before(jiffies, timeout)) {
}
- genphy_read_status(greth->phy);
+ phy_read_status(greth->phy);
greth_link_change(greth->netdev);
}
--
1.8.3.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 4/9] net: bfin_mac: do not reset PHY after phy_start()
2013-12-06 0:55 [PATCH 0/9] net: phy: PHY reset consolidation Florian Fainelli
` (2 preceding siblings ...)
2013-12-06 0:55 ` [PATCH 3/9] net: greth: use phy_read_status() Florian Fainelli
@ 2013-12-06 0:55 ` Florian Fainelli
2013-12-06 0:55 ` [PATCH 5/9] net: phy: consolidate PHY reset in phy_init_hw() Florian Fainelli
` (4 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Florian Fainelli @ 2013-12-06 0:55 UTC (permalink / raw)
To: netdev
Cc: davem, sebastian.hesselbarth, sergei.shtylyov, afleming, kyle,
Florian Fainelli
The PHY is already reset during driver probing, and this manual reset
after calling phy_start() will wipe out board-specific PHY fixups and
driver specific configuration initialization. Remove that explicit PHY
reset.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/ethernet/adi/bfin_mac.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/net/ethernet/adi/bfin_mac.c b/drivers/net/ethernet/adi/bfin_mac.c
index 75fb1d2..2ce382e 100644
--- a/drivers/net/ethernet/adi/bfin_mac.c
+++ b/drivers/net/ethernet/adi/bfin_mac.c
@@ -1544,7 +1544,6 @@ static int bfin_mac_open(struct net_device *dev)
return ret;
phy_start(lp->phydev);
- phy_write(lp->phydev, MII_BMCR, BMCR_RESET);
setup_system_regs(dev);
setup_mac_addr(dev->dev_addr);
--
1.8.3.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 5/9] net: phy: consolidate PHY reset in phy_init_hw()
2013-12-06 0:55 [PATCH 0/9] net: phy: PHY reset consolidation Florian Fainelli
` (3 preceding siblings ...)
2013-12-06 0:55 ` [PATCH 4/9] net: bfin_mac: do not reset PHY after phy_start() Florian Fainelli
@ 2013-12-06 0:55 ` Florian Fainelli
2013-12-06 0:55 ` [PATCH 6/9] net: mv643xx_eth: use phy_init_hw to reset PHY Florian Fainelli
` (3 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Florian Fainelli @ 2013-12-06 0:55 UTC (permalink / raw)
To: netdev
Cc: davem, sebastian.hesselbarth, sergei.shtylyov, afleming, kyle,
Florian Fainelli
There are quite a lot of drivers touching a PHY device MII_BMCR
register to reset the PHY without taking care of:
1) ensuring that BMCR_RESET is cleared after a given timeout
2) the PHY state machine resuming to the proper state and re-applying
potentially changed settings such as auto-negotiation
Introduce phy_poll_reset() which will take care of polling the MII_BMCR
for the BMCR_RESET bit to be cleared after a given timeout or return a
timeout error code.
In order to make sure the PHY is in a correct state, phy_init_hw() first
issues a software reset through MII_BMCR and then applies any fixups.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
Documentation/networking/phy.txt | 3 ++-
drivers/net/phy/phy.c | 5 ++--
drivers/net/phy/phy_device.c | 56 +++++++++++++++++++++++++++++++++++++++-
3 files changed, 60 insertions(+), 4 deletions(-)
diff --git a/Documentation/networking/phy.txt b/Documentation/networking/phy.txt
index d5b1a39..ebf2707 100644
--- a/Documentation/networking/phy.txt
+++ b/Documentation/networking/phy.txt
@@ -255,7 +255,8 @@ Writing a PHY driver
config_init: configures PHY into a sane state after a reset.
For instance, a Davicom PHY requires descrambling disabled.
- probe: Does any setup needed by the driver
+ probe: Allocate phy->priv, optionally refuse to bind.
+ PHY may not have been reset or had fixups run yet.
suspend/resume: power management
config_aneg: Changes the speed/duplex/negotiation settings
read_status: Reads the current speed/duplex/negotiation settings
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 5d7101b..e3dd691 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -318,6 +318,7 @@ int phy_mii_ioctl(struct phy_device *phydev,
{
struct mii_ioctl_data *mii_data = if_mii(ifr);
u16 val = mii_data->val_in;
+ int ret = 0;
switch (cmd) {
case SIOCGMIIPHY:
@@ -362,7 +363,7 @@ int phy_mii_ioctl(struct phy_device *phydev,
if (mii_data->reg_num == MII_BMCR &&
val & BMCR_RESET)
- phy_init_hw(phydev);
+ ret = phy_init_hw(phydev);
break;
case SIOCSHWTSTAMP:
@@ -374,7 +375,7 @@ int phy_mii_ioctl(struct phy_device *phydev,
return -EOPNOTSUPP;
}
- return 0;
+ return ret;
}
EXPORT_SYMBOL(phy_mii_ioctl);
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 6db3659..5a619f0 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -364,7 +364,11 @@ int phy_device_register(struct phy_device *phydev)
phydev->bus->phy_map[phydev->addr] = phydev;
/* Run all of the fixups for this PHY */
- phy_scan_fixups(phydev);
+ err = phy_init_hw(phydev);
+ if (err) {
+ pr_err("PHY %d failed to initialize\n", phydev->addr);
+ goto out;
+ }
err = device_add(&phydev->dev);
if (err) {
@@ -497,6 +501,47 @@ void phy_disconnect(struct phy_device *phydev)
}
EXPORT_SYMBOL(phy_disconnect);
+/**
+ * phy_poll_reset - Safely wait until a PHY reset has properly completed
+ * @phydev: The PHY device to poll
+ *
+ * Description: According to IEEE 802.3, Section 2, Subsection 22.2.4.1.1, as
+ * published in 2008, a PHY reset may take up to 0.5 seconds. The MII BMCR
+ * register must be polled until the BMCR_RESET bit clears.
+ *
+ * Furthermore, any attempts to write to PHY registers may have no effect
+ * or even generate MDIO bus errors until this is complete.
+ *
+ * Some PHYs (such as the Marvell 88E1111) don't entirely conform to the
+ * standard and do not fully reset after the BMCR_RESET bit is set, and may
+ * even *REQUIRE* a soft-reset to properly restart autonegotiation. In an
+ * effort to support such broken PHYs, this function is separate from the
+ * standard phy_init_hw() which will zero all the other bits in the BMCR
+ * and reapply all driver-specific and board-specific fixups.
+ */
+static int phy_poll_reset(struct phy_device *phydev)
+{
+ /* Poll until the reset bit clears (50ms per retry == 0.6 sec) */
+ unsigned int retries = 12;
+ int ret;
+
+ do {
+ msleep(50);
+ ret = phy_read(phydev, MII_BMCR);
+ if (ret < 0)
+ return ret;
+ } while (ret & BMCR_RESET && --retries);
+ if (ret & BMCR_RESET)
+ return -ETIMEDOUT;
+
+ /*
+ * Some chips (smsc911x) may still need up to another 1ms after the
+ * BMCR_RESET bit is cleared before they are usable.
+ */
+ msleep(1);
+ return 0;
+}
+
int phy_init_hw(struct phy_device *phydev)
{
int ret;
@@ -504,12 +549,21 @@ int phy_init_hw(struct phy_device *phydev)
if (!phydev->drv || !phydev->drv->config_init)
return 0;
+ ret = phy_write(phydev, MII_BMCR, BMCR_RESET);
+ if (ret < 0)
+ return ret;
+
+ ret = phy_poll_reset(phydev);
+ if (ret < 0)
+ return ret;
+
ret = phy_scan_fixups(phydev);
if (ret < 0)
return ret;
return phydev->drv->config_init(phydev);
}
+EXPORT_SYMBOL(phy_init_hw);
/**
* phy_attach_direct - attach a network device to a given PHY device pointer
--
1.8.3.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 6/9] net: mv643xx_eth: use phy_init_hw to reset PHY
2013-12-06 0:55 [PATCH 0/9] net: phy: PHY reset consolidation Florian Fainelli
` (4 preceding siblings ...)
2013-12-06 0:55 ` [PATCH 5/9] net: phy: consolidate PHY reset in phy_init_hw() Florian Fainelli
@ 2013-12-06 0:55 ` Florian Fainelli
2013-12-06 2:16 ` Sergei Shtylyov
2013-12-06 0:55 ` [PATCH 7/9] net: pxa168_eth: use phy_init_hw for PHY reset Florian Fainelli
` (2 subsequent siblings)
8 siblings, 1 reply; 12+ messages in thread
From: Florian Fainelli @ 2013-12-06 0:55 UTC (permalink / raw)
To: netdev
Cc: davem, sebastian.hesselbarth, sergei.shtylyov, afleming, kyle,
Florian Fainelli
Instead of open-coding a PHY reset through the MII BMCR register, use
phy_init_hw() which does that for us and will also make sure that PHY
fixups are applied if required.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/ethernet/marvell/mv643xx_eth.c | 21 +--------------------
1 file changed, 1 insertion(+), 20 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
index 61088a6..8d9bb6b 100644
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -2067,23 +2067,6 @@ static inline void oom_timer_wrapper(unsigned long data)
napi_schedule(&mp->napi);
}
-static void phy_reset(struct mv643xx_eth_private *mp)
-{
- int data;
-
- data = phy_read(mp->phy, MII_BMCR);
- if (data < 0)
- return;
-
- data |= BMCR_RESET;
- if (phy_write(mp->phy, MII_BMCR, data) < 0)
- return;
-
- do {
- data = phy_read(mp->phy, MII_BMCR);
- } while (data >= 0 && data & BMCR_RESET);
-}
-
static void port_start(struct mv643xx_eth_private *mp)
{
u32 pscr;
@@ -2096,7 +2079,7 @@ static void port_start(struct mv643xx_eth_private *mp)
struct ethtool_cmd cmd;
mv643xx_eth_get_settings(mp->dev, &cmd);
- phy_reset(mp);
+ phy_init_hw(mp);
mv643xx_eth_set_settings(mp->dev, &cmd);
}
@@ -2764,8 +2747,6 @@ static void phy_init(struct mv643xx_eth_private *mp, int speed, int duplex)
{
struct phy_device *phy = mp->phy;
- phy_reset(mp);
-
if (speed == 0) {
phy->autoneg = AUTONEG_ENABLE;
phy->speed = 0;
--
1.8.3.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 7/9] net: pxa168_eth: use phy_init_hw for PHY reset
2013-12-06 0:55 [PATCH 0/9] net: phy: PHY reset consolidation Florian Fainelli
` (5 preceding siblings ...)
2013-12-06 0:55 ` [PATCH 6/9] net: mv643xx_eth: use phy_init_hw to reset PHY Florian Fainelli
@ 2013-12-06 0:55 ` Florian Fainelli
2013-12-06 1:06 ` Florian Fainelli
2013-12-06 0:55 ` [PATCH 8/9] net: tc35815: " Florian Fainelli
2013-12-06 0:55 ` [PATCH 9/9] net: sh_eth: do not issue a wild PHY reset through BMCR Florian Fainelli
8 siblings, 1 reply; 12+ messages in thread
From: Florian Fainelli @ 2013-12-06 0:55 UTC (permalink / raw)
To: netdev
Cc: davem, sebastian.hesselbarth, sergei.shtylyov, afleming, kyle,
Florian Fainelli
Instead of open-coding a PHY reset through the MII BMCR register, use
phy_init_hw() which does this for us and ensures that PHY device fixups
are also applied.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/ethernet/marvell/pxa168_eth.c | 19 +------------------
1 file changed, 1 insertion(+), 18 deletions(-)
diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c
index fff6246..b3642a0 100644
--- a/drivers/net/ethernet/marvell/pxa168_eth.c
+++ b/drivers/net/ethernet/marvell/pxa168_eth.c
@@ -321,23 +321,6 @@ static void ethernet_phy_set_addr(struct pxa168_eth_private *pep, int phy_addr)
wrl(pep, PHY_ADDRESS, reg_data);
}
-static void ethernet_phy_reset(struct pxa168_eth_private *pep)
-{
- int data;
-
- data = phy_read(pep->phy, MII_BMCR);
- if (data < 0)
- return;
-
- data |= BMCR_RESET;
- if (phy_write(pep->phy, MII_BMCR, data) < 0)
- return;
-
- do {
- data = phy_read(pep->phy, MII_BMCR);
- } while (data >= 0 && data & BMCR_RESET);
-}
-
static void rxq_refill(struct net_device *dev)
{
struct pxa168_eth_private *pep = netdev_priv(dev);
@@ -646,7 +629,7 @@ static void eth_port_start(struct net_device *dev)
struct ethtool_cmd cmd;
pxa168_get_settings(pep->dev, &cmd);
- ethernet_phy_reset(pep);
+ phy_init_hw(pep);
pxa168_set_settings(pep->dev, &cmd);
}
--
1.8.3.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 8/9] net: tc35815: use phy_init_hw for PHY reset
2013-12-06 0:55 [PATCH 0/9] net: phy: PHY reset consolidation Florian Fainelli
` (6 preceding siblings ...)
2013-12-06 0:55 ` [PATCH 7/9] net: pxa168_eth: use phy_init_hw for PHY reset Florian Fainelli
@ 2013-12-06 0:55 ` Florian Fainelli
2013-12-06 0:55 ` [PATCH 9/9] net: sh_eth: do not issue a wild PHY reset through BMCR Florian Fainelli
8 siblings, 0 replies; 12+ messages in thread
From: Florian Fainelli @ 2013-12-06 0:55 UTC (permalink / raw)
To: netdev
Cc: davem, sebastian.hesselbarth, sergei.shtylyov, afleming, kyle,
Florian Fainelli
Instead of open-coding the PHY reset through MII BMCR, use phy_init_hw()
which does that for us and also makes sure that any PHY specific fixups
are applied.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/ethernet/toshiba/tc35815.c | 15 ++++-----------
1 file changed, 4 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/toshiba/tc35815.c b/drivers/net/ethernet/toshiba/tc35815.c
index 1322546..f6b3212 100644
--- a/drivers/net/ethernet/toshiba/tc35815.c
+++ b/drivers/net/ethernet/toshiba/tc35815.c
@@ -1170,19 +1170,12 @@ static int tc35815_tx_full(struct net_device *dev)
static void tc35815_restart(struct net_device *dev)
{
struct tc35815_local *lp = netdev_priv(dev);
+ int ret;
if (lp->phy_dev) {
- int timeout;
-
- phy_write(lp->phy_dev, MII_BMCR, BMCR_RESET);
- timeout = 100;
- while (--timeout) {
- if (!(phy_read(lp->phy_dev, MII_BMCR) & BMCR_RESET))
- break;
- udelay(1);
- }
- if (!timeout)
- printk(KERN_ERR "%s: BMCR reset failed.\n", dev->name);
+ ret = phy_init_hw(lp->phy_dev);
+ if (ret)
+ printk(KERN_ERR "%s: PHY init failed.\n", dev->name);
}
spin_lock_bh(&lp->rx_lock);
--
1.8.3.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 9/9] net: sh_eth: do not issue a wild PHY reset through BMCR
2013-12-06 0:55 [PATCH 0/9] net: phy: PHY reset consolidation Florian Fainelli
` (7 preceding siblings ...)
2013-12-06 0:55 ` [PATCH 8/9] net: tc35815: " Florian Fainelli
@ 2013-12-06 0:55 ` Florian Fainelli
8 siblings, 0 replies; 12+ messages in thread
From: Florian Fainelli @ 2013-12-06 0:55 UTC (permalink / raw)
To: netdev
Cc: davem, sebastian.hesselbarth, sergei.shtylyov, afleming, kyle,
Florian Fainelli
The sh_eth driver issues an uncontrolled PHY reset through the MII
register BMCR but fails to wait for the reset to complete, and will also
implicitely wipe out all possible PHY fixups applied. Use phy_init_hw()
which remedies both problems.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/ethernet/renesas/sh_eth.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index d256ce1..6761dde 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -1704,7 +1704,10 @@ static int sh_eth_phy_start(struct net_device *ndev)
return ret;
/* reset phy - this also wakes it from PDOWN */
- phy_write(mdp->phydev, MII_BMCR, BMCR_RESET);
+ ret = phy_init_hw(mdp->phydev);
+ if (ret)
+ return ret;
+
phy_start(mdp->phydev);
return 0;
--
1.8.3.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 7/9] net: pxa168_eth: use phy_init_hw for PHY reset
2013-12-06 0:55 ` [PATCH 7/9] net: pxa168_eth: use phy_init_hw for PHY reset Florian Fainelli
@ 2013-12-06 1:06 ` Florian Fainelli
0 siblings, 0 replies; 12+ messages in thread
From: Florian Fainelli @ 2013-12-06 1:06 UTC (permalink / raw)
To: netdev
Cc: David Miller, Sebastian Hesselbarth, Sergei Shtylyov,
Andy Fleming, Kyle Moffett, Florian Fainelli
2013/12/5 Florian Fainelli <f.fainelli@gmail.com>:
> Instead of open-coding a PHY reset through the MII BMCR register, use
> phy_init_hw() which does this for us and ensures that PHY device fixups
> are also applied.
>
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> ---
> drivers/net/ethernet/marvell/pxa168_eth.c | 19 +------------------
> 1 file changed, 1 insertion(+), 18 deletions(-)
>
> diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c
> index fff6246..b3642a0 100644
> --- a/drivers/net/ethernet/marvell/pxa168_eth.c
> +++ b/drivers/net/ethernet/marvell/pxa168_eth.c
> @@ -321,23 +321,6 @@ static void ethernet_phy_set_addr(struct pxa168_eth_private *pep, int phy_addr)
> wrl(pep, PHY_ADDRESS, reg_data);
> }
>
> -static void ethernet_phy_reset(struct pxa168_eth_private *pep)
> -{
> - int data;
> -
> - data = phy_read(pep->phy, MII_BMCR);
> - if (data < 0)
> - return;
> -
> - data |= BMCR_RESET;
> - if (phy_write(pep->phy, MII_BMCR, data) < 0)
> - return;
> -
> - do {
> - data = phy_read(pep->phy, MII_BMCR);
> - } while (data >= 0 && data & BMCR_RESET);
> -}
I forgot a reference to ethernet_phy_reset() somewhere later in the
driver. Will wait for comments until I issue a respin of these
patches.
--
Florian
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 6/9] net: mv643xx_eth: use phy_init_hw to reset PHY
2013-12-06 0:55 ` [PATCH 6/9] net: mv643xx_eth: use phy_init_hw to reset PHY Florian Fainelli
@ 2013-12-06 2:16 ` Sergei Shtylyov
0 siblings, 0 replies; 12+ messages in thread
From: Sergei Shtylyov @ 2013-12-06 2:16 UTC (permalink / raw)
To: Florian Fainelli, netdev; +Cc: davem, sebastian.hesselbarth, afleming, kyle
Hello.
On 12/06/2013 03:55 AM, Florian Fainelli wrote:
> Instead of open-coding a PHY reset through the MII BMCR register, use
> phy_init_hw() which does that for us and will also make sure that PHY
> fixups are applied if required.
You failed to mention that you stopped resetting PHY in phy_init()...
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> ---
> drivers/net/ethernet/marvell/mv643xx_eth.c | 21 +--------------------
> 1 file changed, 1 insertion(+), 20 deletions(-)
> diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
> index 61088a6..8d9bb6b 100644
> --- a/drivers/net/ethernet/marvell/mv643xx_eth.c
> +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
[...]
> @@ -2764,8 +2747,6 @@ static void phy_init(struct mv643xx_eth_private *mp, int speed, int duplex)
> {
> struct phy_device *phy = mp->phy;
>
> - phy_reset(mp);
> -
> if (speed == 0) {
> phy->autoneg = AUTONEG_ENABLE;
> phy->speed = 0;
>
WBR, Sergei
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2013-12-06 1:16 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-12-06 0:55 [PATCH 0/9] net: phy: PHY reset consolidation Florian Fainelli
2013-12-06 0:55 ` [PATCH 1/9] net: phy: report link partner features through ethtool Florian Fainelli
2013-12-06 0:55 ` [PATCH 2/9] net: phy: use phy_init_hw instead of open-coding it Florian Fainelli
2013-12-06 0:55 ` [PATCH 3/9] net: greth: use phy_read_status() Florian Fainelli
2013-12-06 0:55 ` [PATCH 4/9] net: bfin_mac: do not reset PHY after phy_start() Florian Fainelli
2013-12-06 0:55 ` [PATCH 5/9] net: phy: consolidate PHY reset in phy_init_hw() Florian Fainelli
2013-12-06 0:55 ` [PATCH 6/9] net: mv643xx_eth: use phy_init_hw to reset PHY Florian Fainelli
2013-12-06 2:16 ` Sergei Shtylyov
2013-12-06 0:55 ` [PATCH 7/9] net: pxa168_eth: use phy_init_hw for PHY reset Florian Fainelli
2013-12-06 1:06 ` Florian Fainelli
2013-12-06 0:55 ` [PATCH 8/9] net: tc35815: " Florian Fainelli
2013-12-06 0:55 ` [PATCH 9/9] net: sh_eth: do not issue a wild PHY reset through BMCR Florian Fainelli
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).