Netdev List
 help / color / mirror / Atom feed
* [net-2.6 PATCH 2/3] ixgbe: disable tx engine before disabling tx laser
From: Jeff Kirsher @ 2010-06-30  4:28 UTC (permalink / raw)
  To: davem
  Cc: netdev, gospo, bphilips, John Fastabend, Peter P Waskiewicz Jr,
	Jeff Kirsher
In-Reply-To: <20100630042739.8925.24962.stgit@localhost.localdomain>

From: John Fastabend <john.r.fastabend@intel.com>

Disabling the tx laser while receiving DMA requests
can hang the device.  After this occurs the device
is in a bad state. The GPIO bit never clears when
PCI master access is disabled and a reboot is required
to get the device in a good state again.

Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
Acked-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/ixgbe/ixgbe_main.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index e237748..7ddd60e 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -3684,10 +3684,6 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
 	/* signal that we are down to the interrupt handler */
 	set_bit(__IXGBE_DOWN, &adapter->state);
 
-	/* power down the optics */
-	if (hw->phy.multispeed_fiber)
-		hw->mac.ops.disable_tx_laser(hw);
-
 	/* disable receive for all VFs and wait one second */
 	if (adapter->num_vfs) {
 		/* ping all the active vfs to let them know we are going down */
@@ -3742,6 +3738,10 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
 		                (IXGBE_READ_REG(hw, IXGBE_DMATXCTL) &
 		                 ~IXGBE_DMATXCTL_TE));
 
+	/* power down the optics */
+	if (hw->phy.multispeed_fiber)
+		hw->mac.ops.disable_tx_laser(hw);
+
 	/* clear n-tuple filters that are cached */
 	ethtool_ntuple_flush(netdev);
 


^ permalink raw reply related

* [net-2.6 PATCH 1/3] ixgbe: fix panic when shutting down system with WoL enabled
From: Jeff Kirsher @ 2010-06-30  4:28 UTC (permalink / raw)
  To: davem
  Cc: netdev, gospo, bphilips, Andy Gospodarek, Jesse Brandeburg,
	Jeff Kirsher

From: Andy Gospodarek <andy@greyhouse.net>

This patch added to 2.6.34:

	commit 5f6c01819979afbfec7e0b15fe52371b8eed87e8
	Author: Jesse Brandeburg <jesse.brandeburg@intel.com>
	Date:   Wed Apr 14 16:04:23 2010 -0700

	    ixgbe: fix bug with vlan strip in promsic mode

among other things added a function called ixgbe_vlan_filter_enable.
This new function wants to access and set some rx_ring parameters, but
adapter->rx_ring has already been freed.  This simply moves the free
until after the access and makes __ixgbe_shutdown look more like
ixgbe_remove.

Signed-off-by: Andy Gospodarek <andy@greyhouse.net>
Acked-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: Emil Tantilov <emil.s.tantilov@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/ixgbe/ixgbe_main.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index ce30c62..e237748 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -5195,7 +5195,6 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
 		ixgbe_free_all_tx_resources(adapter);
 		ixgbe_free_all_rx_resources(adapter);
 	}
-	ixgbe_clear_interrupt_scheme(adapter);
 
 #ifdef CONFIG_PM
 	retval = pci_save_state(pdev);
@@ -5230,6 +5229,8 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
 
 	*enable_wake = !!wufc;
 
+	ixgbe_clear_interrupt_scheme(adapter);
+
 	ixgbe_release_hw_control(adapter);
 
 	pci_disable_device(pdev);


^ permalink raw reply related

* [net-next-2.6 PATCH 4/4] e1000e: disable EEE support by default
From: Jeff Kirsher @ 2010-06-30  4:13 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, bphilips, bhutchings, Bruce Allan, Jeff Kirsher
In-Reply-To: <20100630040959.8652.31147.stgit@localhost.localdomain>

From: Bruce Allan <bruce.w.allan@intel.com>

Based on community feedback, EEE should be disabled by default until the
IEEE802.3az specification has been finalized.

Cc: bhutchings@solarflare.com
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Tested-by: Emil Tantilov <emil.s.tantilov@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000e/ich8lan.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index 6b5e108..63930d1 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -731,6 +731,10 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter)
 	    (adapter->hw.phy.type == e1000_phy_igp_3))
 		adapter->flags |= FLAG_LSC_GIG_SPEED_DROP;
 
+	/* Disable EEE by default until IEEE802.3az spec is finalized */
+	if (adapter->flags2 & FLAG2_HAS_EEE)
+		adapter->hw.dev_spec.ich8lan.eee_disable = true;
+
 	return 0;
 }
 


^ permalink raw reply related

* [net-next-2.6 PATCH 3/4] e1000e: remove EEE module parameter
From: Jeff Kirsher @ 2010-06-30  4:12 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, bphilips, Bruce Allan, Jeff Kirsher
In-Reply-To: <20100630040959.8652.31147.stgit@localhost.localdomain>

From: Bruce Allan <bruce.w.allan@intel.com>

As requested by Dave Miller.  A follow-on set of patches will allow for
ethtool to enable/disable the feature instead.

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Tested-by: Emil Tantilov <emil.s.tantilov@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000e/param.c |   28 ----------------------------
 1 files changed, 0 insertions(+), 28 deletions(-)

diff --git a/drivers/net/e1000e/param.c b/drivers/net/e1000e/param.c
index 593251c..34aeec1 100644
--- a/drivers/net/e1000e/param.c
+++ b/drivers/net/e1000e/param.c
@@ -161,15 +161,6 @@ E1000_PARAM(WriteProtectNVM, "Write-protect NVM [WARNING: disabling this can lea
 E1000_PARAM(CrcStripping, "Enable CRC Stripping, disable if your BMC needs " \
                           "the CRC");
 
-/*
- * Enable/disable EEE (a.k.a. IEEE802.3az)
- *
- * Valid Range: 0, 1
- *
- * Default Value: 1
- */
-E1000_PARAM(EEE, "Enable/disable on parts that support the feature");
-
 struct e1000_option {
 	enum { enable_option, range_option, list_option } type;
 	const char *name;
@@ -486,23 +477,4 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
 			}
 		}
 	}
-	{ /* EEE for parts supporting the feature */
-		static const struct e1000_option opt = {
-			.type = enable_option,
-			.name = "EEE Support",
-			.err  = "defaulting to Enabled",
-			.def  = OPTION_ENABLED
-		};
-
-		if (adapter->flags2 & FLAG2_HAS_EEE) {
-			/* Currently only supported on 82579 */
-			if (num_EEE > bd) {
-				unsigned int eee = EEE[bd];
-				e1000_validate_option(&eee, &opt, adapter);
-				hw->dev_spec.ich8lan.eee_disable = !eee;
-			} else {
-				hw->dev_spec.ich8lan.eee_disable = !opt.def;
-			}
-		}
-	}
 }


^ permalink raw reply related

* [net-next-2.6 PATCH 2/4] e1000e: suppress compile warnings on certain archs
From: Jeff Kirsher @ 2010-06-30  4:12 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, bphilips, Bruce Allan, Jeff Kirsher
In-Reply-To: <20100630040959.8652.31147.stgit@localhost.localdomain>

From: Bruce Allan <bruce.w.allan@intel.com>

Commit 84f4ee902ad3ee964b7b3a13d5b7cf9c086e9916 causes compile warnings on
architectures that have unsigned long long's that are not 64-bit, e.g.
ia64.

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000e/netdev.c |   38 +++++++++++++++++++++-----------------
 1 files changed, 21 insertions(+), 17 deletions(-)

diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 3e53ca7..6aa795a 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -224,10 +224,10 @@ static void e1000e_dump(struct e1000_adapter *adapter)
 	buffer_info = &tx_ring->buffer_info[tx_ring->next_to_clean];
 	printk(KERN_INFO " %5d %5X %5X %016llX %04X %3X %016llX\n",
 		0, tx_ring->next_to_use, tx_ring->next_to_clean,
-		(u64)buffer_info->dma,
+		(unsigned long long)buffer_info->dma,
 		buffer_info->length,
 		buffer_info->next_to_watch,
-		(u64)buffer_info->time_stamp);
+		(unsigned long long)buffer_info->time_stamp);
 
 	/* Print TX Rings */
 	if (!netif_msg_tx_done(adapter))
@@ -279,9 +279,11 @@ static void e1000e_dump(struct e1000_adapter *adapter)
 			"%04X  %3X %016llX %p",
 		       (!(le64_to_cpu(u0->b) & (1<<29)) ? 'l' :
 			((le64_to_cpu(u0->b) & (1<<20)) ? 'd' : 'c')), i,
-		       le64_to_cpu(u0->a), le64_to_cpu(u0->b),
-		       (u64)buffer_info->dma, buffer_info->length,
-		       buffer_info->next_to_watch, (u64)buffer_info->time_stamp,
+		       (unsigned long long)le64_to_cpu(u0->a),
+		       (unsigned long long)le64_to_cpu(u0->b),
+		       (unsigned long long)buffer_info->dma,
+		       buffer_info->length, buffer_info->next_to_watch,
+		       (unsigned long long)buffer_info->time_stamp,
 		       buffer_info->skb);
 		if (i == tx_ring->next_to_use && i == tx_ring->next_to_clean)
 			printk(KERN_CONT " NTC/U\n");
@@ -356,19 +358,19 @@ rx_ring_summary:
 				printk(KERN_INFO "RWB[0x%03X]     %016llX "
 					"%016llX %016llX %016llX "
 					"---------------- %p", i,
-					le64_to_cpu(u1->a),
-					le64_to_cpu(u1->b),
-					le64_to_cpu(u1->c),
-					le64_to_cpu(u1->d),
+					(unsigned long long)le64_to_cpu(u1->a),
+					(unsigned long long)le64_to_cpu(u1->b),
+					(unsigned long long)le64_to_cpu(u1->c),
+					(unsigned long long)le64_to_cpu(u1->d),
 					buffer_info->skb);
 			} else {
 				printk(KERN_INFO "R  [0x%03X]     %016llX "
 					"%016llX %016llX %016llX %016llX %p", i,
-					le64_to_cpu(u1->a),
-					le64_to_cpu(u1->b),
-					le64_to_cpu(u1->c),
-					le64_to_cpu(u1->d),
-					(u64)buffer_info->dma,
+					(unsigned long long)le64_to_cpu(u1->a),
+					(unsigned long long)le64_to_cpu(u1->b),
+					(unsigned long long)le64_to_cpu(u1->c),
+					(unsigned long long)le64_to_cpu(u1->d),
+					(unsigned long long)buffer_info->dma,
 					buffer_info->skb);
 
 				if (netif_msg_pktdata(adapter))
@@ -405,9 +407,11 @@ rx_ring_summary:
 			buffer_info = &rx_ring->buffer_info[i];
 			u0 = (struct my_u0 *)rx_desc;
 			printk(KERN_INFO "Rl[0x%03X]    %016llX %016llX "
-				"%016llX %p",
-				i, le64_to_cpu(u0->a), le64_to_cpu(u0->b),
-				(u64)buffer_info->dma, buffer_info->skb);
+				"%016llX %p", i,
+				(unsigned long long)le64_to_cpu(u0->a),
+				(unsigned long long)le64_to_cpu(u0->b),
+				(unsigned long long)buffer_info->dma,
+				buffer_info->skb);
 			if (i == rx_ring->next_to_use)
 				printk(KERN_CONT " NTU\n");
 			else if (i == rx_ring->next_to_clean)


^ permalink raw reply related

* [net-next-2.6 PATCH 1/4] e1000e: don't inadvertently re-set INTX_DISABLE
From: Jeff Kirsher @ 2010-06-30  4:12 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, bphilips, Dean Nelson, stable, Jeff Kirsher

From: Dean Nelson <dnelson@redhat.com>

Should e1000_test_msi() fail to see an msi interrupt, it attempts to
fallback to legacy INTx interrupts. But an error in the code may prevent
this from happening correctly.

Before calling e1000_test_msi_interrupt(), e1000_test_msi() disables SERR
by clearing the SERR bit from the just read PCI_COMMAND bits as it writes
them back out.

Upon return from calling e1000_test_msi_interrupt(), it re-enables SERR
by writing out the version of PCI_COMMAND it had previously read.

The problem with this is that e1000_test_msi_interrupt() calls
pci_disable_msi(), which eventually ends up in pci_intx(). And because
pci_intx() was called with enable set to 1, the INTX_DISABLE bit gets
cleared from PCI_COMMAND, which is what we want. But when we get back to
e1000_test_msi(), the INTX_DISABLE bit gets inadvertently re-set because
of the attempt by e1000_test_msi() to re-enable SERR.

The solution is to have e1000_test_msi() re-read the PCI_COMMAND bits as
part of its attempt to re-enable SERR.

During debugging/testing of this issue I found that not all the systems
I ran on had the SERR bit set to begin with. And on some of the systems
the same could be said for the INTX_DISABLE bit. Needless to say these
latter systems didn't have a problem falling back to legacy INTx
interrupts with the code as is.

Signed-off-by: Dean Nelson <dnelson@redhat.com>
CC: stable@kernel.org
Tested-by: Emil Tantilov <emil.s.tantilov@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000e/netdev.c |   13 +++++++++----
 1 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 71592ed..3e53ca7 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -3439,13 +3439,18 @@ static int e1000_test_msi(struct e1000_adapter *adapter)
 
 	/* disable SERR in case the MSI write causes a master abort */
 	pci_read_config_word(adapter->pdev, PCI_COMMAND, &pci_cmd);
-	pci_write_config_word(adapter->pdev, PCI_COMMAND,
-			      pci_cmd & ~PCI_COMMAND_SERR);
+	if (pci_cmd & PCI_COMMAND_SERR)
+		pci_write_config_word(adapter->pdev, PCI_COMMAND,
+				      pci_cmd & ~PCI_COMMAND_SERR);
 
 	err = e1000_test_msi_interrupt(adapter);
 
-	/* restore previous setting of command word */
-	pci_write_config_word(adapter->pdev, PCI_COMMAND, pci_cmd);
+	/* re-enable SERR */
+	if (pci_cmd & PCI_COMMAND_SERR) {
+		pci_read_config_word(adapter->pdev, PCI_COMMAND, &pci_cmd);
+		pci_cmd |= PCI_COMMAND_SERR;
+		pci_write_config_word(adapter->pdev, PCI_COMMAND, pci_cmd);
+	}
 
 	/* success ! */
 	if (!err)


^ permalink raw reply related

* Re: nat bypass
From: Simon Horman @ 2010-06-30  2:37 UTC (permalink / raw)
  To: ratheesh k; +Cc: Netfilter mailing list, netdev
In-Reply-To: <AANLkTil_H1QeaCHQYhMjVRFiLwtqF9yLAJZ9BWecOIDW@mail.gmail.com>

On Mon, Jun 28, 2010 at 03:43:46PM +0530, ratheesh k wrote:
> Hi,
> 
>   A -------> R ------->S
> 
> I have a linux machine A is connected to Linux machine R . Machine R
> is having two network interfaces and acting as a router .
> It has a dhcp server running  . It will assign ip in 192.168.1.0/24
> subnet to all machine connected on lan side ( A is connected also in
> lan side ) . Wan side of R is connected to HTTP server S . There is
> also a DHCP server running on S to assign ip in 10.232.18.0/24 subnet
> .  Is there any way , in which NAT should be bypassed to get ip from
> DHCP server running  on S . My question is : How can A will get  an ip
> from 10.232.18.0/24 pool ip .?
> ebtables is an option ? How can we make it ?
> Is there any other optimal way ?

Let me try and understand this.

R is routing between 192.168.1.0/24 and 10.232.18.0/24.
As A is on the 192.168.1.0/24 side of R.
But to give A an 10.232.18.0/24 address (dynamically)?

Why?


^ permalink raw reply

* [PATCHv2 net-next-2.6] 3c59x: Use fine-grained locks for MII and windowed register access
From: Ben Hutchings @ 2010-06-30  1:26 UTC (permalink / raw)
  To: David Miller; +Cc: steffen.klassert, netdev, chase.douglas, nordmark
In-Reply-To: <20100628.231812.35040625.davem@davemloft.net>

This avoids scheduling in atomic context and also means that IRQs
will only be deferred for relatively short periods of time.

Previously discussed in:
http://article.gmane.org/gmane.linux.network/155024

Reported-by: Arne Nordmark <nordmark@mech.kth.se>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
Added the missing spin_lock_init() calls.

Ben.

 drivers/net/3c59x.c |   68 ++++++++++++++++++++++++++++++--------------------
 1 files changed, 41 insertions(+), 27 deletions(-)

diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index beddef9..069a03f 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -644,9 +644,15 @@ struct vortex_private {
 	u16 deferred;						/* Resend these interrupts when we
 										 * bale from the ISR */
 	u16 io_size;						/* Size of PCI region (for release_region) */
-	spinlock_t lock;					/* Serialise access to device & its vortex_private */
-	struct mii_if_info mii;				/* MII lib hooks/info */
-	int window;					/* Register window */
+
+	/* Serialises access to hardware other than MII and variables below.
+	 * The lock hierarchy is rtnl_lock > lock > mii_lock > window_lock. */
+	spinlock_t lock;
+
+	spinlock_t mii_lock;		/* Serialises access to MII */
+	struct mii_if_info mii;		/* MII lib hooks/info */
+	spinlock_t window_lock;		/* Serialises access to windowed regs */
+	int window;			/* Register window */
 };
 
 static void window_set(struct vortex_private *vp, int window)
@@ -661,15 +667,23 @@ static void window_set(struct vortex_private *vp, int window)
 static u ## size							\
 window_read ## size(struct vortex_private *vp, int window, int addr)	\
 {									\
+	unsigned long flags;						\
+	u ## size ret;							\
+	spin_lock_irqsave(&vp->window_lock, flags);			\
 	window_set(vp, window);						\
-	return ioread ## size(vp->ioaddr + addr);			\
+	ret = ioread ## size(vp->ioaddr + addr);			\
+	spin_unlock_irqrestore(&vp->window_lock, flags);		\
+	return ret;							\
 }									\
 static void								\
 window_write ## size(struct vortex_private *vp, u ## size value,	\
 		     int window, int addr)				\
 {									\
+	unsigned long flags;						\
+	spin_lock_irqsave(&vp->window_lock, flags);			\
 	window_set(vp, window);						\
 	iowrite ## size(value, vp->ioaddr + addr);			\
+	spin_unlock_irqrestore(&vp->window_lock, flags);		\
 }
 DEFINE_WINDOW_IO(8)
 DEFINE_WINDOW_IO(16)
@@ -1181,6 +1195,8 @@ static int __devinit vortex_probe1(struct device *gendev,
 	}
 
 	spin_lock_init(&vp->lock);
+	spin_lock_init(&vp->mii_lock);
+	spin_lock_init(&vp->window_lock);
 	vp->gendev = gendev;
 	vp->mii.dev = dev;
 	vp->mii.mdio_read = mdio_read;
@@ -1784,7 +1800,6 @@ vortex_timer(unsigned long data)
 		pr_debug("dev->watchdog_timeo=%d\n", dev->watchdog_timeo);
 	}
 
-	disable_irq_lockdep(dev->irq);
 	media_status = window_read16(vp, 4, Wn4_Media);
 	switch (dev->if_port) {
 	case XCVR_10baseT:  case XCVR_100baseTx:  case XCVR_100baseFx:
@@ -1805,10 +1820,7 @@ vortex_timer(unsigned long data)
 	case XCVR_MII: case XCVR_NWAY:
 		{
 			ok = 1;
-			/* Interrupts are already disabled */
-			spin_lock(&vp->lock);
 			vortex_check_media(dev, 0);
-			spin_unlock(&vp->lock);
 		}
 		break;
 	  default:					/* Other media types handled by Tx timeouts. */
@@ -1827,6 +1839,8 @@ vortex_timer(unsigned long data)
 	if (!ok) {
 		unsigned int config;
 
+		spin_lock_irq(&vp->lock);
+
 		do {
 			dev->if_port = media_tbl[dev->if_port].next;
 		} while ( ! (vp->available_media & media_tbl[dev->if_port].mask));
@@ -1855,6 +1869,8 @@ vortex_timer(unsigned long data)
 		if (vortex_debug > 1)
 			pr_debug("wrote 0x%08x to Wn3_Config\n", config);
 		/* AKPM: FIXME: Should reset Rx & Tx here.  P60 of 3c90xc.pdf */
+
+		spin_unlock_irq(&vp->lock);
 	}
 
 leave_media_alone:
@@ -1862,7 +1878,6 @@ leave_media_alone:
 	  pr_debug("%s: Media selection timer finished, %s.\n",
 			 dev->name, media_tbl[dev->if_port].name);
 
-	enable_irq_lockdep(dev->irq);
 	mod_timer(&vp->timer, RUN_AT(next_tick));
 	if (vp->deferred)
 		iowrite16(FakeIntr, ioaddr + EL3_CMD);
@@ -2051,9 +2066,11 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		int len = (skb->len + 3) & ~3;
 		vp->tx_skb_dma = pci_map_single(VORTEX_PCI(vp), skb->data, len,
 						PCI_DMA_TODEVICE);
+		spin_lock_irq(&vp->window_lock);
 		window_set(vp, 7);
 		iowrite32(vp->tx_skb_dma, ioaddr + Wn7_MasterAddr);
 		iowrite16(len, ioaddr + Wn7_MasterLen);
+		spin_unlock_irq(&vp->window_lock);
 		vp->tx_skb = skb;
 		iowrite16(StartDMADown, ioaddr + EL3_CMD);
 		/* netif_wake_queue() will be called at the DMADone interrupt. */
@@ -2225,6 +2242,7 @@ vortex_interrupt(int irq, void *dev_id)
 		pr_debug("%s: interrupt, status %4.4x, latency %d ticks.\n",
 			   dev->name, status, ioread8(ioaddr + Timer));
 
+	spin_lock(&vp->window_lock);
 	window_set(vp, 7);
 
 	do {
@@ -2285,6 +2303,8 @@ vortex_interrupt(int irq, void *dev_id)
 		iowrite16(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
 	} while ((status = ioread16(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete));
 
+	spin_unlock(&vp->window_lock);
+
 	if (vortex_debug > 4)
 		pr_debug("%s: exiting interrupt, status %4.4x.\n",
 			   dev->name, status);
@@ -2806,37 +2826,22 @@ static void update_stats(void __iomem *ioaddr, struct net_device *dev)
 static int vortex_nway_reset(struct net_device *dev)
 {
 	struct vortex_private *vp = netdev_priv(dev);
-	unsigned long flags;
-	int rc;
 
-	spin_lock_irqsave(&vp->lock, flags);
-	rc = mii_nway_restart(&vp->mii);
-	spin_unlock_irqrestore(&vp->lock, flags);
-	return rc;
+	return mii_nway_restart(&vp->mii);
 }
 
 static int vortex_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct vortex_private *vp = netdev_priv(dev);
-	unsigned long flags;
-	int rc;
 
-	spin_lock_irqsave(&vp->lock, flags);
-	rc = mii_ethtool_gset(&vp->mii, cmd);
-	spin_unlock_irqrestore(&vp->lock, flags);
-	return rc;
+	return mii_ethtool_gset(&vp->mii, cmd);
 }
 
 static int vortex_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct vortex_private *vp = netdev_priv(dev);
-	unsigned long flags;
-	int rc;
 
-	spin_lock_irqsave(&vp->lock, flags);
-	rc = mii_ethtool_sset(&vp->mii, cmd);
-	spin_unlock_irqrestore(&vp->lock, flags);
-	return rc;
+	return mii_ethtool_sset(&vp->mii, cmd);
 }
 
 static u32 vortex_get_msglevel(struct net_device *dev)
@@ -3059,6 +3064,8 @@ static int mdio_read(struct net_device *dev, int phy_id, int location)
 	int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;
 	unsigned int retval = 0;
 
+	spin_lock_bh(&vp->mii_lock);
+
 	if (mii_preamble_required)
 		mdio_sync(vp, 32);
 
@@ -3082,6 +3089,9 @@ static int mdio_read(struct net_device *dev, int phy_id, int location)
 			       4, Wn4_PhysicalMgmt);
 		mdio_delay(vp);
 	}
+
+	spin_unlock_bh(&vp->mii_lock);
+
 	return retval & 0x20000 ? 0xffff : retval>>1 & 0xffff;
 }
 
@@ -3091,6 +3101,8 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val
 	int write_cmd = 0x50020000 | (phy_id << 23) | (location << 18) | value;
 	int i;
 
+	spin_lock_bh(&vp->mii_lock);
+
 	if (mii_preamble_required)
 		mdio_sync(vp, 32);
 
@@ -3111,6 +3123,8 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val
 			       4, Wn4_PhysicalMgmt);
 		mdio_delay(vp);
 	}
+
+	spin_unlock_bh(&vp->mii_lock);
 }
 
 /* ACPI: Advanced Configuration and Power Interface. */
-- 
1.7.1


-- 
Ben Hutchings
Once a job is fouled up, anything done to improve it makes it worse.

^ permalink raw reply related

* Re: [PATCH] s2io: read rx_packets count from the hardware stats
From: Jon Mason @ 2010-06-30  0:54 UTC (permalink / raw)
  To: Michal Schmidt
  Cc: netdev@vger.kernel.org, Ramkrishna Vepa, Sivakumar Subramani,
	Sreenivasa Honnur
In-Reply-To: <20100624233230.5864.67401.stgit@leela.lan>

On Thu, Jun 24, 2010 at 04:32:32PM -0700, Michal Schmidt wrote:
> Most of the statistics the s2io driver provides in /proc/net/dev
> it reads directly from the hardware counters. For some reason it does
> not do that for rx_packets. It counts rx_packets purely in software.
>
> A customer reported a bug where in /proc/net/dev the 'multicast' counter
> was increasing faster than 'packets' ( = rx_packets in the source code).
> This confuses userspace, especially snmpd.
>
> The hardware provides a counter for the total number of received
> frames (RMAC_VLD_FRMS) which the driver can use for the rx_packets
> statistic. By reading both statistics from the hardware it makes sure
> that all multicast frames are included in the total.

On the Xframe adapter, there is a issue with the multicast statistics
counter.  It includes broadcast and pause frames in its count.  This
is most likely the cause of the issue you are seeing.

While, looking over the patch you submitted, I noticed other issues
with the s2io_get_stats function.  I have a patch that I will push
soon that addresses the multicast issue, the issues I discovered, and
the octet issues Dave suggested.

Thanks,
Jon

>
> The customer tested a patch like this (only modified for RHEL5) with
> S2io Inc. Xframe II 10Gbps Ethernet (rev 02)
> and it fixed the problem.
>
> Signed-off-by: Michal Schmidt <mschmidt@redhat.com>
> ---
>
>  drivers/net/s2io.c |   11 ++++++-----
>  drivers/net/s2io.h |    1 -
>  2 files changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
> index 668327c..eefc4b2 100644
> --- a/drivers/net/s2io.c
> +++ b/drivers/net/s2io.c
> @@ -4919,6 +4919,10 @@ static struct net_device_stats *s2io_get_stats(struct net_device *dev)
>               sp->stats.tx_packets;
>       sp->stats.tx_packets = le32_to_cpu(stats->tmac_frms);
>
> +     dev->stats.rx_packets += le32_to_cpu(stats->rmac_vld_frms) -
> +             sp->stats.rx_packets;
> +     sp->stats.rx_packets = le32_to_cpu(stats->rmac_vld_frms);
> +
>       dev->stats.tx_errors += le32_to_cpu(stats->tmac_any_err_frms) -
>               sp->stats.tx_errors;
>       sp->stats.tx_errors = le32_to_cpu(stats->tmac_any_err_frms);
> @@ -4935,12 +4939,11 @@ static struct net_device_stats *s2io_get_stats(struct net_device *dev)
>               sp->stats.rx_length_errors;
>       sp->stats.rx_length_errors = le64_to_cpu(stats->rmac_long_frms);
>
> -     /* collect per-ring rx_packets and rx_bytes */
> -     dev->stats.rx_packets = dev->stats.rx_bytes = 0;
> +     /* collect per-ring rx_bytes */
> +     dev->stats.rx_bytes = 0;
>       for (i = 0; i < config->rx_ring_num; i++) {
>               struct ring_info *ring = &mac_control->rings[i];
>
> -             dev->stats.rx_packets += ring->rx_packets;
>               dev->stats.rx_bytes += ring->rx_bytes;
>       }
>
> @@ -7455,8 +7458,6 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
>               }
>       }
>
> -     /* Updating statistics */
> -     ring_data->rx_packets++;
>       rxdp->Host_Control = 0;
>       if (sp->rxd_mode == RXD_MODE_1) {
>               int len = RXD_GET_BUFFER0_SIZE_1(rxdp->Control_2);
> diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
> index 47c36e0..4da9ab8 100644
> --- a/drivers/net/s2io.h
> +++ b/drivers/net/s2io.h
> @@ -747,7 +747,6 @@ struct ring_info {
>       struct buffAdd **ba;
>
>       /* per-Ring statistics */
> -     unsigned long rx_packets;
>       unsigned long rx_bytes;
>  } ____cacheline_aligned;
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

The information and any attached documents contained in this message
may be confidential and/or legally privileged.  The message is
intended solely for the addressee(s).  If you are not the intended
recipient, you are hereby notified that any use, dissemination, or
reproduction is strictly prohibited and may be unlawful.  If you are
not the intended recipient, please contact the sender immediately by
return e-mail and destroy all copies of the original message.

^ permalink raw reply

* Re: [PATCH 0/9] New cxgb4vf network driver for Chelsio T4 Virtual Function NIC
From: Casey Leedom @ 2010-06-29 23:02 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <201006290904.50370.leedom@chelsio.com>

| From: Casey Leedom <leedom@chelsio.com>
| Date: Tuesday, June 29, 2010 09:04 am
| 
|   Thank you and I'm sorry for the mess. (sigh) I'm using the Kubuntu
| supplied email client and I mistakenly assumed that its "Insert File"
| action would do the right job.  I'll just use Thunderbird from now on.

  Hopefully my latest effort at getting patches submitted will be better.  
There's evidently a way to get git to mail them directly with which I'm fighting, 
so in the mean time I disabled word wrap on my current mailer.  I will get 
someone here to help me out with the git (and stgit) patch support.

|   Odd that patch #3 didn't apply cleanly.  I'll do a "pull" and verify
| correct operation.

  I did a complete new pull, compared the submitted and the pulled source and 
found no differences.  I then did a thorough test run and discovered that I'd 
accidentally translated one of our internal symbolic names into the wrong 
kernel.org symbolic names.  By "luck" it worked for some packet sizes so I 
didn't catch it. (sigh)  I've submitted patches for that bug and the deletion of 
an obsolete comment which I forgot to get rid of earlier.

  I hope these new patches apply cleanly.  If not, just drop them and I'll got 
to remedial git school here and get someone to help me do it right.

Casey

^ permalink raw reply

* [PATCH 0/2] cxgb4vf: small fixes to new driver
From: Casey Leedom @ 2010-06-29 22:52 UTC (permalink / raw)
  To: netdev

>From d9aed637fc8a9f1bf1bccf6f23aed0342870f868 Mon Sep 17 00:00:00 2001
From: Casey Leedom <leedom@chelsio.com>
Date: Tue, 29 Jun 2010 15:41:14 -0700
Subject: [PATCH 0/2] cxgb4vf: small fixes to new driver

  In my cxgb4vf driver testing I got very "lucky" and the use of an
incorrect shift factor just happened to work for the packet size I was
using. (sigh) (All of this happened because I had to translate our internal
version of the driver to use the different constant names used in the
kernel.org tree.)

Casey Leedom (2):
  Remove obsolete comment about the lack of a TX Timer Callback --
    which we now _do_ have ...

  Use correct shift factor for extracting the SGE DMA Ingress Padding  
    Boundary.  Was accidentally using the register field's shift which
    was close enough (4 instead of the propper value of 5) that it
    actually sort of worked for various packet sizes ...

 drivers/net/cxgb4vf/sge.c |   15 ++-------------
 1 files changed, 2 insertions(+), 13 deletions(-)


^ permalink raw reply

* [PATCH 2/2] Use correct shift factor for extracting the SGE DMA Ingress Padding ...
From: Casey Leedom @ 2010-06-29 22:54 UTC (permalink / raw)
  To: netdev

>From d9aed637fc8a9f1bf1bccf6f23aed0342870f868 Mon Sep 17 00:00:00 2001
From: Casey Leedom <leedom@chelsio.com>
Date: Tue, 29 Jun 2010 15:15:11 -0700
Subject: [PATCH 2/2] Use correct shift factor for extracting the SGE DMA Ingress Padding
 Boundary.  Was accidentally using the register field's shift which was close
 enough (4 instead of the propper value of 5) that it actually sort of
 worked for various packet sizes ...


Signed-off-by: Casey Leedom <leedom@chelsio.com>
---
 drivers/net/cxgb4vf/sge.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/cxgb4vf/sge.c b/drivers/net/cxgb4vf/sge.c
index 5c4a81d..3a7c02f 100644
--- a/drivers/net/cxgb4vf/sge.c
+++ b/drivers/net/cxgb4vf/sge.c
@@ -2432,7 +2432,7 @@ int t4vf_sge_init(struct adapter *adapter)
 	STAT_LEN = ((sge_params->sge_control & EGRSTATUSPAGESIZE) ? 128 : 64);
 	PKTSHIFT = PKTSHIFT_GET(sge_params->sge_control);
 	FL_ALIGN = 1 << (INGPADBOUNDARY_GET(sge_params->sge_control) +
-			 INGPADBOUNDARY_SHIFT);
+			 SGE_INGPADBOUNDARY_SHIFT);
 
 	/*
 	 * Set up tasklet timers.
-- 
1.7.0.4


^ permalink raw reply related

* PATCH 1/2] Remove obsolete comment about the lack of a TX Timer Callback -- which we ...
From: Casey Leedom @ 2010-06-29 22:53 UTC (permalink / raw)
  To: netdev

>From fab966adc65f1b500e261867b3cb26bf35482b36 Mon Sep 17 00:00:00 2001
From: Casey Leedom <leedom@chelsio.com>
Date: Tue, 29 Jun 2010 15:14:38 -0700
Subject: [PATCH 1/2] Remove obsolete comment about the lack of a TX Timer Callback -- which we
 now _do_ have ...


Signed-off-by: Casey Leedom <leedom@chelsio.com>
---
 drivers/net/cxgb4vf/sge.c |   13 +------------
 1 files changed, 1 insertions(+), 12 deletions(-)

diff --git a/drivers/net/cxgb4vf/sge.c b/drivers/net/cxgb4vf/sge.c
index f857d20..5c4a81d 100644
--- a/drivers/net/cxgb4vf/sge.c
+++ b/drivers/net/cxgb4vf/sge.c
@@ -1301,18 +1301,7 @@ int t4vf_eth_xmit(struct sk_buff *skb, struct net_device *dev)
 		 * wait for acks to really free up the data the extra memory
 		 * is even less.  On the positive side we run the destructors
 		 * on the sending CPU rather than on a potentially different
-		 * completing CPU, usually a good thing.  We also run them
-		 * without holding our TX queue lock, unlike what
-		 * reclaim_completed_tx() would otherwise do.
-		 *
-		 * XXX Actually the above is somewhat incorrect since we don't
-		 * XXX yet have a periodic timer which reclaims TX Descriptors.
-		 * XXX What's our plan for this?
-		 * XXX
-		 * XXX Also, we don't currently have a TX Queue lock but
-		 * XXX that may be the result of not having any current
-		 * XXX asynchronous path for reclaiming completed TX
-		 * XXX Descriptors ...
+		 * completing CPU, usually a good thing.
 		 *
 		 * Run the destructor before telling the DMA engine about the
 		 * packet to make sure it doesn't complete and get freed
-- 
1.7.0.4


^ permalink raw reply related

* Re: [patch] isdn/gigaset: add a kfree() to error path
From: Dan Carpenter @ 2010-06-29 22:33 UTC (permalink / raw)
  To: Tilman Schmidt
  Cc: Hansjoerg Lipp, Karsten Keil, David S. Miller, gigaset307x-common,
	netdev, kernel-janitors
In-Reply-To: <4C2A7127.3040609@imap.cc>

On Wed, Jun 30, 2010 at 12:18:15AM +0200, Tilman Schmidt wrote:
> Dan,
> 
> thanks for your patch. It is quite correct as it stands.
> There is however another problem with that error path, in
> that it also doesn't free the previously allocated channel.
> I prefer not to carry two separate patches for that, so I'm
> replacing your patch with the following augmented patch,
> which I'll submit together with my other pending patches
> for 2.6.36 soon:
> 

Good deal.

Acked-by: Dan Carpenter <error27@gmail.com>

regards,
dan carpenter


^ permalink raw reply

* Re: [PATCH] drivers/net/Makefile: conditionally descend to wireless
From: David Miller @ 2010-06-29 22:33 UTC (permalink / raw)
  To: nikai; +Cc: netdev, linux-kbuild, linux-kernel
In-Reply-To: <20100627234452.0f9d19f1@absol.kitzblitz>

From: Nicolas Kaiser <nikai@nikai.net>
Date: Sun, 27 Jun 2010 23:44:52 +0200

> Don't descend to wireless unless it is actually used.
> 
> Signed-off-by: Nicolas Kaiser <nikai@nikai.net>

Applied.

^ permalink raw reply

* Re: [PATCH] net/Makefile: conditionally descend to wireless and ieee802154
From: David Miller @ 2010-06-29 22:32 UTC (permalink / raw)
  To: nikai; +Cc: netdev, linux-kbuild, linux-kernel
In-Reply-To: <20100627120025.0232a9d0@absol.kitzblitz>

From: Nicolas Kaiser <nikai@nikai.net>
Date: Sun, 27 Jun 2010 12:00:25 +0200

> Don't descend to wireless and ieee802154 unless they are actually used.
> 
> Signed-off-by: Nicolas Kaiser <nikai@nikai.net>

Applied.

^ permalink raw reply

* Re: [PATCH 0/4] Extend Time Stamping
From: David Miller @ 2010-06-29 22:31 UTC (permalink / raw)
  To: richardcochran; +Cc: netdev
In-Reply-To: <cover.1277737222.git.richard.cochran@omicron.at>


Richard, last round I told you:

--------------------
By this I mean you should provide these inline helpers by default
then we can begin to put them into the drivers.
--------------------

This means no config option.

^ permalink raw reply

* Re: [PATCH] net/core: use htons for skb->protocol
From: David Daney @ 2010-06-29 22:19 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior; +Cc: netdev
In-Reply-To: <20100629163246.GA18647@Chamillionaire.breakpoint.cc>

On 06/29/2010 09:32 AM, Sebastian Andrzej Siewior wrote:
> From: Sebastian Andrzej Siewior<bigeasy@linutronix.de>
>
> This is only noticed by people that are not doing everything correct in
> the first place.
>
> Signed-off-by: Sebastian Andrzej Siewior<bigeasy@linutronix.de>
> ---
>   net/core/dev.c |    3 ++-
>   1 files changed, 2 insertions(+), 1 deletions(-)
>
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 2b3bf53..78ad37c 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -1541,7 +1541,8 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
>   				if (net_ratelimit())
>   					printk(KERN_CRIT "protocol %04x is "
>   					       "buggy, dev %s\n",
> -					       skb2->protocol, dev->name);
> +					       htons(skb2->protocol),

Would ntohs() be more appropriate here?  It looks like you are 
converting from network order to host order for printing.

David Daney

^ permalink raw reply

* Re: [patch] isdn/gigaset: add a kfree() to error path
From: Tilman Schmidt @ 2010-06-29 22:18 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: Hansjoerg Lipp, Karsten Keil, David S. Miller, gigaset307x-common,
	netdev, kernel-janitors
In-Reply-To: <20100628212046.GM19184@bicker>

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

Dan,

thanks for your patch. It is quite correct as it stands.
There is however another problem with that error path, in
that it also doesn't free the previously allocated channel.
I prefer not to carry two separate patches for that, so I'm
replacing your patch with the following augmented patch,
which I'll submit together with my other pending patches
for 2.6.36 soon:

Subject: [PATCH] isdn/gigaset: fix leaks in error path

Take care to free all previously allocated ressources in the
"out of memory" error path of the ISDN_CMD_DIAL branch.
Based on an original patch by Dan Carpenter.

Impact: bugfix
Reported-by: Dan Carpenter <error27@gmail.com>
Signed-off-by: Tilman Schmidt <tilman@imap.cc>
---
 drivers/isdn/gigaset/i4l.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c
index 1d084bb..34bca37 100644
--- a/drivers/isdn/gigaset/i4l.c
+++ b/drivers/isdn/gigaset/i4l.c
@@ -419,6 +419,8 @@ oom:
 	dev_err(bcs->cs->dev, "out of memory\n");
 	for (i = 0; i < AT_NUM; ++i)
 		kfree(commands[i]);
+	kfree(commands);
+	gigaset_free_channel(bcs);
 	return -ENOMEM;
 }
 
-- 
1.6.5.3.298.g39add

-- 
Tilman Schmidt                    E-Mail: tilman@imap.cc
Bonn, Germany
Diese Nachricht besteht zu 100% aus wiederverwerteten Bits.
Ungeöffnet mindestens haltbar bis: (siehe Rückseite)


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply related

* Re: [PATCH] net/core: use htons for skb->protocol
From: David Miller @ 2010-06-29 22:17 UTC (permalink / raw)
  To: sebastian; +Cc: netdev
In-Reply-To: <20100629163246.GA18647@Chamillionaire.breakpoint.cc>

From: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
Date: Tue, 29 Jun 2010 18:32:46 +0200

> From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> 
> This is only noticed by people that are not doing everything correct in
> the first place.
> 
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>

It's in network byte order so you should use ntohs().

^ permalink raw reply

* Re: [PATCH 1/3] gianfar: Implement workaround for eTSEC74 erratum
From: David Miller @ 2010-06-29 22:16 UTC (permalink / raw)
  To: avorontsov
  Cc: manfred.rudigier, Sandeep.Kumar, afleming, netdev, linuxppc-dev
In-Reply-To: <20100629205959.GA10905@oksana.dev.rtsoft.ru>


I really don't see any value at all to this config option,
the errata fixup code should be there all the time.

It really does no harm to be there in the cases where it isn't
used, and forcing users to turn this on is just another
obscure way to end up with an incorrect configuration.

^ permalink raw reply

* Re: [PATCH net-next-2.6 0/2] qlcnic: Driver fixes
From: David Miller @ 2010-06-29 22:12 UTC (permalink / raw)
  To: anirban.chakraborty; +Cc: netdev, ameen.rahman, Dept_NX_Linux_NIC_Driver
In-Reply-To: <alpine.OSX.2.00.1006291023350.30643@macintosh-2.qlogic.org>

From: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
Date: Tue, 29 Jun 2010 10:51:59 -0700

> Resubmitting following two patches. Please apply.

Both applied, thanks.

^ permalink raw reply

* [PATCH 3/3] gianfar: Implement workaround for eTSEC-A002 erratum
From: Anton Vorontsov @ 2010-06-29 21:00 UTC (permalink / raw)
  To: David Miller
  Cc: Manfred Rudigier, Sandeep Gopalpet, Andy Fleming, netdev,
	linuxppc-dev

MPC8313ECE says:

"If the controller receives a 1- or 2-byte frame (such as an illegal
 runt packet or a packet with RX_ER asserted) before GRS is asserted
 and does not receive any other frames, the controller may fail to set
 GRSC even when the receive logic is completely idle. Any subsequent
 receive frame that is larger than two bytes will reset the state so
 the graceful stop can complete. A MAC receiver (Rx) reset will also
 reset the state."

This patch implements the proposed workaround:

"If IEVENT[GRSC] is still not set after the timeout, read the eTSEC
 register at offset 0xD1C. If bits 7-14 are the same as bits 23-30,
 the eTSEC Rx is assumed to be idle and the Rx can be safely reset.
 If the register fields are not equal, wait for another timeout
 period and check again."

Signed-off-by: Anton Vorontsov <avorontsov@mvista.com>
---
 drivers/net/gianfar.c |   40 +++++++++++++++++++++++++++++++++++++---
 drivers/net/gianfar.h |    1 +
 2 files changed, 38 insertions(+), 3 deletions(-)

diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index f8b9693..f3da17a 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -947,6 +947,11 @@ static void gfar_detect_errata(struct gfar_private *priv)
 			(pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0))
 		priv->errata |= GFAR_ERRATA_76;
 
+	/* MPC8313 and MPC837x all rev */
+	if ((pvr == 0x80850010 && mod == 0x80b0) ||
+			(pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0))
+		priv->errata |= GFAR_ERRATA_A002;
+
 	if (priv->errata) {
 #ifdef CONFIG_GIANFAR_ERRATA
 		dev_info(dev, "enabled errata workarounds, flags: 0x%x\n",
@@ -1577,6 +1582,29 @@ static void init_registers(struct net_device *dev)
 	gfar_write(&regs->minflr, MINFLR_INIT_SETTINGS);
 }
 
+static int __gfar_is_rx_idle(struct gfar_private *priv)
+{
+	u32 res;
+
+	/*
+	 * Normaly TSEC should not hang on GRS commands, so we should
+	 * actually wait for IEVENT_GRSC flag.
+	 */
+	if (likely(!gfar_has_errata(priv, A002)))
+		return 0;
+
+	/*
+	 * Read the eTSEC register at offset 0xD1C. If bits 7-14 are
+	 * the same as bits 23-30, the eTSEC Rx is assumed to be idle
+	 * and the Rx can be safely reset.
+	 */
+	res = gfar_read((void __iomem *)priv->gfargrp[0].regs + 0xd1c);
+	res &= 0x7f807f80;
+	if ((res & 0xffff) == (res >> 16))
+		return 1;
+
+	return 0;
+}
 
 /* Halt the receive and transmit queues */
 static void gfar_halt_nodisable(struct net_device *dev)
@@ -1600,12 +1628,18 @@ static void gfar_halt_nodisable(struct net_device *dev)
 	tempval = gfar_read(&regs->dmactrl);
 	if ((tempval & (DMACTRL_GRS | DMACTRL_GTS))
 	    != (DMACTRL_GRS | DMACTRL_GTS)) {
+		int ret;
+
 		tempval |= (DMACTRL_GRS | DMACTRL_GTS);
 		gfar_write(&regs->dmactrl, tempval);
 
-		spin_event_timeout(((gfar_read(&regs->ievent) &
-			 (IEVENT_GRSC | IEVENT_GTSC)) ==
-			 (IEVENT_GRSC | IEVENT_GTSC)), -1, 0);
+		do {
+			ret = spin_event_timeout(((gfar_read(&regs->ievent) &
+				 (IEVENT_GRSC | IEVENT_GTSC)) ==
+				 (IEVENT_GRSC | IEVENT_GTSC)), 1000000, 0);
+			if (!(gfar_read(&regs->ievent) & IEVENT_GRSC))
+				ret = __gfar_is_rx_idle(priv);
+		} while (!ret);
 	}
 }
 
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index fb308c8..e0907eb 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -1028,6 +1028,7 @@ struct gfar_priv_grp {
 enum gfar_errata {
 	GFAR_ERRATA_74		= 0x01,
 	GFAR_ERRATA_76		= 0x02,
+	GFAR_ERRATA_A002	= 0x04,
 };
 
 #ifdef CONFIG_GIANFAR_ERRATA
-- 
1.7.0.5

^ permalink raw reply related

* [PATCH 2/3] gianfar: Implement workaround for eTSEC76 erratum
From: Anton Vorontsov @ 2010-06-29 21:00 UTC (permalink / raw)
  To: David Miller
  Cc: Manfred Rudigier, Sandeep Gopalpet, Andy Fleming, netdev,
	linuxppc-dev

MPC8313ECE says:

"For TOE=1 huge or jumbo frames, the data required to generate the
 checksum may exceed the 2500-byte threshold beyond which the controller
 constrains itself to one memory fetch every 256 eTSEC system clocks.

 This throttling threshold is supposed to trigger only when the
 controller has sufficient data to keep transmit active for the duration
 of the memory fetches. The state machine handling this threshold,
 however, fails to take large TOE frames into account. As a result,
 TOE=1 frames larger than 2500 bytes often see excess delays before start
 of transmission."

This patch implements the workaround as suggested by the errata
document, i.e.:

"Limit TOE=1 frames to less than 2500 bytes to avoid excess delays due to
 memory throttling.
 When using packets larger than 2700 bytes, it is recommended to turn TOE
 off."

To be sure, we limit the TOE frames to 2500 bytes, and do software
checksumming instead.

Signed-off-by: Anton Vorontsov <avorontsov@mvista.com>
---
 drivers/net/gianfar.c |   19 +++++++++++++++++++
 drivers/net/gianfar.h |    1 +
 2 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 9c85d05..f8b9693 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -942,6 +942,11 @@ static void gfar_detect_errata(struct gfar_private *priv)
 			(pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0))
 		priv->errata |= GFAR_ERRATA_74;
 
+	/* MPC8313 and MPC837x all rev */
+	if ((pvr == 0x80850010 && mod == 0x80b0) ||
+			(pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0))
+		priv->errata |= GFAR_ERRATA_76;
+
 	if (priv->errata) {
 #ifdef CONFIG_GIANFAR_ERRATA
 		dev_info(dev, "enabled errata workarounds, flags: 0x%x\n",
@@ -2018,6 +2023,20 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	unsigned int nr_frags, nr_txbds, length;
 	union skb_shared_tx *shtx;
 
+	/*
+	 * TOE=1 frames larger than 2500 bytes may see excess delays
+	 * before start of transmission.
+	 */
+	if (unlikely(gfar_has_errata(priv, 76) &&
+			skb->ip_summed == CHECKSUM_PARTIAL &&
+			skb->len > 2500)) {
+		int ret;
+
+		ret = skb_checksum_help(skb);
+		if (ret)
+			return ret;
+	}
+
 	rq = skb->queue_mapping;
 	tx_queue = priv->tx_queue[rq];
 	txq = netdev_get_tx_queue(dev, rq);
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index d1e2986..fb308c8 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -1027,6 +1027,7 @@ struct gfar_priv_grp {
 
 enum gfar_errata {
 	GFAR_ERRATA_74		= 0x01,
+	GFAR_ERRATA_76		= 0x02,
 };
 
 #ifdef CONFIG_GIANFAR_ERRATA
-- 
1.7.0.5


^ permalink raw reply related

* [PATCH 1/3] gianfar: Implement workaround for eTSEC74 erratum
From: Anton Vorontsov @ 2010-06-29 20:59 UTC (permalink / raw)
  To: David Miller
  Cc: Manfred Rudigier, Sandeep Gopalpet, Andy Fleming, netdev,
	linuxppc-dev

MPC8313ECE says:

"If MACCFG2[Huge Frame]=0 and the Ethernet controller receives frames
 which are larger than MAXFRM, the controller truncates the frames to
 length MAXFRM and marks RxBD[TR]=1 to indicate the error. The controller
 also erroneously marks RxBD[TR]=1 if the received frame length is MAXFRM
 or MAXFRM-1, even though those frames are not truncated.
 No truncation or truncation error occurs if MACCFG2[Huge Frame]=1."

There are two options to workaround the issue:

"1. Set MACCFG2[Huge Frame]=1, so no truncation occurs for invalid large
 frames. Software can determine if a frame is larger than MAXFRM by
 reading RxBD[LG] or RxBD[Data Length].

 2. Set MAXFRM to 1538 (0x602) instead of the default 1536 (0x600), so
 normal-length frames are not marked as truncated. Software can examine
 RxBD[Data Length] to determine if the frame was larger than MAXFRM-2."

This patch implements the first workaround option by setting HUGEFRAME
bit, and gfar_clean_rx_ring() already checks the RxBD[Data Length].

Signed-off-by: Anton Vorontsov <avorontsov@mvista.com>
---
 drivers/net/Kconfig   |   10 ++++++++++
 drivers/net/gianfar.c |   36 ++++++++++++++++++++++++++++++++++--
 drivers/net/gianfar.h |   11 +++++++++++
 3 files changed, 55 insertions(+), 2 deletions(-)

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index ce2fcdd..d3fcaba 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2400,6 +2400,16 @@ config GIANFAR
 	  This driver supports the Gigabit TSEC on the MPC83xx, MPC85xx,
 	  and MPC86xx family of chips, and the FEC on the 8540.
 
+config GIANFAR_ERRATA
+	bool "Gianfar Ethernet errata handling"
+	depends on GIANFAR && (PPC_MPC837x || PPC_MPC831x)
+	default y
+	help
+	  With this option enabled, gianfar driver will able to cope with
+	  some TSEC errata.
+
+	  If unsure, say Y.
+
 config UCC_GETH
 	tristate "Freescale QE Gigabit Ethernet"
 	depends on QUICC_ENGINE
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 28b53d1..9c85d05 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -85,6 +85,7 @@
 #include <linux/net_tstamp.h>
 
 #include <asm/io.h>
+#include <asm/reg.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 #include <linux/module.h>
@@ -928,6 +929,31 @@ static void gfar_init_filer_table(struct gfar_private *priv)
 	}
 }
 
+static void gfar_detect_errata(struct gfar_private *priv)
+{
+	struct device *dev = &priv->ofdev->dev;
+	unsigned int pvr = mfspr(SPRN_PVR);
+	unsigned int svr = mfspr(SPRN_SVR);
+	unsigned int mod = (svr >> 16) & 0xfff6; /* w/o E suffix */
+	unsigned int rev = svr & 0xffff;
+
+	/* MPC8313 Rev 2.0 and higher; All MPC837x */
+	if ((pvr == 0x80850010 && mod == 0x80b0 && rev >= 0x0020) ||
+			(pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0))
+		priv->errata |= GFAR_ERRATA_74;
+
+	if (priv->errata) {
+#ifdef CONFIG_GIANFAR_ERRATA
+		dev_info(dev, "enabled errata workarounds, flags: 0x%x\n",
+			priv->errata);
+#else
+		dev_warn(dev, "consider enabling CONFIG_GIANFAR_ERRATA, "
+			 "flags: 0x%x\n", priv->errata);
+		WARN_ON(1);
+#endif /* CONFIG_GIANFAR_ERRATA */
+	}
+}
+
 /* Set up the ethernet device structure, private data,
  * and anything else we need before we start */
 static int gfar_probe(struct of_device *ofdev,
@@ -960,6 +986,8 @@ static int gfar_probe(struct of_device *ofdev,
 	dev_set_drvdata(&ofdev->dev, priv);
 	regs = priv->gfargrp[0].regs;
 
+	gfar_detect_errata(priv);
+
 	/* Stop the DMA engine now, in case it was running before */
 	/* (The firmware could have used it, and left it running). */
 	gfar_halt(dev);
@@ -974,7 +1002,10 @@ static int gfar_probe(struct of_device *ofdev,
 	gfar_write(&regs->maccfg1, tempval);
 
 	/* Initialize MACCFG2. */
-	gfar_write(&regs->maccfg2, MACCFG2_INIT_SETTINGS);
+	tempval = MACCFG2_INIT_SETTINGS;
+	if (gfar_has_errata(priv, 74))
+		tempval |= MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK;
+	gfar_write(&regs->maccfg2, tempval);
 
 	/* Initialize ECNTRL */
 	gfar_write(&regs->ecntrl, ECNTRL_INIT_SETTINGS);
@@ -2300,7 +2331,8 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu)
 	 * to allow huge frames, and to check the length */
 	tempval = gfar_read(&regs->maccfg2);
 
-	if (priv->rx_buffer_size > DEFAULT_RX_BUFFER_SIZE)
+	if (priv->rx_buffer_size > DEFAULT_RX_BUFFER_SIZE ||
+			gfar_has_errata(priv, 74))
 		tempval |= (MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK);
 	else
 		tempval &= ~(MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK);
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index ac4a92e..d1e2986 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -1025,6 +1025,16 @@ struct gfar_priv_grp {
 	char int_name_er[GFAR_INT_NAME_MAX];
 };
 
+enum gfar_errata {
+	GFAR_ERRATA_74		= 0x01,
+};
+
+#ifdef CONFIG_GIANFAR_ERRATA
+#define gfar_has_errata(priv, err) ((priv)->errata & GFAR_ERRATA_##err)
+#else
+#define gfar_has_errata(priv, err) 0
+#endif /* CONFIG_GIANFAR_ERRATA */
+
 /* Struct stolen almost completely (and shamelessly) from the FCC enet source
  * (Ok, that's not so true anymore, but there is a family resemblence)
  * The GFAR buffer descriptors track the ring buffers.  The rx_bd_base
@@ -1049,6 +1059,7 @@ struct gfar_private {
 	struct device_node *node;
 	struct net_device *ndev;
 	struct of_device *ofdev;
+	enum gfar_errata errata;
 
 	struct gfar_priv_grp gfargrp[MAXGROUPS];
 	struct gfar_priv_tx_q *tx_queue[MAX_TX_QS];
-- 
1.7.0.5


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox