From fde9403a982218fa8a437f815e7aa0e583e2d6ed Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Mon, 11 Aug 2008 12:56:44 +0800 Subject: [netdrvr] remove unnecessary #include The drivers below do not use LINUX_VERSION_CODE nor KERNEL_VERSION. drivers/net/acenic.c drivers/net/bnx2x_link.c drivers/net/bnx2x_main.c drivers/net/cpmac.c drivers/net/gianfar_sysfs.c drivers/net/ipg.h drivers/net/ppp_mppe.c drivers/net/pppol2tp.c drivers/net/r6040.c drivers/net/sh_eth.c drivers/net/sky2.c drivers/net/tehuti.h drivers/net/typhoon.c This patch removes the said #include . Signed-off-by: Huang Weiyi Signed-off-by: Jeff Garzik --- drivers/net/acenic.c | 1 - drivers/net/bnx2x_link.c | 1 - drivers/net/bnx2x_main.c | 1 - drivers/net/cpmac.c | 1 - drivers/net/gianfar_sysfs.c | 1 - drivers/net/ipg.h | 2 -- drivers/net/ppp_mppe.c | 1 - drivers/net/pppol2tp.c | 1 - drivers/net/r6040.c | 1 - drivers/net/sh_eth.c | 1 - drivers/net/sky2.c | 1 - drivers/net/tehuti.h | 1 - drivers/net/typhoon.c | 1 - 13 files changed, 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c index e4483de84e7f..66de80b64b92 100644 --- a/drivers/net/acenic.c +++ b/drivers/net/acenic.c @@ -52,7 +52,6 @@ #include #include -#include #include #include #include diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c index 8b92c6ad0759..4ce7fe9c5251 100644 --- a/drivers/net/bnx2x_link.c +++ b/drivers/net/bnx2x_link.c @@ -21,7 +21,6 @@ #include #include #include -#include #include "bnx2x_reg.h" #include "bnx2x_fw_defs.h" diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 3e7dc171cdf1..971576b43687 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -44,7 +44,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index a7800e559090..ec6b0af3d46b 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/drivers/net/gianfar_sysfs.c b/drivers/net/gianfar_sysfs.c index 5116f68e01b9..782c20170082 100644 --- a/drivers/net/gianfar_sysfs.c +++ b/drivers/net/gianfar_sysfs.c @@ -33,7 +33,6 @@ #include #include -#include #include "gianfar.h" diff --git a/drivers/net/ipg.h b/drivers/net/ipg.h index e0e718ab4c2e..dd9318f19497 100644 --- a/drivers/net/ipg.h +++ b/drivers/net/ipg.h @@ -7,7 +7,6 @@ #ifndef __LINUX_IPG_H #define __LINUX_IPG_H -#include #include #include @@ -21,7 +20,6 @@ #include #include #include -#include #include /* diff --git a/drivers/net/ppp_mppe.c b/drivers/net/ppp_mppe.c index b35d79449500..88f03c9e9403 100644 --- a/drivers/net/ppp_mppe.c +++ b/drivers/net/ppp_mppe.c @@ -46,7 +46,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c index f9298827a76c..ff175e8f36b2 100644 --- a/drivers/net/pppol2tp.c +++ b/drivers/net/pppol2tp.c @@ -61,7 +61,6 @@ */ #include -#include #include #include #include diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 6531ff565c54..5d86281d9363 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -24,7 +24,6 @@ #include #include -#include #include #include #include diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index 25e62cf58d3a..1c370e6aa641 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -20,7 +20,6 @@ * the file called "COPYING". */ -#include #include #include #include diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 7d29edcd40b4..06dfc950f33e 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -24,7 +24,6 @@ #include #include -#include #include #include #include diff --git a/drivers/net/tehuti.h b/drivers/net/tehuti.h index c66dfc9ec1ec..7db48f1cd949 100644 --- a/drivers/net/tehuti.h +++ b/drivers/net/tehuti.h @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 8549f1159a30..734ce0977f02 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -128,7 +128,6 @@ static const int multicast_filter_limit = 32; #include #include #include -#include #include #include "typhoon.h" -- cgit v1.2.2 From 2a54adc3ad771c997bfa721f098d2d4a6ef6ea38 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Tue, 12 Aug 2008 15:10:46 -0500 Subject: gianfar: Call gfar_halt_nodisable() from gfar_halt(). gfar_halt() was factored out into halting and disabling by commit d87eb12785c14de1586e3bad86ca2c0991300339, as the suspend() method only wants to do the former. However, the call to gfar_halt_nodisable() from gfar_halt() apparently got lost during the patch respin process. This adds it back. Signed-off-by: Scott Wood Signed-off-by: Jeff Garzik --- drivers/net/gianfar.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index ca6cf6ecb37b..999d69168277 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -134,9 +134,7 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int l static void gfar_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp); void gfar_halt(struct net_device *dev); -#ifdef CONFIG_PM static void gfar_halt_nodisable(struct net_device *dev); -#endif void gfar_start(struct net_device *dev); static void gfar_clear_exact_match(struct net_device *dev); static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr); @@ -631,7 +629,6 @@ static void init_registers(struct net_device *dev) } -#ifdef CONFIG_PM /* Halt the receive and transmit queues */ static void gfar_halt_nodisable(struct net_device *dev) { @@ -657,7 +654,6 @@ static void gfar_halt_nodisable(struct net_device *dev) cpu_relax(); } } -#endif /* Halt the receive and transmit queues */ void gfar_halt(struct net_device *dev) @@ -666,6 +662,8 @@ void gfar_halt(struct net_device *dev) struct gfar __iomem *regs = priv->regs; u32 tempval; + gfar_halt_nodisable(dev); + /* Disable Rx and Tx */ tempval = gfar_read(®s->maccfg1); tempval &= ~(MACCFG1_RX_EN | MACCFG1_TX_EN); -- cgit v1.2.2 From 7144decb0f482fcb2152c10c376f0574d563ca52 Mon Sep 17 00:00:00 2001 From: Mikael Pettersson Date: Wed, 13 Aug 2008 21:08:14 +0200 Subject: ixp4xx_eth: fix dma_mapping_error() compile errors The arm ixp4xx_eth driver doesn't compile in 2.6.27-rc1: CC [M] drivers/net/arm/ixp4xx_eth.o drivers/net/arm/ixp4xx_eth.c: In function 'eth_poll': drivers/net/arm/ixp4xx_eth.c:554: warning: passing argument 1 of 'dma_mapping_error' makes pointer from integer without a cast drivers/net/arm/ixp4xx_eth.c:554: error: too few arguments to function 'dma_mapping_error' drivers/net/arm/ixp4xx_eth.c: In function 'eth_xmit': drivers/net/arm/ixp4xx_eth.c:701: warning: passing argument 1 of 'dma_mapping_error' makes pointer from integer without a cast drivers/net/arm/ixp4xx_eth.c:701: error: too few arguments to function 'dma_mapping_error' drivers/net/arm/ixp4xx_eth.c: In function 'init_queues': drivers/net/arm/ixp4xx_eth.c:886: warning: passing argument 1 of 'dma_mapping_error' makes pointer from integer without a cast drivers/net/arm/ixp4xx_eth.c:886: error: too few arguments to function 'dma_mapping_error' make[3]: *** [drivers/net/arm/ixp4xx_eth.o] Error 1 make[2]: *** [drivers/net/arm] Error 2 make[1]: *** [drivers/net] Error 2 make: *** [drivers] Error 2 dma_mapping_error() changed in 2.6.27-rc1 to also take a device parameter, but nobody bothered updating ixp4xx_eth.c. Fixed by passing the appropriate device value in the dma_mapping_error() calls. Tested on an ixp425 box. Signed-off-by: Mikael Pettersson Acked-by: Krzysztof Halasa Signed-off-by: Jeff Garzik --- drivers/net/arm/ixp4xx_eth.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/arm/ixp4xx_eth.c b/drivers/net/arm/ixp4xx_eth.c index 9b777d9433cd..7d5db2ece1bd 100644 --- a/drivers/net/arm/ixp4xx_eth.c +++ b/drivers/net/arm/ixp4xx_eth.c @@ -551,7 +551,7 @@ static int eth_poll(struct napi_struct *napi, int budget) if ((skb = netdev_alloc_skb(dev, RX_BUFF_SIZE))) { phys = dma_map_single(&dev->dev, skb->data, RX_BUFF_SIZE, DMA_FROM_DEVICE); - if (dma_mapping_error(phys)) { + if (dma_mapping_error(&dev->dev, phys)) { dev_kfree_skb(skb); skb = NULL; } @@ -698,7 +698,7 @@ static int eth_xmit(struct sk_buff *skb, struct net_device *dev) #endif phys = dma_map_single(&dev->dev, mem, bytes, DMA_TO_DEVICE); - if (dma_mapping_error(phys)) { + if (dma_mapping_error(&dev->dev, phys)) { #ifdef __ARMEB__ dev_kfree_skb(skb); #else @@ -883,7 +883,7 @@ static int init_queues(struct port *port) desc->buf_len = MAX_MRU; desc->data = dma_map_single(&port->netdev->dev, data, RX_BUFF_SIZE, DMA_FROM_DEVICE); - if (dma_mapping_error(desc->data)) { + if (dma_mapping_error(&port->netdev->dev, desc->data)) { free_buffer(buff); return -EIO; } -- cgit v1.2.2 From 13b2738cbb4b59f695bd72bcaabd71317e7731d2 Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Wed, 13 Aug 2008 21:05:52 +0200 Subject: myri10ge: myri10ge_fw_name also overrides the rss firmware When myri10ge_fw_name is given, use it to override the rss firmware name as well. Signed-off-by: Brice Goglin Signed-off-by: Jeff Garzik --- drivers/net/myri10ge/myri10ge.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index f1de38f8b742..5d76cd09e246 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -3548,7 +3548,11 @@ static void myri10ge_probe_slices(struct myri10ge_priv *mgp) /* try to load the slice aware rss firmware */ old_fw = mgp->fw_name; - if (old_fw == myri10ge_fw_aligned) + if (myri10ge_fw_name != NULL) { + dev_info(&mgp->pdev->dev, "overriding rss firmware to %s\n", + myri10ge_fw_name); + mgp->fw_name = myri10ge_fw_name; + } else if (old_fw == myri10ge_fw_aligned) mgp->fw_name = myri10ge_fw_rss_aligned; else mgp->fw_name = myri10ge_fw_rss_unaligned; -- cgit v1.2.2 From 2726fcf0dab1a9b1fd04dea3837b2b0bb639c1bd Mon Sep 17 00:00:00 2001 From: Vegard Nossum Date: Wed, 6 Aug 2008 14:12:11 +0200 Subject: au1000_eth: use 'unsigned long' for irqflags The patch was generated using the Coccinelle semantic patch framework. Cc: Julia Lawall Cc: Alexey Dobriyan Cc: Jeff Garzik Signed-off-by: Vegard Nossum Signed-off-by: Jeff Garzik --- drivers/net/au1000_eth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index cb8be490e5ae..5ee1b0557a02 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c @@ -807,7 +807,7 @@ err_out: static int au1000_init(struct net_device *dev) { struct au1000_private *aup = (struct au1000_private *) dev->priv; - u32 flags; + unsigned long flags; int i; u32 control; -- cgit v1.2.2 From e484d5f5c8c64e2c4f110c59e9e964884107822a Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 10 Aug 2008 19:30:28 +0200 Subject: sky2: Fix suspend/hibernation/shutdown regression with WOL enabled (rev. 2) On my test box with the Asus M3A32-MVP main board there is a regression from 2.6.26 related to suspend, hibernation and shutdown. Namely, if Wake-on-LAN is enabled with 'ethtool -s eth0 wol g', the box hangs solid during all of these operations, while executing either sky2_suspend(), or sky2_shutdown(). This patch fixes it for me. Signed-off-by: Rafael J. Wysocki Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 06dfc950f33e..e24b25ca1c69 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -665,11 +665,16 @@ static void sky2_phy_power_down(struct sky2_hw *hw, unsigned port) if (hw->chip_id != CHIP_ID_YUKON_EC) { if (hw->chip_id == CHIP_ID_YUKON_EC_U) { - ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL); + /* select page 2 to access MAC control register */ + gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 2); + ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL); /* enable Power Down */ ctrl |= PHY_M_PC_POW_D_ENA; gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl); + + /* set page register back to 0 */ + gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0); } /* set IEEE compatible Power Down Mode (dev. #4.99) */ -- cgit v1.2.2 From 0d63bea2c20651588e5e631799a961468a735eb9 Mon Sep 17 00:00:00 2001 From: Robert Fitzsimons Date: Sat, 9 Aug 2008 17:54:02 +0100 Subject: tlan: Fix two regressions introduced by 64bit conversion. Two regressions were introduced by the recent tlan: 64bit conversion commit (93e16847c9db0093065c98063cfc639cdfccf19a). The first in TLan_GetSKB caused a NULL pointer dereference. With the second causing the link to fail to come up. Signed-off-by: Robert Fitzsimons Signed-off-by: Jeff Garzik --- drivers/net/tlan.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c index 85246ed7cb9c..ec871f646766 100644 --- a/drivers/net/tlan.c +++ b/drivers/net/tlan.c @@ -360,8 +360,8 @@ TLan_GetSKB( const struct tlan_list_tag *tag) { unsigned long addr; - addr = tag->buffer[8].address; - addr |= (tag->buffer[9].address << 16) << 16; + addr = tag->buffer[9].address; + addr |= (tag->buffer[8].address << 16) << 16; return (struct sk_buff *) addr; } @@ -1984,7 +1984,6 @@ static void TLan_ResetLists( struct net_device *dev ) TLanList *list; dma_addr_t list_phys; struct sk_buff *skb; - void *t = NULL; priv->txHead = 0; priv->txTail = 0; @@ -2022,7 +2021,8 @@ static void TLan_ResetLists( struct net_device *dev ) } skb_reserve( skb, NET_IP_ALIGN ); - list->buffer[0].address = pci_map_single(priv->pciDev, t, + list->buffer[0].address = pci_map_single(priv->pciDev, + skb->data, TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE); TLan_StoreSKB(list, skb); -- cgit v1.2.2 From 56e1f82968af79f70902008098a4687198142ce7 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 8 Aug 2008 18:35:44 -0700 Subject: e1000e: Return 1 instead of a non-zero value for link up indication A number of users have mentioned they have tools that rely on a link-up indication having a return value of 1 rather than a non-zero value. Signed-off-by: Bruce Allan Signed-off-by: Jeff Kirsher Signed-off-by: Jeff Garzik --- drivers/net/e1000e/ethtool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index cf9679f2b7c4..e21c9e0f3738 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -177,7 +177,7 @@ static u32 e1000_get_link(struct net_device *netdev) u32 status; status = er32(STATUS); - return (status & E1000_STATUS_LU); + return (status & E1000_STATUS_LU) ? 1 : 0; } static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx) -- cgit v1.2.2 From 2d06cad1a5ceb3b04dc9547e261ad4fcebf7433d Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 8 Aug 2008 18:35:51 -0700 Subject: e1000e: Set InterruptThrottleRate to default when invalid value used During module load, seting the InterruptThrottleRate parameter to an invalid value would result in the itr/itr_setting pair being set to unexpected values which would result in poor performance. Signed-off-by: Bruce Allan Signed-off-by: Jeff Kirsher Signed-off-by: Jeff Garzik --- drivers/net/e1000e/param.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000e/param.c b/drivers/net/e1000e/param.c index 8effc3107f9a..b0499f27e5ff 100644 --- a/drivers/net/e1000e/param.c +++ b/drivers/net/e1000e/param.c @@ -327,11 +327,26 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter) e1000_validate_option(&adapter->itr, &opt, adapter); /* - * save the setting, because the dynamic bits - * change itr. clear the lower two bits - * because they are used as control + * Save the setting, because the dynamic bits + * change itr. */ - adapter->itr_setting = adapter->itr & ~3; + if (e1000_validate_option(&adapter->itr, &opt, + adapter) && + (adapter->itr == 3)) { + /* + * In case of invalid user value, + * default to conservative mode. + */ + adapter->itr_setting = adapter->itr; + adapter->itr = 20000; + } else { + /* + * Clear the lower two bits because + * they are used as control. + */ + adapter->itr_setting = + adapter->itr & ~3; + } break; } } else { -- cgit v1.2.2 From 808ff676c46d8e259c2cb38579f94f8e6ae38009 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 8 Aug 2008 18:35:56 -0700 Subject: e1000e: Use skb_copy_to_linear_data_offset introduced in 2.6.22 The e1000e driver was based on a version of e1000 prior to acme's introduction of skb_copy_to_linear_data_offset, and was submitted after acme went through and coverted all the drivers to use it. Signed-off-by: Bruce Allan Signed-off-by: Jeff Kirsher Signed-off-by: Jeff Garzik --- drivers/net/e1000e/netdev.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 05b0b2f9c54b..efa944509a39 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -510,9 +510,12 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, netdev_alloc_skb(netdev, length + NET_IP_ALIGN); if (new_skb) { skb_reserve(new_skb, NET_IP_ALIGN); - memcpy(new_skb->data - NET_IP_ALIGN, - skb->data - NET_IP_ALIGN, - length + NET_IP_ALIGN); + skb_copy_to_linear_data_offset(new_skb, + -NET_IP_ALIGN, + (skb->data - + NET_IP_ALIGN), + (length + + NET_IP_ALIGN)); /* save the skb in buffer_info as good */ buffer_info->skb = skb; skb = new_skb; -- cgit v1.2.2 From 10f1b492135620a87970cad9f80439249dcce299 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 8 Aug 2008 18:36:01 -0700 Subject: e1000e: Increase Tx timeout factor for 10Mbps Prevent Tx hangs from happening on 10Mb flood ping by increasing the timeout factor. Signed-off-by: Bruce Allan Signed-off-by: Jeff Kirsher Signed-off-by: Jeff Garzik --- drivers/net/e1000e/netdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index efa944509a39..4573c7b9cbd9 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -3058,7 +3058,7 @@ static void e1000_watchdog_task(struct work_struct *work) case SPEED_10: txb2b = 0; netdev->tx_queue_len = 10; - adapter->tx_timeout_factor = 14; + adapter->tx_timeout_factor = 16; break; case SPEED_100: txb2b = 0; -- cgit v1.2.2 From d53f706da808e6d93dc60b1910233a309009939f Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 8 Aug 2008 18:36:06 -0700 Subject: e1000e: increase minimum frame size allowed Setting an MTU value below 68 was disabling the network connection and would not reconnect until the driver was reloaded. Prevent changing the MTU to anything below 68. Signed-off-by: Bruce Allan Signed-off-by: Jeff Kirsher Signed-off-by: Jeff Garzik --- drivers/net/e1000e/netdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 4573c7b9cbd9..b8b26cf78de5 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -3724,7 +3724,7 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) struct e1000_adapter *adapter = netdev_priv(netdev); int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; - if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) || + if ((new_mtu < ETH_ZLEN + ETH_FCS_LEN + VLAN_HLEN) || (max_frame > MAX_JUMBO_FRAME_SIZE)) { e_err("Invalid MTU setting\n"); return -EINVAL; -- cgit v1.2.2 From f8d59f7826aa73c5e7682fbed6db38020635d466 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 8 Aug 2008 18:36:11 -0700 Subject: e1000e: test for unusable MSI support Some systems do not like 82571/2 use of 16-bit MSI messages and some other systems claim to support MSI, but neither really works. Setup a test MSI handler to detect whether or not MSI is working properly, and if not, fallback to legacy INTx interrupts. Signed-off-by: Bruce Allan Signed-off-by: Jeff Kirsher Signed-off-by: Jeff Garzik --- drivers/net/e1000e/defines.h | 2 +- drivers/net/e1000e/e1000.h | 1 + drivers/net/e1000e/netdev.c | 172 ++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 164 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h index f823b8ba5785..14b0e6cd3b8d 100644 --- a/drivers/net/e1000e/defines.h +++ b/drivers/net/e1000e/defines.h @@ -389,7 +389,7 @@ /* Interrupt Cause Set */ #define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */ -#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */ +#define E1000_ICS_RXSEQ E1000_ICR_RXSEQ /* Rx sequence error */ #define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* Rx desc min. threshold */ /* Transmit Descriptor Control */ diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index cf57050d99d8..ac4e506b4f88 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -326,6 +326,7 @@ struct e1000_info { #define FLAG_RX_CSUM_ENABLED (1 << 28) #define FLAG_TSO_FORCE (1 << 29) #define FLAG_RX_RESTART_NOW (1 << 30) +#define FLAG_MSI_TEST_FAILED (1 << 31) #define E1000_RX_DESC_PS(R, i) \ (&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index b8b26cf78de5..d266510c8a94 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -1236,26 +1236,36 @@ static irqreturn_t e1000_intr(int irq, void *data) return IRQ_HANDLED; } +/** + * e1000_request_irq - initialize interrupts + * + * Attempts to configure interrupts using the best available + * capabilities of the hardware and kernel. + **/ static int e1000_request_irq(struct e1000_adapter *adapter) { struct net_device *netdev = adapter->netdev; - irq_handler_t handler = e1000_intr; int irq_flags = IRQF_SHARED; int err; - if (!pci_enable_msi(adapter->pdev)) { - adapter->flags |= FLAG_MSI_ENABLED; - handler = e1000_intr_msi; - irq_flags = 0; + if (!(adapter->flags & FLAG_MSI_TEST_FAILED)) { + err = pci_enable_msi(adapter->pdev); + if (!err) { + adapter->flags |= FLAG_MSI_ENABLED; + irq_flags = 0; + } } - err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name, - netdev); + err = request_irq(adapter->pdev->irq, + ((adapter->flags & FLAG_MSI_ENABLED) ? + &e1000_intr_msi : &e1000_intr), + irq_flags, netdev->name, netdev); if (err) { - e_err("Unable to allocate %s interrupt (return: %d)\n", - adapter->flags & FLAG_MSI_ENABLED ? "MSI":"INTx", err); - if (adapter->flags & FLAG_MSI_ENABLED) + if (adapter->flags & FLAG_MSI_ENABLED) { pci_disable_msi(adapter->pdev); + adapter->flags &= ~FLAG_MSI_ENABLED; + } + e_err("Unable to allocate interrupt, Error: %d\n", err); } return err; @@ -2594,6 +2604,135 @@ err: return -ENOMEM; } +/** + * e1000_intr_msi_test - Interrupt Handler + * @irq: interrupt number + * @data: pointer to a network interface device structure + **/ +static irqreturn_t e1000_intr_msi_test(int irq, void *data) +{ + struct net_device *netdev = data; + struct e1000_adapter *adapter = netdev_priv(netdev); + struct e1000_hw *hw = &adapter->hw; + u32 icr = er32(ICR); + + e_dbg("%s: icr is %08X\n", netdev->name, icr); + if (icr & E1000_ICR_RXSEQ) { + adapter->flags &= ~FLAG_MSI_TEST_FAILED; + wmb(); + } + + return IRQ_HANDLED; +} + +/** + * e1000_test_msi_interrupt - Returns 0 for successful test + * @adapter: board private struct + * + * code flow taken from tg3.c + **/ +static int e1000_test_msi_interrupt(struct e1000_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + struct e1000_hw *hw = &adapter->hw; + int err; + + /* poll_enable hasn't been called yet, so don't need disable */ + /* clear any pending events */ + er32(ICR); + + /* free the real vector and request a test handler */ + e1000_free_irq(adapter); + + /* Assume that the test fails, if it succeeds then the test + * MSI irq handler will unset this flag */ + adapter->flags |= FLAG_MSI_TEST_FAILED; + + err = pci_enable_msi(adapter->pdev); + if (err) + goto msi_test_failed; + + err = request_irq(adapter->pdev->irq, &e1000_intr_msi_test, 0, + netdev->name, netdev); + if (err) { + pci_disable_msi(adapter->pdev); + goto msi_test_failed; + } + + wmb(); + + e1000_irq_enable(adapter); + + /* fire an unusual interrupt on the test handler */ + ew32(ICS, E1000_ICS_RXSEQ); + e1e_flush(); + msleep(50); + + e1000_irq_disable(adapter); + + rmb(); + + if (adapter->flags & FLAG_MSI_TEST_FAILED) { + err = -EIO; + e_info("MSI interrupt test failed!\n"); + } + + free_irq(adapter->pdev->irq, netdev); + pci_disable_msi(adapter->pdev); + + if (err == -EIO) + goto msi_test_failed; + + /* okay so the test worked, restore settings */ + e_dbg("%s: MSI interrupt test succeeded!\n", netdev->name); +msi_test_failed: + /* restore the original vector, even if it failed */ + e1000_request_irq(adapter); + return err; +} + +/** + * e1000_test_msi - Returns 0 if MSI test succeeds or INTx mode is restored + * @adapter: board private struct + * + * code flow taken from tg3.c, called with e1000 interrupts disabled. + **/ +static int e1000_test_msi(struct e1000_adapter *adapter) +{ + int err; + u16 pci_cmd; + + if (!(adapter->flags & FLAG_MSI_ENABLED)) + return 0; + + /* disable SERR in case the MSI write causes a master abort */ + pci_read_config_word(adapter->pdev, PCI_COMMAND, &pci_cmd); + pci_write_config_word(adapter->pdev, PCI_COMMAND, + pci_cmd & ~PCI_COMMAND_SERR); + + err = e1000_test_msi_interrupt(adapter); + + /* restore previous setting of command word */ + pci_write_config_word(adapter->pdev, PCI_COMMAND, pci_cmd); + + /* success ! */ + if (!err) + return 0; + + /* EIO means MSI test failed */ + if (err != -EIO) + return err; + + /* back to INTx mode */ + e_warn("MSI interrupt test failed, using legacy interrupt.\n"); + + e1000_free_irq(adapter); + + err = e1000_request_irq(adapter); + + return err; +} + /** * e1000_open - Called when a network interface is made active * @netdev: network interface device structure @@ -2652,6 +2791,19 @@ static int e1000_open(struct net_device *netdev) if (err) goto err_req_irq; + /* + * Work around PCIe errata with MSI interrupts causing some chipsets to + * ignore e1000e MSI messages, which means we need to test our MSI + * interrupt now + */ + { + err = e1000_test_msi(adapter); + if (err) { + e_err("Interrupt allocation failed\n"); + goto err_req_irq; + } + } + /* From here on the code is the same as e1000e_up() */ clear_bit(__E1000_DOWN, &adapter->state); -- cgit v1.2.2 From 05c550babecfc129a8d9331edf43107192bae115 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 8 Aug 2008 18:36:16 -0700 Subject: e1000e: remove unnecessary snippet missed in prior check_options update The removal of this bit of code was missed in an earlier patch submittal. Signed-off-by: Bruce Allan Signed-off-by: Jeff Kirsher Signed-off-by: Jeff Garzik --- drivers/net/e1000e/param.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000e/param.c b/drivers/net/e1000e/param.c index b0499f27e5ff..ed912e023a72 100644 --- a/drivers/net/e1000e/param.c +++ b/drivers/net/e1000e/param.c @@ -324,8 +324,6 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter) adapter->itr = 20000; break; default: - e1000_validate_option(&adapter->itr, &opt, - adapter); /* * Save the setting, because the dynamic bits * change itr. -- cgit v1.2.2 From 8d792cd990938c4d06b86141465ff8d52a946a0a Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Fri, 8 Aug 2008 16:24:19 -0700 Subject: ixgbe: add cx4 device ID This is a simple device ID add for adapters that support CX4 (copper infiniband style cable) connectors for 10GbE. Signed-off-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher Signed-off-by: Jeff Garzik --- drivers/net/ixgbe/ixgbe_82598.c | 1 + drivers/net/ixgbe/ixgbe_main.c | 4 +++- drivers/net/ixgbe/ixgbe_type.h | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index 2f38e847e2cd..f96358b641af 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -190,6 +190,7 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw) case IXGBE_DEV_ID_82598AF_DUAL_PORT: case IXGBE_DEV_ID_82598AF_SINGLE_PORT: case IXGBE_DEV_ID_82598EB_CX4: + case IXGBE_DEV_ID_82598_CX4_DUAL_PORT: media_type = ixgbe_media_type_fiber; break; case IXGBE_DEV_ID_82598AT_DUAL_PORT: diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index e5f3da8468cc..34bca16d48a6 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -48,7 +48,7 @@ char ixgbe_driver_name[] = "ixgbe"; static const char ixgbe_driver_string[] = "Intel(R) 10 Gigabit PCI Express Network Driver"; -#define DRV_VERSION "1.3.18-k2" +#define DRV_VERSION "1.3.18-k4" const char ixgbe_driver_version[] = DRV_VERSION; static const char ixgbe_copyright[] = "Copyright (c) 1999-2007 Intel Corporation."; @@ -72,6 +72,8 @@ static struct pci_device_id ixgbe_pci_tbl[] = { board_82598 }, {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_CX4), board_82598 }, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_CX4_DUAL_PORT), + board_82598 }, /* required last entry */ {0, } diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 1ad7cb9c25a8..c0282a223df3 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -39,6 +39,7 @@ #define IXGBE_DEV_ID_82598AF_SINGLE_PORT 0x10C7 #define IXGBE_DEV_ID_82598AT_DUAL_PORT 0x10C8 #define IXGBE_DEV_ID_82598EB_CX4 0x10DD +#define IXGBE_DEV_ID_82598_CX4_DUAL_PORT 0x10EC /* General Registers */ #define IXGBE_CTRL 0x00000 -- cgit v1.2.2 From 9dc28efeee98a4f81d5469d3576f55c5e6d1a5db Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Fri, 8 Aug 2008 00:08:39 -0700 Subject: netxen: fix mac addr setup For NX3031 mac addr should be read from firmware. mac addr in flash is still valid, but can be overridden by firmware if running in virtualization environment. For old revisions, mac addr is retrieved directly from flash. Signed-off-by: Dhananjay Phadke Signed-off-by: Jeff Garzik --- drivers/net/netxen/netxen_nic.h | 3 +- drivers/net/netxen/netxen_nic_hw.c | 51 ++++++++++++++++++------- drivers/net/netxen/netxen_nic_main.c | 65 ++++++++++++++++++++------------ drivers/net/netxen/netxen_nic_phan_reg.h | 2 + 4 files changed, 83 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 93a7b9b668d5..2cf6e41291e6 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -1615,7 +1615,8 @@ dma_watchdog_wakeup(struct netxen_adapter *adapter) int netxen_is_flash_supported(struct netxen_adapter *adapter); -int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 mac[]); +int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac); +int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac); extern void netxen_change_ringparam(struct netxen_adapter *adapter); extern int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp); diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 9aa20f961618..f5db48bcd266 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -733,31 +733,56 @@ static int netxen_get_flash_block(struct netxen_adapter *adapter, int base, return 0; } -int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 mac[]) +int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac) { - __le32 *pmac = (__le32 *) & mac[0]; + __le32 *pmac = (__le32 *) mac; + u32 offset; - if (netxen_get_flash_block(adapter, - NETXEN_USER_START + - offsetof(struct netxen_new_user_info, - mac_addr), - FLASH_NUM_PORTS * sizeof(u64), pmac) == -1) { + offset = NETXEN_USER_START + + offsetof(struct netxen_new_user_info, mac_addr) + + adapter->portnum * sizeof(u64); + + if (netxen_get_flash_block(adapter, offset, sizeof(u64), pmac) == -1) return -1; - } + if (*mac == cpu_to_le64(~0ULL)) { + + offset = NETXEN_USER_START_OLD + + offsetof(struct netxen_user_old_info, mac_addr) + + adapter->portnum * sizeof(u64); + if (netxen_get_flash_block(adapter, - NETXEN_USER_START_OLD + - offsetof(struct netxen_user_old_info, - mac_addr), - FLASH_NUM_PORTS * sizeof(u64), - pmac) == -1) + offset, sizeof(u64), pmac) == -1) return -1; + if (*mac == cpu_to_le64(~0ULL)) return -1; } return 0; } +int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac) +{ + uint32_t crbaddr, mac_hi, mac_lo; + int pci_func = adapter->ahw.pci_func; + + crbaddr = CRB_MAC_BLOCK_START + + (4 * ((pci_func/2) * 3)) + (4 * (pci_func & 1)); + + adapter->hw_read_wx(adapter, crbaddr, &mac_lo, 4); + adapter->hw_read_wx(adapter, crbaddr+4, &mac_hi, 4); + + mac_hi = cpu_to_le32(mac_hi); + mac_lo = cpu_to_le32(mac_lo); + + if (pci_func & 1) + *mac = ((mac_lo >> 16) | ((u64)mac_hi << 16)); + else + *mac = ((mac_lo) | ((u64)mac_hi << 32)); + + return 0; +} + #define CRB_WIN_LOCK_TIMEOUT 100000000 static int crb_win_lock(struct netxen_adapter *adapter) diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 7615c715e66e..6fc42cd30729 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -501,6 +501,44 @@ static void netxen_init_msix_entries(struct netxen_adapter *adapter) adapter->msix_entries[i].entry = i; } +static int +netxen_read_mac_addr(struct netxen_adapter *adapter) +{ + int i; + unsigned char *p; + __le64 mac_addr; + DECLARE_MAC_BUF(mac); + struct net_device *netdev = adapter->netdev; + struct pci_dev *pdev = adapter->pdev; + + if (netxen_is_flash_supported(adapter) != 0) + return -EIO; + + if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { + if (netxen_p3_get_mac_addr(adapter, &mac_addr) != 0) + return -EIO; + } else { + if (netxen_get_flash_mac_addr(adapter, &mac_addr) != 0) + return -EIO; + } + + p = (unsigned char *)&mac_addr; + for (i = 0; i < 6; i++) + netdev->dev_addr[i] = *(p + 5 - i); + + memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len); + + /* set station address */ + + if (!is_valid_ether_addr(netdev->perm_addr)) { + dev_warn(&pdev->dev, "Bad MAC address %s.\n", + print_mac(mac, netdev->dev_addr)); + } else + adapter->macaddr_set(adapter, netdev->dev_addr); + + return 0; +} + /* * netxen_nic_probe() * @@ -529,10 +567,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) unsigned long mem_base, mem_len, db_base, db_len, pci_len0 = 0; int i = 0, err; int first_driver, first_boot; - __le64 mac_addr[FLASH_NUM_PORTS + 1]; u32 val; int pci_func_id = PCI_FUNC(pdev->devfn); - DECLARE_MAC_BUF(mac); struct netxen_legacy_intr_set *legacy_intrp; uint8_t revision_id; @@ -904,28 +940,9 @@ request_msi: INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task); INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task); - if (netxen_is_flash_supported(adapter) == 0 && - netxen_get_flash_mac_addr(adapter, mac_addr) == 0) { - unsigned char *p; - - p = (unsigned char *)&mac_addr[adapter->portnum]; - netdev->dev_addr[0] = *(p + 5); - netdev->dev_addr[1] = *(p + 4); - netdev->dev_addr[2] = *(p + 3); - netdev->dev_addr[3] = *(p + 2); - netdev->dev_addr[4] = *(p + 1); - netdev->dev_addr[5] = *(p + 0); - - memcpy(netdev->perm_addr, netdev->dev_addr, - netdev->addr_len); - if (!is_valid_ether_addr(netdev->perm_addr)) { - printk(KERN_ERR "%s: Bad MAC address %s.\n", - netxen_nic_driver_name, - print_mac(mac, netdev->dev_addr)); - } else { - adapter->macaddr_set(adapter, netdev->dev_addr); - } - } + err = netxen_read_mac_addr(adapter); + if (err) + dev_warn(&pdev->dev, "failed to read mac addr\n"); netif_carrier_off(netdev); netif_stop_queue(netdev); diff --git a/drivers/net/netxen/netxen_nic_phan_reg.h b/drivers/net/netxen/netxen_nic_phan_reg.h index 83e5ee57bfef..b293adcc95ab 100644 --- a/drivers/net/netxen/netxen_nic_phan_reg.h +++ b/drivers/net/netxen/netxen_nic_phan_reg.h @@ -125,6 +125,8 @@ #define CRB_SW_INT_MASK_2 NETXEN_NIC_REG(0x1e4) #define CRB_SW_INT_MASK_3 NETXEN_NIC_REG(0x1e8) +#define CRB_MAC_BLOCK_START NETXEN_CAM_RAM(0x1c0) + /* * capabilities register, can be used to selectively enable/disable features * for backward compability -- cgit v1.2.2 From 9e410778047d0f2887adb888b44eda4d72d4f67d Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Fri, 8 Aug 2008 00:08:40 -0700 Subject: netxen: fix rxbuf leak across driver reload Free up rx ring during driver unload or open() failure. Signed-off-by: Dhananjay Phadke Signed-off-by: Jeff Garzik --- drivers/net/netxen/netxen_nic_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 6fc42cd30729..056f6b17a331 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -1017,6 +1017,7 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { netxen_free_hw_resources(adapter); + netxen_release_rx_buffers(adapter); netxen_free_sw_resources(adapter); } @@ -1111,7 +1112,7 @@ static int netxen_nic_open(struct net_device *netdev) flags, netdev->name, adapter); if (err) { printk(KERN_ERR "request_irq failed with: %d\n", err); - goto err_out_free_hw; + goto err_out_free_rxbuf; } adapter->is_up = NETXEN_ADAPTER_UP_MAGIC; @@ -1144,7 +1145,8 @@ static int netxen_nic_open(struct net_device *netdev) err_out_free_irq: free_irq(adapter->irq, adapter); -err_out_free_hw: +err_out_free_rxbuf: + netxen_release_rx_buffers(adapter); netxen_free_hw_resources(adapter); err_out_free_sw: netxen_free_sw_resources(adapter); -- cgit v1.2.2 From 922c4f2c70c156ac38b4e6affbd30d4b1efd5864 Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Fri, 8 Aug 2008 00:08:41 -0700 Subject: netxen: force link update across ifdown/ifup Re-read link status in dev open(). Schedule link watchdog only if dev is up. Signed-off-by: Dhananjay Phadke Signed-off-by: Jeff Garzik --- drivers/net/netxen/netxen_nic_main.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 056f6b17a331..f69807c9432b 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -934,7 +934,6 @@ request_msi: goto err_out_disable_msi; init_timer(&adapter->watchdog_timer); - adapter->ahw.linkup = 0; adapter->watchdog_timer.function = &netxen_watchdog; adapter->watchdog_timer.data = (unsigned long)adapter; INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task); @@ -1134,6 +1133,7 @@ static int netxen_nic_open(struct net_device *netdev) if (adapter->set_mtu) adapter->set_mtu(adapter, netdev->mtu); + adapter->ahw.linkup = 0; mod_timer(&adapter->watchdog_timer, jiffies); napi_enable(&adapter->napi); @@ -1171,10 +1171,8 @@ static int netxen_nic_close(struct net_device *netdev) netxen_release_tx_buffers(adapter); - if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { - FLUSH_SCHEDULED_WORK(); - del_timer_sync(&adapter->watchdog_timer); - } + FLUSH_SCHEDULED_WORK(); + del_timer_sync(&adapter->watchdog_timer); return 0; } @@ -1477,7 +1475,8 @@ void netxen_watchdog_task(struct work_struct *work) netxen_nic_handle_phy_intr(adapter); - mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); + if (netif_running(adapter->netdev)) + mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); } static void netxen_tx_timeout(struct net_device *netdev) -- cgit v1.2.2 From 15eef1e1b718667981da92d2fa18283f181c117c Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Fri, 8 Aug 2008 00:08:42 -0700 Subject: netxen: fix dma watchdog NX3031 does not require driver to kill dma watchdog. Signed-off-by: Dhananjay Phadke Signed-off-by: Jeff Garzik --- drivers/net/netxen/netxen_nic_init.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 519fc860e17e..5bba675d0504 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -1079,10 +1079,12 @@ int netxen_initialize_adapter_offload(struct netxen_adapter *adapter) void netxen_free_adapter_offload(struct netxen_adapter *adapter) { - int i; + int i = 100; + + if (!adapter->dummy_dma.addr) + return; - if (adapter->dummy_dma.addr) { - i = 100; + if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { do { if (dma_watchdog_shutdown_request(adapter) == 1) break; @@ -1090,17 +1092,17 @@ void netxen_free_adapter_offload(struct netxen_adapter *adapter) if (dma_watchdog_shutdown_poll_result(adapter) == 1) break; } while (--i); + } - if (i) { - pci_free_consistent(adapter->pdev, - NETXEN_HOST_DUMMY_DMA_SIZE, - adapter->dummy_dma.addr, - adapter->dummy_dma.phys_addr); - adapter->dummy_dma.addr = NULL; - } else { - printk(KERN_ERR "%s: dma_watchdog_shutdown failed\n", - adapter->netdev->name); - } + if (i) { + pci_free_consistent(adapter->pdev, + NETXEN_HOST_DUMMY_DMA_SIZE, + adapter->dummy_dma.addr, + adapter->dummy_dma.phys_addr); + adapter->dummy_dma.addr = NULL; + } else { + printk(KERN_ERR "%s: dma_watchdog_shutdown failed\n", + adapter->netdev->name); } } -- cgit v1.2.2 From 092bc57184842229ee41f87d9c408a3f1302aaa6 Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Fri, 8 Aug 2008 00:08:43 -0700 Subject: netxen: cleanup interrupt code Mark interrupt scheme in very old firmware incompatible. Interrupt mask and status registers are per pci function / port. Signed-off-by: Dhananjay Phadke Signed-off-by: Jeff Garzik --- drivers/net/netxen/netxen_nic_main.c | 123 ++++++++++++----------------------- 1 file changed, 40 insertions(+), 83 deletions(-) (limited to 'drivers') diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index f69807c9432b..3c424a88d8fc 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -149,76 +149,18 @@ static uint32_t msi_tgt_status[8] = { static struct netxen_legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG; -static void netxen_nic_disable_int(struct netxen_adapter *adapter) +static inline void netxen_nic_disable_int(struct netxen_adapter *adapter) { - u32 mask = 0x7ff; - int retries = 32; - int pci_fn = adapter->ahw.pci_func; - - if (adapter->msi_mode != MSI_MODE_MULTIFUNC) - adapter->pci_write_normalize(adapter, - adapter->crb_intr_mask, 0); - - if (adapter->intr_scheme != -1 && - adapter->intr_scheme != INTR_SCHEME_PERPORT) - adapter->pci_write_immediate(adapter, ISR_INT_MASK, mask); - - if (!NETXEN_IS_MSI_FAMILY(adapter)) { - do { - adapter->pci_write_immediate(adapter, - adapter->legacy_intr.tgt_status_reg, - 0xffffffff); - mask = adapter->pci_read_immediate(adapter, - ISR_INT_VECTOR); - if (!(mask & 0x80)) - break; - udelay(10); - } while (--retries); - - if (!retries) { - printk(KERN_NOTICE "%s: Failed to disable interrupt\n", - netxen_nic_driver_name); - } - } else { - if (adapter->msi_mode == MSI_MODE_MULTIFUNC) { - adapter->pci_write_immediate(adapter, - msi_tgt_status[pci_fn], 0xffffffff); - } - } + adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0); } -static void netxen_nic_enable_int(struct netxen_adapter *adapter) +static inline void netxen_nic_enable_int(struct netxen_adapter *adapter) { - u32 mask; - - if (adapter->intr_scheme != -1 && - adapter->intr_scheme != INTR_SCHEME_PERPORT) { - switch (adapter->ahw.board_type) { - case NETXEN_NIC_GBE: - mask = 0x77b; - break; - case NETXEN_NIC_XGBE: - mask = 0x77f; - break; - default: - mask = 0x7ff; - break; - } - - adapter->pci_write_immediate(adapter, ISR_INT_MASK, mask); - } - adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0x1); - if (!NETXEN_IS_MSI_FAMILY(adapter)) { - mask = 0xbff; - if (adapter->intr_scheme == INTR_SCHEME_PERPORT) - adapter->pci_write_immediate(adapter, - adapter->legacy_intr.tgt_mask_reg, mask); - else - adapter->pci_write_normalize(adapter, - CRB_INT_VECTOR, 0); - } + if (!NETXEN_IS_MSI_FAMILY(adapter)) + adapter->pci_write_immediate(adapter, + adapter->legacy_intr.tgt_mask_reg, 0xfbff); } static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id) @@ -1086,6 +1028,15 @@ static int netxen_nic_open(struct net_device *netdev) goto err_out_free_sw; } + if ((adapter->msi_mode != MSI_MODE_MULTIFUNC) || + (adapter->intr_scheme != INTR_SCHEME_PERPORT)) { + printk(KERN_ERR "%s: Firmware interrupt scheme is " + "incompatible with driver\n", + netdev->name); + adapter->driver_mismatch = 1; + goto err_out_free_hw; + } + if (adapter->fw_major < 4) { adapter->crb_addr_cmd_producer = crb_cmd_producer[adapter->portnum]; @@ -1147,6 +1098,7 @@ err_out_free_irq: free_irq(adapter->irq, adapter); err_out_free_rxbuf: netxen_release_rx_buffers(adapter); +err_out_free_hw: netxen_free_hw_resources(adapter); err_out_free_sw: netxen_free_sw_resources(adapter); @@ -1536,18 +1488,9 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev) return stats; } -static inline void -netxen_handle_int(struct netxen_adapter *adapter) -{ - netxen_nic_disable_int(adapter); - napi_schedule(&adapter->napi); -} - static irqreturn_t netxen_intr(int irq, void *data) { struct netxen_adapter *adapter = data; - u32 our_int = 0; - u32 status = 0; status = adapter->pci_read_immediate(adapter, ISR_INT_VECTOR); @@ -1562,22 +1505,32 @@ static irqreturn_t netxen_intr(int irq, void *data) if (!ISR_LEGACY_INT_TRIGGERED(status)) return IRQ_NONE; - } else if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { + } else { + unsigned long our_int = 0; our_int = adapter->pci_read_normalize(adapter, CRB_INT_VECTOR); + /* not our interrupt */ - if ((our_int & (0x80 << adapter->portnum)) == 0) + if (!test_and_clear_bit((7 + adapter->portnum), &our_int)) return IRQ_NONE; - if (adapter->intr_scheme == INTR_SCHEME_PERPORT) { - /* claim interrupt */ - adapter->pci_write_normalize(adapter, - CRB_INT_VECTOR, - our_int & ~((u32)(0x80 << adapter->portnum))); - } + /* claim interrupt */ + adapter->pci_write_normalize(adapter, + CRB_INT_VECTOR, (our_int & 0xffffffff)); } - netxen_handle_int(adapter); + /* clear interrupt */ + if (adapter->fw_major < 4) + netxen_nic_disable_int(adapter); + + adapter->pci_write_immediate(adapter, + adapter->legacy_intr.tgt_status_reg, + 0xffffffff); + /* read twice to ensure write is flushed */ + adapter->pci_read_immediate(adapter, ISR_INT_VECTOR); + adapter->pci_read_immediate(adapter, ISR_INT_VECTOR); + + napi_schedule(&adapter->napi); return IRQ_HANDLED; } @@ -1586,7 +1539,11 @@ static irqreturn_t netxen_msi_intr(int irq, void *data) { struct netxen_adapter *adapter = data; - netxen_handle_int(adapter); + /* clear interrupt */ + adapter->pci_write_immediate(adapter, + msi_tgt_status[adapter->ahw.pci_func], 0xffffffff); + + napi_schedule(&adapter->napi); return IRQ_HANDLED; } -- cgit v1.2.2 From 11d89d639352ef27bb3f0e7513dd406284bf034a Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Fri, 8 Aug 2008 00:08:45 -0700 Subject: netxen: update driver version Raise driver version to 4.0.11. Signed-off-by: Dhananjay Phadke Signed-off-by: Jeff Garzik --- drivers/net/netxen/netxen_nic.h | 4 ++-- drivers/net/netxen/netxen_nic_hw.c | 8 ++++---- drivers/net/netxen/netxen_nic_main.c | 7 +++++++ 3 files changed, 13 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 2cf6e41291e6..ab871df6b1db 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -66,8 +66,8 @@ #define _NETXEN_NIC_LINUX_MAJOR 4 #define _NETXEN_NIC_LINUX_MINOR 0 -#define _NETXEN_NIC_LINUX_SUBVERSION 0 -#define NETXEN_NIC_LINUX_VERSIONID "4.0.0" +#define _NETXEN_NIC_LINUX_SUBVERSION 11 +#define NETXEN_NIC_LINUX_VERSIONID "4.0.11" #define NETXEN_VERSION_CODE(a, b, c) (((a) << 16) + ((b) << 8) + (c)) diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index f5db48bcd266..84978f80f396 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -2208,10 +2208,10 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter) if (adapter->portnum == 0) { get_brd_name_by_type(board_info->board_type, brd_name); - printk("NetXen %s Board S/N %s Chip id 0x%x\n", - brd_name, serial_num, board_info->chip_id); - printk("NetXen Firmware version %d.%d.%d\n", fw_major, - fw_minor, fw_build); + printk(KERN_INFO "NetXen %s Board S/N %s Chip rev 0x%x\n", + brd_name, serial_num, adapter->ahw.revision_id); + printk(KERN_INFO "NetXen Firmware version %d.%d.%d\n", + fw_major, fw_minor, fw_build); } if (NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build) < diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 3c424a88d8fc..32bb47adbe39 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -523,6 +523,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return -ENODEV; } + if (pdev->revision >= NX_P3_A0 && pdev->revision < NX_P3_B1) { + printk(KERN_WARNING "NetXen chip revisions between 0x%x-0x%x" + "will not be enabled.\n", + NX_P3_A0, NX_P3_B1); + return -ENODEV; + } + if ((err = pci_enable_device(pdev))) return err; -- cgit v1.2.2 From 1595ab5d7d99bc6c9a5548ab3fb83e278eeae409 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 8 Aug 2008 21:33:34 +0300 Subject: [netdrvr] uninline atl1e_setup_mac_ctrl() There doesn't seem to be a compelling reason why atl1e_setup_mac_ctrl() is marked as "inline": It's not used in any place where speed would matter much, and as long as it has only one caller non-ancient gcc versions anyway inline it automatically. This patch fixes the following compile error with gcc 3.4: <-- snip --> ... CC drivers/net/atl1e/atl1e_main.o atl1e_main.c: In function `atl1e_check_link': atl1e_main.c:50: sorry, unimplemented: inlining failed in call to atl1e_main.c:196: sorry, unimplemented: called from here make[4]: *** [drivers/net/atl1e/atl1e_main.o] Error 1 <-- snip --> Reported-by: Adrian Bunk Signed-off-by: Adrian Bunk Signed-off-by: Jeff Garzik --- drivers/net/atl1e/atl1e_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c index 35264c244cfd..82d7be1655d3 100644 --- a/drivers/net/atl1e/atl1e_main.c +++ b/drivers/net/atl1e/atl1e_main.c @@ -47,7 +47,7 @@ MODULE_DESCRIPTION("Atheros 1000M Ethernet Network Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); -static inline void atl1e_setup_mac_ctrl(struct atl1e_adapter *adapter); +static void atl1e_setup_mac_ctrl(struct atl1e_adapter *adapter); static const u16 atl1e_rx_page_vld_regs[AT_MAX_RECEIVE_QUEUE][AT_PAGE_NUM_PER_QUEUE] = @@ -1037,7 +1037,7 @@ static inline void atl1e_configure_dma(struct atl1e_adapter *adapter) return; } -static inline void atl1e_setup_mac_ctrl(struct atl1e_adapter *adapter) +static void atl1e_setup_mac_ctrl(struct atl1e_adapter *adapter) { u32 value; struct atl1e_hw *hw = &adapter->hw; -- cgit v1.2.2 From add477df674db00377d9a4dc0d9b553ce79bc06d Mon Sep 17 00:00:00 2001 From: Olivier Blin Date: Fri, 8 Aug 2008 12:01:11 -0700 Subject: hso: fix oops in read/write callbacks The tty may be closed already when the read/write callbacks are called. This patch checks that the ttys still exist before waking them up. Signed-off-by: Olivier Blin Acked-by: Alan Cox Cc: Jari Tenhunen Signed-off-by: Greg Kroah-Hartman Signed-off-by: Jeff Garzik --- drivers/net/usb/hso.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 031d07b105af..94a27f764e6b 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -1467,7 +1467,8 @@ static void hso_std_serial_write_bulk_callback(struct urb *urb) return; } hso_put_activity(serial->parent); - tty_wakeup(serial->tty); + if (serial->tty) + tty_wakeup(serial->tty); hso_kick_transmit(serial); D1(" "); @@ -1538,7 +1539,8 @@ static void ctrl_callback(struct urb *urb) clear_bit(HSO_SERIAL_FLAG_RX_SENT, &serial->flags); } else { hso_put_activity(serial->parent); - tty_wakeup(serial->tty); + if (serial->tty) + tty_wakeup(serial->tty); /* response to a write command */ hso_kick_transmit(serial); } -- cgit v1.2.2 From 6d558a52ba295fc1c281c671d7daab2f74ddb4f2 Mon Sep 17 00:00:00 2001 From: Olivier Blin Date: Fri, 8 Aug 2008 12:01:41 -0700 Subject: hso: fix refcounting on the ttyHSx devices The references on ttyHSx devices were not decremented correctly when the tty was closed. The helper freeing the serial devices was never called because of that, and the module left some dangling sysfs devices after being unloaded. Signed-off-by: Olivier Blin Cc: Jari Tenhunen Signed-off-by: Greg Kroah-Hartman Signed-off-by: Jeff Garzik --- drivers/net/usb/hso.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 94a27f764e6b..94c41bbedee9 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -1103,8 +1103,8 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp) /* reset the rts and dtr */ /* do the actual close */ serial->open_count--; + kref_put(&serial->parent->ref, hso_serial_ref_free); if (serial->open_count <= 0) { - kref_put(&serial->parent->ref, hso_serial_ref_free); serial->open_count = 0; if (serial->tty) { serial->tty->driver_data = NULL; -- cgit v1.2.2 From 6c59f56978c3dffd447176d218bc5852842c9ce9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 8 Aug 2008 12:02:14 -0700 Subject: USB: HSO: make tty_operations const As recommended by Arjan. Cc: Arjan van de Ven Cc: Andrew Bird Signed-off-by: Greg Kroah-Hartman Signed-off-by: Jeff Garzik --- drivers/net/usb/hso.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 94c41bbedee9..35a7772cf1a6 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -2725,7 +2725,7 @@ static int hso_mux_submit_intr_urb(struct hso_shared_int *shared_int, } /* operations setup of the serial interface */ -static struct tty_operations hso_serial_ops = { +static const struct tty_operations hso_serial_ops = { .open = hso_serial_open, .close = hso_serial_close, .write = hso_serial_write, -- cgit v1.2.2 From 0235f64175db41fa17a6ce5c9b58fd3550986eb4 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 8 Aug 2008 12:02:57 -0700 Subject: USB: HSO: minor fixes due to code review Fix up problems in hso.c driver as pointed out by Andrew. Cc: Andrew Morton Signed-off-by: Greg Kroah-Hartman Signed-off-by: Jeff Garzik --- drivers/net/usb/hso.c | 43 ++++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 35a7772cf1a6..1b7cac77159e 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -102,8 +102,12 @@ #define MAX_RX_URBS 2 -#define get_serial_by_tty(x) \ - (x ? (struct hso_serial *)x->driver_data : NULL) +static inline struct hso_serial *get_serial_by_tty(struct tty_struct *tty) +{ + if (tty) + return tty->driver_data; + return NULL; +} /*****************************************************************************/ /* Debugging functions */ @@ -294,24 +298,25 @@ static int hso_get_activity(struct hso_device *hso_dev); /* #define DEBUG */ -#define dev2net(x) (x->port_data.dev_net) -#define dev2ser(x) (x->port_data.dev_serial) +static inline struct hso_net *dev2net(struct hso_device *hso_dev) +{ + return hso_dev->port_data.dev_net; +} + +static inline struct hso_serial *dev2ser(struct hso_device *hso_dev) +{ + return hso_dev->port_data.dev_serial; +} /* Debugging functions */ #ifdef DEBUG static void dbg_dump(int line_count, const char *func_name, unsigned char *buf, unsigned int len) { - u8 i = 0; - - printk(KERN_DEBUG "[%d:%s]: len %d", line_count, func_name, len); + static char name[255]; - for (i = 0; i < len; i++) { - if (!(i % 16)) - printk("\n 0x%03x: ", i); - printk("%02x ", (unsigned char)buf[i]); - } - printk("\n"); + sprintf(name, "hso[%d:%s]", line_count, func_name); + print_hex_dump_bytes(name, DUMP_PREFIX_NONE, buf, len); } #define DUMP(buf_, len_) \ @@ -528,13 +533,12 @@ static struct hso_serial *get_serial_by_shared_int_and_type( static struct hso_serial *get_serial_by_index(unsigned index) { - struct hso_serial *serial; + struct hso_serial *serial = NULL; unsigned long flags; - if (!serial_table[index]) - return NULL; spin_lock_irqsave(&serial_table_lock, flags); - serial = dev2ser(serial_table[index]); + if (serial_table[index]) + serial = dev2ser(serial_table[index]); spin_unlock_irqrestore(&serial_table_lock, flags); return serial; @@ -561,6 +565,7 @@ static int get_free_serial_index(void) static void set_serial_by_index(unsigned index, struct hso_serial *serial) { unsigned long flags; + spin_lock_irqsave(&serial_table_lock, flags); if (serial) serial_table[index] = serial->parent; @@ -569,7 +574,7 @@ static void set_serial_by_index(unsigned index, struct hso_serial *serial) spin_unlock_irqrestore(&serial_table_lock, flags); } -/* log a meaningfull explanation of an USB status */ +/* log a meaningful explanation of an USB status */ static void log_usb_status(int status, const char *function) { char *explanation; @@ -2654,7 +2659,7 @@ static void hso_free_interface(struct usb_interface *interface) hso_stop_net_device(network_table[i]); cancel_work_sync(&network_table[i]->async_put_intf); cancel_work_sync(&network_table[i]->async_get_intf); - if(rfk) + if (rfk) rfkill_unregister(rfk); hso_free_net_device(network_table[i]); } -- cgit v1.2.2 From 85a73b333c0c06fcadb8e32f1e30f00e980f2fc7 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Fri, 8 Aug 2008 13:53:29 -0700 Subject: Kconfig: HSO driver bugfixes and updates Move the Kconfig for the new "Option" driver so it's not in the middle of the usbnet-based drivers, so the dependency displays in the Kconfig user interfaces don't get trashed. Signed-off-by: David Brownell Signed-off-by: Jeff Garzik --- drivers/net/usb/Kconfig | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 68e198bd538b..0973b6e37024 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -154,17 +154,6 @@ config USB_NET_AX8817X This driver creates an interface named "ethX", where X depends on what other networking devices you have in use. -config USB_HSO - tristate "Option USB High Speed Mobile Devices" - depends on USB && RFKILL - default n - help - Choose this option if you have an Option HSDPA/HSUPA card. - These cards support downlink speeds of 7.2Mbps or greater. - - To compile this driver as a module, choose M here: the - module will be called hso. - config USB_NET_CDCETHER tristate "CDC Ethernet support (smart devices such as cable modems)" depends on USB_USBNET @@ -337,5 +326,15 @@ config USB_NET_ZAURUS really need this non-conformant variant of CDC Ethernet (or in some cases CDC MDLM) protocol, not "g_ether". +config USB_HSO + tristate "Option USB High Speed Mobile Devices" + depends on USB && RFKILL + default n + help + Choose this option if you have an Option HSDPA/HSUPA card. + These cards support downlink speeds of 7.2Mbps or greater. + + To compile this driver as a module, choose M here: the + module will be called hso. endmenu -- cgit v1.2.2 From c7e65c17d75f29c846ff711b1dc5e823ba8de314 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Fri, 8 Aug 2008 00:55:17 +0900 Subject: [netdrvr] ne: Use CONFIG_MACH_TX49XX After some cleanups in arch/mips area, now MACH_TX49XX is selected for both TOSHIBA_RBTX4927 and TOSHIBA_RBTX4938. Fold these two conditions to one. Signed-off-by: Atsushi Nemoto Signed-off-by: Jeff Garzik --- drivers/net/Kconfig | 2 +- drivers/net/ne.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 4b4cb2bf4f11..a5c141cecd4e 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1172,7 +1172,7 @@ config ETH16I config NE2000 tristate "NE2000/NE1000 support" - depends on NET_ISA || (Q40 && m) || M32R || TOSHIBA_RBTX4927 || TOSHIBA_RBTX4938 + depends on NET_ISA || (Q40 && m) || M32R || MACH_TX49XX select CRC32 ---help--- If you have a network (Ethernet) card of this type, say Y and read diff --git a/drivers/net/ne.c b/drivers/net/ne.c index 42443d697423..fa3ceca4e15c 100644 --- a/drivers/net/ne.c +++ b/drivers/net/ne.c @@ -118,7 +118,7 @@ bad_clone_list[] __initdata = { {"E-LAN100", "E-LAN200", {0x00, 0x00, 0x5d}}, /* Broken ne1000 clones */ {"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */ {"REALTEK", "RTL8019", {0x00, 0x00, 0xe8}}, /* no-name with Realtek chip */ -#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938) +#ifdef CONFIG_MACH_TX49XX {"RBHMA4X00-RTL8019", "RBHMA4X00/RTL8019", {0x00, 0x60, 0x0a}}, /* Toshiba built-in */ #endif {"LCS-8834", "LCS-8836", {0x04, 0x04, 0x37}}, /* ShinyNet (SET) */ @@ -142,7 +142,7 @@ bad_clone_list[] __initdata = { #if defined(CONFIG_PLAT_MAPPI) # define DCR_VAL 0x4b #elif defined(CONFIG_PLAT_OAKS32R) || \ - defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938) + defined(CONFIG_MACH_TX49XX) # define DCR_VAL 0x48 /* 8-bit mode */ #else # define DCR_VAL 0x49 -- cgit v1.2.2 From 1a3c4bc61547e5a75fd3b85b425624756da4cffb Mon Sep 17 00:00:00 2001 From: roel kluin Date: Thu, 7 Aug 2008 12:24:42 -0400 Subject: atl1e: WAKE_MCAST 2x. 1st WAKE_UCAST? Signed-off-by: Jeff Garzik --- drivers/net/atl1e/atl1e_ethtool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/atl1e/atl1e_ethtool.c b/drivers/net/atl1e/atl1e_ethtool.c index cdc3b85b10b9..619c6583e1aa 100644 --- a/drivers/net/atl1e/atl1e_ethtool.c +++ b/drivers/net/atl1e/atl1e_ethtool.c @@ -355,7 +355,7 @@ static int atl1e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) struct atl1e_adapter *adapter = netdev_priv(netdev); if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE | - WAKE_MCAST | WAKE_BCAST | WAKE_MCAST)) + WAKE_UCAST | WAKE_MCAST | WAKE_BCAST)) return -EOPNOTSUPP; /* these settings will always override what we currently have */ adapter->wol = 0; -- cgit v1.2.2 From c0912585ec8b64d846d56995241f2c8a7f48ee75 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 7 Aug 2008 17:21:09 +0100 Subject: AX88796: Fix locking in ethtool support Fix a pair of nasty locking problems in the ax88796 driver spotted by a sparse check: warning: context imbalance in 'ax_get_settings' - wrong count at exit warning: context imbalance in 'ax_set_settings' - wrong count at exit Signed-off-by: Ben Dooks Signed-off-by: Jeff Garzik --- drivers/net/ax88796.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c index 0b4adf4a0f7d..a886a4b9f7e5 100644 --- a/drivers/net/ax88796.c +++ b/drivers/net/ax88796.c @@ -554,7 +554,7 @@ static int ax_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) spin_lock_irqsave(&ax->mii_lock, flags); mii_ethtool_gset(&ax->mii, cmd); - spin_lock_irqsave(&ax->mii_lock, flags); + spin_unlock_irqrestore(&ax->mii_lock, flags); return 0; } @@ -567,7 +567,7 @@ static int ax_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) spin_lock_irqsave(&ax->mii_lock, flags); rc = mii_ethtool_sset(&ax->mii, cmd); - spin_lock_irqsave(&ax->mii_lock, flags); + spin_unlock_irqrestore(&ax->mii_lock, flags); return rc; } -- cgit v1.2.2 From 7c6337a15e3d4689efe703e8bb65ae82cc13c435 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 14 Aug 2008 15:29:09 -0700 Subject: bnx2: Fix logic to setup VLAN rx tagging. We should now be checking BNX2_FLAG_CAN_KEEP_VLAN to determine how to set the VLAN rx tagging in the RX_MODE register. Signed-off-by: Michael Chan Signed-off-by: Benjamin Li Signed-off-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 5ebde67d4297..0623ceb7a0e2 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -3237,10 +3237,10 @@ bnx2_set_rx_mode(struct net_device *dev) BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG); sort_mode = 1 | BNX2_RPM_SORT_USER0_BC_EN; #ifdef BCM_VLAN - if (!bp->vlgrp && !(bp->flags & BNX2_FLAG_ASF_ENABLE)) + if (!bp->vlgrp && (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN)) rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG; #else - if (!(bp->flags & BNX2_FLAG_ASF_ENABLE)) + if (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN) rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG; #endif if (dev->flags & IFF_PROMISC) { -- cgit v1.2.2 From 729b85cd47f4e63657505cb5c6af104e19250805 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 14 Aug 2008 15:29:39 -0700 Subject: bnx2: Use proper CONFIG_VLAN_8021Q to compile the VLAN code. Signed-off-by: Michael Chan Signed-off-by: Benjamin Li Signed-off-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 0623ceb7a0e2..a2a010ede591 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -35,7 +35,7 @@ #include #include #include -#ifdef NETIF_F_HW_VLAN_TX +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) #include #define BCM_VLAN 1 #endif @@ -5963,10 +5963,12 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) vlan_tag_flags |= TX_BD_FLAGS_TCP_UDP_CKSUM; } +#ifdef BCM_VLAN if (bp->vlgrp && vlan_tx_tag_present(skb)) { vlan_tag_flags |= (TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16)); } +#endif if ((mss = skb_shinfo(skb)->gso_size)) { u32 tcp_opt_len, ip_tcp_len; struct iphdr *iph; -- cgit v1.2.2 From f22828e89f4f3e8c74ca7ffa69b0410afbd80eee Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 14 Aug 2008 15:30:14 -0700 Subject: bnx2: Reinsert VLAN tag when necessary. In certain cases when ASF or other management firmware is running, the chip may be configured to always strip out the VLAN tag even when VLAN acceleration is not enabled. This causes some VLAN tagged packets to be received by the host stack without any knowledge that the original packet was VLAN tagged. We fix this by re-inserting the VLAN tag into the packet when necessary. Signed-off-by: Michael Chan Signed-off-by: Benjamin Li Signed-off-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index a2a010ede591..1f2e76fda01e 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -2876,6 +2876,8 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) struct sw_bd *rx_buf; struct sk_buff *skb; dma_addr_t dma_addr; + u16 vtag = 0; + int hw_vlan __maybe_unused = 0; sw_ring_cons = RX_RING_IDX(sw_cons); sw_ring_prod = RX_RING_IDX(sw_prod); @@ -2919,7 +2921,7 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) if (len <= bp->rx_copy_thresh) { struct sk_buff *new_skb; - new_skb = netdev_alloc_skb(bp->dev, len + 2); + new_skb = netdev_alloc_skb(bp->dev, len + 6); if (new_skb == NULL) { bnx2_reuse_rx_skb(bp, rxr, skb, sw_ring_cons, sw_ring_prod); @@ -2928,9 +2930,9 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) /* aligned copy */ skb_copy_from_linear_data_offset(skb, - BNX2_RX_OFFSET - 2, - new_skb->data, len + 2); - skb_reserve(new_skb, 2); + BNX2_RX_OFFSET - 6, + new_skb->data, len + 6); + skb_reserve(new_skb, 6); skb_put(new_skb, len); bnx2_reuse_rx_skb(bp, rxr, skb, @@ -2941,6 +2943,25 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) dma_addr, (sw_ring_cons << 16) | sw_ring_prod))) goto next_rx; + if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) && + !(bp->rx_mode & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG)) { + vtag = rx_hdr->l2_fhdr_vlan_tag; +#ifdef BCM_VLAN + if (bp->vlgrp) + hw_vlan = 1; + else +#endif + { + struct vlan_ethhdr *ve = (struct vlan_ethhdr *) + __skb_push(skb, 4); + + memmove(ve, skb->data + 4, ETH_ALEN * 2); + ve->h_vlan_proto = htons(ETH_P_8021Q); + ve->h_vlan_TCI = htons(vtag); + len += 4; + } + } + skb->protocol = eth_type_trans(skb, bp->dev); if ((len > (bp->dev->mtu + ETH_HLEN)) && @@ -2962,10 +2983,8 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) } #ifdef BCM_VLAN - if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) && bp->vlgrp) { - vlan_hwaccel_receive_skb(skb, bp->vlgrp, - rx_hdr->l2_fhdr_vlan_tag); - } + if (hw_vlan) + vlan_hwaccel_receive_skb(skb, bp->vlgrp, vtag); else #endif netif_receive_skb(skb); -- cgit v1.2.2 From 0eb8b1fe9238ca4c1797e4c105d5790abda1726f Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 14 Aug 2008 15:30:31 -0700 Subject: bnx2: Update version to 1.8.0. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 1f2e76fda01e..d4548101e495 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -57,8 +57,8 @@ #define DRV_MODULE_NAME "bnx2" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "1.7.9" -#define DRV_MODULE_RELDATE "July 18, 2008" +#define DRV_MODULE_VERSION "1.8.0" +#define DRV_MODULE_RELDATE "Aug 14, 2008" #define RUN_AT(x) (jiffies + (x)) -- cgit v1.2.2 From 77b483f132ba25edf4ef455dd87a91ab7bbf4170 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Fri, 15 Aug 2008 14:07:24 -0700 Subject: tg3: Add APE register access locking If the driver resets the chip while the APE is performing a register access, that register access will never complete and the APE will hang indefinitely. To prevent this race condition, the driver must acquire an APE mutex before resetting the chip. The APE will not attempt a register access until it acquires this lock. Signed-off-by: Matt Carlson Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 6 ++++++ drivers/net/tg3.h | 1 + 2 files changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index d2439b85a790..e3fd74b871a3 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -536,6 +536,7 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum) return 0; switch (locknum) { + case TG3_APE_LOCK_GRC: case TG3_APE_LOCK_MEM: break; default: @@ -573,6 +574,7 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum) return; switch (locknum) { + case TG3_APE_LOCK_GRC: case TG3_APE_LOCK_MEM: break; default: @@ -5760,6 +5762,8 @@ static int tg3_chip_reset(struct tg3 *tp) tg3_mdio_stop(tp); + tg3_ape_lock(tp, TG3_APE_LOCK_GRC); + /* No matching tg3_nvram_unlock() after this because * chip reset below will undo the nvram lock. */ @@ -5914,6 +5918,8 @@ static int tg3_chip_reset(struct tg3 *tp) tg3_mdio_start(tp); + tg3_ape_unlock(tp, TG3_APE_LOCK_GRC); + err = tg3_poll_fw(tp); if (err) return err; diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index df07842172b7..dd1af508023a 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -1889,6 +1889,7 @@ #define APE_EVENT_STATUS_EVENT_PENDING 0x80000000 /* APE convenience enumerations. */ +#define TG3_APE_LOCK_GRC 1 #define TG3_APE_LOCK_MEM 4 #define TG3_EEPROM_SB_F1R2_MBA_OFF 0x10 -- cgit v1.2.2 From 731fd79c133dc04cabee17ecfa7661189a8df5c8 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Fri, 15 Aug 2008 14:07:51 -0700 Subject: tg3: Refine APE status check Recently, more status bits have been added to the APE status register. This patch refines the status register check so that the driver can send more events than it would have otherwise. Signed-off-by: Matt Carlson Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index e3fd74b871a3..13640f1cab3b 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -5495,7 +5495,7 @@ static void tg3_ape_send_event(struct tg3 *tp, u32 event) return; apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS); - if (apedata != APE_FW_STATUS_READY) + if (!(apedata & APE_FW_STATUS_READY)) return; /* Wait for up to 1 millisecond for APE to service previous event. */ -- cgit v1.2.2 From 3bda12589646caa22b2ed4ef7cf82d17ea59d7a6 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Fri, 15 Aug 2008 14:08:22 -0700 Subject: tg3: Preserve register settings for DASH Broadcom's DASH (Desktop and mobile Architecture for System Hardware) implementation requires that the driver preserve particular register settings. If the driver does not preserve them, communication with the DASH firmware will be lost. Signed-off-by: Matt Carlson Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 26 ++++++++++++++++++++++++-- drivers/net/tg3.h | 2 ++ 2 files changed, 26 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 13640f1cab3b..0ebf2ff60c4b 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -2126,6 +2126,13 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)) mac_mode |= MAC_MODE_MAGIC_PKT_ENABLE; + if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) { + mac_mode |= tp->mac_mode & + (MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN); + if (mac_mode & MAC_MODE_APE_TX_EN) + mac_mode |= MAC_MODE_TDE_ENABLE; + } + tw32_f(MAC_MODE, mac_mode); udelay(100); @@ -5912,6 +5919,11 @@ static int tg3_chip_reset(struct tg3 *tp) } else if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) { tp->mac_mode = MAC_MODE_PORT_MODE_GMII; tw32_f(MAC_MODE, tp->mac_mode); + } else if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) { + tp->mac_mode &= (MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN); + if (tp->mac_mode & MAC_MODE_APE_TX_EN) + tp->mac_mode |= MAC_MODE_TDE_ENABLE; + tw32_f(MAC_MODE, tp->mac_mode); } else tw32_f(MAC_MODE, 0); udelay(40); @@ -7412,7 +7424,11 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) udelay(10); } - tp->mac_mode = MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE | + if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) + tp->mac_mode &= MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN; + else + tp->mac_mode = 0; + tp->mac_mode |= MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE | MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | MAC_MODE_FHDE_ENABLE; if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) && !(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) && @@ -12422,6 +12438,13 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) tp->misc_host_ctrl); } + /* Preserve the APE MAC_MODE bits */ + if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) + tp->mac_mode = tr32(MAC_MODE) | + MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN; + else + tp->mac_mode = TG3_DEF_MAC_MODE; + /* these are limited to 10/100 only */ if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 && (grc_misc_cfg == 0x8000 || grc_misc_cfg == 0x4000)) || @@ -13281,7 +13304,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, tp->pdev = pdev; tp->dev = dev; tp->pm_cap = pm_cap; - tp->mac_mode = TG3_DEF_MAC_MODE; tp->rx_mode = TG3_DEF_RX_MODE; tp->tx_mode = TG3_DEF_TX_MODE; diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index dd1af508023a..377234947e4f 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -325,6 +325,8 @@ #define MAC_MODE_TDE_ENABLE 0x00200000 #define MAC_MODE_RDE_ENABLE 0x00400000 #define MAC_MODE_FHDE_ENABLE 0x00800000 +#define MAC_MODE_APE_RX_EN 0x08000000 +#define MAC_MODE_APE_TX_EN 0x10000000 #define MAC_STATUS 0x00000404 #define MAC_STATUS_PCS_SYNCED 0x00000001 #define MAC_STATUS_SIGNAL_DET 0x00000002 -- cgit v1.2.2 From bc7959b2cbb57393b625b423c73e6fd07610257f Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Fri, 15 Aug 2008 14:08:55 -0700 Subject: tg3: Turn off ASF "driver alive" heartbeats for APE The ENABLE_ASF flag is set when DASH is enabled on the NIC, but DASH does not run on the RX CPU. Instead it runs on the APE. Consequently, the driver does not need to send "driver alive" updates to the RX CPU when the APE is present. Signed-off-by: Matt Carlson Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 0ebf2ff60c4b..e952b91ca2ac 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -7862,7 +7862,8 @@ static void tg3_timer(unsigned long __opaque) * resets. */ if (!--tp->asf_counter) { - if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { + if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) && + !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) { u32 val; tg3_wait_for_event_ack(tp); -- cgit v1.2.2 From 4ba526ced990f4d61ee8d65fe8a6f0745e8e455c Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Fri, 15 Aug 2008 14:10:04 -0700 Subject: tg3: Fix firmware event timeouts The git commit 7c5026aa9b81dd45df8d3f4e0be73e485976a8b6 ("tg3: Add link state reporting to UMP firmware") introduced code that waits for previous firmware events to be serviced before attempting to submit a new event. Unfortunately that patch contained a bug that cause the driver to wait 2.5 seconds, rather than 2.5 milliseconds as intended. This patch fixes that bug. This bug revealed that not all firmware versions service driver events though. Since we do not know which versions of the firmware do and don't service these events, the driver needs some way to minimize the effects of the delay. This patch solves the problem by recording a jiffies timestamp when it submits an event to the hardware. If the jiffies counter shows that 2.5 milliseconds have already passed, a wait is not needed and the driver can proceed to submit a new event. Signed-off-by: Matt Carlson Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 53 +++++++++++++++++++++++++++++++++++++---------------- drivers/net/tg3.h | 3 +++ 2 files changed, 40 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index e952b91ca2ac..c26011eaa2be 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -1019,16 +1019,44 @@ static void tg3_mdio_fini(struct tg3 *tp) } } +/* tp->lock is held. */ +static inline void tg3_generate_fw_event(struct tg3 *tp) +{ + u32 val; + + val = tr32(GRC_RX_CPU_EVENT); + val |= GRC_RX_CPU_DRIVER_EVENT; + tw32_f(GRC_RX_CPU_EVENT, val); + + tp->last_event_jiffies = jiffies; +} + +#define TG3_FW_EVENT_TIMEOUT_USEC 2500 + /* tp->lock is held. */ static void tg3_wait_for_event_ack(struct tg3 *tp) { int i; + unsigned int delay_cnt; + long time_remain; + + /* If enough time has passed, no wait is necessary. */ + time_remain = (long)(tp->last_event_jiffies + 1 + + usecs_to_jiffies(TG3_FW_EVENT_TIMEOUT_USEC)) - + (long)jiffies; + if (time_remain < 0) + return; - /* Wait for up to 2.5 milliseconds */ - for (i = 0; i < 250000; i++) { + /* Check if we can shorten the wait time. */ + delay_cnt = jiffies_to_usecs(time_remain); + if (delay_cnt > TG3_FW_EVENT_TIMEOUT_USEC) + delay_cnt = TG3_FW_EVENT_TIMEOUT_USEC; + delay_cnt = (delay_cnt >> 3) + 1; + + for (i = 0; i < delay_cnt; i++) { if (!(tr32(GRC_RX_CPU_EVENT) & GRC_RX_CPU_DRIVER_EVENT)) break; - udelay(10); + udelay(8); } } @@ -1077,9 +1105,7 @@ static void tg3_ump_link_report(struct tg3 *tp) val = 0; tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 12, val); - val = tr32(GRC_RX_CPU_EVENT); - val |= GRC_RX_CPU_DRIVER_EVENT; - tw32_f(GRC_RX_CPU_EVENT, val); + tg3_generate_fw_event(tp); } static void tg3_link_report(struct tg3 *tp) @@ -5953,6 +5979,7 @@ static int tg3_chip_reset(struct tg3 *tp) tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg); if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) { tp->tg3_flags |= TG3_FLAG_ENABLE_ASF; + tp->last_event_jiffies = jiffies; if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) tp->tg3_flags2 |= TG3_FLG2_ASF_NEW_HANDSHAKE; } @@ -5966,15 +5993,12 @@ static void tg3_stop_fw(struct tg3 *tp) { if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) && !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) { - u32 val; - /* Wait for RX cpu to ACK the previous event. */ tg3_wait_for_event_ack(tp); tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_PAUSE_FW); - val = tr32(GRC_RX_CPU_EVENT); - val |= GRC_RX_CPU_DRIVER_EVENT; - tw32(GRC_RX_CPU_EVENT, val); + + tg3_generate_fw_event(tp); /* Wait for RX cpu to ACK this event. */ tg3_wait_for_event_ack(tp); @@ -7864,8 +7888,6 @@ static void tg3_timer(unsigned long __opaque) if (!--tp->asf_counter) { if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) && !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) { - u32 val; - tg3_wait_for_event_ack(tp); tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, @@ -7873,9 +7895,8 @@ static void tg3_timer(unsigned long __opaque) tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4); /* 5 seconds timeout */ tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5); - val = tr32(GRC_RX_CPU_EVENT); - val |= GRC_RX_CPU_DRIVER_EVENT; - tw32_f(GRC_RX_CPU_EVENT, val); + + tg3_generate_fw_event(tp); } tp->asf_counter = tp->asf_multiplier; } diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 377234947e4f..f5b8cab8d4b5 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2432,7 +2432,10 @@ struct tg3 { struct tg3_ethtool_stats estats; struct tg3_ethtool_stats estats_prev; + union { unsigned long phy_crc_errors; + unsigned long last_event_jiffies; + }; u32 rx_offset; u32 tg3_flags; -- cgit v1.2.2 From 816f8b86621000fc82e16ae5f172164de761d5eb Mon Sep 17 00:00:00 2001 From: Stefan Buehler Date: Fri, 15 Aug 2008 14:10:54 -0700 Subject: tg3: fix 64 bit counter for ethtool stats Ethtool stats are 64-bits in length. net_device_stats members are unsigned long types. When gathering information for a get_ethtool_stats call, the driver will call a driver-private, inlined get_stat64() function, which returns an unsigned long value. This call will inadvertently mask off the upper 32-bits of a stat on 32-bit machines. This patch defines a new get_estat() inline function and modifies the ESTAT_ADD() macro to use it. Signed-off-by: Stefan Buehler Signed-off-by: Matt Carlson Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index c26011eaa2be..ada1d0d11045 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -8466,6 +8466,11 @@ static inline unsigned long get_stat64(tg3_stat64_t *val) return ret; } +static inline u64 get_estat64(tg3_stat64_t *val) +{ + return ((u64)val->high << 32) | ((u64)val->low); +} + static unsigned long calc_crc_errors(struct tg3 *tp) { struct tg3_hw_stats *hw_stats = tp->hw_stats; @@ -8494,7 +8499,7 @@ static unsigned long calc_crc_errors(struct tg3 *tp) #define ESTAT_ADD(member) \ estats->member = old_estats->member + \ - get_stat64(&hw_stats->member) + get_estat64(&hw_stats->member) static struct tg3_ethtool_stats *tg3_get_estats(struct tg3 *tp) { -- cgit v1.2.2 From 23197916c447a1623d196e6547781180905f0bb2 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Fri, 15 Aug 2008 14:11:19 -0700 Subject: tg3: Update version to 3.94 This patch updates the version number to 3.94. Signed-off-by: Matt Carlson Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index ada1d0d11045..71d2c5cfdad9 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -66,8 +66,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.93" -#define DRV_MODULE_RELDATE "May 22, 2008" +#define DRV_MODULE_VERSION "3.94" +#define DRV_MODULE_RELDATE "August 14, 2008" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 -- cgit v1.2.2 From f22f8567cb0a530d8958d177e0f268783bd0d894 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Fri, 15 Aug 2008 14:52:08 -0700 Subject: loopback: Enable TSO This patch enables TSO since the loopback device is naturally capable of handling packets of any size. This also means that we won't enable GSO on lo which is good until GSO is fixed to preserve netfilter state as netfilter treats loopback packets in a special way. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- drivers/net/loopback.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index 49f6bc036a92..46e87cc87251 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -234,9 +234,7 @@ static void loopback_setup(struct net_device *dev) dev->type = ARPHRD_LOOPBACK; /* 0x0001*/ dev->flags = IFF_LOOPBACK; dev->features = NETIF_F_SG | NETIF_F_FRAGLIST -#ifdef LOOPBACK_TSO | NETIF_F_TSO -#endif | NETIF_F_NO_CSUM | NETIF_F_HIGHDMA | NETIF_F_LLTX -- cgit v1.2.2 From 7447ef63cf2dfdc444f4c72ae13f604350b2e25f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 15 Aug 2008 14:54:03 -0700 Subject: loopback: Remove rest of LOOPBACK_TSO code. It hasn't been enabled for a long time and the generic GSO engine is better documentation of what is expected of a device implementing TSO. Signed-off-by: David S. Miller --- drivers/net/loopback.c | 62 -------------------------------------------------- 1 file changed, 62 deletions(-) (limited to 'drivers') diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index 46e87cc87251..489d53be2f5d 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -64,68 +64,6 @@ struct pcpu_lstats { unsigned long bytes; }; -/* KISS: just allocate small chunks and copy bits. - * - * So, in fact, this is documentation, explaining what we expect - * of largesending device modulo TCP checksum, which is ignored for loopback. - */ - -#ifdef LOOPBACK_TSO -static void emulate_large_send_offload(struct sk_buff *skb) -{ - struct iphdr *iph = ip_hdr(skb); - struct tcphdr *th = (struct tcphdr *)(skb_network_header(skb) + - (iph->ihl * 4)); - unsigned int doffset = (iph->ihl + th->doff) * 4; - unsigned int mtu = skb_shinfo(skb)->gso_size + doffset; - unsigned int offset = 0; - u32 seq = ntohl(th->seq); - u16 id = ntohs(iph->id); - - while (offset + doffset < skb->len) { - unsigned int frag_size = min(mtu, skb->len - offset) - doffset; - struct sk_buff *nskb = alloc_skb(mtu + 32, GFP_ATOMIC); - - if (!nskb) - break; - skb_reserve(nskb, 32); - skb_set_mac_header(nskb, -ETH_HLEN); - skb_reset_network_header(nskb); - iph = ip_hdr(nskb); - skb_copy_to_linear_data(nskb, skb_network_header(skb), - doffset); - if (skb_copy_bits(skb, - doffset + offset, - nskb->data + doffset, - frag_size)) - BUG(); - skb_put(nskb, doffset + frag_size); - nskb->ip_summed = CHECKSUM_UNNECESSARY; - nskb->dev = skb->dev; - nskb->priority = skb->priority; - nskb->protocol = skb->protocol; - nskb->dst = dst_clone(skb->dst); - memcpy(nskb->cb, skb->cb, sizeof(skb->cb)); - nskb->pkt_type = skb->pkt_type; - - th = (struct tcphdr *)(skb_network_header(nskb) + iph->ihl * 4); - iph->tot_len = htons(frag_size + doffset); - iph->id = htons(id); - iph->check = 0; - iph->check = ip_fast_csum((unsigned char *) iph, iph->ihl); - th->seq = htonl(seq); - if (offset + doffset + frag_size < skb->len) - th->fin = th->psh = 0; - netif_rx(nskb); - offset += frag_size; - seq += frag_size; - id++; - } - - dev_kfree_skb(skb); -} -#endif /* LOOPBACK_TSO */ - /* * The higher levels take care of making this non-reentrant (it's * called with bh's disabled). -- cgit v1.2.2 From 04a0551c87363f100b04d28d7a15a632b70e18e7 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Fri, 15 Aug 2008 14:56:37 -0700 Subject: loopback: Drop obsolete ip_summed setting Now that the network stack can handle inbound packets with partial checksums, we should no longer clobber the ip_summed field in the loopback driver. This is because CHECKSUM_UNNECESSARY implies that the checksum field is actually valid which is not true for loopback packets since it's only partial (and thus complemented). This allows packets from lo to then be SNATed to an external source while still preserving the checksum's validity. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- drivers/net/loopback.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index 489d53be2f5d..3b43bfd85a0f 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -75,9 +75,6 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev) skb_orphan(skb); skb->protocol = eth_type_trans(skb,dev); -#ifndef LOOPBACK_MUST_CHECKSUM - skb->ip_summed = CHECKSUM_UNNECESSARY; -#endif #ifdef LOOPBACK_TSO if (skb_is_gso(skb)) { -- cgit v1.2.2 From e3b99556975907530aeb9745e7b3945a0da48f17 Mon Sep 17 00:00:00 2001 From: Mark McLoughlin Date: Fri, 15 Aug 2008 15:09:56 -0700 Subject: tun: TUNGETIFF interface to query name and flags Add a TUNGETIFF interface so that userspace can query a tun/tap descriptor for its name and flags. This is needed because it is common for one app to create a tap interface, exec another app and pass it the file descriptor for the interface. Without TUNGETIFF the spawned app has no way of detecting wheter the interface has e.g. IFF_VNET_HDR set. Signed-off-by: Mark McLoughlin Acked-by: Max Krasnyansky Signed-off-by: David S. Miller --- drivers/net/tun.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'drivers') diff --git a/drivers/net/tun.c b/drivers/net/tun.c index e6bbc639c2d0..95931a5a9883 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -748,6 +748,36 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) return err; } +static int tun_get_iff(struct net *net, struct file *file, struct ifreq *ifr) +{ + struct tun_struct *tun = file->private_data; + + if (!tun) + return -EBADFD; + + DBG(KERN_INFO "%s: tun_get_iff\n", tun->dev->name); + + strcpy(ifr->ifr_name, tun->dev->name); + + ifr->ifr_flags = 0; + + if (ifr->ifr_flags & TUN_TUN_DEV) + ifr->ifr_flags |= IFF_TUN; + else + ifr->ifr_flags |= IFF_TAP; + + if (tun->flags & TUN_NO_PI) + ifr->ifr_flags |= IFF_NO_PI; + + if (tun->flags & TUN_ONE_QUEUE) + ifr->ifr_flags |= IFF_ONE_QUEUE; + + if (tun->flags & TUN_VNET_HDR) + ifr->ifr_flags |= IFF_VNET_HDR; + + return 0; +} + /* This is like a cut-down ethtool ops, except done via tun fd so no * privs required. */ static int set_offload(struct net_device *dev, unsigned long arg) @@ -833,6 +863,15 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file, DBG(KERN_INFO "%s: tun_chr_ioctl cmd %d\n", tun->dev->name, cmd); switch (cmd) { + case TUNGETIFF: + ret = tun_get_iff(current->nsproxy->net_ns, file, &ifr); + if (ret) + return ret; + + if (copy_to_user(argp, &ifr, sizeof(ifr))) + return -EFAULT; + break; + case TUNSETNOCSUM: /* Disable/Enable checksum */ if (arg) -- cgit v1.2.2 From f42157cb568c1eb02eca7df4da67553a9edae24a Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 15 Aug 2008 15:15:10 -0700 Subject: tun: fallback if skb_alloc() fails on big packets skb_alloc produces linear packets (using kmalloc()). That can fail, so should we fall back to making paged skbs. My original version of this patch always allocate paged skbs for big packets. But that made performance drop from 8.4 seconds to 8.8 seconds on 1G lguest->Host TCP xmit. So now we only do that as a fallback. Signed-off-by: Rusty Russell Acked-by: Max Krasnyansky Signed-off-by: David S. Miller --- drivers/net/tun.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 95931a5a9883..6daea0c91862 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -358,6 +358,66 @@ static unsigned int tun_chr_poll(struct file *file, poll_table * wait) return mask; } +/* prepad is the amount to reserve at front. len is length after that. + * linear is a hint as to how much to copy (usually headers). */ +static struct sk_buff *tun_alloc_skb(size_t prepad, size_t len, size_t linear, + gfp_t gfp) +{ + struct sk_buff *skb; + unsigned int i; + + skb = alloc_skb(prepad + len, gfp|__GFP_NOWARN); + if (skb) { + skb_reserve(skb, prepad); + skb_put(skb, len); + return skb; + } + + /* Under a page? Don't bother with paged skb. */ + if (prepad + len < PAGE_SIZE) + return NULL; + + /* Start with a normal skb, and add pages. */ + skb = alloc_skb(prepad + linear, gfp); + if (!skb) + return NULL; + + skb_reserve(skb, prepad); + skb_put(skb, linear); + + len -= linear; + + for (i = 0; i < MAX_SKB_FRAGS; i++) { + skb_frag_t *f = &skb_shinfo(skb)->frags[i]; + + f->page = alloc_page(gfp|__GFP_ZERO); + if (!f->page) + break; + + f->page_offset = 0; + f->size = PAGE_SIZE; + + skb->data_len += PAGE_SIZE; + skb->len += PAGE_SIZE; + skb->truesize += PAGE_SIZE; + skb_shinfo(skb)->nr_frags++; + + if (len < PAGE_SIZE) { + len = 0; + break; + } + len -= PAGE_SIZE; + } + + /* Too large, or alloc fail? */ + if (unlikely(len)) { + kfree_skb(skb); + skb = NULL; + } + + return skb; +} + /* Get packet from user space buffer */ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv, size_t count) { @@ -391,14 +451,12 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv, return -EINVAL; } - if (!(skb = alloc_skb(len + align, GFP_KERNEL))) { + if (!(skb = tun_alloc_skb(align, len, gso.hdr_len, GFP_KERNEL))) { tun->dev->stats.rx_dropped++; return -ENOMEM; } - if (align) - skb_reserve(skb, align); - if (memcpy_fromiovec(skb_put(skb, len), iv, len)) { + if (skb_copy_datagram_from_iovec(skb, 0, iv, len)) { tun->dev->stats.rx_dropped++; kfree_skb(skb); return -EFAULT; -- cgit v1.2.2 From 08013fa353fdcfc0a03cae805393abfc56722387 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 15 Aug 2008 19:46:01 -0700 Subject: bnx2: Fix build with VLAN_8021Q disabled. Reported by Randy Dunlap. Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index d4548101e495..2486a656f12d 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -35,8 +35,8 @@ #include #include #include -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) #include +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) #define BCM_VLAN 1 #endif #include -- cgit v1.2.2 From 9bfa35fe422c74882e27cc54450a5f76c96aad68 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 18 Aug 2008 13:23:52 +0200 Subject: [Bluetooth] Add SCO support to btusb driver The new generic driver for Bluetooth USB devices was missing proper SCO support. The driver now claims the second interface for these USB devices to allow the flow of SCO packets. It also handles switching of the alternate setting and re-submission of isochronous URBs. The btusb driver is now a full replacement for hci_usb and thus the experimental tag has been removed and this driver is promoted as preferred one. Signed-off-by: Marcel Holtmann --- drivers/bluetooth/Kconfig | 10 +- drivers/bluetooth/btusb.c | 282 +++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 272 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig index a235ca787465..7cb4029a5375 100644 --- a/drivers/bluetooth/Kconfig +++ b/drivers/bluetooth/Kconfig @@ -3,8 +3,8 @@ menu "Bluetooth device drivers" depends on BT config BT_HCIUSB - tristate "HCI USB driver" - depends on USB + tristate "HCI USB driver (old version)" + depends on USB && BT_HCIBTUSB=n help Bluetooth HCI USB driver. This driver is required if you want to use Bluetooth devices with @@ -23,15 +23,13 @@ config BT_HCIUSB_SCO Say Y here to compile support for SCO over HCI USB. config BT_HCIBTUSB - tristate "HCI USB driver (alternate version)" - depends on USB && EXPERIMENTAL && BT_HCIUSB=n + tristate "HCI USB driver" + depends on USB help Bluetooth HCI USB driver. This driver is required if you want to use Bluetooth devices with USB interface. - This driver is still experimental and has no SCO support. - Say Y here to compile support for Bluetooth USB devices into the kernel or say M to compile it as module (btusb). diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 95ae9ba5661e..6a010681ecf3 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -2,7 +2,7 @@ * * Generic Bluetooth USB driver * - * Copyright (C) 2005-2007 Marcel Holtmann + * Copyright (C) 2005-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -41,7 +41,7 @@ #define BT_DBG(D...) #endif -#define VERSION "0.2" +#define VERSION "0.3" static int ignore_dga; static int ignore_csr; @@ -160,12 +160,16 @@ static struct usb_device_id blacklist_table[] = { { } /* Terminating entry */ }; +#define BTUSB_MAX_ISOC_FRAMES 10 + #define BTUSB_INTR_RUNNING 0 #define BTUSB_BULK_RUNNING 1 +#define BTUSB_ISOC_RUNNING 2 struct btusb_data { struct hci_dev *hdev; struct usb_device *udev; + struct usb_interface *isoc; spinlock_t lock; @@ -176,10 +180,15 @@ struct btusb_data { struct usb_anchor tx_anchor; struct usb_anchor intr_anchor; struct usb_anchor bulk_anchor; + struct usb_anchor isoc_anchor; struct usb_endpoint_descriptor *intr_ep; struct usb_endpoint_descriptor *bulk_tx_ep; struct usb_endpoint_descriptor *bulk_rx_ep; + struct usb_endpoint_descriptor *isoc_tx_ep; + struct usb_endpoint_descriptor *isoc_rx_ep; + + int isoc_altsetting; }; static void btusb_intr_complete(struct urb *urb) @@ -195,6 +204,8 @@ static void btusb_intr_complete(struct urb *urb) return; if (urb->status == 0) { + hdev->stat.byte_rx += urb->actual_length; + if (hci_recv_fragment(hdev, HCI_EVENT_PKT, urb->transfer_buffer, urb->actual_length) < 0) { @@ -216,7 +227,7 @@ static void btusb_intr_complete(struct urb *urb) } } -static inline int btusb_submit_intr_urb(struct hci_dev *hdev) +static int btusb_submit_intr_urb(struct hci_dev *hdev) { struct btusb_data *data = hdev->driver_data; struct urb *urb; @@ -226,6 +237,9 @@ static inline int btusb_submit_intr_urb(struct hci_dev *hdev) BT_DBG("%s", hdev->name); + if (!data->intr_ep) + return -ENODEV; + urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) return -ENOMEM; @@ -274,6 +288,8 @@ static void btusb_bulk_complete(struct urb *urb) return; if (urb->status == 0) { + hdev->stat.byte_rx += urb->actual_length; + if (hci_recv_fragment(hdev, HCI_ACLDATA_PKT, urb->transfer_buffer, urb->actual_length) < 0) { @@ -295,7 +311,7 @@ static void btusb_bulk_complete(struct urb *urb) } } -static inline int btusb_submit_bulk_urb(struct hci_dev *hdev) +static int btusb_submit_bulk_urb(struct hci_dev *hdev) { struct btusb_data *data = hdev->driver_data; struct urb *urb; @@ -305,6 +321,9 @@ static inline int btusb_submit_bulk_urb(struct hci_dev *hdev) BT_DBG("%s", hdev->name); + if (!data->bulk_rx_ep) + return -ENODEV; + urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) return -ENOMEM; @@ -339,6 +358,127 @@ static inline int btusb_submit_bulk_urb(struct hci_dev *hdev) return err; } +static void btusb_isoc_complete(struct urb *urb) +{ + struct hci_dev *hdev = urb->context; + struct btusb_data *data = hdev->driver_data; + int i, err; + + BT_DBG("%s urb %p status %d count %d", hdev->name, + urb, urb->status, urb->actual_length); + + if (!test_bit(HCI_RUNNING, &hdev->flags)) + return; + + if (urb->status == 0) { + for (i = 0; i < urb->number_of_packets; i++) { + unsigned int offset = urb->iso_frame_desc[i].offset; + unsigned int length = urb->iso_frame_desc[i].actual_length; + + if (urb->iso_frame_desc[i].status) + continue; + + hdev->stat.byte_rx += length; + + if (hci_recv_fragment(hdev, HCI_SCODATA_PKT, + urb->transfer_buffer + offset, + length) < 0) { + BT_ERR("%s corrupted SCO packet", hdev->name); + hdev->stat.err_rx++; + } + } + } + + if (!test_bit(BTUSB_ISOC_RUNNING, &data->flags)) + return; + + usb_anchor_urb(urb, &data->isoc_anchor); + + err = usb_submit_urb(urb, GFP_ATOMIC); + if (err < 0) { + BT_ERR("%s urb %p failed to resubmit (%d)", + hdev->name, urb, -err); + usb_unanchor_urb(urb); + } +} + +static void inline __fill_isoc_descriptor(struct urb *urb, int len, int mtu) +{ + int i, offset = 0; + + BT_DBG("len %d mtu %d", len, mtu); + + for (i = 0; i < BTUSB_MAX_ISOC_FRAMES && len >= mtu; + i++, offset += mtu, len -= mtu) { + urb->iso_frame_desc[i].offset = offset; + urb->iso_frame_desc[i].length = mtu; + } + + if (len && i < BTUSB_MAX_ISOC_FRAMES) { + urb->iso_frame_desc[i].offset = offset; + urb->iso_frame_desc[i].length = len; + i++; + } + + urb->number_of_packets = i; +} + +static int btusb_submit_isoc_urb(struct hci_dev *hdev) +{ + struct btusb_data *data = hdev->driver_data; + struct urb *urb; + unsigned char *buf; + unsigned int pipe; + int err, size; + + BT_DBG("%s", hdev->name); + + if (!data->isoc_rx_ep) + return -ENODEV; + + urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_KERNEL); + if (!urb) + return -ENOMEM; + + size = le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize) * + BTUSB_MAX_ISOC_FRAMES; + + buf = kmalloc(size, GFP_KERNEL); + if (!buf) { + usb_free_urb(urb); + return -ENOMEM; + } + + pipe = usb_rcvisocpipe(data->udev, data->isoc_rx_ep->bEndpointAddress); + + urb->dev = data->udev; + urb->pipe = pipe; + urb->context = hdev; + urb->complete = btusb_isoc_complete; + urb->interval = data->isoc_rx_ep->bInterval; + + urb->transfer_flags = URB_FREE_BUFFER | URB_ISO_ASAP; + urb->transfer_buffer = buf; + urb->transfer_buffer_length = size; + + __fill_isoc_descriptor(urb, size, + le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize)); + + usb_anchor_urb(urb, &data->isoc_anchor); + + err = usb_submit_urb(urb, GFP_KERNEL); + if (err < 0) { + BT_ERR("%s urb %p submission failed (%d)", + hdev->name, urb, -err); + usb_unanchor_urb(urb); + kfree(buf); + } + + usb_free_urb(urb); + + return err; +} + static void btusb_tx_complete(struct urb *urb) { struct sk_buff *skb = urb->context; @@ -392,6 +532,9 @@ static int btusb_close(struct hci_dev *hdev) if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) return 0; + clear_bit(BTUSB_ISOC_RUNNING, &data->flags); + usb_kill_anchored_urbs(&data->intr_anchor); + clear_bit(BTUSB_BULK_RUNNING, &data->flags); usb_kill_anchored_urbs(&data->bulk_anchor); @@ -453,6 +596,9 @@ static int btusb_send_frame(struct sk_buff *skb) break; case HCI_ACLDATA_PKT: + if (!data->bulk_tx_ep || hdev->conn_hash.acl_num < 1) + return -ENODEV; + urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) return -ENOMEM; @@ -467,9 +613,31 @@ static int btusb_send_frame(struct sk_buff *skb) break; case HCI_SCODATA_PKT: + if (!data->isoc_tx_ep || hdev->conn_hash.sco_num < 1) + return -ENODEV; + + urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_ATOMIC); + if (!urb) + return -ENOMEM; + + pipe = usb_sndisocpipe(data->udev, + data->isoc_tx_ep->bEndpointAddress); + + urb->dev = data->udev; + urb->pipe = pipe; + urb->context = skb; + urb->complete = btusb_tx_complete; + urb->interval = data->isoc_tx_ep->bInterval; + + urb->transfer_flags = URB_ISO_ASAP; + urb->transfer_buffer = skb->data; + urb->transfer_buffer_length = skb->len; + + __fill_isoc_descriptor(urb, skb->len, + le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize)); + hdev->stat.sco_tx++; - kfree_skb(skb); - return 0; + break; default: return -EILSEQ; @@ -508,22 +676,86 @@ static void btusb_notify(struct hci_dev *hdev, unsigned int evt) schedule_work(&data->work); } +static int inline __set_isoc_interface(struct hci_dev *hdev, int altsetting) +{ + struct btusb_data *data = hdev->driver_data; + struct usb_interface *intf = data->isoc; + struct usb_endpoint_descriptor *ep_desc; + int i, err; + + if (!data->isoc) + return -ENODEV; + + err = usb_set_interface(data->udev, 1, altsetting); + if (err < 0) { + BT_ERR("%s setting interface failed (%d)", hdev->name, -err); + return err; + } + + data->isoc_altsetting = altsetting; + + data->isoc_tx_ep = NULL; + data->isoc_rx_ep = NULL; + + for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) { + ep_desc = &intf->cur_altsetting->endpoint[i].desc; + + if (!data->isoc_tx_ep && usb_endpoint_is_isoc_out(ep_desc)) { + data->isoc_tx_ep = ep_desc; + continue; + } + + if (!data->isoc_rx_ep && usb_endpoint_is_isoc_in(ep_desc)) { + data->isoc_rx_ep = ep_desc; + continue; + } + } + + if (!data->isoc_tx_ep || !data->isoc_rx_ep) { + BT_ERR("%s invalid SCO descriptors", hdev->name); + return -ENODEV; + } + + return 0; +} + static void btusb_work(struct work_struct *work) { struct btusb_data *data = container_of(work, struct btusb_data, work); struct hci_dev *hdev = data->hdev; - if (hdev->conn_hash.acl_num == 0) { + if (hdev->conn_hash.acl_num > 0) { + if (!test_and_set_bit(BTUSB_BULK_RUNNING, &data->flags)) { + if (btusb_submit_bulk_urb(hdev) < 0) + clear_bit(BTUSB_BULK_RUNNING, &data->flags); + else + btusb_submit_bulk_urb(hdev); + } + } else { clear_bit(BTUSB_BULK_RUNNING, &data->flags); usb_kill_anchored_urbs(&data->bulk_anchor); - return; } - if (!test_and_set_bit(BTUSB_BULK_RUNNING, &data->flags)) { - if (btusb_submit_bulk_urb(hdev) < 0) - clear_bit(BTUSB_BULK_RUNNING, &data->flags); - else - btusb_submit_bulk_urb(hdev); + if (hdev->conn_hash.sco_num > 0) { + if (data->isoc_altsetting != 2) { + clear_bit(BTUSB_ISOC_RUNNING, &data->flags); + usb_kill_anchored_urbs(&data->isoc_anchor); + + if (__set_isoc_interface(hdev, 2) < 0) + return; + } + + if (!test_and_set_bit(BTUSB_ISOC_RUNNING, &data->flags)) { + if (btusb_submit_isoc_urb(hdev) < 0) + clear_bit(BTUSB_ISOC_RUNNING, &data->flags); + else + btusb_submit_isoc_urb(hdev); + } + } else { + clear_bit(BTUSB_ISOC_RUNNING, &data->flags); + usb_kill_anchored_urbs(&data->isoc_anchor); + + __set_isoc_interface(hdev, 0); } } @@ -597,6 +829,7 @@ static int btusb_probe(struct usb_interface *intf, init_usb_anchor(&data->tx_anchor); init_usb_anchor(&data->intr_anchor); init_usb_anchor(&data->bulk_anchor); + init_usb_anchor(&data->isoc_anchor); hdev = hci_alloc_dev(); if (!hdev) { @@ -620,6 +853,9 @@ static int btusb_probe(struct usb_interface *intf, hdev->owner = THIS_MODULE; + /* interface numbers are hardcoded in the spec */ + data->isoc = usb_ifnum_to_if(data->udev, 1); + if (reset || id->driver_info & BTUSB_RESET) set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks); @@ -628,11 +864,16 @@ static int btusb_probe(struct usb_interface *intf, set_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks); } + if (id->driver_info & BTUSB_BROKEN_ISOC) + data->isoc = NULL; + if (id->driver_info & BTUSB_SNIFFER) { - struct usb_device *udev = interface_to_usbdev(intf); + struct usb_device *udev = data->udev; if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997) set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); + + data->isoc = NULL; } if (id->driver_info & BTUSB_BCM92035) { @@ -646,6 +887,16 @@ static int btusb_probe(struct usb_interface *intf, } } + if (data->isoc) { + err = usb_driver_claim_interface(&btusb_driver, + data->isoc, NULL); + if (err < 0) { + hci_free_dev(hdev); + kfree(data); + return err; + } + } + err = hci_register_dev(hdev); if (err < 0) { hci_free_dev(hdev); @@ -670,6 +921,9 @@ static void btusb_disconnect(struct usb_interface *intf) hdev = data->hdev; + if (data->isoc) + usb_driver_release_interface(&btusb_driver, data->isoc); + usb_set_intfdata(intf, NULL); hci_unregister_dev(hdev); -- cgit v1.2.2 From 63fbd24e5102eecfc9d049ed7f4be7f9a25f814f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 18 Aug 2008 13:23:53 +0200 Subject: [Bluetooth] Consolidate maintainers information The Bluetooth entries for the MAINTAINERS file are a little bit too much. Consolidate them into two entries. One for Bluetooth drivers and another one for the Bluetooth subsystem. Also the MODULE_AUTHOR should indicate the current maintainer of the module and actually not the original author. Fix all Bluetooth modules to provide current maintainer information. Signed-off-by: Marcel Holtmann --- drivers/bluetooth/bt3c_cs.c | 2 +- drivers/bluetooth/hci_ldisc.c | 2 +- drivers/bluetooth/hci_usb.c | 2 +- drivers/bluetooth/hci_vhci.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index 593b7c595038..27058477cc8b 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c @@ -60,7 +60,7 @@ /* ======================== Module parameters ======================== */ -MODULE_AUTHOR("Marcel Holtmann , Jose Orlando Pereira "); +MODULE_AUTHOR("Marcel Holtmann "); MODULE_DESCRIPTION("Bluetooth driver for the 3Com Bluetooth PCMCIA card"); MODULE_LICENSE("GPL"); MODULE_FIRMWARE("BT3CPCC.bin"); diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 69df187d74ce..8dfcf77cb717 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -577,7 +577,7 @@ module_exit(hci_uart_exit); module_param(reset, bool, 0644); MODULE_PARM_DESC(reset, "Send HCI reset command on initialization"); -MODULE_AUTHOR("Maxim Krasnyansky , Marcel Holtmann "); +MODULE_AUTHOR("Marcel Holtmann "); MODULE_DESCRIPTION("Bluetooth HCI UART driver ver " VERSION); MODULE_VERSION(VERSION); MODULE_LICENSE("GPL"); diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c index e397572bf574..3c453924f838 100644 --- a/drivers/bluetooth/hci_usb.c +++ b/drivers/bluetooth/hci_usb.c @@ -1130,7 +1130,7 @@ module_param(isoc, int, 0644); MODULE_PARM_DESC(isoc, "Set isochronous transfers for SCO over HCI support"); #endif -MODULE_AUTHOR("Maxim Krasnyansky , Marcel Holtmann "); +MODULE_AUTHOR("Marcel Holtmann "); MODULE_DESCRIPTION("Bluetooth HCI USB driver ver " VERSION); MODULE_VERSION(VERSION); MODULE_LICENSE("GPL"); diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c index d97700aa54a9..7320a71b6368 100644 --- a/drivers/bluetooth/hci_vhci.c +++ b/drivers/bluetooth/hci_vhci.c @@ -377,7 +377,7 @@ module_exit(vhci_exit); module_param(minor, int, 0444); MODULE_PARM_DESC(minor, "Miscellaneous minor device number"); -MODULE_AUTHOR("Maxim Krasnyansky , Marcel Holtmann "); +MODULE_AUTHOR("Marcel Holtmann "); MODULE_DESCRIPTION("Bluetooth virtual HCI driver ver " VERSION); MODULE_VERSION(VERSION); MODULE_LICENSE("GPL"); -- cgit v1.2.2 From 88b9e2bef3e38c053ec8f054f2cbb9345724cdb1 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 5 Aug 2008 22:06:51 +0300 Subject: ath9k: work around gcc ICEs (again) (I missed the fact that the original post said to apply this patch twice... -- JWL) Original commit log message: This patch works around an internal compiler error (gcc bug #37014) in all gcc 4.2 compilers and the gcc 4.3 series up to at least 4.3.1 on at least powerpc and mips. Many thanks to Andrew Pinski for analyzing the gcc bug. Signed-off-by: Adrian Bunk Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/hw.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c index bde162f128ab..a17eb130f574 100644 --- a/drivers/net/wireless/ath9k/hw.c +++ b/drivers/net/wireless/ath9k/hw.c @@ -5017,7 +5017,11 @@ static void ath9k_hw_spur_mitigate(struct ath_hal *ah, for (i = 0; i < 123; i++) { if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) { - if ((abs(cur_vit_mask - bin)) < 75) + + /* workaround for gcc bug #37014 */ + volatile int tmp = abs(cur_vit_mask - bin); + + if (tmp < 75) mask_amt = 1; else mask_amt = 0; -- cgit v1.2.2 From aaa1553512b9105699113ea7e2ea726f3d9d4de2 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 9 Aug 2008 19:20:47 -0500 Subject: p54: Fix regression due to "net: Delete NETDEVICES_MULTIQUEUE kconfig option" Commit b19fa1f, entitled "net: Delete NETDEVICES_MULTIQUEUE kconfig option" breaks p54pci and p54usb. Additionally, the old logic always tx'ed cts frames (if enabled) with a short preamble when [rate > 3]. (i.e. with any 802.11g rate). Of course this isn't that bad, but it's still wrong! (This patch also clarifies the meanings of some of the fields in the tx header for the hardware. -- JWL) Signed-off-by: Christian Lamparter Acked-by: Larry Finger Cc: [2.6.25.x, 2.6.26.x] Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54common.c | 31 ++++++++++++++++--------------- drivers/net/wireless/p54/p54common.h | 18 +++++++++--------- 2 files changed, 25 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index 83cd85e1f847..49afd20d2c30 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c @@ -413,12 +413,12 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb) last_addr = range->end_addr; __skb_unlink(entry, &priv->tx_queue); memset(&info->status, 0, sizeof(info->status)); - priv->tx_stats[skb_get_queue_mapping(skb)].len--; entry_hdr = (struct p54_control_hdr *) entry->data; entry_data = (struct p54_tx_control_allocdata *) entry_hdr->data; if ((entry_hdr->magic1 & cpu_to_le16(0x4000)) != 0) pad = entry_data->align[0]; + priv->tx_stats[entry_data->hw_queue - 4].len--; if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { if (!(payload->status & 0x01)) info->flags |= IEEE80211_TX_STAT_ACK; @@ -557,6 +557,7 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb) struct p54_tx_control_allocdata *txhdr; size_t padding, len; u8 rate; + u8 cts_rate = 0x20; current_queue = &priv->tx_stats[skb_get_queue_mapping(skb)]; if (unlikely(current_queue->len > current_queue->limit)) @@ -581,28 +582,28 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb) hdr->type = (info->flags & IEEE80211_TX_CTL_NO_ACK) ? 0 : cpu_to_le16(1); hdr->retry1 = hdr->retry2 = info->control.retry_limit; - memset(txhdr->wep_key, 0x0, 16); - txhdr->padding = 0; - txhdr->padding2 = 0; - /* TODO: add support for alternate retry TX rates */ rate = ieee80211_get_tx_rate(dev, info)->hw_value; - if (info->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE) + if (info->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE) { rate |= 0x10; - if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) + cts_rate |= 0x10; + } + if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) { rate |= 0x40; - else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) + cts_rate |= ieee80211_get_rts_cts_rate(dev, info)->hw_value; + } else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) { rate |= 0x20; + cts_rate |= ieee80211_get_rts_cts_rate(dev, info)->hw_value; + } memset(txhdr->rateset, rate, 8); - txhdr->wep_key_present = 0; - txhdr->wep_key_len = 0; - txhdr->frame_type = cpu_to_le32(skb_get_queue_mapping(skb) + 4); - txhdr->magic4 = 0; - txhdr->antenna = (info->antenna_sel_tx == 0) ? + txhdr->key_type = 0; + txhdr->key_len = 0; + txhdr->hw_queue = skb_get_queue_mapping(skb) + 4; + txhdr->tx_antenna = (info->antenna_sel_tx == 0) ? 2 : info->antenna_sel_tx - 1; txhdr->output_power = 0x7f; // HW Maximum - txhdr->magic5 = (info->flags & IEEE80211_TX_CTL_NO_ACK) ? - 0 : ((rate > 0x3) ? cpu_to_le32(0x33) : cpu_to_le32(0x23)); + txhdr->cts_rate = (info->flags & IEEE80211_TX_CTL_NO_ACK) ? + 0 : cts_rate; if (padding) txhdr->align[0] = padding; diff --git a/drivers/net/wireless/p54/p54common.h b/drivers/net/wireless/p54/p54common.h index 2245fcce92dc..8db6c0e8e540 100644 --- a/drivers/net/wireless/p54/p54common.h +++ b/drivers/net/wireless/p54/p54common.h @@ -183,16 +183,16 @@ struct p54_frame_sent_hdr { struct p54_tx_control_allocdata { u8 rateset[8]; - u16 padding; - u8 wep_key_present; - u8 wep_key_len; - u8 wep_key[16]; - __le32 frame_type; - u32 padding2; - __le16 magic4; - u8 antenna; + u8 unalloc0[2]; + u8 key_type; + u8 key_len; + u8 key[16]; + u8 hw_queue; + u8 unalloc1[9]; + u8 tx_antenna; u8 output_power; - __le32 magic5; + u8 cts_rate; + u8 unalloc2[3]; u8 align[0]; } __attribute__ ((packed)); -- cgit v1.2.2 From 7f37441c21d3ae9fec47ef418ccafb2823d12a27 Mon Sep 17 00:00:00 2001 From: Holger Schurig Date: Thu, 7 Aug 2008 18:24:12 +0200 Subject: ssb: allow compilation on systems without PCI Makes ssb work on system without a PCI bus. Signed-off-by: Holger Schurig Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/ssb/main.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index d831a2beff39..87ab2443e66d 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -1165,15 +1165,19 @@ EXPORT_SYMBOL(ssb_dma_translation); int ssb_dma_set_mask(struct ssb_device *dev, u64 mask) { +#ifdef CONFIG_SSB_PCIHOST int err; +#endif switch (dev->bus->bustype) { case SSB_BUSTYPE_PCI: +#ifdef CONFIG_SSB_PCIHOST err = pci_set_dma_mask(dev->bus->host_pci, mask); if (err) return err; err = pci_set_consistent_dma_mask(dev->bus->host_pci, mask); return err; +#endif case SSB_BUSTYPE_SSB: return dma_set_mask(dev->dev, mask); default: @@ -1188,6 +1192,7 @@ void * ssb_dma_alloc_consistent(struct ssb_device *dev, size_t size, { switch (dev->bus->bustype) { case SSB_BUSTYPE_PCI: +#ifdef CONFIG_SSB_PCIHOST if (gfp_flags & GFP_DMA) { /* Workaround: The PCI API does not support passing * a GFP flag. */ @@ -1195,6 +1200,7 @@ void * ssb_dma_alloc_consistent(struct ssb_device *dev, size_t size, size, dma_handle, gfp_flags); } return pci_alloc_consistent(dev->bus->host_pci, size, dma_handle); +#endif case SSB_BUSTYPE_SSB: return dma_alloc_coherent(dev->dev, size, dma_handle, gfp_flags); default: @@ -1210,6 +1216,7 @@ void ssb_dma_free_consistent(struct ssb_device *dev, size_t size, { switch (dev->bus->bustype) { case SSB_BUSTYPE_PCI: +#ifdef CONFIG_SSB_PCIHOST if (gfp_flags & GFP_DMA) { /* Workaround: The PCI API does not support passing * a GFP flag. */ @@ -1220,6 +1227,7 @@ void ssb_dma_free_consistent(struct ssb_device *dev, size_t size, pci_free_consistent(dev->bus->host_pci, size, vaddr, dma_handle); return; +#endif case SSB_BUSTYPE_SSB: dma_free_coherent(dev->dev, size, vaddr, dma_handle); return; -- cgit v1.2.2 From 37465c8a3ec7279e3314623d1e2d2a50c10cf79f Mon Sep 17 00:00:00 2001 From: Michael Karcher Date: Thu, 7 Aug 2008 19:34:01 +0200 Subject: ath5k: Don't fiddle with MSI on suspend/resume. Commit 256b152b005e319f985f50f2a910a75ba0def74f (ath5k: don't enable MSI, we cannot handle it yet) has removed msi support, but overlooked the suspend/resume code. This patch completes msi removal. I don't consider this patch copyrightable, and thus put it into the public domain. The result is of course a base.c file dual-licensed under 3-clause-BSD and GPL. Signed-off-by: Michael Karcher Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath5k/base.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index 2028866f5995..f19f33c4e336 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c @@ -587,7 +587,6 @@ ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state) ath5k_stop_hw(sc); free_irq(pdev->irq, sc); - pci_disable_msi(pdev); pci_save_state(pdev); pci_disable_device(pdev); pci_set_power_state(pdev, PCI_D3hot); @@ -616,12 +615,10 @@ ath5k_pci_resume(struct pci_dev *pdev) */ pci_write_config_byte(pdev, 0x41, 0); - pci_enable_msi(pdev); - err = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc); if (err) { ATH5K_ERR(sc, "request_irq failed\n"); - goto err_msi; + goto err_no_irq; } err = ath5k_init(sc); @@ -642,8 +639,7 @@ ath5k_pci_resume(struct pci_dev *pdev) return 0; err_irq: free_irq(pdev->irq, sc); -err_msi: - pci_disable_msi(pdev); +err_no_irq: pci_disable_device(pdev); return err; } -- cgit v1.2.2 From a58d452290aafae30b021c8bf185853b1aaf2092 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sun, 10 Aug 2008 10:19:33 -0500 Subject: b43: Fix for SPROM coding error in Linksys WMP54G (BCM4306/3) The Linksys WMP54G (BCM4306/3) card in a PCI format has an SPROM coding error and needs the fix found for several other cards. Signed-off-by: Larry Finger Cc: Stable [2.6.25.x, 2.6.26.x] Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/net/wireless/b43/main.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 3bf3a869361f..ee462b514104 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -4616,6 +4616,7 @@ static void b43_sprom_fixup(struct ssb_bus *bus) pdev = bus->host_pci; if (IS_PDEV(pdev, BROADCOM, 0x4318, ASUSTEK, 0x100F) || IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0015) || + IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0014) || IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0013)) bus->sprom.boardflags_lo &= ~B43_BFL_BTCOEXIST; } -- cgit v1.2.2 From fcd7cc1496681f7241ef8b80f32bb35d72a4e78b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?matthieu=20Barth=C3=A9lemy?= Date: Sun, 10 Aug 2008 23:34:59 -0500 Subject: rtl8187: Add USB ID for Netgear WG111V3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the USB ID for a Netgear WG111v3. Signed-off-by: matthieu Barthélemy Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtl8187_dev.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c index 57376fb993ed..ca5deb6244e6 100644 --- a/drivers/net/wireless/rtl8187_dev.c +++ b/drivers/net/wireless/rtl8187_dev.c @@ -40,6 +40,7 @@ static struct usb_device_id rtl8187_table[] __devinitdata = { /* Netgear */ {USB_DEVICE(0x0846, 0x6100), .driver_info = DEVICE_RTL8187}, {USB_DEVICE(0x0846, 0x6a00), .driver_info = DEVICE_RTL8187}, + {USB_DEVICE(0x0846, 0x4260), .driver_info = DEVICE_RTL8187B}, /* HP */ {USB_DEVICE(0x03f0, 0xca02), .driver_info = DEVICE_RTL8187}, /* Sitecom */ -- cgit v1.2.2 From 6f14792610905fe006c0c3c4d9e1478fb6be7cec Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 11 Aug 2008 23:49:41 +0200 Subject: iwlwifi: fix printk newlines Add newlines at printk outputs to not break dmesg. Signed-off-by: Jiri Slaby Cc: Zhu Yi Cc: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-4965.c | 2 +- drivers/net/wireless/iwlwifi/iwl-eeprom.c | 6 +++--- drivers/net/wireless/iwlwifi/iwl-sta.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-tx.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl3945-base.c | 6 +++--- 5 files changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 22bb26985c2e..4a0cc78d55e3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -967,7 +967,7 @@ static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel, s = iwl4965_get_sub_band(priv, channel); if (s >= EEPROM_TX_POWER_BANDS) { - IWL_ERROR("Tx Power can not find channel %d ", channel); + IWL_ERROR("Tx Power can not find channel %d\n", channel); return -1; } diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index bce53830b301..19985bf0dccf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -146,7 +146,7 @@ int iwlcore_eeprom_verify_signature(struct iwl_priv *priv) { u32 gp = iwl_read32(priv, CSR_EEPROM_GP); if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) { - IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x", gp); + IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp); return -ENOENT; } return 0; @@ -227,7 +227,7 @@ int iwl_eeprom_init(struct iwl_priv *priv) ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv); if (ret < 0) { - IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x", gp); + IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp); ret = -ENOENT; goto err; } @@ -254,7 +254,7 @@ int iwl_eeprom_init(struct iwl_priv *priv) } if (!(r & CSR_EEPROM_REG_READ_VALID_MSK)) { - IWL_ERROR("Time out reading EEPROM[%d]", addr); + IWL_ERROR("Time out reading EEPROM[%d]\n", addr); ret = -ETIMEDOUT; goto done; } diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 60a6e0106036..6283a3a707f5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -207,7 +207,7 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, case WLAN_HT_CAP_MIMO_PS_DISABLED: break; default: - IWL_WARNING("Invalid MIMO PS mode %d", mimo_ps_mode); + IWL_WARNING("Invalid MIMO PS mode %d\n", mimo_ps_mode); break; } @@ -969,7 +969,7 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) return priv->hw_params.bcast_sta_id; default: - IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode); + IWL_WARNING("Unknown mode of operation: %d\n", priv->iw_mode); return priv->hw_params.bcast_sta_id; } } diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 4108c7c8f00f..d82823b5c8ab 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -493,7 +493,7 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv) /* Alloc keep-warm buffer */ ret = iwl_kw_alloc(priv); if (ret) { - IWL_ERROR("Keep Warm allocation failed"); + IWL_ERROR("Keep Warm allocation failed\n"); goto error_kw; } spin_lock_irqsave(&priv->lock, flags); @@ -1463,7 +1463,7 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv, u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn); if (scd_flow >= priv->hw_params.max_txq_num) { - IWL_ERROR("BUG_ON scd_flow is bigger than number of queues"); + IWL_ERROR("BUG_ON scd_flow is bigger than number of queues\n"); return; } diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 444847ab1b5a..348048a4b6cf 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -1558,7 +1558,7 @@ int iwl3945_eeprom_init(struct iwl3945_priv *priv) BUILD_BUG_ON(sizeof(priv->eeprom) != IWL_EEPROM_IMAGE_SIZE); if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) { - IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x", gp); + IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp); return -ENOENT; } @@ -1583,7 +1583,7 @@ int iwl3945_eeprom_init(struct iwl3945_priv *priv) } if (!(r & CSR_EEPROM_REG_READ_VALID_MSK)) { - IWL_ERROR("Time out reading EEPROM[%d]", addr); + IWL_ERROR("Time out reading EEPROM[%d]\n", addr); return -ETIMEDOUT; } e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16)); @@ -2507,7 +2507,7 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h return priv->hw_setting.bcast_sta_id; default: - IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode); + IWL_WARNING("Unknown mode of operation: %d\n", priv->iw_mode); return priv->hw_setting.bcast_sta_id; } } -- cgit v1.2.2 From 69bbc7dc9f59fedb6067c7f9f9f9bc1da27407ad Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Wed, 13 Aug 2008 23:41:45 +0200 Subject: p54: move p54_vdcf_init to the right place. priv->tx_hdr_len is set by the driver _after_ it called p54_init_common. While this isn't much a problem for any PCI or ISL3887 cards/sticks, because they don't need any extra header and therefore tx_hdr_len is zero for them... Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54common.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index 49afd20d2c30..29be3dc8ee09 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c @@ -837,10 +837,21 @@ static int p54_start(struct ieee80211_hw *dev) struct p54_common *priv = dev->priv; int err; + if (!priv->cached_vdcf) { + priv->cached_vdcf = kzalloc(sizeof(struct p54_tx_control_vdcf)+ + priv->tx_hdr_len + sizeof(struct p54_control_hdr), + GFP_KERNEL); + + if (!priv->cached_vdcf) + return -ENOMEM; + } + err = priv->open(dev); if (!err) priv->mode = IEEE80211_IF_TYPE_MNTR; + p54_init_vdcf(dev); + return err; } @@ -1020,15 +1031,6 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len) dev->extra_tx_headroom = sizeof(struct p54_control_hdr) + 4 + sizeof(struct p54_tx_control_allocdata); - priv->cached_vdcf = kzalloc(sizeof(struct p54_tx_control_vdcf) + - priv->tx_hdr_len + sizeof(struct p54_control_hdr), GFP_KERNEL); - - if (!priv->cached_vdcf) { - ieee80211_free_hw(dev); - return NULL; - } - - p54_init_vdcf(dev); mutex_init(&priv->conf_mutex); return dev; -- cgit v1.2.2 From d47c3cebf5aae9d72b2cc18e5ac3b520fdbb0bca Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Wed, 13 Aug 2008 23:41:48 +0200 Subject: p54u: reset skb's data/tail pointer on requeue (Only important for USB V1 Adaptors) If an incoming frame wasn't accepted by p54_rx function the skb will be reused for new frames... But, we must not forget to set the skb's data pointers into the same state in which it was initialized by p54u_init_urbs. Otherwise we either end up with 16 bytes less on every requeue, or if a new frame is worthy enough to be accepted, the data is in the wrong place (urb->transfer_buffer wasn't updated!) and mac80211 has a hard time to recognize it... Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54usb.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 815c095ef797..cbaca23a9453 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -109,7 +109,17 @@ static void p54u_rx_cb(struct urb *urb) urb->context = skb; skb_queue_tail(&priv->rx_queue, skb); } else { + if (!priv->hw_type) + skb_push(skb, sizeof(struct net2280_tx_hdr)); + + skb_reset_tail_pointer(skb); skb_trim(skb, 0); + if (urb->transfer_buffer != skb_tail_pointer(skb)) { + /* this should not happen */ + WARN_ON(1); + urb->transfer_buffer = skb_tail_pointer(skb); + } + skb_queue_tail(&priv->rx_queue, skb); } -- cgit v1.2.2 From 430cd47fa98178b5199105fab4fb74e04bd0635c Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Thu, 14 Aug 2008 18:57:11 -0500 Subject: b43: Fix for another Bluetooth Coexistence SPROM Programming error for BCM4306 In trying to help users on the Ubuntu Bugzilla, I discovered another BCM4306 with the Bluetooth Coexistence programming error in the SPROM. This patch is contingent on the one that added the Linksys device with subdevice code of 0x0014. Signed-off-by: Larry Finger Cc: Stable Signed-off-by: John W. Linville --- drivers/net/wireless/b43/main.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index ee462b514104..8e09982fdeda 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -4615,6 +4615,7 @@ static void b43_sprom_fixup(struct ssb_bus *bus) if (bus->bustype == SSB_BUSTYPE_PCI) { pdev = bus->host_pci; if (IS_PDEV(pdev, BROADCOM, 0x4318, ASUSTEK, 0x100F) || + IS_PDEV(pdev, BROADCOM, 0x4320, DELL, 0x0003) || IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0015) || IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0014) || IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0013)) -- cgit v1.2.2 From f126cba427170eac9e37311b2ab7afc0e2261906 Mon Sep 17 00:00:00 2001 From: Jochen Friedrich Date: Fri, 15 Aug 2008 14:47:46 +0200 Subject: rt2x00: Fix txdone_entry_desc_flags txdone_entry_desc_flags is used with __set_bit and test_bit which bit-shift the values, so don't bit-shift the flags in the enum. Also make sure flags are initialized before being used. Signed-off-by: Jochen Friedrich Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00queue.h | 8 ++++---- drivers/net/wireless/rt2x00/rt2x00usb.c | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index a4a8c57004db..ff78e52ce43c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -173,10 +173,10 @@ struct rxdone_entry_desc { * frame transmission failed due to excessive retries. */ enum txdone_entry_desc_flags { - TXDONE_UNKNOWN = 1 << 0, - TXDONE_SUCCESS = 1 << 1, - TXDONE_FAILURE = 1 << 2, - TXDONE_EXCESSIVE_RETRY = 1 << 3, + TXDONE_UNKNOWN, + TXDONE_SUCCESS, + TXDONE_FAILURE, + TXDONE_EXCESSIVE_RETRY, }; /** diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 8d76bb2e0312..2050227ea530 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -181,6 +181,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) * (Only indirectly by looking at the failed TX counters * in the register). */ + txdesc.flags = 0; if (!urb->status) __set_bit(TXDONE_UNKNOWN, &txdesc.flags); else -- cgit v1.2.2 From 3eb75aac8907e7ea36f0d078b2cc7393986001cf Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Sun, 17 Aug 2008 07:50:47 +0800 Subject: removed unused #include The drivers below do not use LINUX_VERSION_CODE nor KERNEL_VERSION. drivers/net/wireless/ath5k/base.c drivers/net/wireless/b43/main.c drivers/net/wireless/ipw2100.c drivers/net/wireless/ipw2200.c drivers/net/wireless/iwlwifi/iwl-3945.c drivers/net/wireless/iwlwifi/iwl-4965.c drivers/net/wireless/iwlwifi/iwl-5000.c drivers/net/wireless/iwlwifi/iwl-agn.c drivers/net/wireless/iwlwifi/iwl-core.c drivers/net/wireless/iwlwifi/iwl-eeprom.c drivers/net/wireless/iwlwifi/iwl-hcmd.c drivers/net/wireless/iwlwifi/iwl-power.c drivers/net/wireless/iwlwifi/iwl3945-base.c This patch removes the said #include . Signed-off-by: Huang Weiyi Signed-off-by: John W. Linville --- drivers/net/wireless/ath5k/base.c | 1 - drivers/net/wireless/b43/main.c | 1 - drivers/net/wireless/ipw2100.c | 1 - drivers/net/wireless/ipw2200.c | 1 - drivers/net/wireless/iwlwifi/iwl-3945.c | 1 - drivers/net/wireless/iwlwifi/iwl-4965.c | 1 - drivers/net/wireless/iwlwifi/iwl-5000.c | 1 - drivers/net/wireless/iwlwifi/iwl-agn.c | 1 - drivers/net/wireless/iwlwifi/iwl-core.c | 1 - drivers/net/wireless/iwlwifi/iwl-eeprom.c | 1 - drivers/net/wireless/iwlwifi/iwl-hcmd.c | 1 - drivers/net/wireless/iwlwifi/iwl-power.c | 1 - drivers/net/wireless/iwlwifi/iwl3945-base.c | 1 - 13 files changed, 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index f19f33c4e336..b20a45aa8680 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c @@ -40,7 +40,6 @@ * */ -#include #include #include #include diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 8e09982fdeda..7205a936ec74 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c index c6f886ec08a3..19a401c4a0dc 100644 --- a/drivers/net/wireless/ipw2100.c +++ b/drivers/net/wireless/ipw2100.c @@ -157,7 +157,6 @@ that only one external action is invoked at a time. #include #include #include -#include #include #include #include diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index 36e8d2f6e7b4..dcce3542d5a7 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c @@ -31,7 +31,6 @@ ******************************************************************************/ #include "ipw2200.h" -#include #ifndef KBUILD_EXTMOD diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index b3931f6135a4..3f51f3635344 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -26,7 +26,6 @@ #include #include -#include #include #include #include diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 4a0cc78d55e3..e2581229d8b2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -26,7 +26,6 @@ #include #include -#include #include #include #include diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index f3d139b663e6..cbc01a00eaf4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -25,7 +25,6 @@ #include #include -#include #include #include #include diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index ed09e48b1b61..061ffba9c884 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -29,7 +29,6 @@ #include #include -#include #include #include #include diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 9bd61809129f..c72f72579bea 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -28,7 +28,6 @@ #include #include -#include #include struct iwl_priv; /* FIXME: remove */ diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 19985bf0dccf..37155755efc5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -63,7 +63,6 @@ #include #include -#include #include #include diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 6512834bb916..2eb03eea1908 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -28,7 +28,6 @@ #include #include -#include #include #include "iwl-dev.h" /* FIXME: remove */ diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 028e3053c0ca..a099c9e30e55 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -29,7 +29,6 @@ #include #include -#include #include #include diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 348048a4b6cf..b775d5bab668 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -29,7 +29,6 @@ #include #include -#include #include #include #include -- cgit v1.2.2 From 9f593653742d1dd816c4e94c6e5154a57ccba6d1 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 18 Aug 2008 21:32:32 -0700 Subject: nf_nat: use secure_ipv4_port_ephemeral() for NAT port randomization Use incoming network tuple as seed for NAT port randomization. This avoids concerns of leaking net_random() bits, and also gives better port distribution. Don't have NAT server, compile tested only. Signed-off-by: Stephen Hemminger [ added missing EXPORT_SYMBOL_GPL ] Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- drivers/char/random.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/char/random.c b/drivers/char/random.c index e0d0e371909c..1838aa3d24fe 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1571,6 +1571,7 @@ u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport) return half_md4_transform(hash, keyptr->secret); } +EXPORT_SYMBOL_GPL(secure_ipv4_port_ephemeral); #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, -- cgit v1.2.2