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

Commit d617e629 authored by Finn Thain's avatar Finn Thain Committed by Greg Kroah-Hartman
Browse files

net/sonic: Quiesce SONIC before re-initializing descriptor memory



[ Upstream commit 3f4b7e6a2be982fd8820a2b54d46dd9c351db899 ]

Make sure the SONIC's DMA engine is idle before altering the transmit
and receive descriptors. Add a helper for this as it will be needed
again.

Fixes: 1da177e4 ("Linux-2.6.12-rc2")
Tested-by: default avatarStan Johnson <userm57@yahoo.com>
Signed-off-by: default avatarFinn Thain <fthain@telegraphics.com.au>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 26904aa9
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -103,6 +103,24 @@ static int sonic_open(struct net_device *dev)
	return 0;
}

/* Wait for the SONIC to become idle. */
static void sonic_quiesce(struct net_device *dev, u16 mask)
{
	struct sonic_local * __maybe_unused lp = netdev_priv(dev);
	int i;
	u16 bits;

	for (i = 0; i < 1000; ++i) {
		bits = SONIC_READ(SONIC_CMD) & mask;
		if (!bits)
			return;
		if (irqs_disabled() || in_interrupt())
			udelay(20);
		else
			usleep_range(100, 200);
	}
	WARN_ONCE(1, "command deadline expired! 0x%04x\n", bits);
}

/*
 * Close the SONIC device
@@ -120,6 +138,9 @@ static int sonic_close(struct net_device *dev)
	/*
	 * stop the SONIC, disable interrupts
	 */
	SONIC_WRITE(SONIC_CMD, SONIC_CR_RXDIS);
	sonic_quiesce(dev, SONIC_CR_ALL);

	SONIC_WRITE(SONIC_IMR, 0);
	SONIC_WRITE(SONIC_ISR, 0x7fff);
	SONIC_WRITE(SONIC_CMD, SONIC_CR_RST);
@@ -159,6 +180,9 @@ static void sonic_tx_timeout(struct net_device *dev)
	 * put the Sonic into software-reset mode and
	 * disable all interrupts before releasing DMA buffers
	 */
	SONIC_WRITE(SONIC_CMD, SONIC_CR_RXDIS);
	sonic_quiesce(dev, SONIC_CR_ALL);

	SONIC_WRITE(SONIC_IMR, 0);
	SONIC_WRITE(SONIC_ISR, 0x7fff);
	SONIC_WRITE(SONIC_CMD, SONIC_CR_RST);
@@ -638,6 +662,7 @@ static int sonic_init(struct net_device *dev)
	 */
	SONIC_WRITE(SONIC_CMD, 0);
	SONIC_WRITE(SONIC_CMD, SONIC_CR_RXDIS);
	sonic_quiesce(dev, SONIC_CR_ALL);

	/*
	 * initialize the receive resource area
+3 −0
Original line number Diff line number Diff line
@@ -109,6 +109,9 @@
#define SONIC_CR_TXP            0x0002
#define SONIC_CR_HTX            0x0001

#define SONIC_CR_ALL (SONIC_CR_LCAM | SONIC_CR_RRRA | \
		      SONIC_CR_RXEN | SONIC_CR_TXP)

/*
 * SONIC data configuration bits
 */