From e4ce71231276629d7aedb8610b9d6c99c7043906 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 24 Jan 2015 19:41:51 +0000 Subject: [PATCH] ar8216: fix ATU flushing The functionality to flush the address translation table contains two bugs which luckily compensate each other. 1. Just setting the operation is not sufficient to perform the flushing. The "active" bit needs to be set to actually trigger an action. For the vtu operations this is implemented correctly. 2. ar8xxx_phy_read_status is called every 2s by the phy state machine to check for link changes. This would have caused an ATU flush every 2s. Fix the chip-specific ATU flush functions and remove the ATU flush call from ar8xxx_phy_read_status. Signed-off-by: Heiner Kallweit SVN-Revision: 44101 --- target/linux/generic/files/drivers/net/phy/ar8216.c | 11 +++-------- target/linux/generic/files/drivers/net/phy/ar8327.c | 3 ++- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.c b/target/linux/generic/files/drivers/net/phy/ar8216.c index 90484d6462..370f1acc89 100644 --- a/target/linux/generic/files/drivers/net/phy/ar8216.c +++ b/target/linux/generic/files/drivers/net/phy/ar8216.c @@ -613,7 +613,8 @@ ar8216_atu_flush(struct ar8xxx_priv *priv) ret = ar8216_wait_bit(priv, AR8216_REG_ATU, AR8216_ATU_ACTIVE, 0); if (!ret) - ar8xxx_write(priv, AR8216_REG_ATU, AR8216_ATU_OP_FLUSH); + ar8xxx_write(priv, AR8216_REG_ATU, AR8216_ATU_OP_FLUSH | + AR8216_ATU_ACTIVE); return ret; } @@ -1711,7 +1712,6 @@ ar8xxx_phy_read_status(struct phy_device *phydev) { struct ar8xxx_priv *priv = phydev->priv; struct switch_port_link link; - int ret; if (phydev->addr != 0) return genphy_read_status(phydev); @@ -1736,16 +1736,11 @@ ar8xxx_phy_read_status(struct phy_device *phydev) } phydev->duplex = link.duplex ? DUPLEX_FULL : DUPLEX_HALF; - /* flush the address translation unit */ - mutex_lock(&priv->reg_mutex); - ret = priv->chip->atu_flush(priv); - mutex_unlock(&priv->reg_mutex); - phydev->state = PHY_RUNNING; netif_carrier_on(phydev->attached_dev); phydev->adjust_link(phydev->attached_dev); - return ret; + return 0; } static int diff --git a/target/linux/generic/files/drivers/net/phy/ar8327.c b/target/linux/generic/files/drivers/net/phy/ar8327.c index ea880bc927..fd5bcdc19b 100644 --- a/target/linux/generic/files/drivers/net/phy/ar8327.c +++ b/target/linux/generic/files/drivers/net/phy/ar8327.c @@ -759,7 +759,8 @@ ar8327_atu_flush(struct ar8xxx_priv *priv) AR8327_ATU_FUNC_BUSY, 0); if (!ret) ar8xxx_write(priv, AR8327_REG_ATU_FUNC, - AR8327_ATU_FUNC_OP_FLUSH); + AR8327_ATU_FUNC_OP_FLUSH | + AR8327_ATU_FUNC_BUSY); return ret; } -- 2.30.2