Commit 8beb79b7 authored by Harini Katakam's avatar Harini Katakam Committed by David S. Miller

net: macb: Check MDIO state before read/write and use timeouts

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: default avatarShubhrajyoti Datta <shubhrajyoti.datta@xilinx.com>
Signed-off-by: default avatarSai Pavan Boddu <sai.pavan.boddu@xilinx.com>
Signed-off-by: default avatarHarini Katakam <harini.katakam@xilinx.com>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 41bc0ddb
...@@ -715,6 +715,8 @@ ...@@ -715,6 +715,8 @@
__v; \ __v; \
}) })
#define MACB_READ_NSR(bp) macb_readl(bp, NSR)
/* struct macb_dma_desc - Hardware DMA descriptor /* struct macb_dma_desc - Hardware DMA descriptor
* @addr: DMA address of data buffer * @addr: DMA address of data buffer
* @ctrl: Control and status bits * @ctrl: Control and status bits
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <linux/ip.h> #include <linux/ip.h>
#include <linux/udp.h> #include <linux/udp.h>
#include <linux/tcp.h> #include <linux/tcp.h>
#include <linux/iopoll.h>
#include "macb.h" #include "macb.h"
#define MACB_RX_BUFFER_SIZE 128 #define MACB_RX_BUFFER_SIZE 128
...@@ -79,6 +80,8 @@ ...@@ -79,6 +80,8 @@
*/ */
#define MACB_HALT_TIMEOUT 1230 #define MACB_HALT_TIMEOUT 1230
#define MACB_MDIO_TIMEOUT 1000000 /* in usecs */
/* DMA buffer descriptor might be different size /* DMA buffer descriptor might be different size
* depends on hardware configuration: * depends on hardware configuration:
* *
...@@ -318,10 +321,23 @@ static void macb_get_hwaddr(struct macb *bp) ...@@ -318,10 +321,23 @@ static void macb_get_hwaddr(struct macb *bp)
eth_hw_addr_random(bp->dev); eth_hw_addr_random(bp->dev);
} }
static int macb_mdio_wait_for_idle(struct macb *bp)
{
u32 val;
return readx_poll_timeout(MACB_READ_NSR, bp, val, val & MACB_BIT(IDLE),
1, MACB_MDIO_TIMEOUT);
}
static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum) static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
{ {
struct macb *bp = bus->priv; struct macb *bp = bus->priv;
int value; 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_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_SOF)
| MACB_BF(RW, MACB_MAN_READ) | MACB_BF(RW, MACB_MAN_READ)
...@@ -329,9 +345,9 @@ static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum) ...@@ -329,9 +345,9 @@ static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
| MACB_BF(REGA, regnum) | MACB_BF(REGA, regnum)
| MACB_BF(CODE, MACB_MAN_CODE))); | MACB_BF(CODE, MACB_MAN_CODE)));
/* wait for end of transfer */ err = macb_mdio_wait_for_idle(bp);
while (!MACB_BFEXT(IDLE, macb_readl(bp, NSR))) if (err < 0)
cpu_relax(); return err;
value = MACB_BFEXT(DATA, macb_readl(bp, MAN)); value = MACB_BFEXT(DATA, macb_readl(bp, MAN));
...@@ -342,6 +358,11 @@ static int macb_mdio_write(struct mii_bus *bus, int mii_id, int regnum, ...@@ -342,6 +358,11 @@ static int macb_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
u16 value) u16 value)
{ {
struct macb *bp = bus->priv; 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_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_SOF)
| MACB_BF(RW, MACB_MAN_WRITE) | MACB_BF(RW, MACB_MAN_WRITE)
...@@ -350,9 +371,9 @@ static int macb_mdio_write(struct mii_bus *bus, int mii_id, int regnum, ...@@ -350,9 +371,9 @@ static int macb_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
| MACB_BF(CODE, MACB_MAN_CODE) | MACB_BF(CODE, MACB_MAN_CODE)
| MACB_BF(DATA, value))); | MACB_BF(DATA, value)));
/* wait for end of transfer */ err = macb_mdio_wait_for_idle(bp);
while (!MACB_BFEXT(IDLE, macb_readl(bp, NSR))) if (err < 0)
cpu_relax(); return err;
return 0; return 0;
} }
......
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