From ee6f0988a69b3a81bcea0871418ecf5db332149c Mon Sep 17 00:00:00 2001
From: Marc Kleine-Budde <mkl@pengutronix.de>
Date: Thu, 24 Mar 2011 02:34:32 +0000
Subject: can: c_can: disable one shot mode until driver is fixed

This patch disables the one shot mode, until the driver has been fixed and
tested to support it.

> I'm quite sure I've seen a situation where msg_obj 17 "seemed" to be
> pending, while msg_obj 18 and 19 already have been transmitted. But
> in that case, I enabled ONESHOT for the can interface, which enables
> the DA mode (automatic retransmission is disabled).

Reported-by: Jan Altenberg <jan@linutronix.de>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Kurt Van Dijck <kurt.van.dijck@eia.be>
Cc: Bhupesh Sharma <bhupesh.sharma@st.com>
Acked-by: Wolfgang Grandegger <wg@grandegger.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
 drivers/net/can/c_can/c_can.c | 14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)

(limited to 'drivers/net')

diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
index 110eda01843c..d0bffb08aef5 100644
--- a/drivers/net/can/c_can/c_can.c
+++ b/drivers/net/can/c_can/c_can.c
@@ -588,14 +588,9 @@ static void c_can_chip_config(struct net_device *dev)
 {
 	struct c_can_priv *priv = netdev_priv(dev);
 
-	if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT)
-		/* disable automatic retransmission */
-		priv->write_reg(priv, &priv->regs->control,
-				CONTROL_DISABLE_AR);
-	else
-		/* enable automatic retransmission */
-		priv->write_reg(priv, &priv->regs->control,
-				CONTROL_ENABLE_AR);
+	/* enable automatic retransmission */
+	priv->write_reg(priv, &priv->regs->control,
+			CONTROL_ENABLE_AR);
 
 	if (priv->can.ctrlmode & (CAN_CTRLMODE_LISTENONLY &
 					CAN_CTRLMODE_LOOPBACK)) {
@@ -1112,8 +1107,7 @@ struct net_device *alloc_c_can_dev(void)
 	priv->can.bittiming_const = &c_can_bittiming_const;
 	priv->can.do_set_mode = c_can_set_mode;
 	priv->can.do_get_berr_counter = c_can_get_berr_counter;
-	priv->can.ctrlmode_supported = CAN_CTRLMODE_ONE_SHOT |
-					CAN_CTRLMODE_LOOPBACK |
+	priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
 					CAN_CTRLMODE_LISTENONLY |
 					CAN_CTRLMODE_BERR_REPORTING;
 
-- 
cgit v1.2.3


From b0052b088cf0cb688b4630c1d520c57276da71a5 Mon Sep 17 00:00:00 2001
From: Marc Kleine-Budde <mkl@pengutronix.de>
Date: Thu, 24 Mar 2011 02:34:33 +0000
Subject: can: c_can_platform: fix irq check in probe

This patch fixes the check in the probe function whether a IRQ was supplied
to the driver. The original driver check the irq "struct resource *" against
<= 0. Use "platform_get_irq" instead.

Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Cc: Bhupesh Sharma <bhupesh.sharma@st.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
 drivers/net/can/c_can/c_can_platform.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

(limited to 'drivers/net')

diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
index e629b961ae2d..cc90824f2c9c 100644
--- a/drivers/net/can/c_can/c_can_platform.c
+++ b/drivers/net/can/c_can/c_can_platform.c
@@ -73,7 +73,8 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev)
 	void __iomem *addr;
 	struct net_device *dev;
 	struct c_can_priv *priv;
-	struct resource *mem, *irq;
+	struct resource *mem;
+	int irq;
 #ifdef CONFIG_HAVE_CLK
 	struct clk *clk;
 
@@ -88,8 +89,8 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev)
 
 	/* get the platform data */
 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!mem || (irq <= 0)) {
+	irq = platform_get_irq(pdev, 0);
+	if (!mem || irq <= 0) {
 		ret = -ENODEV;
 		goto exit_free_clk;
 	}
@@ -117,7 +118,7 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev)
 
 	priv = netdev_priv(dev);
 
-	dev->irq = irq->start;
+	dev->irq = irq;
 	priv->regs = addr;
 #ifdef CONFIG_HAVE_CLK
 	priv->can.clock.freq = clk_get_rate(clk);
-- 
cgit v1.2.3


From dc760b375e50a47847d4942811bd9679beeb5535 Mon Sep 17 00:00:00 2001
From: Jan Altenberg <jan@linutronix.de>
Date: Sun, 27 Mar 2011 18:24:10 -0700
Subject: can: c_can: Fix tx_bytes accounting

The current SocketCAN implementation for the Bosch c_can cell doesn't
account the TX bytes correctly, because it calls
c_can_inval_msg_object() (which clears the msg ctrl register) before
reading the DLC value:

for (/* nix */; (priv->tx_next - priv->tx_echo) > 0; priv->tx_echo++) {
        msg_obj_no = get_tx_echo_msg_obj(priv);
        c_can_inval_msg_object(dev, 0, msg_obj_no);
        val = c_can_read_reg32(priv, &priv->regs->txrqst1);
        if (!(val & (1 << msg_obj_no))) {
                can_get_echo_skb(dev,
                                msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST);
                stats->tx_bytes += priv->read_reg(priv,
                                &priv->regs->ifregs[0].msg_cntrl)
                                & IF_MCONT_DLC_MASK;
                stats->tx_packets++;
        }
}

So, we will always read 0 for the DLC value and "ifconfig" will report
*0* TX Bytes.

The fix is quite easy: Just move c_can_inval_msg_object() to the end of
the if() statement. So:
      * We only call c_can_inval_msg_object() if the message was
        actually transmitted
      * We read out the DLC value _before_ clearing the msg ctrl
        register

Signed-off-by: Jan Altenberg <jan@linutronix.de>
Acked-by: Kurt Van Dijck <kurt.van.dijck@eia.be>
Acked-by: Wolfgang Grandegger <wg@grandegger.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
 drivers/net/can/c_can/c_can.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/net')

diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
index d0bffb08aef5..31552959aed7 100644
--- a/drivers/net/can/c_can/c_can.c
+++ b/drivers/net/can/c_can/c_can.c
@@ -699,7 +699,6 @@ static void c_can_do_tx(struct net_device *dev)
 
 	for (/* nix */; (priv->tx_next - priv->tx_echo) > 0; priv->tx_echo++) {
 		msg_obj_no = get_tx_echo_msg_obj(priv);
-		c_can_inval_msg_object(dev, 0, msg_obj_no);
 		val = c_can_read_reg32(priv, &priv->regs->txrqst1);
 		if (!(val & (1 << msg_obj_no))) {
 			can_get_echo_skb(dev,
@@ -708,6 +707,7 @@ static void c_can_do_tx(struct net_device *dev)
 					&priv->regs->ifregs[0].msg_cntrl)
 					& IF_MCONT_DLC_MASK;
 			stats->tx_packets++;
+			c_can_inval_msg_object(dev, 0, msg_obj_no);
 		}
 	}
 
-- 
cgit v1.2.3


From b3cd965739b8677f6e04913aa535fa156b09e73d Mon Sep 17 00:00:00 2001
From: Stanislaw Gruszka <sgruszka@redhat.com>
Date: Fri, 25 Mar 2011 01:21:51 +0000
Subject: myri10ge: small rx_done refactoring

Avoid theoretical race condition regarding accessing dev->features
NETIF_F_LRO flag, which is illustrated below.

CPU1					CPU2

myri10ge_clean_rx_done():		myri10ge_set_flags():
					or
					myri10ge_set_rx_csum():

if (dev->features & NETIF_F_LRO)
        setup lro
					dev->features |= NETIF_F_LRO
					or
					dev->features &= ~NETIF_F_LRO;
if (dev->features & NETIF_F_LRO)
        flush lro

On the way reduce myri10ge_rx_done() number of arguments and calls by
moving mgp->small_bytes check into that function. That reduce code size

from:
   text	   data	    bss	    dec	    hex	filename
  36644	    248	    100	  36992	   9080	drivers/net/myri10ge/myri10ge.o

to:
   text	   data	    bss	    dec	    hex	filename
  36037	    247	    100	  36384	   8e20	drivers/net/myri10ge/myri10ge.o

on my i686 system, what should also make myri10ge_clean_rx_done()
being faster.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
 drivers/net/myri10ge/myri10ge.c | 37 +++++++++++++++++++++++--------------
 1 file changed, 23 insertions(+), 14 deletions(-)

(limited to 'drivers/net')

diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 1f4e8680a96a..673dc600c891 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -1312,17 +1312,26 @@ myri10ge_unmap_rx_page(struct pci_dev *pdev,
 				 * page into an skb */
 
 static inline int
-myri10ge_rx_done(struct myri10ge_slice_state *ss, struct myri10ge_rx_buf *rx,
-		 int bytes, int len, __wsum csum)
+myri10ge_rx_done(struct myri10ge_slice_state *ss, int len, __wsum csum,
+		 int lro_enabled)
 {
 	struct myri10ge_priv *mgp = ss->mgp;
 	struct sk_buff *skb;
 	struct skb_frag_struct rx_frags[MYRI10GE_MAX_FRAGS_PER_FRAME];
-	int i, idx, hlen, remainder;
+	struct myri10ge_rx_buf *rx;
+	int i, idx, hlen, remainder, bytes;
 	struct pci_dev *pdev = mgp->pdev;
 	struct net_device *dev = mgp->dev;
 	u8 *va;
 
+	if (len <= mgp->small_bytes) {
+		rx = &ss->rx_small;
+		bytes = mgp->small_bytes;
+	} else {
+		rx = &ss->rx_big;
+		bytes = mgp->big_bytes;
+	}
+
 	len += MXGEFW_PAD;
 	idx = rx->cnt & rx->mask;
 	va = page_address(rx->info[idx].page) + rx->info[idx].page_offset;
@@ -1341,7 +1350,7 @@ myri10ge_rx_done(struct myri10ge_slice_state *ss, struct myri10ge_rx_buf *rx,
 		remainder -= MYRI10GE_ALLOC_SIZE;
 	}
 
-	if (dev->features & NETIF_F_LRO) {
+	if (lro_enabled) {
 		rx_frags[0].page_offset += MXGEFW_PAD;
 		rx_frags[0].size -= MXGEFW_PAD;
 		len -= MXGEFW_PAD;
@@ -1463,7 +1472,7 @@ myri10ge_clean_rx_done(struct myri10ge_slice_state *ss, int budget)
 {
 	struct myri10ge_rx_done *rx_done = &ss->rx_done;
 	struct myri10ge_priv *mgp = ss->mgp;
-	struct net_device *netdev = mgp->dev;
+
 	unsigned long rx_bytes = 0;
 	unsigned long rx_packets = 0;
 	unsigned long rx_ok;
@@ -1474,18 +1483,18 @@ myri10ge_clean_rx_done(struct myri10ge_slice_state *ss, int budget)
 	u16 length;
 	__wsum checksum;
 
+	/*
+	 * Prevent compiler from generating more than one ->features memory
+	 * access to avoid theoretical race condition with functions that
+	 * change NETIF_F_LRO flag at runtime.
+	 */
+	bool lro_enabled = ACCESS_ONCE(mgp->dev->features) & NETIF_F_LRO;
+
 	while (rx_done->entry[idx].length != 0 && work_done < budget) {
 		length = ntohs(rx_done->entry[idx].length);
 		rx_done->entry[idx].length = 0;
 		checksum = csum_unfold(rx_done->entry[idx].checksum);
-		if (length <= mgp->small_bytes)
-			rx_ok = myri10ge_rx_done(ss, &ss->rx_small,
-						 mgp->small_bytes,
-						 length, checksum);
-		else
-			rx_ok = myri10ge_rx_done(ss, &ss->rx_big,
-						 mgp->big_bytes,
-						 length, checksum);
+		rx_ok = myri10ge_rx_done(ss, length, checksum, lro_enabled);
 		rx_packets += rx_ok;
 		rx_bytes += rx_ok * (unsigned long)length;
 		cnt++;
@@ -1497,7 +1506,7 @@ myri10ge_clean_rx_done(struct myri10ge_slice_state *ss, int budget)
 	ss->stats.rx_packets += rx_packets;
 	ss->stats.rx_bytes += rx_bytes;
 
-	if (netdev->features & NETIF_F_LRO)
+	if (lro_enabled)
 		lro_flush_all(&rx_done->lro_mgr);
 
 	/* restock receive rings if needed */
-- 
cgit v1.2.3


From f4e5bd4f5784c0608078805f29d4a4897ee482f7 Mon Sep 17 00:00:00 2001
From: "Rafael J. Wysocki" <rjw@sisk.pl>
Date: Sat, 26 Mar 2011 01:34:06 +0000
Subject: Net / jme: Do not use legacy PCI power management

The jme driver uses the legacy PCI power management, so it has to do
some PCI-specific things in its ->suspend() and ->resume() callbacks,
which isn't necessary and should better be done by the PCI
sybsystem-level power management code.  It also doesn't use device
wakeup flags correctly.

Convert jme to the new PCI power management framework and make it
let the PCI subsystem take care of all the PCI-specific aspects of
device handling during system power transitions.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
 drivers/net/jme.c | 30 ++++++++++++++++--------------
 1 file changed, 16 insertions(+), 14 deletions(-)

(limited to 'drivers/net')

diff --git a/drivers/net/jme.c b/drivers/net/jme.c
index f690474f4409..994c80939c7a 100644
--- a/drivers/net/jme.c
+++ b/drivers/net/jme.c
@@ -273,7 +273,7 @@ jme_clear_pm(struct jme_adapter *jme)
 {
 	jwrite32(jme, JME_PMCS, 0xFFFF0000 | jme->reg_pmcs);
 	pci_set_power_state(jme->pdev, PCI_D0);
-	pci_enable_wake(jme->pdev, PCI_D0, false);
+	device_set_wakeup_enable(&jme->pdev->dev, false);
 }
 
 static int
@@ -2538,6 +2538,8 @@ jme_set_wol(struct net_device *netdev,
 
 	jwrite32(jme, JME_PMCS, jme->reg_pmcs);
 
+	device_set_wakeup_enable(&jme->pdev->dev, jme->reg_pmcs);
+
 	return 0;
 }
 
@@ -3172,9 +3174,9 @@ jme_shutdown(struct pci_dev *pdev)
 }
 
 #ifdef CONFIG_PM
-static int
-jme_suspend(struct pci_dev *pdev, pm_message_t state)
+static int jme_suspend(struct device *dev)
 {
+	struct pci_dev *pdev = to_pci_dev(dev);
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct jme_adapter *jme = netdev_priv(netdev);
 
@@ -3206,22 +3208,18 @@ jme_suspend(struct pci_dev *pdev, pm_message_t state)
 	tasklet_hi_enable(&jme->rxclean_task);
 	tasklet_hi_enable(&jme->rxempty_task);
 
-	pci_save_state(pdev);
 	jme_powersave_phy(jme);
-	pci_enable_wake(jme->pdev, PCI_D3hot, true);
-	pci_set_power_state(pdev, PCI_D3hot);
 
 	return 0;
 }
 
-static int
-jme_resume(struct pci_dev *pdev)
+static int jme_resume(struct device *dev)
 {
+	struct pci_dev *pdev = to_pci_dev(dev);
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct jme_adapter *jme = netdev_priv(netdev);
 
-	jme_clear_pm(jme);
-	pci_restore_state(pdev);
+	jwrite32(jme, JME_PMCS, 0xFFFF0000 | jme->reg_pmcs);
 
 	jme_phy_on(jme);
 	if (test_bit(JME_FLAG_SSET, &jme->flags))
@@ -3238,6 +3236,13 @@ jme_resume(struct pci_dev *pdev)
 
 	return 0;
 }
+
+static SIMPLE_DEV_PM_OPS(jme_pm_ops, jme_suspend, jme_resume);
+#define JME_PM_OPS (&jme_pm_ops)
+
+#else
+
+#define JME_PM_OPS NULL
 #endif
 
 static DEFINE_PCI_DEVICE_TABLE(jme_pci_tbl) = {
@@ -3251,11 +3256,8 @@ static struct pci_driver jme_driver = {
 	.id_table       = jme_pci_tbl,
 	.probe          = jme_init_one,
 	.remove         = __devexit_p(jme_remove_one),
-#ifdef CONFIG_PM
-	.suspend        = jme_suspend,
-	.resume         = jme_resume,
-#endif /* CONFIG_PM */
 	.shutdown       = jme_shutdown,
+	.driver.pm	= JME_PM_OPS,
 };
 
 static int __init
-- 
cgit v1.2.3


From 3e49e6d520401e1d25ec8d366520aad2c01adc1c Mon Sep 17 00:00:00 2001
From: Cesar Eduardo Barros <cesarb@cesarb.net>
Date: Sat, 26 Mar 2011 05:10:30 +0000
Subject: net: use CHECKSUM_NONE instead of magic number

Two places in the kernel were doing skb->ip_summed = 0.

Change both to skb->ip_summed = CHECKSUM_NONE, which is more readable.

Signed-off-by: Cesar Eduardo Barros <cesarb@cesarb.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
 drivers/net/ksz884x.c | 2 +-
 net/ipv6/ip6mr.c      | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

(limited to 'drivers/net')

diff --git a/drivers/net/ksz884x.c b/drivers/net/ksz884x.c
index 540a8dcbcc46..7f7d5708a658 100644
--- a/drivers/net/ksz884x.c
+++ b/drivers/net/ksz884x.c
@@ -4898,7 +4898,7 @@ static netdev_tx_t netdev_tx(struct sk_buff *skb, struct net_device *dev)
 				goto unlock;
 			}
 			skb_copy_and_csum_dev(org_skb, skb->data);
-			org_skb->ip_summed = 0;
+			org_skb->ip_summed = CHECKSUM_NONE;
 			skb->len = org_skb->len;
 			copy_old_skb(org_skb, skb);
 		}
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 7ff0343e05c7..29e48593bf22 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -663,7 +663,7 @@ static int pim6_rcv(struct sk_buff *skb)
 	skb_pull(skb, (u8 *)encap - skb->data);
 	skb_reset_network_header(skb);
 	skb->protocol = htons(ETH_P_IPV6);
-	skb->ip_summed = 0;
+	skb->ip_summed = CHECKSUM_NONE;
 	skb->pkt_type = PACKET_HOST;
 
 	skb_tunnel_rx(skb, reg_dev);
-- 
cgit v1.2.3


From 27fd9de8eb9bf48e4a09c8f02d13f56e9a074a1e Mon Sep 17 00:00:00 2001
From: Javier Martinez Canillas <martinez.javier@gmail.com>
Date: Sat, 26 Mar 2011 16:42:31 +0000
Subject: tg3: use <linux/io.h> and <linux/uaccess.h> instead <asm/io.h> and
 <asm/uaccess.h>

It is proper style to include linux/foo.h instead asm/foo.h if both exist

Signed-off-by: Javier Martinez Canillas <martinez.javier@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
 drivers/net/tg3.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'drivers/net')

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index ebec88882c3b..513565503f90 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -48,9 +48,9 @@
 #include <net/ip.h>
 
 #include <asm/system.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/byteorder.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 
 #ifdef CONFIG_SPARC
 #include <asm/idprom.h>
-- 
cgit v1.2.3


From 6303e6e8da770e62a4d38f7206fe046514276d14 Mon Sep 17 00:00:00 2001
From: Javier Martinez Canillas <martinez.javier@gmail.com>
Date: Sat, 26 Mar 2011 16:42:33 +0000
Subject: tg3: Fix inline keyword usage

The correct usage is "static inline void" not "static void inline".

Signed-off-by: Javier Martinez Canillas <martinez.javier@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
 drivers/net/tg3.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/net')

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 513565503f90..73c942d85f07 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -13118,7 +13118,7 @@ done:
 
 static struct pci_dev * __devinit tg3_find_peer(struct tg3 *);
 
-static void inline vlan_features_add(struct net_device *dev, unsigned long flags)
+static inline void vlan_features_add(struct net_device *dev, unsigned long flags)
 {
 	dev->vlan_features |= flags;
 }
-- 
cgit v1.2.3


From b5845f9834d8f4c79d324bc59b99dbcf0a40f428 Mon Sep 17 00:00:00 2001
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Sun, 27 Mar 2011 01:01:26 +0000
Subject: mlx4_en: Fix loss of promiscuity

The mlx4_en driver uses the combination stop_port/start_port
in a number of places.  Unfortunately that causes any promiscuous
mode settings on the hardware to be lost.

This patch fixes that problem.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
 drivers/net/mlx4/en_netdev.c | 3 +++
 1 file changed, 3 insertions(+)

(limited to 'drivers/net')

diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c
index 5762ebde4455..4f158baa0246 100644
--- a/drivers/net/mlx4/en_netdev.c
+++ b/drivers/net/mlx4/en_netdev.c
@@ -742,6 +742,9 @@ int mlx4_en_start_port(struct net_device *dev)
 				  0, MLX4_PROT_ETH))
 		mlx4_warn(mdev, "Failed Attaching Broadcast\n");
 
+	/* Must redo promiscuous mode setup. */
+	priv->flags &= ~(MLX4_EN_FLAG_PROMISC | MLX4_EN_FLAG_MC_PROMISC);
+
 	/* Schedule multicast task to populate multicast list */
 	queue_work(mdev->workqueue, &priv->mcast_task);
 
-- 
cgit v1.2.3


From 673e63c688f43104c73aad8ea4237f7ad41fa14d Mon Sep 17 00:00:00 2001
From: Stanislaw Gruszka <sgruszka@redhat.com>
Date: Tue, 22 Mar 2011 23:54:49 +0000
Subject: net: fix ethtool->set_flags not intended -EINVAL return value

After commit d5dbda23804156ae6f35025ade5307a49d1db6d7 "ethtool: Add
support for vlan accleration.", drivers that have NETIF_F_HW_VLAN_TX,
and/or NETIF_F_HW_VLAN_RX feature, but do not allow enable/disable vlan
acceleration via ethtool set_flags, always return -EINVAL from that
function. Fix by returning -EINVAL only if requested features do not
match current settings and can not be changed by driver.

Change any driver that define ethtool->set_flags to use
ethtool_invalid_flags() to avoid similar problems in the future
(also on drivers that do not have the problem).

Tested with modified (to reproduce this bug) myri10ge driver.

Cc: stable@kernel.org # 2.6.37+
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
 drivers/net/netxen/netxen_nic_ethtool.c |  2 +-
 drivers/net/qlcnic/qlcnic_ethtool.c     |  2 +-
 drivers/net/s2io.c                      |  2 +-
 drivers/net/vmxnet3/vmxnet3_ethtool.c   |  4 ++--
 drivers/net/vxge/vxge-ethtool.c         |  4 ++--
 include/linux/ethtool.h                 |  1 +
 net/core/ethtool.c                      | 17 ++++++++++++++++-
 7 files changed, 24 insertions(+), 8 deletions(-)

(limited to 'drivers/net')

diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index 653d308e0f5d..3bdcc803ec68 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -871,7 +871,7 @@ static int netxen_nic_set_flags(struct net_device *netdev, u32 data)
 	struct netxen_adapter *adapter = netdev_priv(netdev);
 	int hw_lro;
 
-	if (data & ~ETH_FLAG_LRO)
+	if (ethtool_invalid_flags(netdev, data, ETH_FLAG_LRO))
 		return -EINVAL;
 
 	if (!(adapter->capabilities & NX_FW_CAPABILITY_HW_LRO))
diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c
index 4c14510e2a87..45b2755d6cba 100644
--- a/drivers/net/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/qlcnic/qlcnic_ethtool.c
@@ -1003,7 +1003,7 @@ static int qlcnic_set_flags(struct net_device *netdev, u32 data)
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 	int hw_lro;
 
-	if (data & ~ETH_FLAG_LRO)
+	if (ethtool_invalid_flags(netdev, data, ETH_FLAG_LRO))
 		return -EINVAL;
 
 	if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO))
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 2ad6364103ea..356e74d20b80 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -6726,7 +6726,7 @@ static int s2io_ethtool_set_flags(struct net_device *dev, u32 data)
 	int rc = 0;
 	int changed = 0;
 
-	if (data & ~ETH_FLAG_LRO)
+	if (ethtool_invalid_flags(dev, data, ETH_FLAG_LRO))
 		return -EINVAL;
 
 	if (data & ETH_FLAG_LRO) {
diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c
index 81254be85b92..51f2ef142a5b 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethtool.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c
@@ -304,8 +304,8 @@ vmxnet3_set_flags(struct net_device *netdev, u32 data)
 	u8 lro_present = (netdev->features & NETIF_F_LRO) == 0 ? 0 : 1;
 	unsigned long flags;
 
-	if (data & ~ETH_FLAG_LRO)
-		return -EOPNOTSUPP;
+	if (ethtool_invalid_flags(netdev, data, ETH_FLAG_LRO))
+		return -EINVAL;
 
 	if (lro_requested ^ lro_present) {
 		/* toggle the LRO feature*/
diff --git a/drivers/net/vxge/vxge-ethtool.c b/drivers/net/vxge/vxge-ethtool.c
index 1dd3a21b3a43..c5eb034107fd 100644
--- a/drivers/net/vxge/vxge-ethtool.c
+++ b/drivers/net/vxge/vxge-ethtool.c
@@ -1117,8 +1117,8 @@ static int vxge_set_flags(struct net_device *dev, u32 data)
 	struct vxgedev *vdev = netdev_priv(dev);
 	enum vxge_hw_status status;
 
-	if (data & ~ETH_FLAG_RXHASH)
-		return -EOPNOTSUPP;
+	if (ethtool_invalid_flags(dev, data, ETH_FLAG_RXHASH))
+		return -EINVAL;
 
 	if (!!(data & ETH_FLAG_RXHASH) == vdev->devh->config.rth_en)
 		return 0;
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index ae757bcf1280..c8fcbdd2b0e7 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -680,6 +680,7 @@ int ethtool_op_set_ufo(struct net_device *dev, u32 data);
 u32 ethtool_op_get_flags(struct net_device *dev);
 int ethtool_op_set_flags(struct net_device *dev, u32 data, u32 supported);
 void ethtool_ntuple_flush(struct net_device *dev);
+bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported);
 
 /**
  * &ethtool_ops - Alter and report network device settings
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 24bd57493c0d..74ead9eca126 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -141,9 +141,24 @@ u32 ethtool_op_get_flags(struct net_device *dev)
 }
 EXPORT_SYMBOL(ethtool_op_get_flags);
 
+/* Check if device can enable (or disable) particular feature coded in "data"
+ * argument. Flags "supported" describe features that can be toggled by device.
+ * If feature can not be toggled, it state (enabled or disabled) must match
+ * hardcoded device features state, otherwise flags are marked as invalid.
+ */
+bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported)
+{
+	u32 features = dev->features & flags_dup_features;
+	/* "data" can contain only flags_dup_features bits,
+	 * see __ethtool_set_flags */
+
+	return (features & ~supported) != (data & ~supported);
+}
+EXPORT_SYMBOL(ethtool_invalid_flags);
+
 int ethtool_op_set_flags(struct net_device *dev, u32 data, u32 supported)
 {
-	if (data & ~supported)
+	if (ethtool_invalid_flags(dev, data, supported))
 		return -EINVAL;
 
 	dev->features = ((dev->features & ~flags_dup_features) |
-- 
cgit v1.2.3


From c211c9698920d2b114bd8fbf913c8bdab3918461 Mon Sep 17 00:00:00 2001
From: Anton Blanchard <anton@samba.org>
Date: Sun, 27 Mar 2011 16:50:41 +0000
Subject: cxgb3: Apply interrupt coalescing settings to all queues

While testing the performance of different receive interrupt
coalescing settings on a single stream TCP benchmark, I noticed two
very different results. With rx-usecs=50, most of the time a
connection would hit 8280 Mbps but once in a while it would hit
9330 Mbps.

It turns out we are only applying the interrupt coalescing settings
to the first queue and whenever the rx hash would direct us onto
that queue we ran faster.

With this patch applied and rx-usecs=50, I get 9330 Mbps
consistently.

Signed-off-by: Anton Blanchard <anton@samba.org>
Acked-by: Divy Le Ray <divy@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
 drivers/net/cxgb3/cxgb3_main.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

(limited to 'drivers/net')

diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 4d538a4e9d55..910893143295 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -1983,14 +1983,20 @@ static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
 {
 	struct port_info *pi = netdev_priv(dev);
 	struct adapter *adapter = pi->adapter;
-	struct qset_params *qsp = &adapter->params.sge.qset[0];
-	struct sge_qset *qs = &adapter->sge.qs[0];
+	struct qset_params *qsp;
+	struct sge_qset *qs;
+	int i;
 
 	if (c->rx_coalesce_usecs * 10 > M_NEWTIMER)
 		return -EINVAL;
 
-	qsp->coalesce_usecs = c->rx_coalesce_usecs;
-	t3_update_qset_coalesce(qs, qsp);
+	for (i = 0; i < pi->nqsets; i++) {
+		qsp = &adapter->params.sge.qset[i];
+		qs = &adapter->sge.qs[i];
+		qsp->coalesce_usecs = c->rx_coalesce_usecs;
+		t3_update_qset_coalesce(qs, qsp);
+	}
+
 	return 0;
 }
 
-- 
cgit v1.2.3


From bc8d7da3f19191f86dcc8274cf1a3f2d6aeb0aaa Mon Sep 17 00:00:00 2001
From: Balaji G <balajig81@gmail.com>
Date: Sun, 27 Mar 2011 17:15:19 +0000
Subject: drivers net: Fix declaration ordering in inline functions.

The correct usage should be "static inline void" instead of "static void inline"

Signed-off-by: G.Balaji <balajig81@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
 drivers/net/bnx2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/net')

diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index d1865cc97313..8e6d618b5305 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -8317,7 +8317,7 @@ static const struct net_device_ops bnx2_netdev_ops = {
 #endif
 };
 
-static void inline vlan_features_add(struct net_device *dev, u32 flags)
+static inline void vlan_features_add(struct net_device *dev, u32 flags)
 {
 	dev->vlan_features |= flags;
 }
-- 
cgit v1.2.3


From 72f49050ba18959472aac723cd9d094bc3547e89 Mon Sep 17 00:00:00 2001
From: Mike Frysinger <vapier@gentoo.org>
Date: Sun, 27 Mar 2011 22:33:13 +0000
Subject: netdev: bfin_mac: document TE setting in RMII modes

The current code sometimes generates build warnings due to how it checks
the silicon revision, so clean it up and properly document things.

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
 drivers/net/bfin_mac.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

(limited to 'drivers/net')

diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index 22abfb39d813..68d45ba2d9b9 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -1237,8 +1237,17 @@ static int bfin_mac_enable(struct phy_device *phydev)
 
 	if (phydev->interface == PHY_INTERFACE_MODE_RMII) {
 		opmode |= RMII; /* For Now only 100MBit are supported */
-#if (defined(CONFIG_BF537) || defined(CONFIG_BF536)) && CONFIG_BF_REV_0_2
-		opmode |= TE;
+#if defined(CONFIG_BF537) || defined(CONFIG_BF536)
+		if (__SILICON_REVISION__ < 3) {
+			/*
+			 * This isn't publicly documented (fun times!), but in
+			 * silicon <=0.2, the RX and TX pins are clocked together.
+			 * So in order to recv, we must enable the transmit side
+			 * as well.  This will cause a spurious TX interrupt too,
+			 * but we can easily consume that.
+			 */
+			opmode |= TE;
+		}
 #endif
 	}
 
-- 
cgit v1.2.3