Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -715,6 +715,8 @@
		__v; \
	})

#define MACB_READ_NSR(bp)	macb_readl(bp, NSR)

/* struct macb_dma_desc - Hardware DMA descriptor
 * @addr: DMA address of data buffer
 * @ctrl: Control and status bits
+27 −6
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@
#include <linux/ip.h>
#include <linux/udp.h>
#include <linux/tcp.h>
#include <linux/iopoll.h>
#include "macb.h"

#define MACB_RX_BUFFER_SIZE	128
@@ -79,6 +80,8 @@
 */
#define MACB_HALT_TIMEOUT	1230

#define MACB_MDIO_TIMEOUT	1000000 /* in usecs */

/* DMA buffer descriptor might be different size
 * depends on hardware configuration:
 *
@@ -318,10 +321,23 @@ static void macb_get_hwaddr(struct macb *bp)
	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)
{
	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 +345,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 +358,11 @@ 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 +371,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;
}