Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 2395

kernel-2.6.18-194.11.1.el5.src.rpm

From: Ivan Vecera <ivecera@redhat.com>
Date: Wed, 22 Apr 2009 16:52:58 +0200
Subject: [net] r8169: fix RxMissed register access
Message-id: 1240411978-5467-1-git-send-email-ivecera@redhat.com
O-Subject: [RHEL5.4 PATCH] r8169: fix RxMissed register access
Bugzilla: 474334
RH-Acked-by: Michal Schmidt <mschmidt@redhat.com>
RH-Acked-by: Prarit Bhargava <prarit@redhat.com>
RH-Acked-by: Stanislaw Gruszka <sgruszka@redhat.com>
RH-Acked-by: David Miller <davem@redhat.com>

BZs:
#474334 - r8169 reports incredible number of RX dropped packets

Description:
Some NIC chipsets handled by r8169 returns incredible (random) number of
RX dropped packets (in ifconfig ethX). The reason is that RxMissed register
is valid only for 8169 chipset (MACs below RTL_GIGA_MAC_VER_06) and this
register is only 24-bit and not 32-bit. For other chipsets this register
is not defined and should not be used.

Test status:
Tested successfully by myself.

Upstream status:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=523a609496dbc3897e530db2a2f27650d125ea00

Signed-off-by: Ivan Vecera <ivecera@redhat.com>

diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 41f99d1..913959b 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -2656,8 +2656,6 @@ static void rtl_hw_start_8168(struct net_device *dev)
 	RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift) |
 		(InterFrameGap << TxInterFrameGapShift));
 
-	RTL_W32(RxMissed, 0);
-
 	RTL_R8(IntrMask);
 
 	switch (tp->mac_version) {
@@ -2832,8 +2830,6 @@ static void rtl_hw_start_8101(struct net_device *dev)
 
 	RTL_R8(IntrMask);
 
-	RTL_W32(RxMissed, 0);
-
 	rtl_set_rx_mode(dev);
 
 	RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
@@ -3612,6 +3608,17 @@ static int rtl8169_poll(struct net_device *dev, int *budget)
 	return (work_done >= work_to_do);
 }
 
+static void rtl8169_rx_missed(struct net_device *dev, void __iomem *ioaddr)
+{
+	struct rtl8169_private *tp = netdev_priv(dev);
+
+	if (tp->mac_version > RTL_GIGA_MAC_VER_06)
+		return;
+
+	tp->stats.rx_missed_errors += (RTL_R32(RxMissed) & 0xffffff);
+	RTL_W32(RxMissed, 0);
+}
+
 static void rtl8169_down(struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
@@ -3629,9 +3636,7 @@ core_down:
 
 	rtl8169_asic_down(ioaddr);
 
-	/* Update the error counts. */
-	tp->stats.rx_missed_errors += RTL_R32(RxMissed);
-	RTL_W32(RxMissed, 0);
+	rtl8169_rx_missed(dev, ioaddr);
 
 	spin_unlock_irq(&tp->lock);
 
@@ -3753,8 +3758,7 @@ static struct net_device_stats *rtl8169_get_stats(struct net_device *dev)
 
 	if (netif_running(dev)) {
 		spin_lock_irqsave(&tp->lock, flags);
-		tp->stats.rx_missed_errors += RTL_R32(RxMissed);
-		RTL_W32(RxMissed, 0);
+		rtl8169_rx_missed(dev, ioaddr);
 		spin_unlock_irqrestore(&tp->lock, flags);
 	}
 
@@ -3779,8 +3783,7 @@ static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state)
 
 	rtl8169_asic_down(ioaddr);
 
-	tp->stats.rx_missed_errors += RTL_R32(RxMissed);
-	RTL_W32(RxMissed, 0);
+	rtl8169_rx_missed(dev, ioaddr);
 
 	spin_unlock_irq(&tp->lock);