From 6c2da9c2182fe64b1443a75efc09e493923e86b0 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 9 Apr 2009 01:09:33 -0700 Subject: [PATCH 01/64] forcedeth: Use napi_complete() not __napi_complete(). It's not enough that forcedeth's interrupts are disabled, local cpu interrupts have to unconditionally be off when we remove the device from the poll list. Based upon a crash report from Alexander Beregalov : WARNING: at lib/list_debug.c:30 __list_add+0x89/0x90() Hardware name: list_add corruption. prev->next should be next (c06ea834), but was f70244c8. (prev=c06ea834). Modules linked in: w83627hf hwmon_vid i2c_nforce2 Pid: 1436, comm: portageq Not tainted 2.6.30-rc1 #1 Call Trace: [] warn_slowpath+0x73/0xd0 [] ? __kfree_skb+0x38/0x90 [] ? tcp_data_snd_check+0x26/0xe0 [] ? tcp_rcv_established+0x2bf/0x5e0 [] ? tcp_v4_rcv+0x47a/0x610 [] ? print_lock_contention_bug+0x1d/0x110 [] ? _spin_unlock+0x27/0x50 [] ? tcp_v4_rcv+0x54b/0x610 [] __list_add+0x89/0x90 [] __napi_schedule+0x29/0x60 [] e1000_intr+0xbd/0x1a0 [] handle_IRQ_event+0x3e/0x120 [] handle_fasteoi_irq+0x60/0xd0 [] handle_irq+0x34/0x60 [] ? rcu_irq_enter+0x8/0x40 [] do_IRQ+0x39/0xa0 [] ? skb_release_head_state+0x2c/0x60 [] common_interrupt+0x2e/0x34 [] ? list_del+0x21/0x90 [] ? trace_hardirqs_on+0xb/0x10 [] __napi_complete+0x1a/0x30 [] nv_napi_poll+0xd1/0x5c0 [] ? trace_hardirqs_on+0xb/0x10 [] net_rx_action+0x106/0x1b0 [] __do_softirq+0x6f/0x100 [] ? _spin_unlock+0x27/0x50 [] ? handle_fasteoi_irq+0x88/0xd0 [] do_softirq+0x5d/0x70 [] irq_exit+0x7d/0xa0 [] do_IRQ+0x42/0xa0 [] ? do_softirq+0x47/0x70 [] common_interrupt+0x2e/0x34 Signed-off-by: David S. Miller --- drivers/net/forcedeth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index d37465020bcc..11d5db16ed9c 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -3745,14 +3745,14 @@ static int nv_napi_poll(struct napi_struct *napi, int budget) mod_timer(&np->nic_poll, jiffies + POLL_WAIT); } spin_unlock_irqrestore(&np->lock, flags); - __napi_complete(napi); + napi_complete(napi); return rx_work; } if (rx_work < budget) { /* re-enable interrupts (msix not enabled in napi) */ - __napi_complete(napi); + napi_complete(napi); writel(np->irqmask, base + NvRegIrqMask); } From d543103a0c75edc0a7a08dfd796de67466a15dfb Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Wed, 8 Apr 2009 13:15:22 +0000 Subject: [PATCH 02/64] net: netif_device_attach/detach should start/stop all queues Currently netif_device_attach/detach are only stopping one queue. They should be starting and stopping all the queues on a given device. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- net/core/dev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index 91d792d17e09..ea8eb2214b09 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1430,7 +1430,7 @@ void netif_device_detach(struct net_device *dev) { if (test_and_clear_bit(__LINK_STATE_PRESENT, &dev->state) && netif_running(dev)) { - netif_stop_queue(dev); + netif_tx_stop_all_queues(dev); } } EXPORT_SYMBOL(netif_device_detach); @@ -1445,7 +1445,7 @@ void netif_device_attach(struct net_device *dev) { if (!test_and_set_bit(__LINK_STATE_PRESENT, &dev->state) && netif_running(dev)) { - netif_wake_queue(dev); + netif_tx_wake_all_queues(dev); __netdev_watchdog_up(dev); } } From 87c1201708381c2791caa78a2caf217778633277 Mon Sep 17 00:00:00 2001 From: PJ Waskiewicz Date: Wed, 8 Apr 2009 13:20:31 +0000 Subject: [PATCH 03/64] ixgbe: Move the LED blink code to common, since 82599 also uses it The LED blink code is common for 82599 as well. It should be moved to ixgbe_common.c so both devices can use it, and not have it duplicated. Signed-off-by: Peter P Waskiewicz Jr Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_82598.c | 59 ++------------------------------ drivers/net/ixgbe/ixgbe_82599.c | 40 ++-------------------- drivers/net/ixgbe/ixgbe_common.c | 55 +++++++++++++++++++++++++++++ drivers/net/ixgbe/ixgbe_common.h | 3 ++ 4 files changed, 62 insertions(+), 95 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index de4db0dc7879..4791238c3f6e 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -884,61 +884,6 @@ static s32 ixgbe_clear_vfta_82598(struct ixgbe_hw *hw) return 0; } -/** - * ixgbe_blink_led_start_82598 - Blink LED based on index. - * @hw: pointer to hardware structure - * @index: led number to blink - **/ -static s32 ixgbe_blink_led_start_82598(struct ixgbe_hw *hw, u32 index) -{ - ixgbe_link_speed speed = 0; - bool link_up = 0; - u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); - u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); - - /* - * Link must be up to auto-blink the LEDs on the 82598EB MAC; - * force it if link is down. - */ - hw->mac.ops.check_link(hw, &speed, &link_up, false); - - if (!link_up) { - autoc_reg |= IXGBE_AUTOC_FLU; - IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); - msleep(10); - } - - led_reg &= ~IXGBE_LED_MODE_MASK(index); - led_reg |= IXGBE_LED_BLINK(index); - IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); - IXGBE_WRITE_FLUSH(hw); - - return 0; -} - -/** - * ixgbe_blink_led_stop_82598 - Stop blinking LED based on index. - * @hw: pointer to hardware structure - * @index: led number to stop blinking - **/ -static s32 ixgbe_blink_led_stop_82598(struct ixgbe_hw *hw, u32 index) -{ - u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); - u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); - - autoc_reg &= ~IXGBE_AUTOC_FLU; - autoc_reg |= IXGBE_AUTOC_AN_RESTART; - IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); - - led_reg &= ~IXGBE_LED_MODE_MASK(index); - led_reg &= ~IXGBE_LED_BLINK(index); - led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index); - IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); - IXGBE_WRITE_FLUSH(hw); - - return 0; -} - /** * ixgbe_read_analog_reg8_82598 - Reads 8 bit Atlas analog register * @hw: pointer to hardware structure @@ -1128,8 +1073,8 @@ static struct ixgbe_mac_operations mac_ops_82598 = { .get_link_capabilities = &ixgbe_get_link_capabilities_82598, .led_on = &ixgbe_led_on_generic, .led_off = &ixgbe_led_off_generic, - .blink_led_start = &ixgbe_blink_led_start_82598, - .blink_led_stop = &ixgbe_blink_led_stop_82598, + .blink_led_start = &ixgbe_blink_led_start_generic, + .blink_led_stop = &ixgbe_blink_led_stop_generic, .set_rar = &ixgbe_set_rar_generic, .clear_rar = &ixgbe_clear_rar_generic, .set_vmdq = &ixgbe_set_vmdq_82598, diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index beae7e012609..29771fbaa42d 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -68,8 +68,6 @@ s32 ixgbe_clear_vmdq_82599(struct ixgbe_hw *hw, u32 rar, u32 vmdq); s32 ixgbe_set_vfta_82599(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on); s32 ixgbe_clear_vfta_82599(struct ixgbe_hw *hw); -s32 ixgbe_blink_led_stop_82599(struct ixgbe_hw *hw, u32 index); -s32 ixgbe_blink_led_start_82599(struct ixgbe_hw *hw, u32 index); s32 ixgbe_init_uta_tables_82599(struct ixgbe_hw *hw); s32 ixgbe_read_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 *val); s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val); @@ -990,40 +988,6 @@ s32 ixgbe_clear_vfta_82599(struct ixgbe_hw *hw) return 0; } -/** - * ixgbe_blink_led_start_82599 - Blink LED based on index. - * @hw: pointer to hardware structure - * @index: led number to blink - **/ -s32 ixgbe_blink_led_start_82599(struct ixgbe_hw *hw, u32 index) -{ - u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); - - led_reg &= ~IXGBE_LED_MODE_MASK(index); - led_reg |= IXGBE_LED_BLINK(index); - IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); - IXGBE_WRITE_FLUSH(hw); - - return 0; -} - -/** - * ixgbe_blink_led_stop_82599 - Stop blinking LED based on index. - * @hw: pointer to hardware structure - * @index: led number to stop blinking - **/ -s32 ixgbe_blink_led_stop_82599(struct ixgbe_hw *hw, u32 index) -{ - u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); - - led_reg &= ~IXGBE_LED_MODE_MASK(index); - led_reg &= ~IXGBE_LED_BLINK(index); - IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); - IXGBE_WRITE_FLUSH(hw); - - return 0; -} - /** * ixgbe_init_uta_tables_82599 - Initialize the Unicast Table Array * @hw: pointer to hardware structure @@ -1243,8 +1207,8 @@ static struct ixgbe_mac_operations mac_ops_82599 = { .get_link_capabilities = &ixgbe_get_link_capabilities_82599, .led_on = &ixgbe_led_on_generic, .led_off = &ixgbe_led_off_generic, - .blink_led_start = &ixgbe_blink_led_start_82599, - .blink_led_stop = &ixgbe_blink_led_stop_82599, + .blink_led_start = &ixgbe_blink_led_start_generic, + .blink_led_stop = &ixgbe_blink_led_stop_generic, .set_rar = &ixgbe_set_rar_generic, .clear_rar = &ixgbe_clear_rar_generic, .set_vmdq = &ixgbe_set_vmdq_82599, diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 63ab6671d08e..5567519676d5 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -2071,3 +2071,58 @@ s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval) return 0; } + +/** + * ixgbe_blink_led_start_generic - Blink LED based on index. + * @hw: pointer to hardware structure + * @index: led number to blink + **/ +s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index) +{ + ixgbe_link_speed speed = 0; + bool link_up = 0; + u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); + u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); + + /* + * Link must be up to auto-blink the LEDs; + * Force it if link is down. + */ + hw->mac.ops.check_link(hw, &speed, &link_up, false); + + if (!link_up) { + autoc_reg |= IXGBE_AUTOC_FLU; + IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); + msleep(10); + } + + led_reg &= ~IXGBE_LED_MODE_MASK(index); + led_reg |= IXGBE_LED_BLINK(index); + IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); + IXGBE_WRITE_FLUSH(hw); + + return 0; +} + +/** + * ixgbe_blink_led_stop_generic - Stop blinking LED based on index. + * @hw: pointer to hardware structure + * @index: led number to stop blinking + **/ +s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index) +{ + u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); + u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); + + autoc_reg &= ~IXGBE_AUTOC_FLU; + autoc_reg |= IXGBE_AUTOC_AN_RESTART; + IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); + + led_reg &= ~IXGBE_LED_MODE_MASK(index); + led_reg &= ~IXGBE_LED_BLINK(index); + led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index); + IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); + IXGBE_WRITE_FLUSH(hw); + + return 0; +} diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h index 24f73e719c3f..dd260890ad0a 100644 --- a/drivers/net/ixgbe/ixgbe_common.h +++ b/drivers/net/ixgbe/ixgbe_common.h @@ -76,6 +76,9 @@ s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw); s32 ixgbe_read_analog_reg8_generic(struct ixgbe_hw *hw, u32 reg, u8 *val); s32 ixgbe_write_analog_reg8_generic(struct ixgbe_hw *hw, u32 reg, u8 val); +s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index); +s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index); + #define IXGBE_WRITE_REG(a, reg, value) writel((value), ((a)->hw_addr + (reg))) #ifndef writeq From d6c519e12984d26d96b91e4482280acbba0e0a22 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Wed, 8 Apr 2009 13:20:50 +0000 Subject: [PATCH 04/64] ixgbe: only allow WOL for 82599 KX4 NIC All NICs were reporting WOL support when only the KX4 NIC is capable of supporting WOL. This patch adds a function to check for and exclude all non-WOL capable nics from enabling WOL in ethtool. Signed-off-by: Alexander Duyck Acked-by: Peter P Waskiewicz Jr Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_ethtool.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index aafc120f164e..f0a20facc650 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -943,6 +943,24 @@ static void ixgbe_get_strings(struct net_device *netdev, u32 stringset, } +static int ixgbe_wol_exclusion(struct ixgbe_adapter *adapter, + struct ethtool_wolinfo *wol) +{ + struct ixgbe_hw *hw = &adapter->hw; + int retval = 1; + + switch(hw->device_id) { + case IXGBE_DEV_ID_82599_KX4: + retval = 0; + break; + default: + wol->supported = 0; + retval = 0; + } + + return retval; +} + static void ixgbe_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) { @@ -952,7 +970,8 @@ static void ixgbe_get_wol(struct net_device *netdev, WAKE_BCAST | WAKE_MAGIC; wol->wolopts = 0; - if (!device_can_wakeup(&adapter->pdev->dev)) + if (ixgbe_wol_exclusion(adapter, wol) || + !device_can_wakeup(&adapter->pdev->dev)) return; if (adapter->wol & IXGBE_WUFC_EX) @@ -974,6 +993,9 @@ static int ixgbe_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE)) return -EOPNOTSUPP; + if (ixgbe_wol_exclusion(adapter, wol)) + return wol->wolopts ? -EOPNOTSUPP : 0; + adapter->wol = 0; if (wol->wolopts & WAKE_UCAST) From 3384901f1b1af676ccb9d75aa23a568c294c527b Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 8 Apr 2009 21:27:28 +0000 Subject: [PATCH 05/64] tr: fix leakage of device in net/802/tr.c Add dev_put() after dev_get_by_index() to avoid leakage of device. Signed-off-by: Wei Yongjun Signed-off-by: David S. Miller --- net/802/tr.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/802/tr.c b/net/802/tr.c index e7eb13084d71..e874447ad144 100644 --- a/net/802/tr.c +++ b/net/802/tr.c @@ -561,6 +561,9 @@ static int rif_seq_show(struct seq_file *seq, void *v) } seq_putc(seq, '\n'); } + + if (dev) + dev_put(dev); } return 0; } From 57401d5e36d2966247e9c06b94f5133609c8da21 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 11 Apr 2009 01:52:29 -0700 Subject: [PATCH 06/64] phy: error handling for platform_device_register_simple() platform_device_register_simple() returns ERR_PTR() and not NULL. Found by smatch (http://repo.or.cz/w/smatch.git). Compile tested. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/net/phy/fixed.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c index cf24cc34debe..e7070515d2e3 100644 --- a/drivers/net/phy/fixed.c +++ b/drivers/net/phy/fixed.c @@ -19,6 +19,7 @@ #include #include #include +#include #define MII_REGS_NUM 29 @@ -207,8 +208,8 @@ static int __init fixed_mdio_bus_init(void) int ret; pdev = platform_device_register_simple("Fixed MDIO bus", 0, NULL, 0); - if (!pdev) { - ret = -ENOMEM; + if (IS_ERR(pdev)) { + ret = PTR_ERR(pdev); goto err_pdev; } From 3ca17dfbdcaf3def764e72751619b1cc2c9760b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9guier=20R=C3=A9gis?= Date: Thu, 9 Apr 2009 01:33:57 +0000 Subject: [PATCH 07/64] via-velocity : fix compilation warning. Fix this warning: drivers/net/via-velocity.c:1924: warning: passing argument 2 of 'request_irq' from incompatible pointer type Signed-off-by: Seguier Regis Signed-off-by: David S. Miller --- drivers/net/via-velocity.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index fb53ef872df3..754a4b182c1d 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -377,7 +377,7 @@ static void velocity_print_info(struct velocity_info *vptr); static int velocity_open(struct net_device *dev); static int velocity_change_mtu(struct net_device *dev, int mtu); static int velocity_xmit(struct sk_buff *skb, struct net_device *dev); -static int velocity_intr(int irq, void *dev_instance); +static irqreturn_t velocity_intr(int irq, void *dev_instance); static void velocity_set_multi(struct net_device *dev); static struct net_device_stats *velocity_get_stats(struct net_device *dev); static int velocity_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); @@ -2215,7 +2215,7 @@ out: * efficiently as possible. */ -static int velocity_intr(int irq, void *dev_instance) +static irqreturn_t velocity_intr(int irq, void *dev_instance) { struct net_device *dev = dev_instance; struct velocity_info *vptr = netdev_priv(dev); From 48f6e8990858fc9a0ca7d3c9347e6774eb941dba Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 9 Apr 2009 05:47:41 +0000 Subject: [PATCH 08/64] net: Update maintainers Essentially all networking changes go through David Miller. Jeff Garzik no longer handles device drivers separately. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- MAINTAINERS | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index c3b215970f7b..686b3dde9353 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3177,18 +3177,12 @@ P: Paul Clements M: Paul.Clements@steeleye.com S: Maintained -NETWORK DEVICE DRIVERS -P: Jeff Garzik -M: jgarzik@pobox.com -L: netdev@vger.kernel.org -T: git kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git -S: Maintained - NETWORKING [GENERAL] -P: Networking Team -M: netdev@vger.kernel.org +P: David S. Miller +M: davem@davemloft.net L: netdev@vger.kernel.org W: http://linux-net.osdl.org/ +T: git kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6.git S: Maintained NETWORKING [IPv4/IPv6] From 499923c7a3254971873e55a1690d07d3700eea47 Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Thu, 9 Apr 2009 17:37:33 +0000 Subject: [PATCH 09/64] ipv6: Fix NULL pointer dereference with time-wait sockets Commit b2f5e7cd3dee2ed721bf0675e1a1ddebb849aee6 (ipv6: Fix conflict resolutions during ipv6 binding) introduced a regression where time-wait sockets were not treated correctly. This resulted in the following: BUG: unable to handle kernel NULL pointer dereference at 0000000000000062 IP: [] ipv4_rcv_saddr_equal+0x61/0x70 ... Call Trace: [] ipv6_rcv_saddr_equal+0x1bb/0x250 [ipv6] [] inet6_csk_bind_conflict+0x88/0xd0 [ipv6] [] inet_csk_get_port+0x1ee/0x400 [] inet6_bind+0x1cf/0x3a0 [ipv6] [] ? sockfd_lookup_light+0x3c/0xd0 [] sys_bind+0x89/0x100 [] ? trace_hardirqs_on_thunk+0x3a/0x3c [] system_call_fastpath+0x16/0x1b Tested-by: Brian Haley Tested-by: Ed Tomlinson Signed-off-by: Vlad Yasevich Signed-off-by: David S. Miller --- include/net/udp.h | 2 -- net/ipv4/udp.c | 3 +-- net/ipv6/udp.c | 6 +++++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/include/net/udp.h b/include/net/udp.h index 93dbe294d459..90e6ce56be65 100644 --- a/include/net/udp.h +++ b/include/net/udp.h @@ -124,8 +124,6 @@ static inline void udp_lib_close(struct sock *sk, long timeout) sk_common_release(sk); } -extern int ipv4_rcv_saddr_equal(const struct sock *sk1, - const struct sock *sk2); extern int udp_lib_get_port(struct sock *sk, unsigned short snum, int (*)(const struct sock*,const struct sock*)); diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index bda08a09357d..7a1d1ce22e66 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -222,7 +222,7 @@ fail: return error; } -int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2) +static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2) { struct inet_sock *inet1 = inet_sk(sk1), *inet2 = inet_sk(sk2); @@ -1823,7 +1823,6 @@ EXPORT_SYMBOL(udp_lib_getsockopt); EXPORT_SYMBOL(udp_lib_setsockopt); EXPORT_SYMBOL(udp_poll); EXPORT_SYMBOL(udp_lib_get_port); -EXPORT_SYMBOL(ipv4_rcv_saddr_equal); #ifdef CONFIG_PROC_FS EXPORT_SYMBOL(udp_proc_register); diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 6842dd2edd5b..8905712cfbb8 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -53,6 +53,8 @@ int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2) { const struct in6_addr *sk_rcv_saddr6 = &inet6_sk(sk)->rcv_saddr; const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2); + __be32 sk_rcv_saddr = inet_sk(sk)->rcv_saddr; + __be32 sk2_rcv_saddr = inet_rcv_saddr(sk2); int sk_ipv6only = ipv6_only_sock(sk); int sk2_ipv6only = inet_v6_ipv6only(sk2); int addr_type = ipv6_addr_type(sk_rcv_saddr6); @@ -60,7 +62,9 @@ int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2) /* if both are mapped, treat as IPv4 */ if (addr_type == IPV6_ADDR_MAPPED && addr_type2 == IPV6_ADDR_MAPPED) - return ipv4_rcv_saddr_equal(sk, sk2); + return (!sk2_ipv6only && + (!sk_rcv_saddr || !sk2_rcv_saddr || + sk_rcv_saddr == sk2_rcv_saddr)); if (addr_type2 == IPV6_ADDR_ANY && !(sk2_ipv6only && addr_type == IPV6_ADDR_MAPPED)) From 8c02acd79867077508ffa5ed4eb6c8c79df73a96 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Thu, 9 Apr 2009 04:46:53 +0000 Subject: [PATCH 10/64] fs_enet: convert to netdev_ops Reported-by: Subrata Modak Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/fs_enet/fs_enet-main.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index b037ce9857bf..a9cbc3191a2a 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -1019,6 +1019,22 @@ out_put_phy: #define IS_FEC(match) 0 #endif +static const struct net_device_ops fs_enet_netdev_ops = { + .ndo_open = fs_enet_open, + .ndo_stop = fs_enet_close, + .ndo_get_stats = fs_enet_get_stats, + .ndo_start_xmit = fs_enet_start_xmit, + .ndo_tx_timeout = fs_timeout, + .ndo_set_multicast_list = fs_set_multicast_list, + .ndo_do_ioctl = fs_ioctl, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, + .ndo_change_mtu = eth_change_mtu, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = fs_enet_netpoll, +#endif +}; + static int __devinit fs_enet_probe(struct of_device *ofdev, const struct of_device_id *match) { @@ -1093,22 +1109,13 @@ static int __devinit fs_enet_probe(struct of_device *ofdev, fep->tx_ring = fpi->tx_ring; fep->rx_ring = fpi->rx_ring; - ndev->open = fs_enet_open; - ndev->hard_start_xmit = fs_enet_start_xmit; - ndev->tx_timeout = fs_timeout; + ndev->netdev_ops = &fs_enet_netdev_ops; ndev->watchdog_timeo = 2 * HZ; - ndev->stop = fs_enet_close; - ndev->get_stats = fs_enet_get_stats; - ndev->set_multicast_list = fs_set_multicast_list; -#ifdef CONFIG_NET_POLL_CONTROLLER - ndev->poll_controller = fs_enet_netpoll; -#endif if (fpi->use_napi) netif_napi_add(ndev, &fep->napi, fs_enet_rx_napi, fpi->napi_weight); ndev->ethtool_ops = &fs_ethtool_ops; - ndev->do_ioctl = fs_ioctl; init_timer(&fep->phy_timer_list); From 15efc02b2625f1bb2b1970b1f4bc777590b9ed73 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Thu, 9 Apr 2009 15:56:14 +0000 Subject: [PATCH 11/64] ibm_newemac: convert to netdev_ops Reported-by: Subrata Modak Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/ibm_newemac/core.c | 41 ++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index 77e4b5b52fc8..806533c831c7 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -2686,6 +2686,32 @@ static int __devinit emac_init_config(struct emac_instance *dev) return 0; } +static const struct net_device_ops emac_netdev_ops = { + .ndo_open = emac_open, + .ndo_stop = emac_close, + .ndo_get_stats = emac_stats, + .ndo_set_multicast_list = emac_set_multicast_list, + .ndo_do_ioctl = emac_ioctl, + .ndo_tx_timeout = emac_tx_timeout, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, + .ndo_start_xmit = emac_start_xmit, + .ndo_change_mtu = eth_change_mtu, +}; + +static const struct net_device_ops emac_gige_netdev_ops = { + .ndo_open = emac_open, + .ndo_stop = emac_close, + .ndo_get_stats = emac_stats, + .ndo_set_multicast_list = emac_set_multicast_list, + .ndo_do_ioctl = emac_ioctl, + .ndo_tx_timeout = emac_tx_timeout, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, + .ndo_start_xmit = emac_start_xmit_sg, + .ndo_change_mtu = emac_change_mtu, +}; + static int __devinit emac_probe(struct of_device *ofdev, const struct of_device_id *match) { @@ -2827,23 +2853,14 @@ static int __devinit emac_probe(struct of_device *ofdev, if (err != 0) goto err_detach_tah; - /* Fill in the driver function table */ - ndev->open = &emac_open; if (dev->tah_dev) ndev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; - ndev->tx_timeout = &emac_tx_timeout; ndev->watchdog_timeo = 5 * HZ; - ndev->stop = &emac_close; - ndev->get_stats = &emac_stats; - ndev->set_multicast_list = &emac_set_multicast_list; - ndev->do_ioctl = &emac_ioctl; if (emac_phy_supports_gige(dev->phy_mode)) { - ndev->hard_start_xmit = &emac_start_xmit_sg; - ndev->change_mtu = &emac_change_mtu; + ndev->netdev_ops = &emac_gige_netdev_ops; dev->commac.ops = &emac_commac_sg_ops; - } else { - ndev->hard_start_xmit = &emac_start_xmit; - } + } else + ndev->netdev_ops = &emac_netdev_ops; SET_ETHTOOL_OPS(ndev, &emac_ethtool_ops); netif_carrier_off(ndev); From f97b1f2a416045c7a9c7e62d575a809bc32c0f1e Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Fri, 10 Apr 2009 07:59:24 +0000 Subject: [PATCH 12/64] ariadne: convert to net_device_ops On Fri, Apr 10, 2009 at 06:13:54PM +0200, Jan Ceuleers wrote: > Alexander Beregalov wrote: > > > > Signed-off-by: Alexander Beregalov > ... > > @@ -197,13 +209,8 @@ static int __devinit ariadne_init_one(struct zorro_dev *z, > > dev->mem_start = ZTWO_VADDR(mem_start); > > dev->mem_end = dev->mem_start+ARIADNE_RAM_SIZE; > > > > - dev->open = &ariadne_open; > > - dev->stop = &ariadne_close; > > - dev->hard_start_xmit = &ariadne_start_xmit; > > - dev->tx_timeout = &ariadne_tx_timeout; > > + dev->netdev_ops = &ariadne_netdev_ops;; > > We don't really need two semicolons there but I suppose that they won't > hurt. Thanks! David, please apply this patch Signed-off-by: David S. Miller --- drivers/net/ariadne.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/net/ariadne.c b/drivers/net/ariadne.c index e1d72e06f3e1..58e8d522e5bc 100644 --- a/drivers/net/ariadne.c +++ b/drivers/net/ariadne.c @@ -155,6 +155,18 @@ static struct zorro_driver ariadne_driver = { .remove = __devexit_p(ariadne_remove_one), }; +static const struct net_device_ops ariadne_netdev_ops = { + .ndo_open = ariadne_open, + .ndo_stop = ariadne_close, + .ndo_start_xmit = ariadne_start_xmit, + .ndo_tx_timeout = ariadne_tx_timeout, + .ndo_get_stats = ariadne_get_stats, + .ndo_set_multicast_list = set_multicast_list, + .ndo_validate_addr = eth_validate_addr, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, +}; + static int __devinit ariadne_init_one(struct zorro_dev *z, const struct zorro_device_id *ent) { @@ -197,13 +209,8 @@ static int __devinit ariadne_init_one(struct zorro_dev *z, dev->mem_start = ZTWO_VADDR(mem_start); dev->mem_end = dev->mem_start+ARIADNE_RAM_SIZE; - dev->open = &ariadne_open; - dev->stop = &ariadne_close; - dev->hard_start_xmit = &ariadne_start_xmit; - dev->tx_timeout = &ariadne_tx_timeout; + dev->netdev_ops = &ariadne_netdev_ops; dev->watchdog_timeo = 5*HZ; - dev->get_stats = &ariadne_get_stats; - dev->set_multicast_list = &set_multicast_list; err = register_netdev(dev); if (err) { From fefbfb1e09cbcd5ad6fd595c52aa8f01dc4e1126 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Thu, 9 Apr 2009 17:25:25 +0000 Subject: [PATCH 13/64] am79c961a: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/arm/am79c961a.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c index 4bc6901b3819..627bc75da17d 100644 --- a/drivers/net/arm/am79c961a.c +++ b/drivers/net/arm/am79c961a.c @@ -665,6 +665,20 @@ static void __init am79c961_banner(void) if (net_debug && version_printed++ == 0) printk(KERN_INFO "%s", version); } +static const struct net_device_ops am79c961_netdev_ops = { + .ndo_open = am79c961_open, + .ndo_stop = am79c961_close, + .ndo_start_xmit = am79c961_sendpacket, + .ndo_get_stats = am79c961_getstats, + .ndo_set_multicast_list = am79c961_setmulticastlist, + .ndo_tx_timeout = am79c961_timeout, + .ndo_validate_addr = eth_validate_addr, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = am79c961_poll_controller, +#endif +}; static int __init am79c961_probe(struct platform_device *pdev) { @@ -732,15 +746,7 @@ static int __init am79c961_probe(struct platform_device *pdev) if (am79c961_hw_init(dev)) goto release; - dev->open = am79c961_open; - dev->stop = am79c961_close; - dev->hard_start_xmit = am79c961_sendpacket; - dev->get_stats = am79c961_getstats; - dev->set_multicast_list = am79c961_setmulticastlist; - dev->tx_timeout = am79c961_timeout; -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = am79c961_poll_controller; -#endif + dev->netdev_ops = &am79c961_netdev_ops; ret = register_netdev(dev); if (ret == 0) { From 531c6804a4299663c7fa798ebfa9dbf843e91e0e Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Thu, 9 Apr 2009 17:27:00 +0000 Subject: [PATCH 14/64] at91_ether: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/arm/at91_ether.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c index 442938d50380..7f4bc8ae5462 100644 --- a/drivers/net/arm/at91_ether.c +++ b/drivers/net/arm/at91_ether.c @@ -577,7 +577,7 @@ static void at91ether_sethashtable(struct net_device *dev) /* * Enable/Disable promiscuous and multicast modes. */ -static void at91ether_set_rx_mode(struct net_device *dev) +static void at91ether_set_multicast_list(struct net_device *dev) { unsigned long cfg; @@ -808,7 +808,7 @@ static int at91ether_close(struct net_device *dev) /* * Transmit packet. */ -static int at91ether_tx(struct sk_buff *skb, struct net_device *dev) +static int at91ether_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct at91_private *lp = netdev_priv(dev); @@ -828,7 +828,7 @@ static int at91ether_tx(struct sk_buff *skb, struct net_device *dev) dev->trans_start = jiffies; } else { - printk(KERN_ERR "at91_ether.c: at91ether_tx() called, but device is busy!\n"); + printk(KERN_ERR "at91_ether.c: at91ether_start_xmit() called, but device is busy!\n"); return 1; /* if we return anything but zero, dev.c:1055 calls kfree_skb(skb) on this skb, he also reports -ENETDOWN and printk's, so either we free and return(0) or don't free and return 1 */ @@ -965,6 +965,21 @@ static void at91ether_poll_controller(struct net_device *dev) } #endif +static const struct net_device_ops at91ether_netdev_ops = { + .ndo_open = at91ether_open, + .ndo_stop = at91ether_close, + .ndo_start_xmit = at91ether_start_xmit, + .ndo_get_stats = at91ether_stats, + .ndo_set_multicast_list = at91ether_set_multicast_list, + .ndo_set_mac_address = set_mac_address, + .ndo_do_ioctl = at91ether_ioctl, + .ndo_validate_addr = eth_validate_addr, + .ndo_change_mtu = eth_change_mtu, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = at91ether_poll_controller, +#endif +}; + /* * Initialize the ethernet interface */ @@ -1005,17 +1020,8 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add spin_lock_init(&lp->lock); ether_setup(dev); - dev->open = at91ether_open; - dev->stop = at91ether_close; - dev->hard_start_xmit = at91ether_tx; - dev->get_stats = at91ether_stats; - dev->set_multicast_list = at91ether_set_rx_mode; - dev->set_mac_address = set_mac_address; + dev->netdev_ops = &at91ether_netdev_ops; dev->ethtool_ops = &at91ether_ethtool_ops; - dev->do_ioctl = at91ether_ioctl; -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = at91ether_poll_controller; -#endif SET_NETDEV_DEV(dev, &pdev->dev); From 9aa7b30ce36f3bfa03b878296d55e0551682de15 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Thu, 9 Apr 2009 17:28:06 +0000 Subject: [PATCH 15/64] ep93xx_eth: convert to net_device_ops Also make ep93xx_dev_alloc static. Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/arm/ep93xx_eth.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c index cc7708775da0..41736772c1dd 100644 --- a/drivers/net/arm/ep93xx_eth.c +++ b/drivers/net/arm/ep93xx_eth.c @@ -770,7 +770,18 @@ static struct ethtool_ops ep93xx_ethtool_ops = { .get_link = ep93xx_get_link, }; -struct net_device *ep93xx_dev_alloc(struct ep93xx_eth_data *data) +static const struct net_device_ops ep93xx_netdev_ops = { + .ndo_open = ep93xx_open, + .ndo_stop = ep93xx_close, + .ndo_start_xmit = ep93xx_xmit, + .ndo_get_stats = ep93xx_get_stats, + .ndo_do_ioctl = ep93xx_ioctl, + .ndo_validate_addr = eth_validate_addr, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, +}; + +static struct net_device *ep93xx_dev_alloc(struct ep93xx_eth_data *data) { struct net_device *dev; @@ -780,12 +791,8 @@ struct net_device *ep93xx_dev_alloc(struct ep93xx_eth_data *data) memcpy(dev->dev_addr, data->dev_addr, ETH_ALEN); - dev->get_stats = ep93xx_get_stats; dev->ethtool_ops = &ep93xx_ethtool_ops; - dev->hard_start_xmit = ep93xx_xmit; - dev->open = ep93xx_open; - dev->stop = ep93xx_close; - dev->do_ioctl = ep93xx_ioctl; + dev->netdev_ops = &ep93xx_netdev_ops; dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM; From 0b179e315ad61e8969b984a4ab4acc65e5ecb506 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Thu, 9 Apr 2009 17:28:55 +0000 Subject: [PATCH 16/64] ether1: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/arm/ether1.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/net/arm/ether1.c b/drivers/net/arm/ether1.c index e380de454463..edf770f639fa 100644 --- a/drivers/net/arm/ether1.c +++ b/drivers/net/arm/ether1.c @@ -991,6 +991,18 @@ static void __devinit ether1_banner(void) printk(KERN_INFO "%s", version); } +static const struct net_device_ops ether1_netdev_ops = { + .ndo_open = ether1_open, + .ndo_stop = ether1_close, + .ndo_start_xmit = ether1_sendpacket, + .ndo_get_stats = ether1_getstats, + .ndo_set_multicast_list = ether1_setmulticastlist, + .ndo_tx_timeout = ether1_timeout, + .ndo_validate_addr = eth_validate_addr, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, +}; + static int __devinit ether1_probe(struct expansion_card *ec, const struct ecard_id *id) { @@ -1031,12 +1043,7 @@ ether1_probe(struct expansion_card *ec, const struct ecard_id *id) goto free; } - dev->open = ether1_open; - dev->stop = ether1_close; - dev->hard_start_xmit = ether1_sendpacket; - dev->get_stats = ether1_getstats; - dev->set_multicast_list = ether1_setmulticastlist; - dev->tx_timeout = ether1_timeout; + dev->netdev_ops = ðer1_netdev_ops; dev->watchdog_timeo = 5 * HZ / 100; ret = register_netdev(dev); From fe146be67bd73aa35db032fe3481ca20efe17fcc Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Thu, 9 Apr 2009 17:29:38 +0000 Subject: [PATCH 17/64] ether3: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/arm/ether3.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/net/arm/ether3.c b/drivers/net/arm/ether3.c index 21a7bef12d3b..ec8a1ae1e887 100644 --- a/drivers/net/arm/ether3.c +++ b/drivers/net/arm/ether3.c @@ -770,6 +770,18 @@ static void __devinit ether3_banner(void) printk(KERN_INFO "%s", version); } +static const struct net_device_ops ether3_netdev_ops = { + .ndo_open = ether3_open, + .ndo_stop = ether3_close, + .ndo_start_xmit = ether3_sendpacket, + .ndo_get_stats = ether3_getstats, + .ndo_set_multicast_list = ether3_setmulticastlist, + .ndo_tx_timeout = ether3_timeout, + .ndo_validate_addr = eth_validate_addr, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, +}; + static int __devinit ether3_probe(struct expansion_card *ec, const struct ecard_id *id) { @@ -846,12 +858,7 @@ ether3_probe(struct expansion_card *ec, const struct ecard_id *id) goto free; } - dev->open = ether3_open; - dev->stop = ether3_close; - dev->hard_start_xmit = ether3_sendpacket; - dev->get_stats = ether3_getstats; - dev->set_multicast_list = ether3_setmulticastlist; - dev->tx_timeout = ether3_timeout; + dev->netdev_ops = ðer3_netdev_ops; dev->watchdog_timeo = 5 * HZ / 100; ret = register_netdev(dev); From ff6f63dde73e0673c09cca22c5005380dfcc79a4 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 9 Apr 2009 22:49:02 +0000 Subject: [PATCH 18/64] igb: fix unused external references introduced with sr-iov changes There were several unused external references added with the sr-iov enablement changes. This patch changes all those references to static local references. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/igb/e1000_mac.c | 2 +- drivers/net/igb/e1000_mac.h | 1 - drivers/net/igb/e1000_mbx.c | 17 ++--------------- drivers/net/igb/e1000_mbx.h | 2 -- 4 files changed, 3 insertions(+), 19 deletions(-) diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c index f4c315b5a900..472f3f124840 100644 --- a/drivers/net/igb/e1000_mac.c +++ b/drivers/net/igb/e1000_mac.c @@ -111,7 +111,7 @@ void igb_clear_vfta(struct e1000_hw *hw) * Writes value at the given offset in the register array which stores * the VLAN filter table. **/ -void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value) +static void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value) { array_wr32(E1000_VFTA, offset, value); wrfl(); diff --git a/drivers/net/igb/e1000_mac.h b/drivers/net/igb/e1000_mac.h index a34de5269637..1d690b4c9ae4 100644 --- a/drivers/net/igb/e1000_mac.h +++ b/drivers/net/igb/e1000_mac.h @@ -66,7 +66,6 @@ void igb_rar_set(struct e1000_hw *hw, u8 *addr, u32 index); s32 igb_check_alt_mac_addr(struct e1000_hw *hw); void igb_reset_adaptive(struct e1000_hw *hw); void igb_update_adaptive(struct e1000_hw *hw); -void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value); bool igb_enable_mng_pass_thru(struct e1000_hw *hw); diff --git a/drivers/net/igb/e1000_mbx.c b/drivers/net/igb/e1000_mbx.c index fe71c7ddaa05..840782fb5736 100644 --- a/drivers/net/igb/e1000_mbx.c +++ b/drivers/net/igb/e1000_mbx.c @@ -188,7 +188,7 @@ out: * returns SUCCESS if it successfully received a message notification and * copied it into the receive buffer. **/ -s32 igb_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) +static s32 igb_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) { struct e1000_mbx_info *mbx = &hw->mbx; s32 ret_val = -E1000_ERR_MBX; @@ -214,7 +214,7 @@ out: * returns SUCCESS if it successfully copied message into the buffer and * received an ack to that message within delay * timeout period **/ -s32 igb_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) +static s32 igb_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) { struct e1000_mbx_info *mbx = &hw->mbx; s32 ret_val = 0; @@ -232,19 +232,6 @@ out: return ret_val; } -/** - * e1000_init_mbx_ops_generic - Initialize NVM function pointers - * @hw: pointer to the HW structure - * - * Setups up the function pointers to no-op functions - **/ -void e1000_init_mbx_ops_generic(struct e1000_hw *hw) -{ - struct e1000_mbx_info *mbx = &hw->mbx; - mbx->ops.read_posted = igb_read_posted_mbx; - mbx->ops.write_posted = igb_write_posted_mbx; -} - static s32 igb_check_for_bit_pf(struct e1000_hw *hw, u32 mask) { u32 mbvficr = rd32(E1000_MBVFICR); diff --git a/drivers/net/igb/e1000_mbx.h b/drivers/net/igb/e1000_mbx.h index 6ec9890a8f7a..ebc02ea3f198 100644 --- a/drivers/net/igb/e1000_mbx.h +++ b/drivers/net/igb/e1000_mbx.h @@ -67,8 +67,6 @@ s32 igb_read_mbx(struct e1000_hw *, u32 *, u16, u16); s32 igb_write_mbx(struct e1000_hw *, u32 *, u16, u16); -s32 igb_read_posted_mbx(struct e1000_hw *, u32 *, u16, u16); -s32 igb_write_posted_mbx(struct e1000_hw *, u32 *, u16, u16); s32 igb_check_for_msg(struct e1000_hw *, u16); s32 igb_check_for_ack(struct e1000_hw *, u16); s32 igb_check_for_rst(struct e1000_hw *, u16); From 2d165771062cae75de26fe7bc7cb2d937ff6f1b4 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 9 Apr 2009 22:49:20 +0000 Subject: [PATCH 19/64] igbvf: fix unused external references The igbvbf driver exposed several unused extrnal references due to the fact that code was copied from igb and then some functionality was removed. This changes that so that unused functions are either removed or made static. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/igbvf/igbvf.h | 3 --- drivers/net/igbvf/netdev.c | 9 ++++++--- drivers/net/igbvf/vf.c | 2 +- drivers/net/igbvf/vf.h | 1 - 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/net/igbvf/igbvf.h b/drivers/net/igbvf/igbvf.h index 936ed2a9435f..4bff35e46871 100644 --- a/drivers/net/igbvf/igbvf.h +++ b/drivers/net/igbvf/igbvf.h @@ -321,14 +321,11 @@ extern void igbvf_set_ethtool_ops(struct net_device *); extern int igbvf_up(struct igbvf_adapter *); extern void igbvf_down(struct igbvf_adapter *); extern void igbvf_reinit_locked(struct igbvf_adapter *); -extern void igbvf_reset(struct igbvf_adapter *); extern int igbvf_setup_rx_resources(struct igbvf_adapter *, struct igbvf_ring *); extern int igbvf_setup_tx_resources(struct igbvf_adapter *, struct igbvf_ring *); extern void igbvf_free_rx_resources(struct igbvf_ring *); extern void igbvf_free_tx_resources(struct igbvf_ring *); extern void igbvf_update_stats(struct igbvf_adapter *); -extern void igbvf_set_interrupt_capability(struct igbvf_adapter *); -extern void igbvf_reset_interrupt_capability(struct igbvf_adapter *); extern unsigned int copybreak; diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index c5648420dedf..b774666ad3cf 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c @@ -52,6 +52,9 @@ static const char igbvf_driver_string[] = static const char igbvf_copyright[] = "Copyright (c) 2009 Intel Corporation."; static int igbvf_poll(struct napi_struct *napi, int budget); +static void igbvf_reset(struct igbvf_adapter *); +static void igbvf_set_interrupt_capability(struct igbvf_adapter *); +static void igbvf_reset_interrupt_capability(struct igbvf_adapter *); static struct igbvf_info igbvf_vf_info = { .mac = e1000_vfadapt, @@ -990,7 +993,7 @@ static void igbvf_configure_msix(struct igbvf_adapter *adapter) e1e_flush(); } -void igbvf_reset_interrupt_capability(struct igbvf_adapter *adapter) +static void igbvf_reset_interrupt_capability(struct igbvf_adapter *adapter) { if (adapter->msix_entries) { pci_disable_msix(adapter->pdev); @@ -1005,7 +1008,7 @@ void igbvf_reset_interrupt_capability(struct igbvf_adapter *adapter) * Attempt to configure interrupts using the best available * capabilities of the hardware and kernel. **/ -void igbvf_set_interrupt_capability(struct igbvf_adapter *adapter) +static void igbvf_set_interrupt_capability(struct igbvf_adapter *adapter) { int err = -ENOMEM; int i; @@ -1447,7 +1450,7 @@ static void igbvf_configure(struct igbvf_adapter *adapter) * set/changed during runtime. After reset the device needs to be * properly configured for Rx, Tx etc. */ -void igbvf_reset(struct igbvf_adapter *adapter) +static void igbvf_reset(struct igbvf_adapter *adapter) { struct e1000_mac_info *mac = &adapter->hw.mac; struct net_device *netdev = adapter->netdev; diff --git a/drivers/net/igbvf/vf.c b/drivers/net/igbvf/vf.c index aa246c93279d..2a4faf9ade69 100644 --- a/drivers/net/igbvf/vf.c +++ b/drivers/net/igbvf/vf.c @@ -44,7 +44,7 @@ static s32 e1000_set_vfta_vf(struct e1000_hw *, u16, bool); * e1000_init_mac_params_vf - Inits MAC params * @hw: pointer to the HW structure **/ -s32 e1000_init_mac_params_vf(struct e1000_hw *hw) +static s32 e1000_init_mac_params_vf(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; diff --git a/drivers/net/igbvf/vf.h b/drivers/net/igbvf/vf.h index ec07228f9478..1e8ce3741a67 100644 --- a/drivers/net/igbvf/vf.h +++ b/drivers/net/igbvf/vf.h @@ -259,7 +259,6 @@ struct e1000_hw { /* These functions must be implemented by drivers */ void e1000_rlpml_set_vf(struct e1000_hw *, u16); void e1000_init_function_pointers_vf(struct e1000_hw *hw); -s32 e1000_init_mac_params_vf(struct e1000_hw *hw); #endif /* _E1000_VF_H_ */ From 9ca046d57412361ac4d220b96fed7fb932616d85 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 9 Apr 2009 22:49:39 +0000 Subject: [PATCH 20/64] igb: do not check for vf_data if we didn't enable vfs The driver is currently dumping a message in the log about failing to allocate vf data when max_vfs is equal to 0. This change makes it so the error message is only displayed if we set max_vfs to a non zero value. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/igb/igb_main.c | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index db7274e62228..08c801490c72 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -1261,25 +1261,32 @@ static int __devinit igb_probe(struct pci_dev *pdev, int i; unsigned char mac_addr[ETH_ALEN]; - if (num_vfs) + if (num_vfs) { adapter->vf_data = kcalloc(num_vfs, sizeof(struct vf_data_storage), GFP_KERNEL); - if (!adapter->vf_data) { - dev_err(&pdev->dev, "Could not allocate VF private " - "data - IOV enable failed\n"); - } else { - err = pci_enable_sriov(pdev, num_vfs); - if (!err) { - adapter->vfs_allocated_count = num_vfs; - dev_info(&pdev->dev, "%d vfs allocated\n", num_vfs); - for (i = 0; i < adapter->vfs_allocated_count; i++) { - random_ether_addr(mac_addr); - igb_set_vf_mac(adapter, i, mac_addr); - } + if (!adapter->vf_data) { + dev_err(&pdev->dev, + "Could not allocate VF private data - " + "IOV enable failed\n"); } else { - kfree(adapter->vf_data); - adapter->vf_data = NULL; + err = pci_enable_sriov(pdev, num_vfs); + if (!err) { + adapter->vfs_allocated_count = num_vfs; + dev_info(&pdev->dev, + "%d vfs allocated\n", + num_vfs); + for (i = 0; + i < adapter->vfs_allocated_count; + i++) { + random_ether_addr(mac_addr); + igb_set_vf_mac(adapter, i, + mac_addr); + } + } else { + kfree(adapter->vf_data); + adapter->vf_data = NULL; + } } } } From 5a31bec014449dc9ca994e4c1dbf2802b7ca458a Mon Sep 17 00:00:00 2001 From: Brian Haley Date: Mon, 13 Apr 2009 00:11:30 -0700 Subject: [PATCH 21/64] Bonding: fix zero address hole bug in arp_ip_target list Fix a zero address hole bug in the bonding arp_ip_target list that was causing the bond to ignore ARP replies (bugz 13006). Instead of just setting the array entry to zero, we now copy any additional entries down one slot, putting the zero entry at the end. With this change we can now have all the loops that walk the array stop when they hit a zero since there will be no addresses after it. Changes are based in part on code fragment provided in kernel: bugzilla 13006: http://bugzilla.kernel.org/show_bug.cgi?id=13006 by Steve Howard Signed-off-by: Brian Haley Signed-off-by: Jay Vosburgh Signed-off-by: David S. Miller --- Documentation/networking/bonding.txt | 2 +- drivers/net/bonding/bond_main.c | 5 ++--- drivers/net/bonding/bond_sysfs.c | 14 ++++++++------ 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt index 5ede7473b425..08762750f121 100644 --- a/Documentation/networking/bonding.txt +++ b/Documentation/networking/bonding.txt @@ -1242,7 +1242,7 @@ monitoring is enabled, and vice-versa. To add ARP targets: # echo +192.168.0.100 > /sys/class/net/bond0/bonding/arp_ip_target # echo +192.168.0.101 > /sys/class/net/bond0/bonding/arp_ip_target - NOTE: up to 10 target addresses may be specified. + NOTE: up to 16 target addresses may be specified. To remove an ARP target: # echo -192.168.0.100 > /sys/class/net/bond0/bonding/arp_ip_target diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 99610f358c40..63369b6b14d4 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -2570,7 +2570,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) { if (!targets[i]) - continue; + break; pr_debug("basa: target %x\n", targets[i]); if (list_empty(&bond->vlan_list)) { pr_debug("basa: empty vlan: arp_send\n"); @@ -2677,7 +2677,6 @@ static void bond_validate_arp(struct bonding *bond, struct slave *slave, __be32 int i; __be32 *targets = bond->params.arp_targets; - targets = bond->params.arp_targets; for (i = 0; (i < BOND_MAX_ARP_TARGETS) && targets[i]; i++) { pr_debug("bva: sip %pI4 tip %pI4 t[%d] %pI4 bhti(tip) %d\n", &sip, &tip, i, &targets[i], bond_has_this_ip(bond, tip)); @@ -3303,7 +3302,7 @@ static void bond_info_show_master(struct seq_file *seq) for(i = 0; (i < BOND_MAX_ARP_TARGETS) ;i++) { if (!bond->params.arp_targets[i]) - continue; + break; if (printed) seq_printf(seq, ","); seq_printf(seq, " %pI4", &bond->params.arp_targets[i]); diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 18cf4787874c..d28731535226 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -684,17 +684,15 @@ static ssize_t bonding_store_arp_targets(struct device *d, goto out; } /* look for an empty slot to put the target in, and check for dupes */ - for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) { + for (i = 0; (i < BOND_MAX_ARP_TARGETS) && !done; i++) { if (targets[i] == newtarget) { /* duplicate */ printk(KERN_ERR DRV_NAME ": %s: ARP target %pI4 is already present\n", bond->dev->name, &newtarget); - if (done) - targets[i] = 0; ret = -EINVAL; goto out; } - if (targets[i] == 0 && !done) { + if (targets[i] == 0) { printk(KERN_INFO DRV_NAME ": %s: adding ARP target %pI4.\n", bond->dev->name, &newtarget); @@ -720,12 +718,16 @@ static ssize_t bonding_store_arp_targets(struct device *d, goto out; } - for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) { + for (i = 0; (i < BOND_MAX_ARP_TARGETS) && !done; i++) { if (targets[i] == newtarget) { + int j; printk(KERN_INFO DRV_NAME ": %s: removing ARP target %pI4.\n", bond->dev->name, &newtarget); - targets[i] = 0; + for (j = i; (j < (BOND_MAX_ARP_TARGETS-1)) && targets[j+1]; j++) + targets[j] = targets[j+1]; + + targets[j] = 0; done = 1; } } From 0d489ffb76de0fe804cf06a9d4d11fa7342d74b9 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Mon, 13 Apr 2009 14:31:51 -0700 Subject: [PATCH 22/64] tg3: fix big endian MAC address collection failure We noticed on parisc that our broadcoms all swapped MAC addresses going from 2.6.29 to 2.6.30-rc1: Apr 11 07:48:24 ion kernel: eth0: Tigon3 [partno(BCM95700A6) rev 0105] (PCI:66MHz:64-bit) MAC address 00:30:6e:4b:15:59 Apr 13 07:34:34 ion kernel: eth0: Tigon3 [partno(BCM95700A6) rev 0105] (PCI:66MHz:64-bit) MAC address 00:00:59:15:4b:6e The problem patch is: commit 6d348f2c1e0bb1cf7a494b51fc921095ead3f6ae Author: Matt Carlson Date: Wed Feb 25 14:25:52 2009 +0000 tg3: Eliminate tg3_nvram_read_swab() With the root cause being the use of memcpy to set the mac address: memcpy(&dev->dev_addr[0], ((char *)&hi) + 2, 2); memcpy(&dev->dev_addr[2], (char *)&lo, sizeof(lo)); This might work on little endian machines, but it can't on big endian ones. You have to use the original setting mechanism to be correct on all architectures. The attached patch fixes parisc. Signed-off-by: James Bottomley Signed-off-by: David S. Miller --- drivers/net/tg3.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 6a736dda3ee2..7a837c465960 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -12443,8 +12443,13 @@ static int __devinit tg3_get_device_address(struct tg3 *tp) /* Next, try NVRAM. */ if (!tg3_nvram_read_be32(tp, mac_offset + 0, &hi) && !tg3_nvram_read_be32(tp, mac_offset + 4, &lo)) { - memcpy(&dev->dev_addr[0], ((char *)&hi) + 2, 2); - memcpy(&dev->dev_addr[2], (char *)&lo, sizeof(lo)); + dev->dev_addr[0] = ((hi >> 16) & 0xff); + dev->dev_addr[1] = ((hi >> 24) & 0xff); + dev->dev_addr[2] = ((lo >> 0) & 0xff); + dev->dev_addr[3] = ((lo >> 8) & 0xff); + dev->dev_addr[4] = ((lo >> 16) & 0xff); + dev->dev_addr[5] = ((lo >> 24) & 0xff); + } /* Finally just fetch it out of the MAC control regs. */ else { From 140bc92903287cff4545e358c1651e4b7312cbd3 Mon Sep 17 00:00:00 2001 From: Sergei Poselenov Date: Tue, 7 Apr 2009 02:01:41 +0000 Subject: [PATCH 23/64] phylib: Basic support for the M88E1121R Marvell chip Add support for the Marvell M88E1121R Dual GigE PHY Signed-off-by: Yuri Tikhonov Signed-off-by: Sergei Poselenov Signed-off-by: Anatolij Gustschin Signed-off-by: David S. Miller --- drivers/net/phy/marvell.c | 41 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index eb6411c4694f..e9f436ba800f 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -69,6 +69,11 @@ #define MII_M1111_COPPER 0 #define MII_M1111_FIBER 1 +#define MII_88E1121_PHY_LED_CTRL 16 +#define MII_88E1121_PHY_LED_PAGE 3 +#define MII_88E1121_PHY_LED_DEF 0x0030 +#define MII_88E1121_PHY_PAGE 22 + #define MII_M1011_PHY_STATUS 0x11 #define MII_M1011_PHY_STATUS_1000 0x8000 #define MII_M1011_PHY_STATUS_100 0x4000 @@ -154,6 +159,30 @@ static int marvell_config_aneg(struct phy_device *phydev) return err; } +static int m88e1121_config_aneg(struct phy_device *phydev) +{ + int err, temp; + + err = phy_write(phydev, MII_BMCR, BMCR_RESET); + if (err < 0) + return err; + + err = phy_write(phydev, MII_M1011_PHY_SCR, + MII_M1011_PHY_SCR_AUTO_CROSS); + if (err < 0) + return err; + + temp = phy_read(phydev, MII_88E1121_PHY_PAGE); + + phy_write(phydev, MII_88E1121_PHY_PAGE, MII_88E1121_PHY_LED_PAGE); + phy_write(phydev, MII_88E1121_PHY_LED_CTRL, MII_88E1121_PHY_LED_DEF); + phy_write(phydev, MII_88E1121_PHY_PAGE, temp); + + err = genphy_config_aneg(phydev); + + return err; +} + static int m88e1111_config_init(struct phy_device *phydev) { int err; @@ -481,6 +510,18 @@ static struct phy_driver marvell_drivers[] = { .config_intr = &marvell_config_intr, .driver = {.owner = THIS_MODULE,}, }, + { + .phy_id = 0x01410cb0, + .phy_id_mask = 0xfffffff0, + .name = "Marvell 88E1121R", + .features = PHY_GBIT_FEATURES, + .flags = PHY_HAS_INTERRUPT, + .config_aneg = &m88e1121_config_aneg, + .read_status = &marvell_read_status, + .ack_interrupt = &marvell_ack_interrupt, + .config_intr = &marvell_config_intr, + .driver = { .owner = THIS_MODULE }, + }, { .phy_id = 0x01410cd0, .phy_id_mask = 0xfffffff0, From a8729eb302a5b5da8b0b4d29582c42648a2e0f12 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Tue, 7 Apr 2009 02:01:42 +0000 Subject: [PATCH 24/64] phylib: Allow early-out in phy_change Marvell 88E1121R Dual PHY device can be hardware-configured to use shared interrupt pin for both PHY ports. For such PHY configurations using shared PHY interrupt phy_interrupt() handler will also schedule a work for PHY port which didn't cause an interrupt. This patch adds a possibility for PHY drivers to provide did_interrupt() function which reports if the PHY (or a PHY port in a multi-PHY device) generated an interrupt. This function is called in phy_change() as phy_change() shouldn't proceed if it is invoked for a PHY which didn't cause an interrupt. So check for interrupt originator in phy_change() to allow early-out. Signed-off-by: Anatolij Gustschin Signed-off-by: David S. Miller --- drivers/net/phy/phy.c | 9 +++++++++ include/linux/phy.h | 6 ++++++ 2 files changed, 15 insertions(+) diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 3ff1f425f1bb..e3b8932d7d74 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -655,6 +655,10 @@ static void phy_change(struct work_struct *work) struct phy_device *phydev = container_of(work, struct phy_device, phy_queue); + if (phydev->drv->did_interrupt && + !phydev->drv->did_interrupt(phydev)) + goto ignore; + err = phy_disable_interrupts(phydev); if (err) @@ -681,6 +685,11 @@ static void phy_change(struct work_struct *work) return; +ignore: + atomic_dec(&phydev->irq_disable); + enable_irq(phydev->irq); + return; + irq_enable_err: disable_irq(phydev->irq); atomic_inc(&phydev->irq_disable); diff --git a/include/linux/phy.h b/include/linux/phy.h index 32cf14a4b034..97e40cb6b588 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -388,6 +388,12 @@ struct phy_driver { /* Enables or disables interrupts */ int (*config_intr)(struct phy_device *phydev); + /* + * Checks if the PHY generated an interrupt. + * For multi-PHY devices with shared PHY interrupt pin + */ + int (*did_interrupt)(struct phy_device *phydev); + /* Clears up any memory if needed */ void (*remove)(struct phy_device *phydev); From dcd07be3ffab7d20f4d498369e7526f6f4945257 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Tue, 7 Apr 2009 02:01:43 +0000 Subject: [PATCH 25/64] phylib: Add interrupt source check function to M88E1121R driver Add did_interrupt() function to check if a PHY port really caused an interrupt. This is needed in the case of shared PHY interrupt pin configuration to stop interrupt event processing for PHY ports which didn't cause an interrupt. Signed-off-by: Anatolij Gustschin Signed-off-by: David S. Miller --- drivers/net/phy/marvell.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index e9f436ba800f..7a3ec9d39a9a 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -458,6 +458,18 @@ static int marvell_read_status(struct phy_device *phydev) return 0; } +static int m88e1121_did_interrupt(struct phy_device *phydev) +{ + int imask; + + imask = phy_read(phydev, MII_M1011_IEVENT); + + if (imask & MII_M1011_IMASK_INIT) + return 1; + + return 0; +} + static struct phy_driver marvell_drivers[] = { { .phy_id = 0x01410c60, @@ -520,6 +532,7 @@ static struct phy_driver marvell_drivers[] = { .read_status = &marvell_read_status, .ack_interrupt = &marvell_ack_interrupt, .config_intr = &marvell_config_intr, + .did_interrupt = &m88e1121_did_interrupt, .driver = { .owner = THIS_MODULE }, }, { From ccd97bb01c7404ee000bb0627d1864b84fc9d904 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Sat, 11 Apr 2009 07:30:19 +0000 Subject: [PATCH 26/64] xtsonic: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/xtsonic.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/net/xtsonic.c b/drivers/net/xtsonic.c index a12a7211c982..5a4ad156f63e 100644 --- a/drivers/net/xtsonic.c +++ b/drivers/net/xtsonic.c @@ -108,6 +108,18 @@ static int xtsonic_close(struct net_device *dev) return err; } +static const struct net_device_ops xtsonic_netdev_ops = { + .ndo_open = xtsonic_open, + .ndo_stop = xtsonic_close, + .ndo_start_xmit = sonic_send_packet, + .ndo_get_stats = sonic_get_stats, + .ndo_set_multicast_list = sonic_multicast_list, + .ndo_tx_timeout = sonic_tx_timeout, + .ndo_validate_addr = eth_validate_addr, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, +}; + static int __init sonic_probe1(struct net_device *dev) { static unsigned version_printed = 0; @@ -205,12 +217,7 @@ static int __init sonic_probe1(struct net_device *dev) lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS * SONIC_BUS_SCALE(lp->dma_bitmode)); - dev->open = xtsonic_open; - dev->stop = xtsonic_close; - dev->hard_start_xmit = sonic_send_packet; - dev->get_stats = sonic_get_stats; - dev->set_multicast_list = &sonic_multicast_list; - dev->tx_timeout = sonic_tx_timeout; + dev->netdev_ops = &xtsonic_netdev_ops; dev->watchdog_timeo = TX_TIMEOUT; /* From 80ef1fc82e3feb541f9645322eab7afa778cce98 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Sat, 11 Apr 2009 07:37:59 +0000 Subject: [PATCH 27/64] tsi108_eth: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/tsi108_eth.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c index bb43e7fb2a50..0f78f99f9b20 100644 --- a/drivers/net/tsi108_eth.c +++ b/drivers/net/tsi108_eth.c @@ -1561,6 +1561,18 @@ static const struct ethtool_ops tsi108_ethtool_ops = { .set_settings = tsi108_set_settings, }; +static const struct net_device_ops tsi108_netdev_ops = { + .ndo_open = tsi108_open, + .ndo_stop = tsi108_close, + .ndo_start_xmit = tsi108_send_packet, + .ndo_set_multicast_list = tsi108_set_rx_mode, + .ndo_get_stats = tsi108_get_stats, + .ndo_do_ioctl = tsi108_do_ioctl, + .ndo_set_mac_address = tsi108_set_mac, + .ndo_validate_addr = eth_validate_addr, + .ndo_change_mtu = eth_change_mtu, +}; + static int tsi108_init_one(struct platform_device *pdev) { @@ -1616,14 +1628,8 @@ tsi108_init_one(struct platform_device *pdev) data->phy_type = einfo->phy_type; data->irq_num = einfo->irq_num; data->id = pdev->id; - dev->open = tsi108_open; - dev->stop = tsi108_close; - dev->hard_start_xmit = tsi108_send_packet; - dev->set_mac_address = tsi108_set_mac; - dev->set_multicast_list = tsi108_set_rx_mode; - dev->get_stats = tsi108_get_stats; netif_napi_add(dev, &data->napi, tsi108_poll, 64); - dev->do_ioctl = tsi108_do_ioctl; + dev->netdev_ops = &tsi108_netdev_ops; dev->ethtool_ops = &tsi108_ethtool_ops; /* Apparently, the Linux networking code won't use scatter-gather From 5a1c28b3e4aa0ac755d73363fd1c84c0063c06be Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Sat, 11 Apr 2009 07:38:54 +0000 Subject: [PATCH 28/64] tc35815: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/tc35815.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c index d91e95b237b7..0ce2db6ce2bf 100644 --- a/drivers/net/tc35815.c +++ b/drivers/net/tc35815.c @@ -862,6 +862,22 @@ static int __devinit tc35815_init_dev_addr(struct net_device *dev) return 0; } +static const struct net_device_ops tc35815_netdev_ops = { + .ndo_open = tc35815_open, + .ndo_stop = tc35815_close, + .ndo_start_xmit = tc35815_send_packet, + .ndo_get_stats = tc35815_get_stats, + .ndo_set_multicast_list = tc35815_set_multicast_list, + .ndo_tx_timeout = tc35815_tx_timeout, + .ndo_do_ioctl = tc35815_ioctl, + .ndo_validate_addr = eth_validate_addr, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = tc35815_poll_controller, +#endif +}; + static int __devinit tc35815_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -904,21 +920,12 @@ static int __devinit tc35815_init_one(struct pci_dev *pdev, ioaddr = pcim_iomap_table(pdev)[1]; /* Initialize the device structure. */ - dev->open = tc35815_open; - dev->hard_start_xmit = tc35815_send_packet; - dev->stop = tc35815_close; - dev->get_stats = tc35815_get_stats; - dev->set_multicast_list = tc35815_set_multicast_list; - dev->do_ioctl = tc35815_ioctl; + dev->netdev_ops = &tc35815_netdev_ops; dev->ethtool_ops = &tc35815_ethtool_ops; - dev->tx_timeout = tc35815_tx_timeout; dev->watchdog_timeo = TC35815_TX_TIMEOUT; #ifdef TC35815_NAPI netif_napi_add(dev, &lp->napi, tc35815_poll, NAPI_WEIGHT); #endif -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = tc35815_poll_controller; -#endif dev->irq = pdev->irq; dev->base_addr = (unsigned long)ioaddr; From 7e4fdcb99cd578c800fb7d6c298950a2938f9ca6 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Sat, 11 Apr 2009 07:39:58 +0000 Subject: [PATCH 29/64] sun3_82586: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/sun3_82586.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/net/sun3_82586.c b/drivers/net/sun3_82586.c index e0d84772771c..a39c0b9ba8b6 100644 --- a/drivers/net/sun3_82586.c +++ b/drivers/net/sun3_82586.c @@ -331,6 +331,18 @@ out: return ERR_PTR(err); } +static const struct net_device_ops sun3_82586_netdev_ops = { + .ndo_open = sun3_82586_open, + .ndo_stop = sun3_82586_close, + .ndo_start_xmit = sun3_82586_send_packet, + .ndo_set_multicast_list = set_multicast_list, + .ndo_tx_timeout = sun3_82586_timeout, + .ndo_get_stats = sun3_82586_get_stats, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, + .ndo_change_mtu = eth_change_mtu, +}; + static int __init sun3_82586_probe1(struct net_device *dev,int ioaddr) { int i, size, retval; @@ -381,13 +393,8 @@ static int __init sun3_82586_probe1(struct net_device *dev,int ioaddr) printk("Memaddr: 0x%lx, Memsize: %d, IRQ %d\n",dev->mem_start,size, dev->irq); - dev->open = sun3_82586_open; - dev->stop = sun3_82586_close; - dev->get_stats = sun3_82586_get_stats; - dev->tx_timeout = sun3_82586_timeout; + dev->netdev_ops = &sun3_82586_netdev_ops; dev->watchdog_timeo = HZ/20; - dev->hard_start_xmit = sun3_82586_send_packet; - dev->set_multicast_list = set_multicast_list; dev->if_port = 0; return 0; From ebf84eaa927be41a440fd4c8f81e1844922bc0b2 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Sat, 11 Apr 2009 07:40:49 +0000 Subject: [PATCH 30/64] sh_eth: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/sh_eth.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index 7b1882765a0c..3ab28bb00c12 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -1188,6 +1188,19 @@ out: return ret; } +static const struct net_device_ops sh_eth_netdev_ops = { + .ndo_open = sh_eth_open, + .ndo_stop = sh_eth_close, + .ndo_start_xmit = sh_eth_start_xmit, + .ndo_get_stats = sh_eth_get_stats, + .ndo_set_multicast_list = sh_eth_set_multicast_list, + .ndo_tx_timeout = sh_eth_tx_timeout, + .ndo_do_ioctl = sh_eth_do_ioctl, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, + .ndo_change_mtu = eth_change_mtu, +}; + static int sh_eth_drv_probe(struct platform_device *pdev) { int ret, i, devno = 0; @@ -1240,13 +1253,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev) mdp->edmac_endian = pd->edmac_endian; /* set function */ - ndev->open = sh_eth_open; - ndev->hard_start_xmit = sh_eth_start_xmit; - ndev->stop = sh_eth_close; - ndev->get_stats = sh_eth_get_stats; - ndev->set_multicast_list = sh_eth_set_multicast_list; - ndev->do_ioctl = sh_eth_do_ioctl; - ndev->tx_timeout = sh_eth_tx_timeout; + ndev->netdev_ops = &sh_eth_netdev_ops; ndev->watchdog_timeo = TX_TIMEOUT; mdp->post_rx = POST_RX >> (devno << 1); From c6e6d8525c415736d961a15c449d8c98cb7562d4 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Sat, 11 Apr 2009 07:41:28 +0000 Subject: [PATCH 31/64] macsonic: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/macsonic.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c index 527166e35d56..acd143da161d 100644 --- a/drivers/net/macsonic.c +++ b/drivers/net/macsonic.c @@ -167,6 +167,18 @@ static int macsonic_close(struct net_device* dev) return err; } +static const struct net_device_ops macsonic_netdev_ops = { + .ndo_open = macsonic_open, + .ndo_stop = macsonic_close, + .ndo_start_xmit = sonic_send_packet, + .ndo_set_multicast_list = sonic_multicast_list, + .ndo_tx_timeout = sonic_tx_timeout, + .ndo_get_stats = sonic_get_stats, + .ndo_validate_addr = eth_validate_addr, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, +}; + static int __init macsonic_init(struct net_device *dev) { struct sonic_local* lp = netdev_priv(dev); @@ -198,12 +210,7 @@ static int __init macsonic_init(struct net_device *dev) lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS * SONIC_BUS_SCALE(lp->dma_bitmode)); - dev->open = macsonic_open; - dev->stop = macsonic_close; - dev->hard_start_xmit = sonic_send_packet; - dev->get_stats = sonic_get_stats; - dev->set_multicast_list = &sonic_multicast_list; - dev->tx_timeout = sonic_tx_timeout; + dev->netdev_ops = &macsonic_netdev_ops; dev->watchdog_timeo = TX_TIMEOUT; /* From 5f1fa992382cf8bb82002aaf19fa03bf67330254 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Sat, 11 Apr 2009 07:42:26 +0000 Subject: [PATCH 32/64] macb: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/macb.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/net/macb.c b/drivers/net/macb.c index f50501013b1c..46073de290cf 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -1100,6 +1100,18 @@ static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) return phy_mii_ioctl(phydev, if_mii(rq), cmd); } +static const struct net_device_ops macb_netdev_ops = { + .ndo_open = macb_open, + .ndo_stop = macb_close, + .ndo_start_xmit = macb_start_xmit, + .ndo_set_multicast_list = macb_set_rx_mode, + .ndo_get_stats = macb_get_stats, + .ndo_do_ioctl = macb_ioctl, + .ndo_validate_addr = eth_validate_addr, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, +}; + static int __init macb_probe(struct platform_device *pdev) { struct eth_platform_data *pdata; @@ -1175,12 +1187,7 @@ static int __init macb_probe(struct platform_device *pdev) goto err_out_iounmap; } - dev->open = macb_open; - dev->stop = macb_close; - dev->hard_start_xmit = macb_start_xmit; - dev->get_stats = macb_get_stats; - dev->set_multicast_list = macb_set_rx_mode; - dev->do_ioctl = macb_ioctl; + dev->netdev_ops = &macb_netdev_ops; netif_napi_add(dev, &bp->napi, macb_poll, 64); dev->ethtool_ops = &macb_ethtool_ops; From d0174aea3ee8d51a82b5793c3a177efff89121fa Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Sat, 11 Apr 2009 07:43:11 +0000 Subject: [PATCH 33/64] mac89x0: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/mac89x0.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/net/mac89x0.c b/drivers/net/mac89x0.c index 380a1a54d530..384e072de2e7 100644 --- a/drivers/net/mac89x0.c +++ b/drivers/net/mac89x0.c @@ -168,6 +168,17 @@ writereg(struct net_device *dev, int portno, int value) nubus_writew(swab16(value), dev->mem_start + portno); } +static const struct net_device_ops mac89x0_netdev_ops = { + .ndo_open = net_open, + .ndo_stop = net_close, + .ndo_start_xmit = net_send_packet, + .ndo_get_stats = net_get_stats, + .ndo_set_multicast_list = set_multicast_list, + .ndo_set_mac_address = set_mac_address, + .ndo_validate_addr = eth_validate_addr, + .ndo_change_mtu = eth_change_mtu, +}; + /* Probe for the CS8900 card in slot E. We won't bother looking anywhere else until we have a really good reason to do so. */ struct net_device * __init mac89x0_probe(int unit) @@ -280,12 +291,7 @@ struct net_device * __init mac89x0_probe(int unit) printk(" IRQ %d ADDR %pM\n", dev->irq, dev->dev_addr); - dev->open = net_open; - dev->stop = net_close; - dev->hard_start_xmit = net_send_packet; - dev->get_stats = net_get_stats; - dev->set_multicast_list = &set_multicast_list; - dev->set_mac_address = &set_mac_address; + dev->netdev_ops = &mac89x0_netdev_ops; err = register_netdev(dev); if (err) From 9b6bfecd6556b9844a70147fe94dd86bb00aee97 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Sat, 11 Apr 2009 07:44:06 +0000 Subject: [PATCH 34/64] isa-skeleton: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/isa-skeleton.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/net/isa-skeleton.c b/drivers/net/isa-skeleton.c index 3126678bdd3c..73585fd8f29f 100644 --- a/drivers/net/isa-skeleton.c +++ b/drivers/net/isa-skeleton.c @@ -181,6 +181,18 @@ out: } #endif +static const struct net_device_ops netcard_netdev_ops = { + .ndo_open = net_open, + .ndo_stop = net_close, + .ndo_start_xmit = net_send_packet, + .ndo_get_stats = net_get_stats, + .ndo_set_multicast_list = set_multicast_list, + .ndo_tx_timeout = net_tx_timeout, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, + .ndo_change_mtu = eth_change_mtu, +}; + /* * This is the real probe routine. Linux has a history of friendly device * probes on the ISA bus. A good device probes avoids doing writes, and @@ -303,13 +315,7 @@ static int __init netcard_probe1(struct net_device *dev, int ioaddr) np = netdev_priv(dev); spin_lock_init(&np->lock); - dev->open = net_open; - dev->stop = net_close; - dev->hard_start_xmit = net_send_packet; - dev->get_stats = net_get_stats; - dev->set_multicast_list = &set_multicast_list; - - dev->tx_timeout = &net_tx_timeout; + dev->netdev_ops = &netcard_netdev_ops; dev->watchdog_timeo = MY_TX_TIMEOUT; err = register_netdev(dev); From 2b1425421212e38c7dade357abaf8804fe236ade Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Sat, 11 Apr 2009 07:44:55 +0000 Subject: [PATCH 35/64] ioc3-eth: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/ioc3-eth.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c index cbc63ff13add..c5593f4665a4 100644 --- a/drivers/net/ioc3-eth.c +++ b/drivers/net/ioc3-eth.c @@ -1214,6 +1214,19 @@ static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3) } #endif +static const struct net_device_ops ioc3_netdev_ops = { + .ndo_open = ioc3_open, + .ndo_stop = ioc3_close, + .ndo_start_xmit = ioc3_start_xmit, + .ndo_tx_timeout = ioc3_timeout, + .ndo_get_stats = ioc3_get_stats, + .ndo_set_multicast_list = ioc3_set_multicast_list, + .ndo_do_ioctl = ioc3_ioctl, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = ioc3_set_mac_address, + .ndo_change_mtu = eth_change_mtu, +}; + static int __devinit ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -1310,15 +1323,8 @@ static int __devinit ioc3_probe(struct pci_dev *pdev, ioc3_get_eaddr(ip); /* The IOC3-specific entries in the device structure. */ - dev->open = ioc3_open; - dev->hard_start_xmit = ioc3_start_xmit; - dev->tx_timeout = ioc3_timeout; dev->watchdog_timeo = 5 * HZ; - dev->stop = ioc3_close; - dev->get_stats = ioc3_get_stats; - dev->do_ioctl = ioc3_ioctl; - dev->set_multicast_list = ioc3_set_multicast_list; - dev->set_mac_address = ioc3_set_mac_address; + dev->netdev_ops = &ioc3_netdev_ops; dev->ethtool_ops = &ioc3_ethtool_ops; dev->features = NETIF_F_IP_CSUM; From a95c2a3b9d6615ef6fad69fbb787a208ad6506b3 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Sat, 11 Apr 2009 07:45:55 +0000 Subject: [PATCH 36/64] eth_v10: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/cris/eth_v10.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c index c9806c58b2fd..7a18dc7e5c7f 100644 --- a/drivers/net/cris/eth_v10.c +++ b/drivers/net/cris/eth_v10.c @@ -257,6 +257,23 @@ struct transceiver_ops transceivers[] = struct transceiver_ops* transceiver = &transceivers[0]; +static const struct net_device_ops e100_netdev_ops = { + .ndo_open = e100_open, + .ndo_stop = e100_close, + .ndo_start_xmit = e100_send_packet, + .ndo_tx_timeout = e100_tx_timeout, + .ndo_get_stats = e100_get_stats, + .ndo_set_multicast_list = set_multicast_list, + .ndo_do_ioctl = e100_ioctl, + .ndo_set_mac_address = e100_set_mac_address, + .ndo_validate_addr = eth_validate_addr, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_config = e100_set_config, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = e100_netpoll, +#endif +}; + #define tx_done(dev) (*R_DMA_CH0_CMD == 0) /* @@ -300,19 +317,8 @@ etrax_ethernet_init(void) /* fill in our handlers so the network layer can talk to us in the future */ - dev->open = e100_open; - dev->hard_start_xmit = e100_send_packet; - dev->stop = e100_close; - dev->get_stats = e100_get_stats; - dev->set_multicast_list = set_multicast_list; - dev->set_mac_address = e100_set_mac_address; dev->ethtool_ops = &e100_ethtool_ops; - dev->do_ioctl = e100_ioctl; - dev->set_config = e100_set_config; - dev->tx_timeout = e100_tx_timeout; -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = e100_netpoll; -#endif + dev->netdev_ops = &e100_netdev_ops; spin_lock_init(&np->lock); spin_lock_init(&np->led_lock); From 03a980d162eb48a79ce21d47f45b9ec7d9db20e9 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Mon, 13 Apr 2009 15:41:50 -0700 Subject: [PATCH 37/64] be2net: fix for default setting of pause auto-negotiation This patch fixes the default value of pause auto-negotiation supported by PCS. Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be_ethtool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index 04f4b73fa8d8..9592f22e4c8c 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c @@ -319,7 +319,7 @@ be_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd) be_cmd_get_flow_control(&adapter->ctrl, &ecmd->tx_pause, &ecmd->rx_pause); - ecmd->autoneg = AUTONEG_ENABLE; + ecmd->autoneg = 0; } static int @@ -328,7 +328,7 @@ be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd) struct be_adapter *adapter = netdev_priv(netdev); int status; - if (ecmd->autoneg != AUTONEG_ENABLE) + if (ecmd->autoneg != 0) return -EINVAL; status = be_cmd_set_flow_control(&adapter->ctrl, ecmd->tx_pause, From 1db9e29bb0ff3c9366e8a50fb09ca8dbc364bfd6 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 13 Apr 2009 04:41:01 +0000 Subject: [PATCH 38/64] gro: Normalise skb before bypassing GRO on netpoll VLAN path Hi: gro: Normalise skb before bypassing GRO on netpoll VLAN path When we detect netpoll RX on the GRO VLAN path we bail out and call the normal VLAN receive handler. However, the packet needs to be normalised by calling eth_type_trans since that's what the normal path expects (normally the GRO path does the fixup). This patch adds the necessary call to vlan_gro_frags. Signed-off-by: Herbert Xu Thanks, Signed-off-by: David S. Miller --- net/8021q/vlan_core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index 654e45f5719d..c67fe6f75653 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c @@ -121,8 +121,10 @@ int vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp, if (!skb) return NET_RX_DROP; - if (netpoll_rx_on(skb)) + if (netpoll_rx_on(skb)) { + skb->protocol = eth_type_trans(skb, skb->dev); return vlan_hwaccel_receive_skb(skb, grp, vlan_tci); + } return napi_frags_finish(napi, skb, vlan_gro_common(napi, grp, vlan_tci, skb)); From 1a31f2042e938f1b467aa3d807cc5666352bf8a3 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 13 Apr 2009 18:12:57 -0700 Subject: [PATCH 39/64] netsched: Allow meta match on vlan tag on receive When vlan acceleration is used on receive, the vlan tag is maintained outside of the skb data. The existing vlan tag match only works on TX path because it uses vlan_get_tag which tests for VLAN_HW_TX_ACCEL. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/sched/em_meta.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index 72cf86e3c090..fad596bf32d7 100644 --- a/net/sched/em_meta.c +++ b/net/sched/em_meta.c @@ -176,8 +176,10 @@ META_COLLECTOR(var_dev) META_COLLECTOR(int_vlan_tag) { - unsigned short uninitialized_var(tag); - if (vlan_get_tag(skb, &tag) < 0) + unsigned short tag; + + tag = vlan_tx_tag_get(skb); + if (!tag && __vlan_get_tag(skb, &tag)) *err = -1; else dst->value = tag; From 86bcebafc5e7f5163ccf828792fe694b112ed6fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Tue, 14 Apr 2009 02:08:53 -0700 Subject: [PATCH 40/64] tcp: fix >2 iw selection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A long-standing feature in tcp_init_metrics() is such that any of its goto reset prevents call to tcp_init_cwnd(). Signed-off-by: Ilpo Järvinen Signed-off-by: David S. Miller --- net/ipv4/tcp_input.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 2bc8e27a163d..c96a6bb25430 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -928,6 +928,8 @@ static void tcp_init_metrics(struct sock *sk) tcp_set_rto(sk); if (inet_csk(sk)->icsk_rto < TCP_TIMEOUT_INIT && !tp->rx_opt.saw_tstamp) goto reset; + +cwnd: tp->snd_cwnd = tcp_init_cwnd(tp, dst); tp->snd_cwnd_stamp = tcp_time_stamp; return; @@ -942,6 +944,7 @@ reset: tp->mdev = tp->mdev_max = tp->rttvar = TCP_TIMEOUT_INIT; inet_csk(sk)->icsk_rto = TCP_TIMEOUT_INIT; } + goto cwnd; } static void tcp_update_reordering(struct sock *sk, const int metric, From 0eca93bcf73e5939053a94f7c48f8d6fe6199e00 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 14 Apr 2009 02:09:43 -0700 Subject: [PATCH 41/64] tun: Fix crash with non-GSO users When I made the tun driver use non-linear packets as the preferred option, it broke non-GSO users because they would end up allocating a completely non-linear packet, which triggers a crash when we call eth_type_trans. This patch reverts non-GSO users to using linear packets and adds a check to ensure that GSO users can't cause crashes in the same way. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- drivers/net/tun.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/tun.c b/drivers/net/tun.c index a1b0697340ba..16716aef184c 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -518,7 +518,7 @@ static inline struct sk_buff *tun_alloc_skb(struct tun_struct *tun, int err; /* Under a page? Don't bother with paged skb. */ - if (prepad + len < PAGE_SIZE) + if (prepad + len < PAGE_SIZE || !linear) linear = len; skb = sock_alloc_send_pskb(sk, prepad + linear, len - linear, noblock, @@ -565,7 +565,8 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) { align = NET_IP_ALIGN; - if (unlikely(len < ETH_HLEN)) + if (unlikely(len < ETH_HLEN || + (gso.hdr_len && gso.hdr_len < ETH_HLEN))) return -EINVAL; } From ce8632ba6b3ed0bf2efa98672e2808de34250389 Mon Sep 17 00:00:00 2001 From: Yang Hongyang Date: Mon, 13 Apr 2009 15:51:00 +0000 Subject: [PATCH 42/64] ipv6:remove useless check After switch (rthdr->type) {...},the check below is completely useless.Because: if the type is 2,then hdrlen must be 2 and segments_left must be 1,clearly the check is redundant;if the type is not 2,then goto sticky_done,the check is useless too. Signed-off-by: Yang Hongyang Reviewed-by: Shan Wei Signed-off-by: David S. Miller --- net/ipv6/ipv6_sockglue.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index d31df0f4bc9a..a7fdf9a27f15 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -380,10 +380,6 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, default: goto sticky_done; } - - if ((rthdr->hdrlen & 1) || - (rthdr->hdrlen >> 1) != rthdr->segments_left) - goto sticky_done; } retv = 0; From fc59f9a3bf8096a1f68a8b78ada7a0e0ab9236b2 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 14 Apr 2009 15:11:06 -0700 Subject: [PATCH 43/64] gro: Restore correct value to gso_size Since everybody has been focusing on baremetal GRO performance no one noticed when I added a bug that zapped gso_size for all GRO packets. This only gets picked up when you forward the skb out of an interface. Thanks to Mark Wagner for noticing this bug when testing kvm. Reported-by: Mark Wagner Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- net/core/dev.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index ea8eb2214b09..343883f65ea7 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2328,8 +2328,10 @@ static int napi_gro_complete(struct sk_buff *skb) struct list_head *head = &ptype_base[ntohs(type) & PTYPE_HASH_MASK]; int err = -ENOENT; - if (NAPI_GRO_CB(skb)->count == 1) + if (NAPI_GRO_CB(skb)->count == 1) { + skb_shinfo(skb)->gso_size = 0; goto out; + } rcu_read_lock(); list_for_each_entry_rcu(ptype, head, list) { @@ -2348,7 +2350,6 @@ static int napi_gro_complete(struct sk_buff *skb) } out: - skb_shinfo(skb)->gso_size = 0; return netif_receive_skb(skb); } From d119b3927994e3d620d6adb0dd1ea6bf24427875 Mon Sep 17 00:00:00 2001 From: Michal Schmidt Date: Tue, 14 Apr 2009 15:16:55 -0700 Subject: [PATCH 44/64] skge: fix occasional BUG during MTU change The BUG_ON(skge->tx_ring.to_use != skge->tx_ring.to_clean) in skge_up() was sometimes observed when setting MTU. skge_down() disables the TX queue, but then reenables it by mistake via skge_tx_clean(). Fix it by moving the waking of the queue from skge_tx_clean() to the other caller. And to make sure start_xmit is not in progress on another CPU, skge_down() should call netif_tx_disable(). The bug was reported to me by Jiri Jilek whose Debian system sometimes failed to boot. He tested the patch and the bug did not happen anymore. Signed-off-by: Michal Schmidt Acked-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/skge.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/skge.c b/drivers/net/skge.c index b8978d4af1b7..c11cdd08ec57 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -2674,7 +2674,7 @@ static int skge_down(struct net_device *dev) if (netif_msg_ifdown(skge)) printk(KERN_INFO PFX "%s: disabling interface\n", dev->name); - netif_stop_queue(dev); + netif_tx_disable(dev); if (hw->chip_id == CHIP_ID_GENESIS && hw->phy_type == SK_PHY_XMAC) del_timer_sync(&skge->link_timer); @@ -2881,7 +2881,6 @@ static void skge_tx_clean(struct net_device *dev) } skge->tx_ring.to_clean = e; - netif_wake_queue(dev); } static void skge_tx_timeout(struct net_device *dev) @@ -2893,6 +2892,7 @@ static void skge_tx_timeout(struct net_device *dev) skge_write8(skge->hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_STOP); skge_tx_clean(dev); + netif_wake_queue(dev); } static int skge_change_mtu(struct net_device *dev, int new_mtu) From 32e8f9a8d9bd52b59b512f8e5177b08e8edfd58b Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Tue, 14 Apr 2009 15:18:00 -0700 Subject: [PATCH 45/64] ehea: Fix incomplete conversion to net_device_ops Reported-by: Subrata Modak Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/ehea/ehea_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index ac0c5b438e0a..604c844d0769 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -3080,7 +3080,8 @@ static const struct net_device_ops ehea_netdev_ops = { .ndo_change_mtu = ehea_change_mtu, .ndo_vlan_rx_register = ehea_vlan_rx_register, .ndo_vlan_rx_add_vid = ehea_vlan_rx_add_vid, - .ndo_vlan_rx_kill_vid = ehea_vlan_rx_kill_vid + .ndo_vlan_rx_kill_vid = ehea_vlan_rx_kill_vid, + .ndo_tx_timeout = ehea_tx_watchdog, }; struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, @@ -3142,7 +3143,6 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, | NETIF_F_HIGHDMA | NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER | NETIF_F_LLTX; - dev->tx_timeout = &ehea_tx_watchdog; dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT; INIT_WORK(&port->reset_task, ehea_reset_port); From df26fd2c594a0876b4e6b802dee7753024e484d9 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Tue, 14 Apr 2009 16:38:49 -0700 Subject: [PATCH 46/64] e1000/e1000: fix compile warning e1000/e1000e compile report a possible unused variable, fix that for now. Shortly after this a small refactor and bug fix will follow in the same code. Signed-off-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/e1000/e1000_main.c | 2 +- drivers/net/e1000e/netdev.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index ddc5c533e89c..4cd8b25c7ed7 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -3834,7 +3834,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter, struct e1000_buffer *buffer_info; unsigned int i, eop; unsigned int count = 0; - bool cleaned; + bool cleaned = false; unsigned int total_tx_bytes=0, total_tx_packets=0; i = tx_ring->next_to_clean; diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 409b58cad0e5..3b0f08773800 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -621,7 +621,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter) struct e1000_buffer *buffer_info; unsigned int i, eop; unsigned int count = 0; - bool cleaned; + bool cleaned = false; unsigned int total_tx_bytes = 0, total_tx_packets = 0; i = tx_ring->next_to_clean; From 2690f8d62e98779c71625dba9a0fd525d8b2263d Mon Sep 17 00:00:00 2001 From: Jay Vosburgh Date: Tue, 14 Apr 2009 16:53:14 -0700 Subject: [PATCH 47/64] bonding: Remove debug printk Remove debug printk I accidently left in as part of commit: commit 6146b1a4da98377e4abddc91ba5856bef8f23f1e Author: Jay Vosburgh Date: Tue Nov 4 17:51:15 2008 -0800 bonding: Fix ALB mode to balance traffic on VLANs Reported by Duncan Gibb Signed-off-by: Jay Vosburgh Signed-off-by: David S. Miller --- drivers/net/bonding/bond_alb.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 8dc6fbb9a41e..553a89919778 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -370,8 +370,6 @@ static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct if (arp->op_code == htons(ARPOP_REPLY)) { /* update rx hash table for this ARP */ - printk("rar: update orig %s bond_dev %s\n", orig_dev->name, - bond_dev->name); bond = netdev_priv(bond_dev); rlb_update_entry_from_arp(bond, arp); pr_debug("Server received an ARP Reply from client\n"); From 718cff1eec595ce6ab0635b8160a51ee37d9268d Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 14 Apr 2009 19:47:46 -0700 Subject: [PATCH 48/64] sfc: Match calls to netif_napi_add() and netif_napi_del() sfc could call netif_napi_add() multiple times for the same napi_struct, corrupting the list of napi_structs for the associated device and leading to a busy-loop on device removal. Move the call to netif_napi_add() and add a call to netif_napi_del() in the obvious places. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/efx.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index dee23b159df2..7269a426051c 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -448,9 +448,6 @@ static void efx_init_channels(struct efx_nic *efx) WARN_ON(channel->rx_pkt != NULL); efx_rx_strategy(channel); - - netif_napi_add(channel->napi_dev, &channel->napi_str, - efx_poll, napi_weight); } } @@ -1321,6 +1318,8 @@ static int efx_init_napi(struct efx_nic *efx) efx_for_each_channel(channel, efx) { channel->napi_dev = efx->net_dev; + netif_napi_add(channel->napi_dev, &channel->napi_str, + efx_poll, napi_weight); } return 0; } @@ -1330,6 +1329,8 @@ static void efx_fini_napi(struct efx_nic *efx) struct efx_channel *channel; efx_for_each_channel(channel, efx) { + if (channel->napi_dev) + netif_napi_del(&channel->napi_str); channel->napi_dev = NULL; } } From 239795adf7f1a40cf0be0e05544d37706c9b4cf9 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 14 Apr 2009 19:48:34 -0700 Subject: [PATCH 49/64] sfc: Use correct macro to set event bitfield falcon_sim_phy_event() used EFX_OWORD_FIELD, which operates on bitfields in 128-bit values, on an event, which is a 64-bit value. This should be harmless - these macros always use little-endian ordering, so it would read and write back the following 8 bytes unchanged - but it is obviously wrong. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index d4629ab2c614..466a8abb0053 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -1176,9 +1176,9 @@ void falcon_sim_phy_event(struct efx_nic *efx) EFX_POPULATE_QWORD_1(phy_event, EV_CODE, GLOBAL_EV_DECODE); if (EFX_IS10G(efx)) - EFX_SET_OWORD_FIELD(phy_event, XG_PHY_INTR, 1); + EFX_SET_QWORD_FIELD(phy_event, XG_PHY_INTR, 1); else - EFX_SET_OWORD_FIELD(phy_event, G_PHY0_INTR, 1); + EFX_SET_QWORD_FIELD(phy_event, G_PHY0_INTR, 1); falcon_generate_event(&efx->channel[0], &phy_event); } From 6fd4777a1fec1f7757b5a302ad3fdcc1eae2abba Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 14 Apr 2009 20:28:00 -0700 Subject: [PATCH 50/64] Revert "rose: zero length frame filtering in af_rose.c" This reverts commit 244f46ae6e9e18f6fc0be7d1f49febde4762c34b. Alan Cox did the research, and just like the other radio protocols zero-length frames have meaning because at the top level ROSE is X.25 PLP. So this zero-length filtering is invalid. Signed-off-by: David S. Miller --- net/rose/af_rose.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 0f36e8d59b29..877a7f65f707 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c @@ -1072,10 +1072,6 @@ static int rose_sendmsg(struct kiocb *iocb, struct socket *sock, unsigned char *asmptr; int n, size, qbit = 0; - /* ROSE empty frame has no meaning : don't send */ - if (len == 0) - return 0; - if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR|MSG_CMSG_COMPAT)) return -EINVAL; @@ -1273,12 +1269,6 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock, skb_reset_transport_header(skb); copied = skb->len; - /* ROSE empty frame has no meaning : ignore it */ - if (copied == 0) { - skb_free_datagram(sk, skb); - return copied; - } - if (copied > size) { copied = size; msg->msg_flags |= MSG_TRUNC; From 95615d90a321349709c80091f2a9cb284757ff0d Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Tue, 14 Apr 2009 21:53:48 -0700 Subject: [PATCH 51/64] ixgbe: fix tx queue index Don't do the num_tx_queues based masking on calculating tx queue index. 1) num_tx_queues is not always power-of-2, because it also depends on the online cpu numbers. So the masking could be a performance bug on a 6 cpu system. 2) queue_mapping will be limited by real_num_tx_queues=num_tx_queues in the generic netdev function set_cur_queue_map(). So the bound limiting here is not necessary. Signed-off-by: Wu Fengguang Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 9ef128ae6458..862dd344533e 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -4342,7 +4342,7 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev) int count = 0; unsigned int f; - r_idx = (adapter->num_tx_queues - 1) & skb->queue_mapping; + r_idx = skb->queue_mapping; tx_ring = &adapter->tx_ring[r_idx]; if (adapter->vlgrp && vlan_tx_tag_present(skb)) { From af22ab1bd20e9dedf3a37cc1d401ef8bbd587ef0 Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Tue, 14 Apr 2009 21:54:07 -0700 Subject: [PATCH 52/64] ixgbe: update real_num_tx_queues on changing num_rx_queues Move the update of real_num_tx_queues from ixgbe_acquire_msix_vectors() to ixgbe_set_num_queues(), to ensure it be always in sync with num_tx_queues. Signed-off-by: Wu Fengguang Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 862dd344533e..11fd153da85f 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2723,17 +2723,21 @@ static inline bool ixgbe_set_rss_queues(struct ixgbe_adapter *adapter) **/ static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter) { - /* Start with base case */ - adapter->num_rx_queues = 1; - adapter->num_tx_queues = 1; - #ifdef CONFIG_IXGBE_DCB if (ixgbe_set_dcb_queues(adapter)) - return; + goto done; #endif if (ixgbe_set_rss_queues(adapter)) - return; + goto done; + + /* fallback to base case */ + adapter->num_rx_queues = 1; + adapter->num_tx_queues = 1; + +done: + /* Notify the stack of the (possibly) reduced Tx Queue count. */ + adapter->netdev->real_num_tx_queues = adapter->num_tx_queues; } static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter, @@ -2992,9 +2996,6 @@ try_msi: } out: - /* Notify the stack of the (possibly) reduced Tx Queue count. */ - adapter->netdev->real_num_tx_queues = adapter->num_tx_queues; - return err; } From 444f1a92702adb9865dd8f509fd55bca9c46a78e Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Tue, 14 Apr 2009 18:30:21 +0000 Subject: [PATCH 53/64] a2065: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/a2065.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/net/a2065.c b/drivers/net/a2065.c index d0d0c2fee054..02f64d578641 100644 --- a/drivers/net/a2065.c +++ b/drivers/net/a2065.c @@ -692,6 +692,17 @@ static struct zorro_driver a2065_driver = { .remove = __devexit_p(a2065_remove_one), }; +static const struct net_device_ops lance_netdev_ops = { + .ndo_open = lance_open, + .ndo_stop = lance_close, + .ndo_start_xmit = lance_start_xmit, + .ndo_tx_timeout = lance_tx_timeout, + .ndo_set_multicast_list = lance_set_multicast, + .ndo_validate_addr = eth_validate_addr, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, +}; + static int __devinit a2065_init_one(struct zorro_dev *z, const struct zorro_device_id *ent) { @@ -753,12 +764,8 @@ static int __devinit a2065_init_one(struct zorro_dev *z, priv->rx_ring_mod_mask = RX_RING_MOD_MASK; priv->tx_ring_mod_mask = TX_RING_MOD_MASK; - dev->open = &lance_open; - dev->stop = &lance_close; - dev->hard_start_xmit = &lance_start_xmit; - dev->tx_timeout = &lance_tx_timeout; + dev->netdev_ops = &lance_netdev_ops; dev->watchdog_timeo = 5*HZ; - dev->set_multicast_list = &lance_set_multicast; dev->dma = 0; init_timer(&priv->multicast_timer); From 8e7678fe0992a6107041b839b08ac4af55d41592 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Tue, 14 Apr 2009 18:30:22 +0000 Subject: [PATCH 54/64] atarilance: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/atarilance.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/net/atarilance.c b/drivers/net/atarilance.c index 2d81f6afcb58..5425ab0c38c0 100644 --- a/drivers/net/atarilance.c +++ b/drivers/net/atarilance.c @@ -453,6 +453,16 @@ static noinline int __init addr_accessible(volatile void *regp, int wordflag, return( ret ); } +static const struct net_device_ops lance_netdev_ops = { + .ndo_open = lance_open, + .ndo_stop = lance_close, + .ndo_start_xmit = lance_start_xmit, + .ndo_set_multicast_list = set_multicast_list, + .ndo_set_mac_address = lance_set_mac_address, + .ndo_tx_timeout = lance_tx_timeout, + .ndo_validate_addr = eth_validate_addr, + .ndo_change_mtu = eth_change_mtu, +}; static unsigned long __init lance_probe1( struct net_device *dev, struct lance_addr *init_rec ) @@ -623,15 +633,9 @@ static unsigned long __init lance_probe1( struct net_device *dev, if (did_version++ == 0) DPRINTK( 1, ( version )); - /* The LANCE-specific entries in the device structure. */ - dev->open = &lance_open; - dev->hard_start_xmit = &lance_start_xmit; - dev->stop = &lance_close; - dev->set_multicast_list = &set_multicast_list; - dev->set_mac_address = &lance_set_mac_address; + dev->netdev_ops = &lance_netdev_ops; /* XXX MSch */ - dev->tx_timeout = lance_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; return( 1 ); From d9a92cee09d2748ec5d4126cf36083a3a8a5449d Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Tue, 14 Apr 2009 18:30:23 +0000 Subject: [PATCH 55/64] au1000: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/au1000_eth.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index 4274e4ac963b..d58c105fc779 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c @@ -1004,12 +1004,12 @@ static void au1000_tx_timeout(struct net_device *dev) netif_wake_queue(dev); } -static void set_rx_mode(struct net_device *dev) +static void au1000_multicast_list(struct net_device *dev) { struct au1000_private *aup = netdev_priv(dev); if (au1000_debug > 4) - printk("%s: set_rx_mode: flags=%x\n", dev->name, dev->flags); + printk("%s: au1000_multicast_list: flags=%x\n", dev->name, dev->flags); if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ aup->mac->control |= MAC_PROMISCUOUS; @@ -1047,6 +1047,18 @@ static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) return phy_mii_ioctl(aup->phy_dev, if_mii(rq), cmd); } +static const struct net_device_ops au1000_netdev_ops = { + .ndo_open = au1000_open, + .ndo_stop = au1000_close, + .ndo_start_xmit = au1000_tx, + .ndo_set_multicast_list = au1000_multicast_list, + .ndo_do_ioctl = au1000_ioctl, + .ndo_tx_timeout = au1000_tx_timeout, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, + .ndo_change_mtu = eth_change_mtu, +}; + static struct net_device * au1000_probe(int port_num) { static unsigned version_printed = 0; @@ -1197,13 +1209,8 @@ static struct net_device * au1000_probe(int port_num) dev->base_addr = base; dev->irq = irq; - dev->open = au1000_open; - dev->hard_start_xmit = au1000_tx; - dev->stop = au1000_close; - dev->set_multicast_list = &set_rx_mode; - dev->do_ioctl = &au1000_ioctl; + dev->netdev_ops = &au1000_netdev_ops; SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops); - dev->tx_timeout = au1000_tx_timeout; dev->watchdog_timeo = ETH_TX_TIMEOUT; /* From 149da651bf340b796576a078574fbb49ed09b7ae Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Tue, 14 Apr 2009 18:30:24 +0000 Subject: [PATCH 56/64] bfin_mac: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/bfin_mac.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c index 9afe8092dfc4..9f971ed6b58d 100644 --- a/drivers/net/bfin_mac.c +++ b/drivers/net/bfin_mac.c @@ -979,6 +979,20 @@ static int bfin_mac_open(struct net_device *dev) return 0; } +static const struct net_device_ops bfin_mac_netdev_ops = { + .ndo_open = bfin_mac_open, + .ndo_stop = bfin_mac_close, + .ndo_start_xmit = bfin_mac_hard_start_xmit, + .ndo_set_mac_address = bfin_mac_set_mac_address, + .ndo_tx_timeout = bfin_mac_timeout, + .ndo_set_multicast_list = bfin_mac_set_multicast_list, + .ndo_validate_addr = eth_validate_addr, + .ndo_change_mtu = eth_change_mtu, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = bfin_mac_poll, +#endif +}; + /* * * this makes the board clean up everything that it can @@ -1086,15 +1100,7 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev) /* Fill in the fields of the device structure with ethernet values. */ ether_setup(ndev); - ndev->open = bfin_mac_open; - ndev->stop = bfin_mac_close; - ndev->hard_start_xmit = bfin_mac_hard_start_xmit; - ndev->set_mac_address = bfin_mac_set_mac_address; - ndev->tx_timeout = bfin_mac_timeout; - ndev->set_multicast_list = bfin_mac_set_multicast_list; -#ifdef CONFIG_NET_POLL_CONTROLLER - ndev->poll_controller = bfin_mac_poll; -#endif + ndev->netdev_ops = &bfin_mac_netdev_ops; ndev->ethtool_ops = &bfin_mac_ethtool_ops; spin_lock_init(&lp->lock); From ad5a24e0944e8a0869d1f685ce4ae739adf84a87 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Tue, 14 Apr 2009 18:30:25 +0000 Subject: [PATCH 57/64] declance: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/declance.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/net/declance.c b/drivers/net/declance.c index 861c867fca87..b62405a69180 100644 --- a/drivers/net/declance.c +++ b/drivers/net/declance.c @@ -1010,6 +1010,17 @@ static void lance_set_multicast_retry(unsigned long _opaque) lance_set_multicast(dev); } +static const struct net_device_ops lance_netdev_ops = { + .ndo_open = lance_open, + .ndo_stop = lance_close, + .ndo_start_xmit = lance_start_xmit, + .ndo_tx_timeout = lance_tx_timeout, + .ndo_set_multicast_list = lance_set_multicast, + .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, +}; + static int __init dec_lance_probe(struct device *bdev, const int type) { static unsigned version_printed; @@ -1223,12 +1234,8 @@ static int __init dec_lance_probe(struct device *bdev, const int type) printk(", addr = %pM, irq = %d\n", dev->dev_addr, dev->irq); - dev->open = &lance_open; - dev->stop = &lance_close; - dev->hard_start_xmit = &lance_start_xmit; - dev->tx_timeout = &lance_tx_timeout; + dev->netdev_ops = &lance_netdev_ops; dev->watchdog_timeo = 5*HZ; - dev->set_multicast_list = &lance_set_multicast; /* lp->ll is the location of the registers for lance card */ lp->ll = ll; From 636d2f68a0814d84de26c021b2c15e3b4ffa29de Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 15 Apr 2009 02:26:49 -0700 Subject: [PATCH 58/64] myr10ge: again fix lro_gen_skb() alignment Add LRO alignment initially committed in 621544eb8c3beaa859c75850f816dd9b056a00a3 ("[LRO]: fix lro_gen_skb() alignment") and removed in 0dcffac1a329be69bab0ac604bf7283737108e68 ("myri10ge: add multislices support") during conversion to multi-slice. Signed-off-by: Stanislaw Gruszka Signed-off-by: David S. Miller --- drivers/net/myri10ge/myri10ge.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 9eed126a82f0..f2c4a665e93f 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -2447,6 +2447,7 @@ static int myri10ge_open(struct net_device *dev) lro_mgr->lro_arr = ss->rx_done.lro_desc; lro_mgr->get_frag_header = myri10ge_get_frag_header; lro_mgr->max_aggr = myri10ge_lro_max_pkts; + lro_mgr->frag_align_pad = 2; if (lro_mgr->max_aggr > MAX_SKB_FRAGS) lro_mgr->max_aggr = MAX_SKB_FRAGS; From cbea270714faae389c48c2901ee7988ecd62f664 Mon Sep 17 00:00:00 2001 From: Markus Brunner Date: Wed, 15 Apr 2009 02:35:40 -0700 Subject: [PATCH 59/64] gianfar: stop send queue before resetting gianfar After a transmit timed out, the reset task will be called, which will free the allocated resources(stop_gfar). If gfar_poll will be called before the resources get allocated again gfar_clean_tx_ring will call dev_kfree_skb_any(NULL). Example crash: ops: Kernel access of bad area, sig: 11 [#1] PREEMPT RSBBA100 Modules linked in: NIP: c01a10c4 LR: c013b254 CTR: c013c038 REGS: c02e7d20 TRAP: 0300 Not tainted (2.6.27.20) MSR: 00001032 CR: 24000082 XER: 20000000 DAR: 000000a0, DSISR: 20000000 TASK = c02ce578[0] 'swapper' THREAD: c02e6000 GPR00: 000000a0 c02e7dd0 c02ce578 00000000 00000040 00000001 c02ec1c0 00001032 GPR08: c080d1e0 df9ea800 00000000 00000000 24000082 ffffffff 0404f000 00000000 GPR16: ffffffbf ffffffff ffffffff ffdff7ff ffffffff c02d0fd4 00100100 00200200 GPR24: c031220c 00000001 00000001 00000000 00000000 df849800 ff109000 df849b80 NIP [c01a10c4] dev_kfree_skb_irq+0x18/0x70 LR [c013b254] gfar_clean_tx_ring+0x70/0x11c Call Trace: [c02e7dd0] [c003e978] update_wall_time+0x730/0x744 (unreliable) [c02e7df0] [c013b254] gfar_clean_tx_ring+0x70/0x11c [c02e7e10] [c013c07c] gfar_poll+0x44/0x150 [c02e7e30] [c01a064c] net_rx_action+0xa8/0x19c [c02e7e70] [c00251d4] __do_softirq+0x64/0xc0 [c02e7e90] [c0006384] do_softirq+0x40/0x58 [c02e7ea0] [c00250a8] irq_exit+0x40/0x9c [c02e7eb0] [c000642c] do_IRQ+0x90/0xac [c02e7ec0] [c0010ab4] ret_from_except+0x0/0x14 --- Exception: 501 at cpu_idle+0x9c/0xf8 LR = cpu_idle+0x9c/0xf8 [c02e7f80] [c0009820] cpu_idle+0x58/0xf8 (unreliable) [c02e7fa0] [c01fb8c8] __got2_end+0x7c/0x90 [c02e7fc0] [c026c794] start_kernel+0x2c0/0x2d4 [c02e7ff0] [00003438] 0x3438 Instruction dump: 7fa00124 80010024 bba10014 38210020 7c0803a6 4e800020 9421ffe0 7c0802a6 7c6b1b78 90010024 380300a0 bfa10014 <7d200028> 3129ffff 7d20012d 40a2fff4 Kernel panic - not syncing: Fatal exception in interrupt This Patch calls netif_stop_queue before calling stop_gfar. Signed-off-by: Markus Brunner Signed-off-by: David S. Miller --- drivers/net/gianfar.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 65f55877be95..b2c49679bba7 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -1583,8 +1583,10 @@ static void gfar_reset_task(struct work_struct *work) struct net_device *dev = priv->ndev; if (dev->flags & IFF_UP) { + netif_stop_queue(dev); stop_gfar(dev); startup_gfar(dev); + netif_start_queue(dev); } netif_tx_schedule_all(dev); From 719bfeaae8104fca4ca5d47c02592b08682f14fa Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 15 Apr 2009 03:39:52 -0700 Subject: [PATCH 60/64] packet: avoid warnings when high-order page allocation fails Latest tcpdump/libpcap triggers annoying messages because of high order page allocation failures (when lowmem exhausted or fragmented) These allocation errors are correctly handled so could be silent. [22660.208901] tcpdump: page allocation failure. order:5, mode:0xc0d0 [22660.208921] Pid: 13866, comm: tcpdump Not tainted 2.6.30-rc2 #170 [22660.208936] Call Trace: [22660.208950] [] ? printk+0x18/0x1a [22660.208965] [] __alloc_pages_internal+0x357/0x460 [22660.208980] [] __get_free_pages+0x21/0x40 [22660.208995] [] packet_set_ring+0x105/0x3d0 [22660.209009] [] packet_setsockopt+0x21d/0x4d0 [22660.209025] [] ? filemap_fault+0x0/0x450 [22660.209040] [] sys_setsockopt+0x54/0xa0 [22660.209053] [] sys_socketcall+0xef/0x270 [22660.209067] [] sysenter_do_call+0x12/0x26 Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/packet/af_packet.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 74776de523ec..f546e81acc45 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -1758,8 +1758,9 @@ static void free_pg_vec(char **pg_vec, unsigned int order, unsigned int len) static inline char *alloc_one_pg_vec_page(unsigned long order) { - return (char *) __get_free_pages(GFP_KERNEL | __GFP_COMP | __GFP_ZERO, - order); + gfp_t gfp_flags = GFP_KERNEL | __GFP_COMP | __GFP_ZERO | __GFP_NOWARN; + + return (char *) __get_free_pages(gfp_flags, order); } static char **alloc_pg_vec(struct tpacket_req *req, int order) From b43fcd7dc7bf0471b3bdda8fee3418e93ac25863 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 15 Apr 2009 17:43:24 +0000 Subject: [PATCH 61/64] NET/e1000: Fix powering off during shutdown Prevent e1000 from putting the adapter into D3 during shutdown except when we're going to power off the system, since doing that may generally cause problems with kexec to happen (such problems were observed for igb and forcedeth). For this purpose seperate e1000_shutdown() from e1000_suspend() and use the appropriate PCI PM callbacks in both of them. Signed-off-by: "Rafael J. Wysocki" Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/e1000/e1000_main.c | 46 ++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 4cd8b25c7ed7..ef12931d302a 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -156,8 +156,8 @@ static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid); static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid); static void e1000_restore_vlan(struct e1000_adapter *adapter); -static int e1000_suspend(struct pci_dev *pdev, pm_message_t state); #ifdef CONFIG_PM +static int e1000_suspend(struct pci_dev *pdev, pm_message_t state); static int e1000_resume(struct pci_dev *pdev); #endif static void e1000_shutdown(struct pci_dev *pdev); @@ -4601,7 +4601,7 @@ int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx) return 0; } -static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) +static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake) { struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev_priv(netdev); @@ -4664,22 +4664,18 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) ew32(WUC, E1000_WUC_PME_EN); ew32(WUFC, wufc); - pci_enable_wake(pdev, PCI_D3hot, 1); - pci_enable_wake(pdev, PCI_D3cold, 1); } else { ew32(WUC, 0); ew32(WUFC, 0); - pci_enable_wake(pdev, PCI_D3hot, 0); - pci_enable_wake(pdev, PCI_D3cold, 0); } e1000_release_manageability(adapter); + *enable_wake = !!wufc; + /* make sure adapter isn't asleep if manageability is enabled */ - if (adapter->en_mng_pt) { - pci_enable_wake(pdev, PCI_D3hot, 1); - pci_enable_wake(pdev, PCI_D3cold, 1); - } + if (adapter->en_mng_pt) + *enable_wake = true; if (hw->phy_type == e1000_phy_igp_3) e1000_phy_powerdown_workaround(hw); @@ -4693,12 +4689,29 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) pci_disable_device(pdev); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); - return 0; } #ifdef CONFIG_PM +static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) +{ + int retval; + bool wake; + + retval = __e1000_shutdown(pdev, &wake); + if (retval) + return retval; + + if (wake) { + pci_prepare_to_sleep(pdev); + } else { + pci_wake_from_d3(pdev, false); + pci_set_power_state(pdev, PCI_D3hot); + } + + return 0; +} + static int e1000_resume(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); @@ -4753,7 +4766,14 @@ static int e1000_resume(struct pci_dev *pdev) static void e1000_shutdown(struct pci_dev *pdev) { - e1000_suspend(pdev, PMSG_SUSPEND); + bool wake; + + __e1000_shutdown(pdev, &wake); + + if (system_state == SYSTEM_POWER_OFF) { + pci_wake_from_d3(pdev, wake); + pci_set_power_state(pdev, PCI_D3hot); + } } #ifdef CONFIG_NET_POLL_CONTROLLER From 4f9de721ab73a5271a79b126f7b5140b01a05c99 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 15 Apr 2009 17:43:43 +0000 Subject: [PATCH 62/64] NET/e1000e: Fix powering off during shutdown Prevent e1000e from putting the adapter into D3 during shutdown except when we're going to power off the system, since doing that may generally cause problems with kexec to happen (such problems were observed for igb and forcedeth). For this purpose seperate e1000e_shutdown() from e1000e_suspend() and use the appropriate PCI PM callbacks in both of them. Signed-off-by: "Rafael J. Wysocki" Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/e1000e/netdev.c | 59 ++++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 14 deletions(-) diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 3b0f08773800..1693ed116b16 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -4346,7 +4346,7 @@ static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) } } -static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) +static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake) { struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev_priv(netdev); @@ -4409,20 +4409,16 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) ew32(WUC, E1000_WUC_PME_EN); ew32(WUFC, wufc); - pci_enable_wake(pdev, PCI_D3hot, 1); - pci_enable_wake(pdev, PCI_D3cold, 1); } else { ew32(WUC, 0); ew32(WUFC, 0); - pci_enable_wake(pdev, PCI_D3hot, 0); - pci_enable_wake(pdev, PCI_D3cold, 0); } + *enable_wake = !!wufc; + /* make sure adapter isn't asleep if manageability is enabled */ - if (adapter->flags & FLAG_MNG_PT_ENABLED) { - pci_enable_wake(pdev, PCI_D3hot, 1); - pci_enable_wake(pdev, PCI_D3cold, 1); - } + if (adapter->flags & FLAG_MNG_PT_ENABLED) + *enable_wake = true; if (adapter->hw.phy.type == e1000_phy_igp_3) e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw); @@ -4435,6 +4431,26 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) pci_disable_device(pdev); + return 0; +} + +static void e1000_power_off(struct pci_dev *pdev, bool sleep, bool wake) +{ + if (sleep && wake) { + pci_prepare_to_sleep(pdev); + return; + } + + pci_wake_from_d3(pdev, wake); + pci_set_power_state(pdev, PCI_D3hot); +} + +static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep, + bool wake) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct e1000_adapter *adapter = netdev_priv(netdev); + /* * The pci-e switch on some quad port adapters will report a * correctable error when the MAC transitions from D0 to D3. To @@ -4450,14 +4466,12 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL, (devctl & ~PCI_EXP_DEVCTL_CERE)); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); + e1000_power_off(pdev, sleep, wake); pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL, devctl); } else { - pci_set_power_state(pdev, pci_choose_state(pdev, state)); + e1000_power_off(pdev, sleep, wake); } - - return 0; } static void e1000e_disable_l1aspm(struct pci_dev *pdev) @@ -4486,6 +4500,18 @@ static void e1000e_disable_l1aspm(struct pci_dev *pdev) } #ifdef CONFIG_PM +static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) +{ + int retval; + bool wake; + + retval = __e1000_shutdown(pdev, &wake); + if (!retval) + e1000_complete_shutdown(pdev, true, wake); + + return retval; +} + static int e1000_resume(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); @@ -4549,7 +4575,12 @@ static int e1000_resume(struct pci_dev *pdev) static void e1000_shutdown(struct pci_dev *pdev) { - e1000_suspend(pdev, PMSG_SUSPEND); + bool wake = false; + + __e1000_shutdown(pdev, &wake); + + if (system_state == SYSTEM_POWER_OFF) + e1000_complete_shutdown(pdev, false, wake); } #ifdef CONFIG_NET_POLL_CONTROLLER From 9d8d05ae66f40642987486f4b107565fc561a77c Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 15 Apr 2009 17:44:01 +0000 Subject: [PATCH 63/64] NET/ixgbe: Fix powering off during shutdown Prevent ixgbe from putting the adapter into D3 during shutdown except when we're going to power off the system, since doing that may generally cause problems with kexec to happen (such problems were observed for igb and forcedeth). For this purpose seperate ixgbe_shutdown() from ixgbe_suspend() and use the appropriate PCI PM callbacks in both of them. Signed-off-by: "Rafael J. Wysocki" Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 38 +++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 11fd153da85f..febde45cf9fa 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3612,9 +3612,9 @@ static int ixgbe_resume(struct pci_dev *pdev) return 0; } - #endif /* CONFIG_PM */ -static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state) + +static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake) { struct net_device *netdev = pci_get_drvdata(pdev); struct ixgbe_adapter *adapter = netdev_priv(netdev); @@ -3673,18 +3673,46 @@ static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state) pci_enable_wake(pdev, PCI_D3cold, 0); } + *enable_wake = !!wufc; + ixgbe_release_hw_control(adapter); pci_disable_device(pdev); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); - return 0; } +#ifdef CONFIG_PM +static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state) +{ + int retval; + bool wake; + + retval = __ixgbe_shutdown(pdev, &wake); + if (retval) + return retval; + + if (wake) { + pci_prepare_to_sleep(pdev); + } else { + pci_wake_from_d3(pdev, false); + pci_set_power_state(pdev, PCI_D3hot); + } + + return 0; +} +#endif /* CONFIG_PM */ + static void ixgbe_shutdown(struct pci_dev *pdev) { - ixgbe_suspend(pdev, PMSG_SUSPEND); + bool wake; + + __ixgbe_shutdown(pdev, &wake); + + if (system_state == SYSTEM_POWER_OFF) { + pci_wake_from_d3(pdev, wake); + pci_set_power_state(pdev, PCI_D3hot); + } } /** From 3664090e199f10cb0282097faae8f8ca58c1e4ae Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Thu, 16 Apr 2009 02:43:37 -0700 Subject: [PATCH 64/64] phylib: Fix delay argument of schedule_delayed_work The commit a390d1f3 ("phylib: convert state_queue work to delayed_work") missed converting 'expires' value to 'delay' value. Signed-off-by: Atsushi Nemoto Acked-by: Marcin Slusarz Signed-off-by: David S. Miller --- drivers/net/phy/phy.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index e3b8932d7d74..61755cbd978e 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -434,7 +434,7 @@ void phy_start_machine(struct phy_device *phydev, phydev->adjust_state = handler; INIT_DELAYED_WORK(&phydev->state_queue, phy_state_machine); - schedule_delayed_work(&phydev->state_queue, jiffies + HZ); + schedule_delayed_work(&phydev->state_queue, HZ); } /** @@ -946,6 +946,5 @@ static void phy_state_machine(struct work_struct *work) if (err < 0) phy_error(phydev); - schedule_delayed_work(&phydev->state_queue, - jiffies + PHY_STATE_TIME * HZ); + schedule_delayed_work(&phydev->state_queue, PHY_STATE_TIME * HZ); }