From mboxrd@z Thu Jan 1 00:00:00 1970 From: Harini Katakam Subject: [PATCH 1/4] net: macb: Check MDIO state before read/write and use timeouts Date: Wed, 31 Oct 2018 09:10:20 +0530 Message-ID: <1540957223-30984-2-git-send-email-harini.katakam@xilinx.com> References: <1540957223-30984-1-git-send-email-harini.katakam@xilinx.com> Mime-Version: 1.0 Content-Type: text/plain Cc: , , , , , Harini Katakam , Shubhrajyoti Datta , Sai Pavan Boddu To: , , Return-path: In-Reply-To: <1540957223-30984-1-git-send-email-harini.katakam@xilinx.com> Sender: linux-kernel-owner@vger.kernel.org List-Id: netdev.vger.kernel.org From: Harini Katakam Replace the while loop in MDIO read/write functions with a timeout. In addition, add a check for MDIO bus busy before initiating a new operation as well to make sure there is no ongoing MDIO operation. Signed-off-by: Shubhrajyoti Datta Signed-off-by: Sai Pavan Boddu Signed-off-by: Harini Katakam --- Changes form RFC: Cleaned up timeout implementation and moved it to a helper. drivers/net/ethernet/cadence/macb_main.c | 44 +++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 0acaef3..b4e26c1 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -318,10 +318,36 @@ static void macb_get_hwaddr(struct macb *bp) eth_hw_addr_random(bp->dev); } +static int macb_mdio_wait_for_idle(struct macb *bp) +{ + ulong timeout; + + timeout = jiffies + msecs_to_jiffies(1000); + /* wait for end of transfer */ + while (1) { + if (MACB_BFEXT(IDLE, macb_readl(bp, NSR))) + break; + + if (time_after_eq(jiffies, timeout)) { + netdev_err(bp->dev, "wait for end of transfer timed out\n"); + return -ETIMEDOUT; + } + + cpu_relax(); + } + + return 0; +} + static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum) { struct macb *bp = bus->priv; int value; + int err; + + err = macb_mdio_wait_for_idle(bp); + if (err < 0) + return err; macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_SOF) | MACB_BF(RW, MACB_MAN_READ) @@ -329,9 +355,9 @@ static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum) | MACB_BF(REGA, regnum) | MACB_BF(CODE, MACB_MAN_CODE))); - /* wait for end of transfer */ - while (!MACB_BFEXT(IDLE, macb_readl(bp, NSR))) - cpu_relax(); + err = macb_mdio_wait_for_idle(bp); + if (err < 0) + return err; value = MACB_BFEXT(DATA, macb_readl(bp, MAN)); @@ -342,6 +368,12 @@ static int macb_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value) { struct macb *bp = bus->priv; + int err; + + + err = macb_mdio_wait_for_idle(bp); + if (err < 0) + return err; macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_SOF) | MACB_BF(RW, MACB_MAN_WRITE) @@ -350,9 +382,9 @@ static int macb_mdio_write(struct mii_bus *bus, int mii_id, int regnum, | MACB_BF(CODE, MACB_MAN_CODE) | MACB_BF(DATA, value))); - /* wait for end of transfer */ - while (!MACB_BFEXT(IDLE, macb_readl(bp, NSR))) - cpu_relax(); + err = macb_mdio_wait_for_idle(bp); + if (err < 0) + return err; return 0; } -- 2.7.4