From 7b0f5df4c88bac46fe749d36d905fc7ad0296587 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Tue, 4 Nov 2008 11:18:56 -0800 Subject: mlx4_core: Fix unused variable warning Fix drivers/net/mlx4/profile.c:55: warning: 'res_name' defined but not used by making mlx4_dbg() always use all of its parameters, regardless of whether CONFIG_MLX4_DEBUG is set or not. Reported-by: Alexander Beregalov Signed-off-by: Roland Dreier --- drivers/net/mlx4/mlx4.h | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h index fa431fad0eec..56a2e213fe62 100644 --- a/drivers/net/mlx4/mlx4.h +++ b/drivers/net/mlx4/mlx4.h @@ -87,6 +87,9 @@ enum { #ifdef CONFIG_MLX4_DEBUG extern int mlx4_debug_level; +#else /* CONFIG_MLX4_DEBUG */ +#define mlx4_debug_level (0) +#endif /* CONFIG_MLX4_DEBUG */ #define mlx4_dbg(mdev, format, arg...) \ do { \ @@ -94,12 +97,6 @@ extern int mlx4_debug_level; dev_printk(KERN_DEBUG, &mdev->pdev->dev, format, ## arg); \ } while (0) -#else /* CONFIG_MLX4_DEBUG */ - -#define mlx4_dbg(mdev, format, arg...) do { (void) mdev; } while (0) - -#endif /* CONFIG_MLX4_DEBUG */ - #define mlx4_err(mdev, format, arg...) \ dev_err(&mdev->pdev->dev, format, ## arg) #define mlx4_info(mdev, format, arg...) \ -- cgit v1.2.3 From 8c2f5fa51e1b22db53acf4f3918b6f590b4a35a1 Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Mon, 10 Nov 2008 13:58:41 +0100 Subject: myri10ge: fix stop/go ordering even more The doorbell writes may be seen out of order by the firmware if they are in WC memory since the tx spin(un)lock does not flush WC writes. Hence if the "stop" is written on a different CPU than the "go", it is possible that the stop will arrive after the go unless we add an explicit memory barrier (and mmiowb() is not enough). It fixes transmit hangs in multi tx queue mode. Signed-off-by: Brice Goglin Signed-off-by: Jeff Garzik --- drivers/net/myri10ge/myri10ge.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index a5f428bcc0eb..b37867097308 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -75,7 +75,7 @@ #include "myri10ge_mcp.h" #include "myri10ge_mcp_gen_header.h" -#define MYRI10GE_VERSION_STR "1.4.3-1.375" +#define MYRI10GE_VERSION_STR "1.4.3-1.378" MODULE_DESCRIPTION("Myricom 10G driver (10GbE)"); MODULE_AUTHOR("Maintainer: help@myri.com"); @@ -1393,6 +1393,7 @@ myri10ge_tx_done(struct myri10ge_slice_state *ss, int mcp_index) if (tx->req == tx->done) { tx->queue_active = 0; put_be32(htonl(1), tx->send_stop); + mb(); mmiowb(); } __netif_tx_unlock(dev_queue); @@ -2865,6 +2866,7 @@ again: if ((mgp->dev->real_num_tx_queues > 1) && tx->queue_active == 0) { tx->queue_active = 1; put_be32(htonl(1), tx->send_go); + mb(); mmiowb(); } tx->pkt_start++; -- cgit v1.2.3 From 9f64306b8a3949b74cb11d3b2f613e8a2af20fa6 Mon Sep 17 00:00:00 2001 From: Divy Le Ray Date: Sun, 9 Nov 2008 00:55:28 -0800 Subject: cxgb3 - eeprom read fixes Protect against invalid phy entries in the eeprom. Extend eeprom access timeout. Signed-off-by: Divy Le Ray Signed-off-by: Jeff Garzik --- drivers/net/cxgb3/t3_hw.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c index 968f64be3743..9a0898b0dbce 100644 --- a/drivers/net/cxgb3/t3_hw.c +++ b/drivers/net/cxgb3/t3_hw.c @@ -572,7 +572,7 @@ struct t3_vpd { u32 pad; /* for multiple-of-4 sizing and alignment */ }; -#define EEPROM_MAX_POLL 4 +#define EEPROM_MAX_POLL 40 #define EEPROM_STAT_ADDR 0x4000 #define VPD_BASE 0xc00 @@ -3690,6 +3690,12 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai, ; pti = &port_types[adapter->params.vpd.port_type[j]]; + if (!pti->phy_prep) { + CH_ALERT(adapter, "Invalid port type index %d\n", + adapter->params.vpd.port_type[j]); + return -EINVAL; + } + ret = pti->phy_prep(&p->phy, adapter, ai->phy_base_addr + j, ai->mdio_ops); if (ret) -- cgit v1.2.3 From f9ee3882969224aa9f086268020c31819be6ae99 Mon Sep 17 00:00:00 2001 From: Divy Le Ray Date: Sun, 9 Nov 2008 00:55:33 -0800 Subject: cxgb3 - Limit multiqueue setting to msi-x Allow multiqueue setting in MSI-X mode only Signed-off-by: Divy Le Ray Signed-off-by: Jeff Garzik --- drivers/net/cxgb3/cxgb3_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 1ace41a13ac3..f66367ed6932 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -2699,7 +2699,7 @@ static void set_nqsets(struct adapter *adap) int hwports = adap->params.nports; int nqsets = SGE_QSETS; - if (adap->params.rev > 0) { + if (adap->params.rev > 0 && adap->flags & USING_MSIX) { if (hwports == 2 && (hwports * nqsets > SGE_QSETS || num_cpus >= nqsets / hwports)) -- cgit v1.2.3 From cf3760dad576c8dfb4fef4b8a8a08a027bf02583 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Thu, 6 Nov 2008 17:06:42 -0600 Subject: RDMA/cxgb3: deadlock in iw_cxgb3 can cause hang when configuring interface. When the iw_cxgb3 module's cxgb3_client "add" func gets called by the cxgb3 module, the iwarp driver ends up calling the ethtool ops get_drvinfo function in cxgb3 to get the fw version and other info. Currently the iwarp driver grabs the rtnl lock around this down call to serialize. As of 2.6.27 or so, things changed such that the rtnl lock is held around the call to the netdev driver open function. Also the cxgb3_client "add" function doesn't get called if the device is down. So, if you load cxgb3, then load iw_cxgb3, then ifconfig up the device, the iw_cxgb3 add func gets called with the rtnl_lock held. If you load cxgb3, ifconfig up the device, then load iw_cxgb3, the add func gets called without the rtnl_lock held. The former causes the deadlock, the latter does not. In addition, there are iw_cxgb3 sysfs handlers that also can call down into cxgb3 to gather the fw and hw versions. These can be called concurrently on different processors and at any time. Thus we need to push this serialization down in the cxgb3 driver get_drvinfo func. The fix is to remove rtnl lock usage, and use a per-device lock in cxgb3. Signed-off-by: Steve Wise Signed-off-by: Jeff Garzik --- drivers/infiniband/hw/cxgb3/iwch_provider.c | 6 ------ drivers/net/cxgb3/cxgb3_main.c | 2 ++ 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c index ecff98043589..160ef482712d 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_provider.c +++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c @@ -1102,9 +1102,7 @@ static u64 fw_vers_string_to_u64(struct iwch_dev *iwch_dev) char *cp, *next; unsigned fw_maj, fw_min, fw_mic; - rtnl_lock(); lldev->ethtool_ops->get_drvinfo(lldev, &info); - rtnl_unlock(); next = info.fw_version + 1; cp = strsep(&next, "."); @@ -1192,9 +1190,7 @@ static ssize_t show_fw_ver(struct device *dev, struct device_attribute *attr, ch struct net_device *lldev = iwch_dev->rdev.t3cdev_p->lldev; PDBG("%s dev 0x%p\n", __func__, dev); - rtnl_lock(); lldev->ethtool_ops->get_drvinfo(lldev, &info); - rtnl_unlock(); return sprintf(buf, "%s\n", info.fw_version); } @@ -1207,9 +1203,7 @@ static ssize_t show_hca(struct device *dev, struct device_attribute *attr, struct net_device *lldev = iwch_dev->rdev.t3cdev_p->lldev; PDBG("%s dev 0x%p\n", __func__, dev); - rtnl_lock(); lldev->ethtool_ops->get_drvinfo(lldev, &info); - rtnl_unlock(); return sprintf(buf, "%s\n", info.driver); } diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index f66367ed6932..2c341f83d327 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -1307,8 +1307,10 @@ static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) u32 fw_vers = 0; u32 tp_vers = 0; + spin_lock(&adapter->stats_lock); t3_get_fw_version(adapter, &fw_vers); t3_get_tp_version(adapter, &tp_vers); + spin_unlock(&adapter->stats_lock); strcpy(info->driver, DRV_NAME); strcpy(info->version, DRV_VERSION); -- cgit v1.2.3 From 347c8d83cd9f546a8357e1ab12fa6867707975d8 Mon Sep 17 00:00:00 2001 From: "Dasgupta, Romit" Date: Thu, 6 Nov 2008 15:46:18 +0530 Subject: [netdrvr] smc911x: fix for driver resume (and compilation warning) I am trying out suspend, resume on an OMAP3 based board. What I see during resume is that the SMC911x driver resume routing gets stuck after trying to transmit the packet out of the controller. Some debug messages below: --> smc911x_drv_resume eth0: --> smc911x_reset eth0: smc911x_reset timeout waiting for PM restore eth0: --> smc911x_enable eth0: --> smc911x_phy_configure() eth0: --> smc911x_phy_reset() eth0: phy caps=0x782d eth0: phy advertised caps=0x0de1 eth0: --> smc911x_phy_check_media smc911x_phy_read: phyaddr=0x1, phyreg=0x01, phydata=0x7809 smc911x_phy_read: phyaddr=0x1, phyreg=0x01, phydata=0x7809 eth0: link down Restarting tasks ... eth0: --> smc911x_hard_start_xmit eth0: --> smc911x_hardware_send_pkt eth0: --> smc911x_hard_start_xmit eth0: --> smc911x_hardware_send_pkt eth0: --> smc911x_hard_start_xmit eth0: --> smc911x_hardware_send_pkt nfs: server 172.24.190.217 not responding, still trying nfs: server 172.24.190.217 not responding, still trying The following change makes it work fine: (The change within smc911x_drv_probe function was to get rid of a compilation warning). Signed-off-by: Romit Dasgupta Signed-off-by: Jeff Garzik --- drivers/net/smc911x.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 5051554ff05b..1f26ab0e7986 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -2050,7 +2050,9 @@ err_out: */ static int smc911x_drv_probe(struct platform_device *pdev) { +#ifdef SMC_DYNAMIC_BUS_CONFIG struct smc911x_platdata *pd = pdev->dev.platform_data; +#endif struct net_device *ndev; struct resource *res; struct smc911x_local *lp; @@ -2182,9 +2184,9 @@ static int smc911x_drv_resume(struct platform_device *dev) if (netif_running(ndev)) { smc911x_reset(ndev); - smc911x_enable(ndev); if (lp->phy_type != 0) smc911x_phy_configure(&lp->phy_configure); + smc911x_enable(ndev); netif_device_attach(ndev); } } -- cgit v1.2.3 From b3e123cf65baadc0cc30a843fd48cfd6a4b2e1ca Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Wed, 12 Nov 2008 10:16:47 -0800 Subject: RDMA/cxgb3: Fix deadlock in iw_cxgb3 (hang when configuring interface) When the iw_cxgb3 module's cxgb3_client "add" func gets called by the cxgb3 module, the iwarp driver ends up calling the ethtool ops get_drvinfo function in cxgb3 to get the fw version and other info. Currently the iwarp driver grabs the rtnl lock around this down call to serialize. As of 2.6.27 or so, things changed such that the rtnl lock is held around the call to the netdev driver open function. Also the cxgb3_client "add" function doesn't get called if the device is down. So, if you load cxgb3, then load iw_cxgb3, then ifconfig up the device, the iw_cxgb3 add func gets called with the rtnl_lock held. If you load cxgb3, ifconfig up the device, then load iw_cxgb3, the add func gets called without the rtnl_lock held. The former causes the deadlock, the latter does not. In addition, there are iw_cxgb3 sysfs handlers that also can call down into cxgb3 to gather the fw and hw versions. These can be called concurrently on different processors and at any time. Thus we need to push this serialization down in the cxgb3 driver get_drvinfo func. The fix is to remove rtnl lock usage, and use a per-device lock in cxgb3. Signed-off-by: Steve Wise Acked-by: Divy Le Ray Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb3/iwch_provider.c | 6 ------ drivers/net/cxgb3/cxgb3_main.c | 2 ++ 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c index ecff98043589..160ef482712d 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_provider.c +++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c @@ -1102,9 +1102,7 @@ static u64 fw_vers_string_to_u64(struct iwch_dev *iwch_dev) char *cp, *next; unsigned fw_maj, fw_min, fw_mic; - rtnl_lock(); lldev->ethtool_ops->get_drvinfo(lldev, &info); - rtnl_unlock(); next = info.fw_version + 1; cp = strsep(&next, "."); @@ -1192,9 +1190,7 @@ static ssize_t show_fw_ver(struct device *dev, struct device_attribute *attr, ch struct net_device *lldev = iwch_dev->rdev.t3cdev_p->lldev; PDBG("%s dev 0x%p\n", __func__, dev); - rtnl_lock(); lldev->ethtool_ops->get_drvinfo(lldev, &info); - rtnl_unlock(); return sprintf(buf, "%s\n", info.fw_version); } @@ -1207,9 +1203,7 @@ static ssize_t show_hca(struct device *dev, struct device_attribute *attr, struct net_device *lldev = iwch_dev->rdev.t3cdev_p->lldev; PDBG("%s dev 0x%p\n", __func__, dev); - rtnl_lock(); lldev->ethtool_ops->get_drvinfo(lldev, &info); - rtnl_unlock(); return sprintf(buf, "%s\n", info.driver); } diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 1ace41a13ac3..5e663ccda4d4 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -1307,8 +1307,10 @@ static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) u32 fw_vers = 0; u32 tp_vers = 0; + spin_lock(&adapter->stats_lock); t3_get_fw_version(adapter, &fw_vers); t3_get_tp_version(adapter, &tp_vers); + spin_unlock(&adapter->stats_lock); strcpy(info->driver, DRV_NAME); strcpy(info->version, DRV_VERSION); -- cgit v1.2.3 From 8f7c41d4cec91cdbfa89b4a77d5a628938875366 Mon Sep 17 00:00:00 2001 From: Ivan Kuten Date: Mon, 10 Nov 2008 19:39:25 -0600 Subject: rtl8187: Add Abocom USB ID Signed-off-by: Ivan Kuten Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtl8187_dev.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c index 431e3c78bf27..0ce9fb037950 100644 --- a/drivers/net/wireless/rtl8187_dev.c +++ b/drivers/net/wireless/rtl8187_dev.c @@ -48,6 +48,8 @@ static struct usb_device_id rtl8187_table[] __devinitdata = { {USB_DEVICE(0x03f0, 0xca02), .driver_info = DEVICE_RTL8187}, /* Sitecom */ {USB_DEVICE(0x0df6, 0x000d), .driver_info = DEVICE_RTL8187}, + /* Abocom */ + {USB_DEVICE(0x13d1, 0xabe6), .driver_info = DEVICE_RTL8187}, {} }; -- cgit v1.2.3 From f3c769185a28b7947d97b3552a977102c1fac3f2 Mon Sep 17 00:00:00 2001 From: Bob Jolliffe Date: Wed, 12 Nov 2008 20:16:59 +0000 Subject: rtl8187 : support for Sitecom WL-168 0001 v4 the Sitecom 0001 v4 with product id 0x0df6:0028, uses Realtek's RTL8187B and work fine with new 2.6.27 driver. Signed-off-by: John W. Linville --- drivers/net/wireless/rtl8187_dev.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c index 0ce9fb037950..69eb0132593b 100644 --- a/drivers/net/wireless/rtl8187_dev.c +++ b/drivers/net/wireless/rtl8187_dev.c @@ -48,6 +48,7 @@ static struct usb_device_id rtl8187_table[] __devinitdata = { {USB_DEVICE(0x03f0, 0xca02), .driver_info = DEVICE_RTL8187}, /* Sitecom */ {USB_DEVICE(0x0df6, 0x000d), .driver_info = DEVICE_RTL8187}, + {USB_DEVICE(0x0df6, 0x0028), .driver_info = DEVICE_RTL8187B}, /* Abocom */ {USB_DEVICE(0x13d1, 0xabe6), .driver_info = DEVICE_RTL8187}, {} -- cgit v1.2.3 From f7cd168645dda3e9067f24fabbfa787f9a237488 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 12 Nov 2008 16:54:22 -0500 Subject: hostap: pad the skb->cb usage in lieu of a proper fix Like mac80211 did, this driver makes 'clever' use of skb->cb to pass information along with an skb as it is requeued from the virtual device to the physical wireless device. Unfortunately, that trick no longer works... Unlike mac80211, code complexity and driver apathy makes this hack the best option we have in the short run. Hopefully someone will eventually be motivated to code a proper fix before all the effected hardware dies. (Above text by me. Johannes officially disavows all knowledge of this hack. -- JWL) Signed-off-by: Johannes Berg Cc: stable@kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/hostap/hostap_wlan.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h index ffdf4876121b..a68f97c39359 100644 --- a/drivers/net/wireless/hostap/hostap_wlan.h +++ b/drivers/net/wireless/hostap/hostap_wlan.h @@ -918,9 +918,12 @@ struct hostap_interface { /* * TX meta data - stored in skb->cb buffer, so this must not be increased over - * the 40-byte limit + * the 48-byte limit. + * THE PADDING THIS STARTS WITH IS A HORRIBLE HACK THAT SHOULD NOT LIVE + * TO SEE THE DAY. */ struct hostap_skb_tx_data { + unsigned int __padding_for_default_qdiscs; u32 magic; /* HOSTAP_SKB_TX_DATA_MAGIC */ u8 rate; /* transmit rate */ #define HOSTAP_TX_FLAGS_WDS BIT(0) -- cgit v1.2.3 From e23a59e1ca6d177a57a7791b3629db93ff1d9813 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 12 Nov 2008 14:32:54 -0800 Subject: niu: Fix readq implementation when architecture does not provide one. This fixes a TX hang reported by Jesper Dangaard Brouer. When an architecutre cannot provide a fully functional 64-bit atomic readq/writeq, the driver must implement it's own. This is because only the driver can say whether doing something like using two 32-bit reads to implement the full 64-bit read will actually work properly. In particular one of the issues is whether the top 32-bits or the bottom 32-bits of the 64-bit register should be read first. There could be side effects, and in fact that is exactly the problem here. The TX_CS register has counters in the upper 32-bits and state bits in the lower 32-bits. A read clears the state bits. We would read the counter half before the state bit half. That first read would clear the state bits, and then the driver thinks that no interrupts are pending because the interrupt indication state bits are seen clear every time. Fix this by reading the bottom half before the upper half. Tested-by: Jesper Dangaard Brouer Signed-off-by: David S. Miller --- drivers/net/niu.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 9acb5d70a3ae..d8463b1c3df3 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -51,8 +51,7 @@ MODULE_VERSION(DRV_MODULE_VERSION); #ifndef readq static u64 readq(void __iomem *reg) { - return (((u64)readl(reg + 0x4UL) << 32) | - (u64)readl(reg)); + return ((u64) readl(reg)) | (((u64) readl(reg + 4UL)) << 32); } static void writeq(u64 val, void __iomem *reg) -- cgit v1.2.3 From b2af2c1d3e4ddeea9d02c46d0df0c322cc7b7061 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Wed, 12 Nov 2008 16:23:44 -0800 Subject: bnx2: fix poll_controller to pass proper structures and check all rx queues Fix bnx2 so that netpoll works properly. Specifically: 1) Fix parameters to bnx2_interrupt to be a struct bnx2_napi rather than a struct net_device 2) Fix poll_controller method to check every queue in the rx case so frames aren't missed Signed-off-by: Neil Horman Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 430d430bce29..d07e3f148951 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -7204,10 +7204,13 @@ static void poll_bnx2(struct net_device *dev) { struct bnx2 *bp = netdev_priv(dev); + int i; - disable_irq(bp->pdev->irq); - bnx2_interrupt(bp->pdev->irq, dev); - enable_irq(bp->pdev->irq); + for (i = 0; i < bp->irq_nvecs; i++) { + disable_irq(bp->irq_tbl[i].vector); + bnx2_interrupt(bp->irq_tbl[i].vector, &bp->bnx2_napi[i]); + enable_irq(bp->irq_tbl[i].vector); + } } #endif -- cgit v1.2.3 From ccf95402d0ae6f433f29ce88cfd589cec8fc81ad Mon Sep 17 00:00:00 2001 From: Jason Cooper Date: Tue, 11 Nov 2008 13:02:53 -0500 Subject: USB: net: asix: add support for Cables-to-Go USB Ethernet adapter Add support to drivers/net/usb/asix.c for the Cables-to-Go "USB 2.0 to 10/100 Ethernet Adapter". USB id 0b95:772a. Signed-off-by: Jason Cooper Signed-off-by: Greg Kroah-Hartman --- drivers/net/usb/asix.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 37ecf845edfe..e12cdb4543b4 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -1444,6 +1444,10 @@ static const struct usb_device_id products [] = { // Apple USB Ethernet Adapter USB_DEVICE(0x05ac, 0x1402), .driver_info = (unsigned long) &ax88772_info, +}, { + // Cables-to-Go USB Ethernet Adapter + USB_DEVICE(0x0b95, 0x772a), + .driver_info = (unsigned long) &ax88772_info, }, { }, // END }; -- cgit v1.2.3 From e3e081e1d5c4791f4416ed57b7a2f143ab9e5b09 Mon Sep 17 00:00:00 2001 From: Santwona Behera Date: Fri, 14 Nov 2008 14:44:08 -0800 Subject: NIU: Add Sun CP3260 ATCA blade support This patch adds support for the Sun CP3260 ATCA blade which is a N2 based ATCA blade with 2 NIU ports. The NIU ports do not have on-board PHY. Signed-off-by: Santwona Behera Signed-off-by: David S. Miller --- drivers/net/niu.c | 286 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- drivers/net/niu.h | 13 +++ 2 files changed, 293 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/niu.c b/drivers/net/niu.c index d8463b1c3df3..be6b4d7e2bb4 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -406,7 +406,7 @@ static int esr2_set_rx_cfg(struct niu *np, unsigned long channel, u32 val) } /* Mode is always 10G fiber. */ -static int serdes_init_niu(struct niu *np) +static int serdes_init_niu_10g_fiber(struct niu *np) { struct niu_link_config *lp = &np->link_config; u32 tx_cfg, rx_cfg; @@ -443,6 +443,223 @@ static int serdes_init_niu(struct niu *np) return 0; } +static int serdes_init_niu_1g_serdes(struct niu *np) +{ + struct niu_link_config *lp = &np->link_config; + u16 pll_cfg, pll_sts; + int max_retry = 100; + u64 sig, mask, val; + u32 tx_cfg, rx_cfg; + unsigned long i; + int err; + + tx_cfg = (PLL_TX_CFG_ENTX | PLL_TX_CFG_SWING_1375MV | + PLL_TX_CFG_RATE_HALF); + rx_cfg = (PLL_RX_CFG_ENRX | PLL_RX_CFG_TERM_0P8VDDT | + PLL_RX_CFG_ALIGN_ENA | PLL_RX_CFG_LOS_LTHRESH | + PLL_RX_CFG_RATE_HALF); + + if (np->port == 0) + rx_cfg |= PLL_RX_CFG_EQ_LP_ADAPTIVE; + + if (lp->loopback_mode == LOOPBACK_PHY) { + u16 test_cfg = PLL_TEST_CFG_LOOPBACK_CML_DIS; + + mdio_write(np, np->port, NIU_ESR2_DEV_ADDR, + ESR2_TI_PLL_TEST_CFG_L, test_cfg); + + tx_cfg |= PLL_TX_CFG_ENTEST; + rx_cfg |= PLL_RX_CFG_ENTEST; + } + + /* Initialize PLL for 1G */ + pll_cfg = (PLL_CFG_ENPLL | PLL_CFG_MPY_8X); + + err = mdio_write(np, np->port, NIU_ESR2_DEV_ADDR, + ESR2_TI_PLL_CFG_L, pll_cfg); + if (err) { + dev_err(np->device, PFX "NIU Port %d " + "serdes_init_niu_1g_serdes: " + "mdio write to ESR2_TI_PLL_CFG_L failed", np->port); + return err; + } + + pll_sts = PLL_CFG_ENPLL; + + err = mdio_write(np, np->port, NIU_ESR2_DEV_ADDR, + ESR2_TI_PLL_STS_L, pll_sts); + if (err) { + dev_err(np->device, PFX "NIU Port %d " + "serdes_init_niu_1g_serdes: " + "mdio write to ESR2_TI_PLL_STS_L failed", np->port); + return err; + } + + udelay(200); + + /* Initialize all 4 lanes of the SERDES. */ + for (i = 0; i < 4; i++) { + err = esr2_set_tx_cfg(np, i, tx_cfg); + if (err) + return err; + } + + for (i = 0; i < 4; i++) { + err = esr2_set_rx_cfg(np, i, rx_cfg); + if (err) + return err; + } + + switch (np->port) { + case 0: + val = (ESR_INT_SRDY0_P0 | ESR_INT_DET0_P0); + mask = val; + break; + + case 1: + val = (ESR_INT_SRDY0_P1 | ESR_INT_DET0_P1); + mask = val; + break; + + default: + return -EINVAL; + } + + while (max_retry--) { + sig = nr64(ESR_INT_SIGNALS); + if ((sig & mask) == val) + break; + + mdelay(500); + } + + if ((sig & mask) != val) { + dev_err(np->device, PFX "Port %u signal bits [%08x] are not " + "[%08x]\n", np->port, (int) (sig & mask), (int) val); + return -ENODEV; + } + + return 0; +} + +static int serdes_init_niu_10g_serdes(struct niu *np) +{ + struct niu_link_config *lp = &np->link_config; + u32 tx_cfg, rx_cfg, pll_cfg, pll_sts; + int max_retry = 100; + u64 sig, mask, val; + unsigned long i; + int err; + + tx_cfg = (PLL_TX_CFG_ENTX | PLL_TX_CFG_SWING_1375MV); + rx_cfg = (PLL_RX_CFG_ENRX | PLL_RX_CFG_TERM_0P8VDDT | + PLL_RX_CFG_ALIGN_ENA | PLL_RX_CFG_LOS_LTHRESH | + PLL_RX_CFG_EQ_LP_ADAPTIVE); + + if (lp->loopback_mode == LOOPBACK_PHY) { + u16 test_cfg = PLL_TEST_CFG_LOOPBACK_CML_DIS; + + mdio_write(np, np->port, NIU_ESR2_DEV_ADDR, + ESR2_TI_PLL_TEST_CFG_L, test_cfg); + + tx_cfg |= PLL_TX_CFG_ENTEST; + rx_cfg |= PLL_RX_CFG_ENTEST; + } + + /* Initialize PLL for 10G */ + pll_cfg = (PLL_CFG_ENPLL | PLL_CFG_MPY_10X); + + err = mdio_write(np, np->port, NIU_ESR2_DEV_ADDR, + ESR2_TI_PLL_CFG_L, pll_cfg & 0xffff); + if (err) { + dev_err(np->device, PFX "NIU Port %d " + "serdes_init_niu_10g_serdes: " + "mdio write to ESR2_TI_PLL_CFG_L failed", np->port); + return err; + } + + pll_sts = PLL_CFG_ENPLL; + + err = mdio_write(np, np->port, NIU_ESR2_DEV_ADDR, + ESR2_TI_PLL_STS_L, pll_sts & 0xffff); + if (err) { + dev_err(np->device, PFX "NIU Port %d " + "serdes_init_niu_10g_serdes: " + "mdio write to ESR2_TI_PLL_STS_L failed", np->port); + return err; + } + + udelay(200); + + /* Initialize all 4 lanes of the SERDES. */ + for (i = 0; i < 4; i++) { + err = esr2_set_tx_cfg(np, i, tx_cfg); + if (err) + return err; + } + + for (i = 0; i < 4; i++) { + err = esr2_set_rx_cfg(np, i, rx_cfg); + if (err) + return err; + } + + /* check if serdes is ready */ + + switch (np->port) { + case 0: + mask = ESR_INT_SIGNALS_P0_BITS; + val = (ESR_INT_SRDY0_P0 | + ESR_INT_DET0_P0 | + ESR_INT_XSRDY_P0 | + ESR_INT_XDP_P0_CH3 | + ESR_INT_XDP_P0_CH2 | + ESR_INT_XDP_P0_CH1 | + ESR_INT_XDP_P0_CH0); + break; + + case 1: + mask = ESR_INT_SIGNALS_P1_BITS; + val = (ESR_INT_SRDY0_P1 | + ESR_INT_DET0_P1 | + ESR_INT_XSRDY_P1 | + ESR_INT_XDP_P1_CH3 | + ESR_INT_XDP_P1_CH2 | + ESR_INT_XDP_P1_CH1 | + ESR_INT_XDP_P1_CH0); + break; + + default: + return -EINVAL; + } + + while (max_retry--) { + sig = nr64(ESR_INT_SIGNALS); + if ((sig & mask) == val) + break; + + mdelay(500); + } + + if ((sig & mask) != val) { + pr_info(PFX "NIU Port %u signal bits [%08x] are not " + "[%08x] for 10G...trying 1G\n", + np->port, (int) (sig & mask), (int) val); + + /* 10G failed, try initializing at 1G */ + err = serdes_init_niu_1g_serdes(np); + if (!err) { + np->flags &= ~NIU_FLAGS_10G; + np->mac_xcvr = MAC_XCVR_PCS; + } else { + dev_err(np->device, PFX "Port %u 10G/1G SERDES " + "Link Failed \n", np->port); + return -ENODEV; + } + } + return 0; +} + static int esr_read_rxtx_ctrl(struct niu *np, unsigned long chan, u32 *val) { int err; @@ -1954,13 +2171,23 @@ static const struct niu_phy_ops phy_ops_10g_serdes = { .link_status = link_status_10g_serdes, }; +static const struct niu_phy_ops phy_ops_10g_serdes_niu = { + .serdes_init = serdes_init_niu_10g_serdes, + .link_status = link_status_10g_serdes, +}; + +static const struct niu_phy_ops phy_ops_1g_serdes_niu = { + .serdes_init = serdes_init_niu_1g_serdes, + .link_status = link_status_1g_serdes, +}; + static const struct niu_phy_ops phy_ops_1g_rgmii = { .xcvr_init = xcvr_init_1g_rgmii, .link_status = link_status_1g_rgmii, }; static const struct niu_phy_ops phy_ops_10g_fiber_niu = { - .serdes_init = serdes_init_niu, + .serdes_init = serdes_init_niu_10g_fiber, .xcvr_init = xcvr_init_10g, .link_status = link_status_10g, }; @@ -1998,11 +2225,21 @@ struct niu_phy_template { u32 phy_addr_base; }; -static const struct niu_phy_template phy_template_niu = { +static const struct niu_phy_template phy_template_niu_10g_fiber = { .ops = &phy_ops_10g_fiber_niu, .phy_addr_base = 16, }; +static const struct niu_phy_template phy_template_niu_10g_serdes = { + .ops = &phy_ops_10g_serdes_niu, + .phy_addr_base = 0, +}; + +static const struct niu_phy_template phy_template_niu_1g_serdes = { + .ops = &phy_ops_1g_serdes_niu, + .phy_addr_base = 0, +}; + static const struct niu_phy_template phy_template_10g_fiber = { .ops = &phy_ops_10g_fiber, .phy_addr_base = 8, @@ -2182,8 +2419,25 @@ static int niu_determine_phy_disposition(struct niu *np) u32 phy_addr_off = 0; if (plat_type == PLAT_TYPE_NIU) { - tp = &phy_template_niu; - phy_addr_off += np->port; + switch (np->flags & + (NIU_FLAGS_10G | + NIU_FLAGS_FIBER | + NIU_FLAGS_XCVR_SERDES)) { + case NIU_FLAGS_10G | NIU_FLAGS_XCVR_SERDES: + /* 10G Serdes */ + tp = &phy_template_niu_10g_serdes; + break; + case NIU_FLAGS_XCVR_SERDES: + /* 1G Serdes */ + tp = &phy_template_niu_1g_serdes; + break; + case NIU_FLAGS_10G | NIU_FLAGS_FIBER: + /* 10G Fiber */ + default: + tp = &phy_template_niu_10g_fiber; + phy_addr_off += np->port; + break; + } } else { switch (np->flags & (NIU_FLAGS_10G | @@ -7213,6 +7467,12 @@ static int __devinit niu_phy_type_prop_decode(struct niu *np, np->flags |= NIU_FLAGS_10G; np->flags &= ~NIU_FLAGS_FIBER; np->mac_xcvr = MAC_XCVR_XPCS; + } else if (!strcmp(phy_prop, "xgsd") || !strcmp(phy_prop, "gsd")) { + /* 10G Serdes or 1G Serdes, default to 10G */ + np->flags |= NIU_FLAGS_10G; + np->flags &= ~NIU_FLAGS_FIBER; + np->flags |= NIU_FLAGS_XCVR_SERDES; + np->mac_xcvr = MAC_XCVR_XPCS; } else { return -EINVAL; } @@ -7741,6 +8001,8 @@ static int __devinit walk_phys(struct niu *np, struct niu_parent *parent) u32 val; int err; + num_10g = num_1g = 0; + if (!strcmp(np->vpd.model, NIU_ALONSO_MDL_STR) || !strcmp(np->vpd.model, NIU_KIMI_MDL_STR)) { num_10g = 0; @@ -7757,6 +8019,16 @@ static int __devinit walk_phys(struct niu *np, struct niu_parent *parent) parent->num_ports = 2; val = (phy_encode(PORT_TYPE_10G, 0) | phy_encode(PORT_TYPE_10G, 1)); + } else if ((np->flags & NIU_FLAGS_XCVR_SERDES) && + (parent->plat_type == PLAT_TYPE_NIU)) { + /* this is the Monza case */ + if (np->flags & NIU_FLAGS_10G) { + val = (phy_encode(PORT_TYPE_10G, 0) | + phy_encode(PORT_TYPE_10G, 1)); + } else { + val = (phy_encode(PORT_TYPE_1G, 0) | + phy_encode(PORT_TYPE_1G, 1)); + } } else { err = fill_phy_probe_info(np, parent, info); if (err) @@ -8656,7 +8928,9 @@ static void __devinit niu_device_announce(struct niu *np) dev->name, (np->flags & NIU_FLAGS_XMAC ? "XMAC" : "BMAC"), (np->flags & NIU_FLAGS_10G ? "10G" : "1G"), - (np->flags & NIU_FLAGS_FIBER ? "FIBER" : "COPPER"), + (np->flags & NIU_FLAGS_FIBER ? "FIBER" : + (np->flags & NIU_FLAGS_XCVR_SERDES ? "SERDES" : + "COPPER")), (np->mac_xcvr == MAC_XCVR_MII ? "MII" : (np->mac_xcvr == MAC_XCVR_PCS ? "PCS" : "XPCS")), np->vpd.phy_type); diff --git a/drivers/net/niu.h b/drivers/net/niu.h index c6fa883daa22..180ca8ae93de 100644 --- a/drivers/net/niu.h +++ b/drivers/net/niu.h @@ -1048,6 +1048,13 @@ #define PLL_CFG_LD_SHIFT 8 #define PLL_CFG_MPY 0x0000001e #define PLL_CFG_MPY_SHIFT 1 +#define PLL_CFG_MPY_4X 0x0 +#define PLL_CFG_MPY_5X 0x00000002 +#define PLL_CFG_MPY_6X 0x00000004 +#define PLL_CFG_MPY_8X 0x00000008 +#define PLL_CFG_MPY_10X 0x0000000a +#define PLL_CFG_MPY_12X 0x0000000c +#define PLL_CFG_MPY_12P5X 0x0000000e #define PLL_CFG_ENPLL 0x00000001 #define ESR2_TI_PLL_STS_L (ESR2_BASE + 0x002) @@ -1093,6 +1100,9 @@ #define PLL_TX_CFG_INVPAIR 0x00000080 #define PLL_TX_CFG_RATE 0x00000060 #define PLL_TX_CFG_RATE_SHIFT 5 +#define PLL_TX_CFG_RATE_FULL 0x0 +#define PLL_TX_CFG_RATE_HALF 0x20 +#define PLL_TX_CFG_RATE_QUAD 0x40 #define PLL_TX_CFG_BUSWIDTH 0x0000001c #define PLL_TX_CFG_BUSWIDTH_SHIFT 2 #define PLL_TX_CFG_ENTEST 0x00000002 @@ -1132,6 +1142,9 @@ #define PLL_RX_CFG_INVPAIR 0x00000080 #define PLL_RX_CFG_RATE 0x00000060 #define PLL_RX_CFG_RATE_SHIFT 5 +#define PLL_RX_CFG_RATE_FULL 0x0 +#define PLL_RX_CFG_RATE_HALF 0x20 +#define PLL_RX_CFG_RATE_QUAD 0x40 #define PLL_RX_CFG_BUSWIDTH 0x0000001c #define PLL_RX_CFG_BUSWIDTH_SHIFT 2 #define PLL_RX_CFG_ENTEST 0x00000002 -- cgit v1.2.3 From d8c3e23d06c1020f38b7b6290135a9522a2e3052 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 14 Nov 2008 14:47:29 -0800 Subject: niu: Bump driver version and release date. This driver is pretty mature, and the worst of the known problems has been fixed (the 32-bit failures due to readq implementation). So let's finally give it a version of 1.0 Signed-off-by: David S. Miller --- drivers/net/niu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/niu.c b/drivers/net/niu.c index be6b4d7e2bb4..1b6f548c4411 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -33,8 +33,8 @@ #define DRV_MODULE_NAME "niu" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "0.9" -#define DRV_MODULE_RELDATE "May 4, 2008" +#define DRV_MODULE_VERSION "1.0" +#define DRV_MODULE_RELDATE "Nov 14, 2008" static char version[] __devinitdata = DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; -- cgit v1.2.3 From 18acfa2597d57c19249346d130fc3334244557b4 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Thu, 13 Nov 2008 21:26:27 +0300 Subject: net/ucc_geth: Fix oops in uec_get_ethtool_stats() p_{tx,rx}_fw_statistics_pram are special: they're available only when a device is open. If the device is closed, we should just fill the data with zeroes. Fixes the following oops: root@b1:~# ifconfig eth1 down root@b1:~# ethtool -S eth1 Unable to handle kernel paging request for data at address 0x00000000 Faulting instruction address: 0xc01e1dcc Oops: Kernel access of bad area, sig: 11 [#1] [...] NIP [c01e1dcc] uec_get_ethtool_stats+0x98/0x124 LR [c0287cc8] ethtool_get_stats+0xfc/0x23c Call Trace: [cfaadde0] [c0287ca8] ethtool_get_stats+0xdc/0x23c (unreliable) [cfaade20] [c0288340] dev_ethtool+0x2fc/0x588 [cfaade50] [c0285648] dev_ioctl+0x290/0x33c [cfaadea0] [c0272238] sock_ioctl+0x80/0x2ec [cfaadec0] [c00b5ae4] vfs_ioctl+0x40/0xc0 [cfaadee0] [c00b5fa8] do_vfs_ioctl+0x78/0x20c [cfaadf10] [c00b617c] sys_ioctl+0x40/0x74 [cfaadf40] [c00142d8] ret_from_syscall+0x0/0x38 [...] ---[ end trace b941007b2dfb9759 ]--- Segmentation fault p.s. While at it, also remove u64 casts, they aren't needed. Signed-off-by: Anton Vorontsov Signed-off-by: Jeff Garzik --- drivers/net/ucc_geth_ethtool.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ucc_geth_ethtool.c b/drivers/net/ucc_geth_ethtool.c index 85f38a6b6a49..68a7f5414133 100644 --- a/drivers/net/ucc_geth_ethtool.c +++ b/drivers/net/ucc_geth_ethtool.c @@ -323,17 +323,17 @@ static void uec_get_ethtool_stats(struct net_device *netdev, if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_HARDWARE) { base = (u32 __iomem *)&ugeth->ug_regs->tx64; for (i = 0; i < UEC_HW_STATS_LEN; i++) - data[j++] = (u64)in_be32(&base[i]); + data[j++] = in_be32(&base[i]); } if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX) { base = (u32 __iomem *)ugeth->p_tx_fw_statistics_pram; for (i = 0; i < UEC_TX_FW_STATS_LEN; i++) - data[j++] = (u64)in_be32(&base[i]); + data[j++] = base ? in_be32(&base[i]) : 0; } if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX) { base = (u32 __iomem *)ugeth->p_rx_fw_statistics_pram; for (i = 0; i < UEC_RX_FW_STATS_LEN; i++) - data[j++] = (u64)in_be32(&base[i]); + data[j++] = base ? in_be32(&base[i]) : 0; } } -- cgit v1.2.3 From 81183059e89c36f9b4c41f9332d642c2e0bff971 Mon Sep 17 00:00:00 2001 From: Andy Fleming Date: Wed, 12 Nov 2008 10:07:11 -0600 Subject: gianfar: Fix DMA unmap invocations We weren't unmapping DMA memory, which will break when gianfar gets used on systems with more than 32-bits of memory. Also, it's just plain wrong. Signed-off-by: Andy Fleming Signed-off-by: Jeff Garzik --- drivers/net/gianfar.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 83a5cb6aa23b..c4af949bf860 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -1407,6 +1407,10 @@ static int gfar_clean_tx_ring(struct net_device *dev) if (bdp->status & TXBD_DEF) dev->stats.collisions++; + /* Unmap the DMA memory */ + dma_unmap_single(&priv->dev->dev, bdp->bufPtr, + bdp->length, DMA_TO_DEVICE); + /* Free the sk buffer associated with this TxBD */ dev_kfree_skb_irq(priv->tx_skbuff[priv->skb_dirtytx]); @@ -1666,6 +1670,9 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit) skb = priv->rx_skbuff[priv->skb_currx]; + dma_unmap_single(&priv->dev->dev, bdp->bufPtr, + priv->rx_buffer_size, DMA_FROM_DEVICE); + /* We drop the frame if we failed to allocate a new buffer */ if (unlikely(!newskb || !(bdp->status & RXBD_LAST) || bdp->status & RXBD_ERR)) { @@ -1674,14 +1681,8 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit) if (unlikely(!newskb)) newskb = skb; - if (skb) { - dma_unmap_single(&priv->dev->dev, - bdp->bufPtr, - priv->rx_buffer_size, - DMA_FROM_DEVICE); - + if (skb) dev_kfree_skb_any(skb); - } } else { /* Increment the number of packets */ dev->stats.rx_packets++; -- cgit v1.2.3 From 7ee0fddfe05f105d3346aa8774695e7130697836 Mon Sep 17 00:00:00 2001 From: "J. K. Cliburn" Date: Tue, 11 Nov 2008 16:21:48 -0600 Subject: atl1e: fix broken multicast by removing unnecessary crc inversion Inverting the crc after calling ether_crc_le() is unnecessary and breaks multicast. Remove it. Tested-by: David Madore Signed-off-by: Jay Cliburn Cc: stable@kernel.org Signed-off-by: Jeff Garzik --- drivers/net/atl1e/atl1e_hw.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/atl1e/atl1e_hw.c b/drivers/net/atl1e/atl1e_hw.c index 8cbc1b59bd62..4a7700620119 100644 --- a/drivers/net/atl1e/atl1e_hw.c +++ b/drivers/net/atl1e/atl1e_hw.c @@ -163,9 +163,6 @@ int atl1e_read_mac_addr(struct atl1e_hw *hw) * atl1e_hash_mc_addr * purpose * set hash value for a multicast address - * hash calcu processing : - * 1. calcu 32bit CRC for multicast address - * 2. reverse crc with MSB to LSB */ u32 atl1e_hash_mc_addr(struct atl1e_hw *hw, u8 *mc_addr) { @@ -174,7 +171,6 @@ u32 atl1e_hash_mc_addr(struct atl1e_hw *hw, u8 *mc_addr) int i; crc32 = ether_crc_le(6, mc_addr); - crc32 = ~crc32; for (i = 0; i < 32; i++) value |= (((crc32 >> i) & 1) << (31 - i)); -- cgit v1.2.3 From 3b259e365998291a02488225e32b9f2b73723b3e Mon Sep 17 00:00:00 2001 From: "J. K. Cliburn" Date: Sun, 9 Nov 2008 15:05:30 -0600 Subject: atl1: Do not enumerate options unsupported by chip Of the various WOL options provided in include/linux/ethtool.h, the L1 NIC supports only magic packet. Remove all options except magic packet from the atl1 driver. Signed-off-by: Jay Cliburn Signed-off-by: Jeff Garzik --- drivers/net/atlx/atl1.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index 246d92b42636..aef403d299ee 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c @@ -3404,14 +3404,8 @@ static void atl1_get_wol(struct net_device *netdev, { struct atl1_adapter *adapter = netdev_priv(netdev); - wol->supported = WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC; + wol->supported = WAKE_MAGIC; wol->wolopts = 0; - if (adapter->wol & ATLX_WUFC_EX) - wol->wolopts |= WAKE_UCAST; - if (adapter->wol & ATLX_WUFC_MC) - wol->wolopts |= WAKE_MCAST; - if (adapter->wol & ATLX_WUFC_BC) - wol->wolopts |= WAKE_BCAST; if (adapter->wol & ATLX_WUFC_MAG) wol->wolopts |= WAKE_MAGIC; return; @@ -3422,15 +3416,10 @@ static int atl1_set_wol(struct net_device *netdev, { struct atl1_adapter *adapter = netdev_priv(netdev); - if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE)) + if (wol->wolopts & (WAKE_PHY | WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | + WAKE_ARP | WAKE_MAGICSECURE)) return -EOPNOTSUPP; adapter->wol = 0; - if (wol->wolopts & WAKE_UCAST) - adapter->wol |= ATLX_WUFC_EX; - if (wol->wolopts & WAKE_MCAST) - adapter->wol |= ATLX_WUFC_MC; - if (wol->wolopts & WAKE_BCAST) - adapter->wol |= ATLX_WUFC_BC; if (wol->wolopts & WAKE_MAGIC) adapter->wol |= ATLX_WUFC_MAG; return 0; -- cgit v1.2.3 From 3e44017b589f001941723dfdfede2ca6284dddce Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Sun, 9 Nov 2008 05:34:47 +0100 Subject: phylib: fix premature freeing of struct mii_bus Commit 46abc02175b3c246dd5141d878f565a8725060c9 ("phylib: give mdio buses a device tree presence") added a call to device_unregister() in a situation where the caller did not intend for the device to be freed yet, but apart from just unregistering the device from the system, device_unregister() does an additional put_device() that is intended to free it. The right function to use in this situation is device_del(), which unregisters the device from the system like device_unregister() does, but without dropping the reference count an additional time. Bug report from Bryan Wu . Signed-off-by: Lennert Buytenhek Tested-by: Bryan Wu Signed-off-by: Jeff Garzik --- drivers/net/phy/mdio_bus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index d0ed1ef284a8..536bda1f428b 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -136,7 +136,7 @@ void mdiobus_unregister(struct mii_bus *bus) BUG_ON(bus->state != MDIOBUS_REGISTERED); bus->state = MDIOBUS_UNREGISTERED; - device_unregister(&bus->dev); + device_del(&bus->dev); for (i = 0; i < PHY_MAX_ADDR; i++) { if (bus->phy_map[i]) device_unregister(&bus->phy_map[i]->dev); -- cgit v1.2.3 From d53b93f2603554c3420e301bd13ee2c354a15ceb Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Wed, 5 Nov 2008 04:48:36 +0000 Subject: mlx4_en: Pause parameters per port Before the change the driver reported the same pause parameters for all the ports, even only one of them was modified. Signed-off-by: Yevgeny Petrilin Signed-off-by: David S. Miller --- drivers/net/mlx4/en_netdev.c | 8 ++++---- drivers/net/mlx4/en_params.c | 30 ++++++++++++++++-------------- drivers/net/mlx4/mlx4_en.h | 8 ++++---- 3 files changed, 24 insertions(+), 22 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c index a3f732418c49..96e709d6440a 100644 --- a/drivers/net/mlx4/en_netdev.c +++ b/drivers/net/mlx4/en_netdev.c @@ -656,10 +656,10 @@ static int mlx4_en_start_port(struct net_device *dev) /* Configure port */ err = mlx4_SET_PORT_general(mdev->dev, priv->port, priv->rx_skb_size + ETH_FCS_LEN, - mdev->profile.tx_pause, - mdev->profile.tx_ppp, - mdev->profile.rx_pause, - mdev->profile.rx_ppp); + priv->prof->tx_pause, + priv->prof->tx_ppp, + priv->prof->rx_pause, + priv->prof->rx_ppp); if (err) { mlx4_err(mdev, "Failed setting port general configurations" " for port %d, with error %d\n", priv->port, err); diff --git a/drivers/net/mlx4/en_params.c b/drivers/net/mlx4/en_params.c index c2e69b1bcd0a..95706ee1c019 100644 --- a/drivers/net/mlx4/en_params.c +++ b/drivers/net/mlx4/en_params.c @@ -90,6 +90,7 @@ MLX4_EN_PARM_INT(rx_ring_size2, MLX4_EN_AUTO_CONF, "Rx ring size for port 2"); int mlx4_en_get_profile(struct mlx4_en_dev *mdev) { struct mlx4_en_profile *params = &mdev->profile; + int i; params->rx_moder_cnt = min_t(int, rx_moder_cnt, MLX4_EN_AUTO_CONF); params->rx_moder_time = min_t(int, rx_moder_time, MLX4_EN_AUTO_CONF); @@ -97,11 +98,13 @@ int mlx4_en_get_profile(struct mlx4_en_dev *mdev) params->rss_xor = (rss_xor != 0); params->rss_mask = rss_mask & 0x1f; params->num_lro = min_t(int, num_lro , MLX4_EN_MAX_LRO_DESCRIPTORS); - params->rx_pause = pprx; - params->rx_ppp = pfcrx; - params->tx_pause = pptx; - params->tx_ppp = pfctx; - if (params->rx_ppp || params->tx_ppp) { + for (i = 1; i <= MLX4_MAX_PORTS; i++) { + params->prof[i].rx_pause = pprx; + params->prof[i].rx_ppp = pfcrx; + params->prof[i].tx_pause = pptx; + params->prof[i].tx_ppp = pfctx; + } + if (pfcrx || pfctx) { params->prof[1].tx_ring_num = MLX4_EN_TX_RING_NUM; params->prof[2].tx_ring_num = MLX4_EN_TX_RING_NUM; } else { @@ -407,14 +410,14 @@ static int mlx4_en_set_pauseparam(struct net_device *dev, struct mlx4_en_dev *mdev = priv->mdev; int err; - mdev->profile.tx_pause = pause->tx_pause != 0; - mdev->profile.rx_pause = pause->rx_pause != 0; + priv->prof->tx_pause = pause->tx_pause != 0; + priv->prof->rx_pause = pause->rx_pause != 0; err = mlx4_SET_PORT_general(mdev->dev, priv->port, priv->rx_skb_size + ETH_FCS_LEN, - mdev->profile.tx_pause, - mdev->profile.tx_ppp, - mdev->profile.rx_pause, - mdev->profile.rx_ppp); + priv->prof->tx_pause, + priv->prof->tx_ppp, + priv->prof->rx_pause, + priv->prof->rx_ppp); if (err) mlx4_err(mdev, "Failed setting pause params to\n"); @@ -425,10 +428,9 @@ static void mlx4_en_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *pause) { struct mlx4_en_priv *priv = netdev_priv(dev); - struct mlx4_en_dev *mdev = priv->mdev; - pause->tx_pause = mdev->profile.tx_pause; - pause->rx_pause = mdev->profile.rx_pause; + pause->tx_pause = priv->prof->tx_pause; + pause->rx_pause = priv->prof->rx_pause; } static void mlx4_en_get_ringparam(struct net_device *dev, diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h index 11fb17c6e97b..98ddc0811f93 100644 --- a/drivers/net/mlx4/mlx4_en.h +++ b/drivers/net/mlx4/mlx4_en.h @@ -322,6 +322,10 @@ struct mlx4_en_port_profile { u32 rx_ring_num; u32 tx_ring_size; u32 rx_ring_size; + u8 rx_pause; + u8 rx_ppp; + u8 tx_pause; + u8 tx_ppp; }; struct mlx4_en_profile { @@ -333,10 +337,6 @@ struct mlx4_en_profile { int rx_moder_cnt; int rx_moder_time; int auto_moder; - u8 rx_pause; - u8 rx_ppp; - u8 tx_pause; - u8 tx_ppp; u8 no_reset; struct mlx4_en_port_profile prof[MLX4_MAX_PORTS + 1]; }; -- cgit v1.2.3 From 605f196efbf8dcbb3581e76ddd0573899dffcf1f Mon Sep 17 00:00:00 2001 From: Ron Madrid Date: Thu, 6 Nov 2008 09:05:26 +0000 Subject: phy: Add support for Marvell 88E1118 PHY This patch will add support for the Marvell 88E1118 PHY which supports gigabit ethernet among other things. Signed-off-by: Ron Madrid Signed-off-by: David S. Miller --- drivers/net/phy/marvell.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index 4aa547947040..eb6411c4694f 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -227,6 +227,59 @@ static int m88e1111_config_init(struct phy_device *phydev) return 0; } +static int m88e1118_config_aneg(struct phy_device *phydev) +{ + int err; + + 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; + + err = genphy_config_aneg(phydev); + return 0; +} + +static int m88e1118_config_init(struct phy_device *phydev) +{ + int err; + + /* Change address */ + err = phy_write(phydev, 0x16, 0x0002); + if (err < 0) + return err; + + /* Enable 1000 Mbit */ + err = phy_write(phydev, 0x15, 0x1070); + if (err < 0) + return err; + + /* Change address */ + err = phy_write(phydev, 0x16, 0x0003); + if (err < 0) + return err; + + /* Adjust LED Control */ + err = phy_write(phydev, 0x10, 0x021e); + if (err < 0) + return err; + + /* Reset address */ + err = phy_write(phydev, 0x16, 0x0); + if (err < 0) + return err; + + err = phy_write(phydev, MII_BMCR, BMCR_RESET); + if (err < 0) + return err; + + return 0; +} + static int m88e1145_config_init(struct phy_device *phydev) { int err; @@ -415,6 +468,19 @@ static struct phy_driver marvell_drivers[] = { .config_intr = &marvell_config_intr, .driver = { .owner = THIS_MODULE }, }, + { + .phy_id = 0x01410e10, + .phy_id_mask = 0xfffffff0, + .name = "Marvell 88E1118", + .features = PHY_GBIT_FEATURES, + .flags = PHY_HAS_INTERRUPT, + .config_init = &m88e1118_config_init, + .config_aneg = &m88e1118_config_aneg, + .read_status = &genphy_read_status, + .ack_interrupt = &marvell_ack_interrupt, + .config_intr = &marvell_config_intr, + .driver = {.owner = THIS_MODULE,}, + }, { .phy_id = 0x01410cd0, .phy_id_mask = 0xfffffff0, -- cgit v1.2.3 From 5f5c4bdb144bf285727867bbd75c13c5a99150c9 Mon Sep 17 00:00:00 2001 From: Joey Zhuo Date: Sun, 16 Nov 2008 00:39:35 -0800 Subject: via-velocity: enable perfect filtering for multicast packets Signed-off-by: Joey Zhuo Acked-by: Francois Romieu Signed-off-by: David S. Miller --- drivers/net/via-velocity.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index 3590ea5a902d..11cb3e504e1c 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -2296,7 +2296,7 @@ static void velocity_set_multi(struct net_device *dev) } mac_set_cam_mask(regs, vptr->mCAMmask); - rx_mode = (RCR_AM | RCR_AB); + rx_mode = RCR_AM | RCR_AB | RCR_AP; } if (dev->mtu > 1500) rx_mode |= RCR_AL; -- cgit v1.2.3 From 6ff68026f4757d68461b7fbeca5c944e1f5f8b44 Mon Sep 17 00:00:00 2001 From: "\\\"Rafael J. Wysocki\\" Date: Wed, 12 Nov 2008 09:52:32 +0000 Subject: e1000e: Use device_set_wakeup_enable Since dev->power.should_wakeup bit is used by the PCI core to decide whether the device should wake up the system from sleep states, set/unset this bit whenever WOL is enabled/disabled using e1000_set_wol(). Accordingly, use device_can_wakeup() for checking if wake-up is supported by the device. Signed-off-by: "Rafael J. Wysocki" Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/e1000e/ethtool.c | 8 ++++++-- drivers/net/e1000e/netdev.c | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index 70c11c811a08..62421ce96311 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -1713,7 +1713,8 @@ static void e1000_get_wol(struct net_device *netdev, wol->supported = 0; wol->wolopts = 0; - if (!(adapter->flags & FLAG_HAS_WOL)) + if (!(adapter->flags & FLAG_HAS_WOL) || + !device_can_wakeup(&adapter->pdev->dev)) return; wol->supported = WAKE_UCAST | WAKE_MCAST | @@ -1751,7 +1752,8 @@ static int e1000_set_wol(struct net_device *netdev, if (wol->wolopts & WAKE_MAGICSECURE) return -EOPNOTSUPP; - if (!(adapter->flags & FLAG_HAS_WOL)) + if (!(adapter->flags & FLAG_HAS_WOL) || + !device_can_wakeup(&adapter->pdev->dev)) return wol->wolopts ? -EOPNOTSUPP : 0; /* these settings will always override what we currently have */ @@ -1770,6 +1772,8 @@ static int e1000_set_wol(struct net_device *netdev, if (wol->wolopts & WAKE_ARP) adapter->wol |= E1000_WUFC_ARP; + device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); + return 0; } diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index abd492b7336d..2c8dffdc889f 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -4970,6 +4970,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, /* initialize the wol settings based on the eeprom settings */ adapter->wol = adapter->eeprom_wol; + device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); /* reset the hardware with the new settings */ e1000e_reset(adapter); -- cgit v1.2.3 From de1264896c8012a261c1cba17e6a61199c276ad3 Mon Sep 17 00:00:00 2001 From: "\\\"Rafael J. Wysocki\\" Date: Fri, 7 Nov 2008 20:30:19 +0000 Subject: e1000: Use device_set_wakeup_enable Since dev->power.should_wakeup bit is used by the PCI core to decide whether the device should wake up the system from sleep states, set/unset this bit whenever WOL is enabled/disabled using e1000_set_wol(). Accordingly, use device_can_wakeup() for checking if wake-up is supported by the device. Signed-off-by: "Rafael J. Wysocki" Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/e1000/e1000_ethtool.c | 8 ++++++-- drivers/net/e1000/e1000_main.c | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index 6a3893acfe04..c854c96f5ab3 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c @@ -1774,7 +1774,8 @@ static void e1000_get_wol(struct net_device *netdev, /* this function will set ->supported = 0 and return 1 if wol is not * supported by this hardware */ - if (e1000_wol_exclusion(adapter, wol)) + if (e1000_wol_exclusion(adapter, wol) || + !device_can_wakeup(&adapter->pdev->dev)) return; /* apply any specific unsupported masks here */ @@ -1811,7 +1812,8 @@ static int e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE)) return -EOPNOTSUPP; - if (e1000_wol_exclusion(adapter, wol)) + if (e1000_wol_exclusion(adapter, wol) || + !device_can_wakeup(&adapter->pdev->dev)) return wol->wolopts ? -EOPNOTSUPP : 0; switch (hw->device_id) { @@ -1838,6 +1840,8 @@ static int e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) if (wol->wolopts & WAKE_MAGIC) adapter->wol |= E1000_WUFC_MAG; + device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); + return 0; } diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index fac82152e4c8..872799b746f5 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -1179,6 +1179,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, /* initialize the wol settings based on the eeprom settings */ adapter->wol = adapter->eeprom_wol; + device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); /* print bus type/speed/width info */ DPRINTK(PROBE, INFO, "(PCI%s:%s:%s) ", -- cgit v1.2.3 From e1b86d8479f90aadee57a3d07d8e61c815c202d9 Mon Sep 17 00:00:00 2001 From: "\\\"Rafael J. Wysocki\\" Date: Fri, 7 Nov 2008 20:30:37 +0000 Subject: igb: Use device_set_wakeup_enable Since dev->power.should_wakeup bit is used by the PCI core to decide whether the device should wake up the system from sleep states, set/unset this bit whenever WOL is enabled/disabled using igb_set_wol(). Accordingly, use device_can_wakeup() for checking if wake-up is supported by the device. Signed-off-by: "Rafael J. Wysocki" Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/igb/igb_ethtool.c | 8 ++++++-- drivers/net/igb/igb_main.c | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c index 58906c984be9..89964fa739a0 100644 --- a/drivers/net/igb/igb_ethtool.c +++ b/drivers/net/igb/igb_ethtool.c @@ -1776,7 +1776,8 @@ static void igb_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) /* this function will set ->supported = 0 and return 1 if wol is not * supported by this hardware */ - if (igb_wol_exclusion(adapter, wol)) + if (igb_wol_exclusion(adapter, wol) || + !device_can_wakeup(&adapter->pdev->dev)) return; /* apply any specific unsupported masks here */ @@ -1805,7 +1806,8 @@ static int igb_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE)) return -EOPNOTSUPP; - if (igb_wol_exclusion(adapter, wol)) + if (igb_wol_exclusion(adapter, wol) || + !device_can_wakeup(&adapter->pdev->dev)) return wol->wolopts ? -EOPNOTSUPP : 0; switch (hw->device_id) { @@ -1825,6 +1827,8 @@ static int igb_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) if (wol->wolopts & WAKE_MAGIC) adapter->wol |= E1000_WUFC_MAG; + device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); + return 0; } diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 1f397cd99414..0a9801516ae0 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -1244,6 +1244,7 @@ static int __devinit igb_probe(struct pci_dev *pdev, /* initialize the wol settings based on the eeprom settings */ adapter->wol = adapter->eeprom_wol; + device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); /* reset the hardware with the new settings */ igb_reset(adapter); -- cgit v1.2.3 From 0f807044980dd51fdf9aa2df8d503d4757501b20 Mon Sep 17 00:00:00 2001 From: Ron Mercer Date: Tue, 11 Nov 2008 07:54:54 +0000 Subject: qla3xxx: Cleanup: Fix link print statements. Removed debug print statements and improved conditionals around informational statements. Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qla3xxx.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c index 3cdd07c45b6d..508452c02151 100644 --- a/drivers/net/qla3xxx.c +++ b/drivers/net/qla3xxx.c @@ -1515,9 +1515,6 @@ static u32 ql_get_link_state(struct ql3_adapter *qdev) linkState = LS_UP; } else { linkState = LS_DOWN; - if (netif_msg_link(qdev)) - printk(KERN_WARNING PFX - "%s: Link is down.\n", qdev->ndev->name); } return linkState; } @@ -1581,10 +1578,6 @@ static int ql_finish_auto_neg(struct ql3_adapter *qdev) ql_mac_enable(qdev, 1); } - if (netif_msg_link(qdev)) - printk(KERN_DEBUG PFX - "%s: Change port_link_state LS_DOWN to LS_UP.\n", - qdev->ndev->name); qdev->port_link_state = LS_UP; netif_start_queue(qdev->ndev); netif_carrier_on(qdev->ndev); @@ -1655,14 +1648,9 @@ static void ql_link_state_machine_work(struct work_struct *work) /* Fall Through */ case LS_DOWN: - if (netif_msg_link(qdev)) - printk(KERN_DEBUG PFX - "%s: port_link_state = LS_DOWN.\n", - qdev->ndev->name); if (curr_link_state == LS_UP) { if (netif_msg_link(qdev)) - printk(KERN_DEBUG PFX - "%s: curr_link_state = LS_UP.\n", + printk(KERN_INFO PFX "%s: Link is up.\n", qdev->ndev->name); if (ql_is_auto_neg_complete(qdev)) ql_finish_auto_neg(qdev); @@ -1670,6 +1658,7 @@ static void ql_link_state_machine_work(struct work_struct *work) if (qdev->port_link_state == LS_UP) ql_link_down_detect_clear(qdev); + qdev->port_link_state = LS_UP; } break; @@ -1678,12 +1667,14 @@ static void ql_link_state_machine_work(struct work_struct *work) * See if the link is currently down or went down and came * back up */ - if ((curr_link_state == LS_DOWN) || ql_link_down_detect(qdev)) { + if (curr_link_state == LS_DOWN) { if (netif_msg_link(qdev)) printk(KERN_INFO PFX "%s: Link is down.\n", qdev->ndev->name); qdev->port_link_state = LS_DOWN; } + if (ql_link_down_detect(qdev)) + qdev->port_link_state = LS_DOWN; break; } spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); -- cgit v1.2.3 From ac450208dea8cf1b9aa8feabd06a7209a282d749 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 13 Nov 2008 06:20:10 +0000 Subject: igb: use dev_printk instead of printk Use dev_printk() instead of printk() to give a little more context and use consistent format. Signed-off-by: Bjorn Helgaas Signed-off-by: David S. Miller --- drivers/net/igb/igb_main.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 0a9801516ae0..1cbae85b1426 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -1019,10 +1019,9 @@ static int __devinit igb_probe(struct pci_dev *pdev, state &= ~PCIE_LINK_STATE_L0S; pci_write_config_word(us_dev, pos + PCI_EXP_LNKCTL, state); - printk(KERN_INFO "Disabling ASPM L0s upstream switch " - "port %x:%x.%x\n", us_dev->bus->number, - PCI_SLOT(us_dev->devfn), - PCI_FUNC(us_dev->devfn)); + dev_info(&pdev->dev, + "Disabling ASPM L0s upstream switch port %s\n", + pci_name(us_dev)); } default: break; -- cgit v1.2.3 From 773c9c1f77174429ad2feb1735a3beb33ff3b6c0 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Fri, 14 Nov 2008 13:51:54 +0000 Subject: e100: fix dma error in direction for mapping The e100 driver triggers BUG_ON(buf->direction != dir) by doing pci_map_single(..., PCI_DMA_BIDIRECTIONAL) and pci_dma_sync_single_for_device(..., PCI_DMA_TODEVICE). Changing the DMA direction, especially with dmabounce will result in unexpected behaviour. Reported-by: Anders Grafstrom Signed-off-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/e100.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 3d69fae781cf..e8bfcce6b319 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -166,7 +166,7 @@ #define DRV_NAME "e100" #define DRV_EXT "-NAPI" -#define DRV_VERSION "3.5.23-k4"DRV_EXT +#define DRV_VERSION "3.5.23-k6"DRV_EXT #define DRV_DESCRIPTION "Intel(R) PRO/100 Network Driver" #define DRV_COPYRIGHT "Copyright(c) 1999-2006 Intel Corporation" #define PFX DRV_NAME ": " @@ -1804,7 +1804,7 @@ static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx) struct rfd *prev_rfd = (struct rfd *)rx->prev->skb->data; put_unaligned_le32(rx->dma_addr, &prev_rfd->link); pci_dma_sync_single_for_device(nic->pdev, rx->prev->dma_addr, - sizeof(struct rfd), PCI_DMA_TODEVICE); + sizeof(struct rfd), PCI_DMA_BIDIRECTIONAL); } return 0; @@ -1823,7 +1823,7 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx, /* Need to sync before taking a peek at cb_complete bit */ pci_dma_sync_single_for_cpu(nic->pdev, rx->dma_addr, - sizeof(struct rfd), PCI_DMA_FROMDEVICE); + sizeof(struct rfd), PCI_DMA_BIDIRECTIONAL); rfd_status = le16_to_cpu(rfd->status); DPRINTK(RX_STATUS, DEBUG, "status=0x%04X\n", rfd_status); @@ -1850,7 +1850,7 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx, /* Get data */ pci_unmap_single(nic->pdev, rx->dma_addr, - RFD_BUF_LEN, PCI_DMA_FROMDEVICE); + RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL); /* If this buffer has the el bit, but we think the receiver * is still running, check to see if it really stopped while @@ -1943,7 +1943,7 @@ static void e100_rx_clean(struct nic *nic, unsigned int *work_done, new_before_last_rfd->command |= cpu_to_le16(cb_el); pci_dma_sync_single_for_device(nic->pdev, new_before_last_rx->dma_addr, sizeof(struct rfd), - PCI_DMA_TODEVICE); + PCI_DMA_BIDIRECTIONAL); /* Now that we have a new stopping point, we can clear the old * stopping point. We must sync twice to get the proper @@ -1951,11 +1951,11 @@ static void e100_rx_clean(struct nic *nic, unsigned int *work_done, old_before_last_rfd->command &= ~cpu_to_le16(cb_el); pci_dma_sync_single_for_device(nic->pdev, old_before_last_rx->dma_addr, sizeof(struct rfd), - PCI_DMA_TODEVICE); + PCI_DMA_BIDIRECTIONAL); old_before_last_rfd->size = cpu_to_le16(VLAN_ETH_FRAME_LEN); pci_dma_sync_single_for_device(nic->pdev, old_before_last_rx->dma_addr, sizeof(struct rfd), - PCI_DMA_TODEVICE); + PCI_DMA_BIDIRECTIONAL); } if(restart_required) { @@ -1978,7 +1978,7 @@ static void e100_rx_clean_list(struct nic *nic) for(rx = nic->rxs, i = 0; i < count; rx++, i++) { if(rx->skb) { pci_unmap_single(nic->pdev, rx->dma_addr, - RFD_BUF_LEN, PCI_DMA_FROMDEVICE); + RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL); dev_kfree_skb(rx->skb); } } @@ -2021,7 +2021,7 @@ static int e100_rx_alloc_list(struct nic *nic) before_last->command |= cpu_to_le16(cb_el); before_last->size = 0; pci_dma_sync_single_for_device(nic->pdev, rx->dma_addr, - sizeof(struct rfd), PCI_DMA_TODEVICE); + sizeof(struct rfd), PCI_DMA_BIDIRECTIONAL); nic->rx_to_use = nic->rx_to_clean = nic->rxs; nic->ru_running = RU_SUSPENDED; @@ -2222,7 +2222,7 @@ static int e100_loopback_test(struct nic *nic, enum loopback loopback_mode) msleep(10); pci_dma_sync_single_for_cpu(nic->pdev, nic->rx_to_clean->dma_addr, - RFD_BUF_LEN, PCI_DMA_FROMDEVICE); + RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL); if(memcmp(nic->rx_to_clean->skb->data + sizeof(struct rfd), skb->data, ETH_DATA_LEN)) -- cgit v1.2.3 From 3ee82383f0098a2e13acc8cf1be8e47512f41e5a Mon Sep 17 00:00:00 2001 From: Giulio Benetti Date: Thu, 13 Nov 2008 21:53:13 +0000 Subject: phy: fix phy address bug PHYID returns 0xffff and not 0xffffffff when not found and in some case(at91sam9263) 0x0. Maybe this patch could be useful. Signed-off-by: Giulio Benetti Signed-off-by: David S. Miller --- drivers/net/phy/phy_device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index e11b03b2b25a..8fb1faca883a 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -227,8 +227,8 @@ struct phy_device * get_phy_device(struct mii_bus *bus, int addr) if (r) return ERR_PTR(r); - /* If the phy_id is all Fs, there is no device there */ - if (0xffffffff == phy_id) + /* If the phy_id is all Fs or all 0s, there is no device there */ + if ((0xffff == phy_id) || (0x00 == phy_id)) return NULL; dev = phy_device_create(bus, addr, phy_id); -- cgit v1.2.3 From e82f54ba030b429c06b5240cbe7eeaaa03a8db11 Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Fri, 14 Nov 2008 06:45:07 +0000 Subject: e1000e: fix warn_on reload after phy_id error If the driver fails to initialize the first time due to the failure in the phy_id check the kernel triggers a warn_on on the second try to load the driver because the driver did not free the msi/x resources in the first load because of the previous failure in phy_id check. Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/e1000e/netdev.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 2c8dffdc889f..f6ebebb8cfa5 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -5009,6 +5009,7 @@ err_hw_init: err_sw_init: if (adapter->hw.flash_address) iounmap(adapter->hw.flash_address); + e1000e_reset_interrupt_capability(adapter); err_flashmap: iounmap(adapter->hw.hw_addr); err_ioremap: -- cgit v1.2.3 From eb7c3adb1ca92450870dbb0d347fc986cd5e2af4 Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Fri, 14 Nov 2008 06:45:23 +0000 Subject: e1000e: fix IPMI traffic Some users reported that they have machines with BMCs enabled that cannot receive IPMI traffic after e1000e is loaded. http://marc.info/?l=e1000-devel&m=121909039127414&w=2 http://marc.info/?l=e1000-devel&m=121365543823387&w=2 This fixes the issue if they load with the new parameter = 0 by disabling crc stripping, but leaves the performance feature on for most users. Based on work done by Hong Zhang. Signed-off-by: Jeff Kirsher Signed-off-by: Jesse Brandeburg Signed-off-by: David S. Miller --- drivers/net/e1000e/e1000.h | 5 +++++ drivers/net/e1000e/netdev.c | 23 +++++++++++++++++++++-- drivers/net/e1000e/param.c | 25 +++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index c55de1c027af..c55fd6fdb91c 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -299,6 +299,7 @@ struct e1000_adapter { unsigned long led_status; unsigned int flags; + unsigned int flags2; struct work_struct downshift_task; struct work_struct update_phy_task; }; @@ -306,6 +307,7 @@ struct e1000_adapter { struct e1000_info { enum e1000_mac_type mac; unsigned int flags; + unsigned int flags2; u32 pba; s32 (*get_variants)(struct e1000_adapter *); struct e1000_mac_operations *mac_ops; @@ -347,6 +349,9 @@ struct e1000_info { #define FLAG_RX_RESTART_NOW (1 << 30) #define FLAG_MSI_TEST_FAILED (1 << 31) +/* CRC Stripping defines */ +#define FLAG2_CRC_STRIPPING (1 << 0) + #define E1000_RX_DESC_PS(R, i) \ (&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) #define E1000_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i])) diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index f6ebebb8cfa5..91795f78c3e4 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -499,6 +499,10 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, goto next_desc; } + /* adjust length to remove Ethernet CRC */ + if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) + length -= 4; + total_rx_bytes += length; total_rx_packets++; @@ -804,6 +808,10 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, pci_dma_sync_single_for_device(pdev, ps_page->dma, PAGE_SIZE, PCI_DMA_FROMDEVICE); + /* remove the CRC */ + if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) + l1 -= 4; + skb_put(skb, l1); goto copydone; } /* if */ @@ -825,6 +833,12 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, skb->truesize += length; } + /* strip the ethernet crc, problem is we're using pages now so + * this whole operation can get a little cpu intensive + */ + if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) + pskb_trim(skb, skb->len - 4); + copydone: total_rx_bytes += skb->len; total_rx_packets++; @@ -2301,8 +2315,12 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) else rctl |= E1000_RCTL_LPE; - /* Enable hardware CRC frame stripping */ - rctl |= E1000_RCTL_SECRC; + /* Some systems expect that the CRC is included in SMBUS traffic. The + * hardware strips the CRC before sending to both SMBUS (BMC) and to + * host memory when this is enabled + */ + if (adapter->flags2 & FLAG2_CRC_STRIPPING) + rctl |= E1000_RCTL_SECRC; /* Setup buffer sizes */ rctl &= ~E1000_RCTL_SZ_4096; @@ -4766,6 +4784,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, adapter->ei = ei; adapter->pba = ei->pba; adapter->flags = ei->flags; + adapter->flags2 = ei->flags2; adapter->hw.adapter = adapter; adapter->hw.mac.type = ei->mac; adapter->msg_enable = (1 << NETIF_MSG_DRV | NETIF_MSG_PROBE) - 1; diff --git a/drivers/net/e1000e/param.c b/drivers/net/e1000e/param.c index 77a3d7207a5f..e909f96698e8 100644 --- a/drivers/net/e1000e/param.c +++ b/drivers/net/e1000e/param.c @@ -151,6 +151,16 @@ E1000_PARAM(KumeranLockLoss, "Enable Kumeran lock loss workaround"); */ E1000_PARAM(WriteProtectNVM, "Write-protect NVM [WARNING: disabling this can lead to corrupted NVM]"); +/* + * Enable CRC Stripping + * + * Valid Range: 0, 1 + * + * Default Value: 1 (enabled) + */ +E1000_PARAM(CrcStripping, "Enable CRC Stripping, disable if your BMC needs " \ + "the CRC"); + struct e1000_option { enum { enable_option, range_option, list_option } type; const char *name; @@ -404,6 +414,21 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter) adapter->flags |= FLAG_SMART_POWER_DOWN; } } + { /* CRC Stripping */ + const struct e1000_option opt = { + .type = enable_option, + .name = "CRC Stripping", + .err = "defaulting to enabled", + .def = OPTION_ENABLED + }; + + if (num_CrcStripping > bd) { + unsigned int crc_stripping = CrcStripping[bd]; + e1000_validate_option(&crc_stripping, &opt, adapter); + if (crc_stripping == OPTION_ENABLED) + adapter->flags2 |= FLAG2_CRC_STRIPPING; + } + } { /* Kumeran Lock Loss Workaround */ const struct e1000_option opt = { .type = enable_option, -- cgit v1.2.3