public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Manfred Spraul <manfred@colorfullife.com>
To: linux-kernel@vger.kernel.org,
	Oliver Seemann <oseemann@cs.tu-berlin.de>,
	jgarzik@mandrakesoft.com
Subject: Re: rtl8139 nic dies with load (2.4.10, kt266)
Date: Sun, 30 Sep 2001 22:35:30 +0200	[thread overview]
Message-ID: <3BB78212.FB3973E0@colorfullife.com> (raw)
In-Reply-To: <3BB742FB.86AB06A5@colorfullife.com>

[-- Attachment #1: Type: text/plain, Size: 183 bytes --]

New patch:
* deadlock in error handling fixed.
* error handling didn't restart the chip properly.

Could you try it?
It should now recover properly from the frame errors.

--
	Manfred

[-- Attachment #2: patch-8139-rx_start --]
[-- Type: text/plain, Size: 3872 bytes --]

--- 2.4/drivers/net/8139too.c	Sun Sep 23 21:20:35 2001
+++ build-2.4/drivers/net/8139too.c	Sun Sep 30 22:31:02 2001
@@ -618,6 +618,7 @@
 static struct net_device_stats *rtl8139_get_stats (struct net_device *dev);
 static inline u32 ether_crc (int length, unsigned char *data);
 static void rtl8139_set_rx_mode (struct net_device *dev);
+static void __set_rx_mode (struct net_device *dev);
 static void rtl8139_hw_start (struct net_device *dev);
 
 #ifdef USE_IO_OPS
@@ -1844,8 +1845,8 @@
 			    struct rtl8139_private *tp, void *ioaddr)
 {
 	u8 tmp8;
-	int tmp_work = 1000;
-
+	int tmp_work;
+    
 	DPRINTK ("%s: Ethernet frame had errors, status %8.8x.\n",
 	         dev->name, rx_status);
 	if (rx_status & RxTooLong) {
@@ -1860,33 +1861,62 @@
 		tp->stats.rx_length_errors++;
 	if (rx_status & RxCRCErr)
 		tp->stats.rx_crc_errors++;
+
 	/* Reset the receiver, based on RealTek recommendation. (Bug?) */
-	tp->cur_rx = 0;
 
 	/* disable receive */
-	RTL_W8 (ChipCmd, CmdTxEnb);
-
-	/* A.C.: Reset the multicast list. */
-	rtl8139_set_rx_mode (dev);
-
-	/* XXX potentially temporary hack to
-	 * restart hung receiver */
+	RTL_W8_F (ChipCmd, CmdTxEnb);
+	tmp_work = 200;
 	while (--tmp_work > 0) {
-		barrier();
+		udelay(1);
+		tmp8 = RTL_R8 (ChipCmd);
+		if (!(tmp8 & CmdRxEnb))
+			break;
+	}
+	if (tmp_work <= 0)
+		printk (KERN_WARNING PFX "rx stop wait too long\n");
+	/* restart receive */
+	tmp_work = 200;
+	while (--tmp_work > 0) {
+		RTL_W8_F (ChipCmd, CmdRxEnb | CmdTxEnb);
+		udelay(1);
 		tmp8 = RTL_R8 (ChipCmd);
 		if ((tmp8 & CmdRxEnb) && (tmp8 & CmdTxEnb))
 			break;
-		RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
 	}
-
-	/* G.S.: Re-enable receiver */
-	/* XXX temporary hack to work around receiver hang */
-	rtl8139_set_rx_mode (dev);
-
 	if (tmp_work <= 0)
 		printk (KERN_WARNING PFX "tx/rx enable wait too long\n");
-}
 
+	/* and reinitialize all rx related registers */
+	{	/* I have no idea what I'm doing, just copied
+		 * from rtl8139_hw_start.
+		 *	Manfred Spraul
+		 */
+		RTL_W8_F (Cfg9346, Cfg9346_Unlock);
+		/* Must enable Tx/Rx before setting transfer thresholds! */
+		RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
+
+		tp->rx_config = rtl8139_rx_config | AcceptBroadcast | AcceptMyPhys;
+		RTL_W32 (RxConfig, tp->rx_config);
+		tp->cur_rx = 0;
+
+		if (tp->chipset >= CH_8139B) {
+			/* disable magic packet scanning, which is enabled
+			 * when PM is enabled in Config1 */
+			RTL_W8 (Config3, RTL_R8 (Config3) & ~(1<<5));
+		}
+
+		DPRINTK("init buffer addresses\n");
+
+		/* Lock Config[01234] and BMCR register writes */
+		RTL_W8 (Cfg9346, Cfg9346_Lock);
+
+		/* init Rx ring buffer DMA address */
+		RTL_W32_F (RxBuf, tp->rx_ring_dma);
+	}
+	/* A.C.: Reset the multicast list. */
+	__set_rx_mode (dev);
+}
 
 static void rtl8139_rx_interrupt (struct net_device *dev,
 				  struct rtl8139_private *tp, void *ioaddr)
@@ -2309,11 +2339,10 @@
 }
 
 
-static void rtl8139_set_rx_mode (struct net_device *dev)
+static void __set_rx_mode (struct net_device *dev)
 {
 	struct rtl8139_private *tp = dev->priv;
 	void *ioaddr = tp->mmio_addr;
-	unsigned long flags;
 	u32 mc_filter[2];	/* Multicast hash filter */
 	int i, rx_mode;
 	u32 tmp;
@@ -2350,22 +2379,28 @@
 		}
 	}
 
-	spin_lock_irqsave (&tp->lock, flags);
-
 	/* We can safely update without stopping the chip. */
 	tmp = rtl8139_rx_config | rx_mode;
 	if (tp->rx_config != tmp) {
-		RTL_W32 (RxConfig, tmp);
+		RTL_W32_F (RxConfig, tmp);
 		tp->rx_config = tmp;
 	}
 	RTL_W32_F (MAR0 + 0, mc_filter[0]);
 	RTL_W32_F (MAR0 + 4, mc_filter[1]);
 
-	spin_unlock_irqrestore (&tp->lock, flags);
 
 	DPRINTK ("EXIT\n");
 }
 
+static void rtl8139_set_rx_mode (struct net_device *dev)
+{
+	unsigned long flags;
+	struct rtl8139_private *tp = dev->priv;
+
+	spin_lock_irqsave (&tp->lock, flags);
+	__set_rx_mode(dev);
+	spin_unlock_irqrestore (&tp->lock, flags);
+}
 
 #ifdef CONFIG_PM
 

  reply	other threads:[~2001-09-30 20:35 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-09-30 16:06 rtl8139 nic dies with load (2.4.10, kt266) Manfred Spraul
2001-09-30 20:35 ` Manfred Spraul [this message]
  -- strict thread matches above, loose matches on Subject: below --
2001-09-30 21:20 Oliver Seemann
2001-09-30 16:29 Oliver Seemann
2001-09-30 15:22 Oliver Seemann
2001-09-30 12:16 Manfred Spraul
2001-09-30 10:44 Oliver Seemann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3BB78212.FB3973E0@colorfullife.com \
    --to=manfred@colorfullife.com \
    --cc=jgarzik@mandrakesoft.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=oseemann@cs.tu-berlin.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox