From: nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Date: Wed, 1 Jun 2011 18:15:43 +0000 (+0000)
Subject: Revert "ar71xx: only enable the rx engine after the link is up..."
X-Git-Url: https://git.rohieb.name/openwrt.git/commitdiff_plain/480dfda6ecb5c30c05ccb591901f618055e29326

Revert "ar71xx: only enable the rx engine after the link is up..."

It messes up the DMA state when the link goes down

git-svn-id: svn://svn.openwrt.org/openwrt/trunk@27088 3c298f89-4303-0410-b956-a3cf2f4a3e73
---

diff --git a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c
index f1eb0716a..6bc4fd356 100644
--- a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c
+++ b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c
@@ -343,71 +343,6 @@ static unsigned char *ag71xx_speed_str(struct ag71xx *ag)
 	return "?";
 }
 
-static void ag71xx_dma_reset(struct ag71xx *ag)
-{
-	u32 val;
-	int i;
-
-	ag71xx_dump_dma_regs(ag);
-
-	/* stop RX and TX */
-	ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0);
-	ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0);
-
-	/*
-	 * give the hardware some time to really stop all rx/tx activity
-	 * clearing the descriptors too early causes random memory corruption
-	 */
-	mdelay(1);
-
-	/* clear descriptor addresses */
-	ag71xx_wr(ag, AG71XX_REG_TX_DESC, 0);
-	ag71xx_wr(ag, AG71XX_REG_RX_DESC, 0);
-
-	/* clear pending RX/TX interrupts */
-	for (i = 0; i < 256; i++) {
-		ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR);
-		ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS);
-	}
-
-	/* clear pending errors */
-	ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE | RX_STATUS_OF);
-	ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE | TX_STATUS_UR);
-
-	val = ag71xx_rr(ag, AG71XX_REG_RX_STATUS);
-	if (val)
-		printk(KERN_ALERT "%s: unable to clear DMA Rx status: %08x\n",
-			ag->dev->name, val);
-
-	val = ag71xx_rr(ag, AG71XX_REG_TX_STATUS);
-
-	/* mask out reserved bits */
-	val &= ~0xff000000;
-
-	if (val)
-		printk(KERN_ALERT "%s: unable to clear DMA Tx status: %08x\n",
-			ag->dev->name, val);
-
-	ag71xx_dump_dma_regs(ag);
-}
-
-static void ag71xx_hw_start(struct ag71xx *ag)
-{
-	/* start RX engine */
-	ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE);
-
-	/* enable interrupts */
-	ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, AG71XX_INT_INIT);
-}
-
-static void ag71xx_hw_stop(struct ag71xx *ag)
-{
-	/* disable all interrupts */
-	ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, 0);
-
-	ag71xx_dma_reset(ag);
-}
-
 void ag71xx_link_adjust(struct ag71xx *ag)
 {
 	struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
@@ -417,7 +352,6 @@ void ag71xx_link_adjust(struct ag71xx *ag)
 	u32 mii_speed;
 
 	if (!ag->link) {
-		ag71xx_hw_stop(ag);
 		netif_carrier_off(ag->dev);
 		if (netif_msg_link(ag))
 			printk(KERN_INFO "%s: link down\n", ag->dev->name);
@@ -470,8 +404,6 @@ void ag71xx_link_adjust(struct ag71xx *ag)
 	ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, fifo5);
 	ag71xx_wr(ag, AG71XX_REG_MAC_IFCTL, ifctl);
 
-	ag71xx_hw_start(ag);
-
 	netif_carrier_on(ag->dev);
 	if (netif_msg_link(ag))
 		printk(KERN_INFO "%s: link up (%sMbps/%s duplex)\n",
@@ -511,6 +443,54 @@ static void ag71xx_hw_set_macaddr(struct ag71xx *ag, unsigned char *mac)
 	ag71xx_wr(ag, AG71XX_REG_MAC_ADDR2, t);
 }
 
+static void ag71xx_dma_reset(struct ag71xx *ag)
+{
+	u32 val;
+	int i;
+
+	ag71xx_dump_dma_regs(ag);
+
+	/* stop RX and TX */
+	ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0);
+	ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0);
+
+	/*
+	 * give the hardware some time to really stop all rx/tx activity
+	 * clearing the descriptors too early causes random memory corruption
+	 */
+	mdelay(1);
+
+	/* clear descriptor addresses */
+	ag71xx_wr(ag, AG71XX_REG_TX_DESC, 0);
+	ag71xx_wr(ag, AG71XX_REG_RX_DESC, 0);
+
+	/* clear pending RX/TX interrupts */
+	for (i = 0; i < 256; i++) {
+		ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR);
+		ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS);
+	}
+
+	/* clear pending errors */
+	ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE | RX_STATUS_OF);
+	ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE | TX_STATUS_UR);
+
+	val = ag71xx_rr(ag, AG71XX_REG_RX_STATUS);
+	if (val)
+		printk(KERN_ALERT "%s: unable to clear DMA Rx status: %08x\n",
+			ag->dev->name, val);
+
+	val = ag71xx_rr(ag, AG71XX_REG_TX_STATUS);
+
+	/* mask out reserved bits */
+	val &= ~0xff000000;
+
+	if (val)
+		printk(KERN_ALERT "%s: unable to clear DMA Tx status: %08x\n",
+			ag->dev->name, val);
+
+	ag71xx_dump_dma_regs(ag);
+}
+
 #define MAC_CFG1_INIT	(MAC_CFG1_RXE | MAC_CFG1_TXE | \
 			 MAC_CFG1_SRX | MAC_CFG1_STX)
 
@@ -569,6 +549,23 @@ static void ag71xx_hw_init(struct ag71xx *ag)
 	ag71xx_dma_reset(ag);
 }
 
+static void ag71xx_hw_start(struct ag71xx *ag)
+{
+	/* start RX engine */
+	ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE);
+
+	/* enable interrupts */
+	ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, AG71XX_INT_INIT);
+}
+
+static void ag71xx_hw_stop(struct ag71xx *ag)
+{
+	/* disable all interrupts */
+	ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, 0);
+
+	ag71xx_dma_reset(ag);
+}
+
 static int ag71xx_open(struct net_device *dev)
 {
 	struct ag71xx *ag = netdev_priv(dev);
@@ -588,6 +585,8 @@ static int ag71xx_open(struct net_device *dev)
 
 	ag71xx_hw_set_macaddr(ag, dev->dev_addr);
 
+	ag71xx_hw_start(ag);
+
 	netif_start_queue(dev);
 
 	return 0;