diff options
77 files changed, 603 insertions, 311 deletions
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index cb7f3148035..f049a1ca186 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -20,7 +20,7 @@ ip_no_pmtu_disc - BOOLEAN  	default FALSE  min_pmtu - INTEGER -	default 562 - minimum discovered Path MTU +	default 552 - minimum discovered Path MTU  route/max_size - INTEGER  	Maximum number of routes allowed in the kernel.  Increase diff --git a/MAINTAINERS b/MAINTAINERS index 1e7cc42a69b..29f9948b2cc 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2586,7 +2586,7 @@ S:	Maintained  F:	drivers/net/ethernet/i825xx/eexpress.*  ETHERNET BRIDGE -M:	Stephen Hemminger <shemminger@linux-foundation.org> +M:	Stephen Hemminger <shemminger@vyatta.com>  L:	bridge@lists.linux-foundation.org  L:	netdev@vger.kernel.org  W:	http://www.linuxfoundation.org/en/Net:Bridge @@ -4473,7 +4473,7 @@ S:	Supported  F:	drivers/infiniband/hw/nes/  NETEM NETWORK EMULATOR -M:	Stephen Hemminger <shemminger@linux-foundation.org> +M:	Stephen Hemminger <shemminger@vyatta.com>  L:	netem@lists.linux-foundation.org  S:	Maintained  F:	net/sched/sch_netem.c @@ -5988,7 +5988,7 @@ S:	Maintained  F:	drivers/usb/misc/sisusbvga/  SKGE, SKY2 10/100/1000 GIGABIT ETHERNET DRIVERS -M:	Stephen Hemminger <shemminger@linux-foundation.org> +M:	Stephen Hemminger <shemminger@vyatta.com>  L:	netdev@vger.kernel.org  S:	Maintained  F:	drivers/net/ethernet/marvell/sk* diff --git a/arch/cris/arch-v10/drivers/Kconfig b/arch/cris/arch-v10/drivers/Kconfig index 32d90867a98..5f2cdb3e428 100644 --- a/arch/cris/arch-v10/drivers/Kconfig +++ b/arch/cris/arch-v10/drivers/Kconfig @@ -3,7 +3,7 @@ if ETRAX_ARCH_V10  config ETRAX_ETHERNET  	bool "Ethernet support"  	depends on ETRAX_ARCH_V10 -	select NET_ETHERNET +	select ETHERNET  	select NET_CORE  	select MII  	help diff --git a/arch/cris/arch-v32/drivers/Kconfig b/arch/cris/arch-v32/drivers/Kconfig index e47e9c3401b..de43aadcdbc 100644 --- a/arch/cris/arch-v32/drivers/Kconfig +++ b/arch/cris/arch-v32/drivers/Kconfig @@ -3,7 +3,7 @@ if ETRAX_ARCH_V32  config ETRAX_ETHERNET  	bool "Ethernet support"  	depends on ETRAX_ARCH_V32 -	select NET_ETHERNET +	select ETHERNET  	select NET_CORE  	select MII  	help diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index f9b726091ad..fe4ebc375b3 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -100,6 +100,9 @@ static struct usb_device_id btusb_table[] = {  	/* Canyon CN-BTU1 with HID interfaces */  	{ USB_DEVICE(0x0c10, 0x0000) }, +	/* Broadcom BCM20702A0 */ +	{ USB_DEVICE(0x413c, 0x8197) }, +  	{ }	/* Terminating entry */  }; diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 583f66cd5bb..654a5e94e0e 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -245,6 +245,8 @@ source "drivers/net/ethernet/Kconfig"  source "drivers/net/fddi/Kconfig" +source "drivers/net/hippi/Kconfig" +  config NET_SB1000  	tristate "General Instruments Surfboard 1000"  	depends on PNP diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 5a20804fdec..4ef7e2fd9fe 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -319,6 +319,13 @@ static ssize_t bonding_store_mode(struct device *d,  		goto out;  	} +	if (bond->slave_cnt > 0) { +		pr_err("unable to update mode of %s because it has slaves.\n", +			bond->dev->name); +		ret = -EPERM; +		goto out; +	} +  	new_value = bond_parse_parm(buf, bond_mode_tbl);  	if (new_value < 0)  {  		pr_err("%s: Ignoring invalid mode value %.*s.\n", diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 6486ab8c8fc..2f6361e949f 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -10548,33 +10548,38 @@ do {									\  int bnx2x_init_firmware(struct bnx2x *bp)  { -	const char *fw_file_name;  	struct bnx2x_fw_file_hdr *fw_hdr;  	int rc; -	if (CHIP_IS_E1(bp)) -		fw_file_name = FW_FILE_NAME_E1; -	else if (CHIP_IS_E1H(bp)) -		fw_file_name = FW_FILE_NAME_E1H; -	else if (!CHIP_IS_E1x(bp)) -		fw_file_name = FW_FILE_NAME_E2; -	else { -		BNX2X_ERR("Unsupported chip revision\n"); -		return -EINVAL; -	} -	BNX2X_DEV_INFO("Loading %s\n", fw_file_name); +	if (!bp->firmware) { +		const char *fw_file_name; -	rc = request_firmware(&bp->firmware, fw_file_name, &bp->pdev->dev); -	if (rc) { -		BNX2X_ERR("Can't load firmware file %s\n", fw_file_name); -		goto request_firmware_exit; -	} +		if (CHIP_IS_E1(bp)) +			fw_file_name = FW_FILE_NAME_E1; +		else if (CHIP_IS_E1H(bp)) +			fw_file_name = FW_FILE_NAME_E1H; +		else if (!CHIP_IS_E1x(bp)) +			fw_file_name = FW_FILE_NAME_E2; +		else { +			BNX2X_ERR("Unsupported chip revision\n"); +			return -EINVAL; +		} +		BNX2X_DEV_INFO("Loading %s\n", fw_file_name); -	rc = bnx2x_check_firmware(bp); -	if (rc) { -		BNX2X_ERR("Corrupt firmware file %s\n", fw_file_name); -		goto request_firmware_exit; +		rc = request_firmware(&bp->firmware, fw_file_name, +				      &bp->pdev->dev); +		if (rc) { +			BNX2X_ERR("Can't load firmware file %s\n", +				  fw_file_name); +			goto request_firmware_exit; +		} + +		rc = bnx2x_check_firmware(bp); +		if (rc) { +			BNX2X_ERR("Corrupt firmware file %s\n", fw_file_name); +			goto request_firmware_exit; +		}  	}  	fw_hdr = (struct bnx2x_fw_file_hdr *)bp->firmware->data; @@ -10630,6 +10635,7 @@ static void bnx2x_release_firmware(struct bnx2x *bp)  	kfree(bp->init_ops);  	kfree(bp->init_data);  	release_firmware(bp->firmware); +	bp->firmware = NULL;  } @@ -10925,6 +10931,8 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev)  	if (bp->doorbells)  		iounmap(bp->doorbells); +	bnx2x_release_firmware(bp); +  	bnx2x_free_mem_bp(bp);  	free_netdev(dev); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c index 0440425c83d..14517691f8d 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c @@ -5380,7 +5380,7 @@ static int bnx2x_func_hw_init(struct bnx2x *bp,  	rc = drv->init_fw(bp);  	if (rc) {  		BNX2X_ERR("Error loading firmware\n"); -		goto fw_init_err; +		goto init_err;  	}  	/* Handle the beginning of COMMON_XXX pases separatelly... */ @@ -5388,25 +5388,25 @@ static int bnx2x_func_hw_init(struct bnx2x *bp,  	case FW_MSG_CODE_DRV_LOAD_COMMON_CHIP:  		rc = bnx2x_func_init_cmn_chip(bp, drv);  		if (rc) -			goto init_hw_err; +			goto init_err;  		break;  	case FW_MSG_CODE_DRV_LOAD_COMMON:  		rc = bnx2x_func_init_cmn(bp, drv);  		if (rc) -			goto init_hw_err; +			goto init_err;  		break;  	case FW_MSG_CODE_DRV_LOAD_PORT:  		rc = bnx2x_func_init_port(bp, drv);  		if (rc) -			goto init_hw_err; +			goto init_err;  		break;  	case FW_MSG_CODE_DRV_LOAD_FUNCTION:  		rc = bnx2x_func_init_func(bp, drv);  		if (rc) -			goto init_hw_err; +			goto init_err;  		break;  	default: @@ -5414,10 +5414,7 @@ static int bnx2x_func_hw_init(struct bnx2x *bp,  		rc = -EINVAL;  	} -init_hw_err: -	drv->release_fw(bp); - -fw_init_err: +init_err:  	drv->gunzip_end(bp);  	/* In case of success, complete the comand immediatelly: no ramrods diff --git a/drivers/net/ethernet/cadence/Kconfig b/drivers/net/ethernet/cadence/Kconfig index 98849a1fc74..b48378a41e4 100644 --- a/drivers/net/ethernet/cadence/Kconfig +++ b/drivers/net/ethernet/cadence/Kconfig @@ -7,6 +7,7 @@ config HAVE_NET_MACB  config NET_ATMEL  	bool "Atmel devices" +	default y  	depends on HAVE_NET_MACB || (ARM && ARCH_AT91RM9200)  	---help---  	  If you have a network (Ethernet) card belonging to this class, say Y. diff --git a/drivers/net/ethernet/lantiq_etop.c b/drivers/net/ethernet/lantiq_etop.c index 6bb2b9506ca..0b3567ab812 100644 --- a/drivers/net/ethernet/lantiq_etop.c +++ b/drivers/net/ethernet/lantiq_etop.c @@ -34,6 +34,8 @@  #include <linux/init.h>  #include <linux/delay.h>  #include <linux/io.h> +#include <linux/dma-mapping.h> +#include <linux/module.h>  #include <asm/checksum.h> diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c index fdc6c394c68..7803efa46eb 100644 --- a/drivers/net/ethernet/marvell/sky2.c +++ b/drivers/net/ethernet/marvell/sky2.c @@ -50,7 +50,7 @@  #include "sky2.h"  #define DRV_NAME		"sky2" -#define DRV_VERSION		"1.29" +#define DRV_VERSION		"1.30"  /*   * The Yukon II chipset takes 64 bit command blocks (called list elements) @@ -68,7 +68,7 @@  #define MAX_SKB_TX_LE	(2 + (sizeof(dma_addr_t)/sizeof(u32))*(MAX_SKB_FRAGS+1))  #define TX_MIN_PENDING		(MAX_SKB_TX_LE+1)  #define TX_MAX_PENDING		1024 -#define TX_DEF_PENDING		127 +#define TX_DEF_PENDING		63  #define TX_WATCHDOG		(5 * HZ)  #define NAPI_WEIGHT		64 @@ -869,6 +869,7 @@ static void sky2_wol_init(struct sky2_port *sky2)  	/* block receiver */  	sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); +	sky2_read32(hw, B0_CTST);  }  static void sky2_set_tx_stfwd(struct sky2_hw *hw, unsigned port) @@ -1274,6 +1275,14 @@ static void rx_set_checksum(struct sky2_port *sky2)  		     ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);  } +/* + * Fixed initial key as seed to RSS. + */ +static const uint32_t rss_init_key[10] = { +	0x7c3351da, 0x51c5cf4e,	0x44adbdd1, 0xe8d38d18,	0x48897c43, +	0xb1d60e7e, 0x6a3dd760, 0x01a2e453, 0x16f46f13, 0x1a0e7b30 +}; +  /* Enable/disable receive hash calculation (RSS) */  static void rx_set_rss(struct net_device *dev, u32 features)  { @@ -1289,12 +1298,9 @@ static void rx_set_rss(struct net_device *dev, u32 features)  	/* Program RSS initial values */  	if (features & NETIF_F_RXHASH) { -		u32 key[nkeys]; - -		get_random_bytes(key, nkeys * sizeof(u32));  		for (i = 0; i < nkeys; i++)  			sky2_write32(hw, SK_REG(sky2->port, RSS_KEY + i * 4), -				     key[i]); +				     rss_init_key[i]);  		/* Need to turn on (undocumented) flag to make hashing work  */  		sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), @@ -1717,6 +1723,8 @@ static int sky2_setup_irq(struct sky2_hw *hw, const char *name)  	if (err)  		dev_err(&pdev->dev, "cannot assign irq %d\n", pdev->irq);  	else { +		hw->flags |= SKY2_HW_IRQ_SETUP; +  		napi_enable(&hw->napi);  		sky2_write32(hw, B0_IMSK, Y2_IS_BASE);  		sky2_read32(hw, B0_IMSK); @@ -1727,7 +1735,7 @@ static int sky2_setup_irq(struct sky2_hw *hw, const char *name)  /* Bring up network interface. */ -static int sky2_up(struct net_device *dev) +static int sky2_open(struct net_device *dev)  {  	struct sky2_port *sky2 = netdev_priv(dev);  	struct sky2_hw *hw = sky2->hw; @@ -1747,6 +1755,11 @@ static int sky2_up(struct net_device *dev)  	sky2_hw_up(sky2); +	if (hw->chip_id == CHIP_ID_YUKON_OPT || +	    hw->chip_id == CHIP_ID_YUKON_PRM || +	    hw->chip_id == CHIP_ID_YUKON_OP_2) +		imask |= Y2_IS_PHY_QLNK;	/* enable PHY Quick Link */ +  	/* Enable interrupts from phy/mac for port */  	imask = sky2_read32(hw, B0_IMSK);  	imask |= portirq_msk[port]; @@ -2040,6 +2053,8 @@ static void sky2_tx_reset(struct sky2_hw *hw, unsigned port)  	sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET);  	sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); + +	sky2_read32(hw, B0_CTST);  }  static void sky2_hw_down(struct sky2_port *sky2) @@ -2090,7 +2105,7 @@ static void sky2_hw_down(struct sky2_port *sky2)  }  /* Network shutdown */ -static int sky2_down(struct net_device *dev) +static int sky2_close(struct net_device *dev)  {  	struct sky2_port *sky2 = netdev_priv(dev);  	struct sky2_hw *hw = sky2->hw; @@ -2101,15 +2116,22 @@ static int sky2_down(struct net_device *dev)  	netif_info(sky2, ifdown, dev, "disabling interface\n"); -	/* Disable port IRQ */ -	sky2_write32(hw, B0_IMSK, -		     sky2_read32(hw, B0_IMSK) & ~portirq_msk[sky2->port]); -	sky2_read32(hw, B0_IMSK); -  	if (hw->ports == 1) { +		sky2_write32(hw, B0_IMSK, 0); +		sky2_read32(hw, B0_IMSK); +  		napi_disable(&hw->napi);  		free_irq(hw->pdev->irq, hw); +		hw->flags &= ~SKY2_HW_IRQ_SETUP;  	} else { +		u32 imask; + +		/* Disable port IRQ */ +		imask  = sky2_read32(hw, B0_IMSK); +		imask &= ~portirq_msk[sky2->port]; +		sky2_write32(hw, B0_IMSK, imask); +		sky2_read32(hw, B0_IMSK); +  		synchronize_irq(hw->pdev->irq);  		napi_synchronize(&hw->napi);  	} @@ -2587,7 +2609,7 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)  	if (netif_running(dev)) {  		sky2_tx_complete(sky2, last); -		/* Wake unless it's detached, and called e.g. from sky2_down() */ +		/* Wake unless it's detached, and called e.g. from sky2_close() */  		if (tx_avail(sky2) > MAX_SKB_TX_LE + 4)  			netif_wake_queue(dev);  	} @@ -3258,7 +3280,6 @@ static void sky2_reset(struct sky2_hw *hw)  	    hw->chip_id == CHIP_ID_YUKON_PRM ||  	    hw->chip_id == CHIP_ID_YUKON_OP_2) {  		u16 reg; -		u32 msk;  		if (hw->chip_id == CHIP_ID_YUKON_OPT && hw->chip_rev == 0) {  			/* disable PCI-E PHY power down (set PHY reg 0x80, bit 7 */ @@ -3281,11 +3302,6 @@ static void sky2_reset(struct sky2_hw *hw)  		sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);  		sky2_pci_write16(hw, PSM_CONFIG_REG4, reg); -		/* enable PHY Quick Link */ -		msk = sky2_read32(hw, B0_IMSK); -		msk |= Y2_IS_PHY_QLNK; -		sky2_write32(hw, B0_IMSK, msk); -  		/* check if PSMv2 was running before */  		reg = sky2_pci_read16(hw, PSM_CONFIG_REG3);  		if (reg & PCI_EXP_LNKCTL_ASPMC) @@ -3383,7 +3399,7 @@ static void sky2_detach(struct net_device *dev)  		netif_tx_lock(dev);  		netif_device_detach(dev);	/* stop txq */  		netif_tx_unlock(dev); -		sky2_down(dev); +		sky2_close(dev);  	}  } @@ -3393,7 +3409,7 @@ static int sky2_reattach(struct net_device *dev)  	int err = 0;  	if (netif_running(dev)) { -		err = sky2_up(dev); +		err = sky2_open(dev);  		if (err) {  			netdev_info(dev, "could not restart %d\n", err);  			dev_close(dev); @@ -3410,10 +3426,13 @@ static void sky2_all_down(struct sky2_hw *hw)  {  	int i; -	sky2_read32(hw, B0_IMSK); -	sky2_write32(hw, B0_IMSK, 0); -	synchronize_irq(hw->pdev->irq); -	napi_disable(&hw->napi); +	if (hw->flags & SKY2_HW_IRQ_SETUP) { +		sky2_read32(hw, B0_IMSK); +		sky2_write32(hw, B0_IMSK, 0); + +		synchronize_irq(hw->pdev->irq); +		napi_disable(&hw->napi); +	}  	for (i = 0; i < hw->ports; i++) {  		struct net_device *dev = hw->dev[i]; @@ -3446,11 +3465,12 @@ static void sky2_all_up(struct sky2_hw *hw)  		netif_wake_queue(dev);  	} -	sky2_write32(hw, B0_IMSK, imask); -	sky2_read32(hw, B0_IMSK); - -	sky2_read32(hw, B0_Y2_SP_LISR); -	napi_enable(&hw->napi); +	if (hw->flags & SKY2_HW_IRQ_SETUP) { +		sky2_write32(hw, B0_IMSK, imask); +		sky2_read32(hw, B0_IMSK); +		sky2_read32(hw, B0_Y2_SP_LISR); +		napi_enable(&hw->napi); +	}  }  static void sky2_restart(struct work_struct *work) @@ -4071,6 +4091,16 @@ static int sky2_set_coalesce(struct net_device *dev,  	return 0;  } +/* + * Hardware is limited to min of 128 and max of 2048 for ring size + * and  rounded up to next power of two + * to avoid division in modulus calclation + */ +static unsigned long roundup_ring_size(unsigned long pending) +{ +	return max(128ul, roundup_pow_of_two(pending+1)); +} +  static void sky2_get_ringparam(struct net_device *dev,  			       struct ethtool_ringparam *ering)  { @@ -4098,7 +4128,7 @@ static int sky2_set_ringparam(struct net_device *dev,  	sky2->rx_pending = ering->rx_pending;  	sky2->tx_pending = ering->tx_pending; -	sky2->tx_ring_size = roundup_pow_of_two(sky2->tx_pending+1); +	sky2->tx_ring_size = roundup_ring_size(sky2->tx_pending);  	return sky2_reattach(dev);  } @@ -4556,7 +4586,7 @@ static int sky2_device_event(struct notifier_block *unused,  	struct net_device *dev = ptr;  	struct sky2_port *sky2 = netdev_priv(dev); -	if (dev->netdev_ops->ndo_open != sky2_up || !sky2_debug) +	if (dev->netdev_ops->ndo_open != sky2_open || !sky2_debug)  		return NOTIFY_DONE;  	switch (event) { @@ -4621,8 +4651,8 @@ static __exit void sky2_debug_cleanup(void)     not allowing netpoll on second port */  static const struct net_device_ops sky2_netdev_ops[2] = {    { -	.ndo_open		= sky2_up, -	.ndo_stop		= sky2_down, +	.ndo_open		= sky2_open, +	.ndo_stop		= sky2_close,  	.ndo_start_xmit		= sky2_xmit_frame,  	.ndo_do_ioctl		= sky2_ioctl,  	.ndo_validate_addr	= eth_validate_addr, @@ -4638,8 +4668,8 @@ static const struct net_device_ops sky2_netdev_ops[2] = {  #endif    },    { -	.ndo_open		= sky2_up, -	.ndo_stop		= sky2_down, +	.ndo_open		= sky2_open, +	.ndo_stop		= sky2_close,  	.ndo_start_xmit		= sky2_xmit_frame,  	.ndo_do_ioctl		= sky2_ioctl,  	.ndo_validate_addr	= eth_validate_addr, @@ -4692,7 +4722,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,  	spin_lock_init(&sky2->phy_lock);  	sky2->tx_pending = TX_DEF_PENDING; -	sky2->tx_ring_size = roundup_pow_of_two(TX_DEF_PENDING+1); +	sky2->tx_ring_size = roundup_ring_size(TX_DEF_PENDING);  	sky2->rx_pending = RX_DEF_PENDING;  	hw->dev[port] = dev; diff --git a/drivers/net/ethernet/marvell/sky2.h b/drivers/net/ethernet/marvell/sky2.h index 0af31b8b5f1..ff6f58bf822 100644 --- a/drivers/net/ethernet/marvell/sky2.h +++ b/drivers/net/ethernet/marvell/sky2.h @@ -2287,6 +2287,7 @@ struct sky2_hw {  #define SKY2_HW_RSS_BROKEN	0x00000100  #define SKY2_HW_VLAN_BROKEN     0x00000200  #define SKY2_HW_RSS_CHKSUM	0x00000400	/* RSS requires chksum */ +#define SKY2_HW_IRQ_SETUP	0x00000800  	u8	     	     chip_id;  	u8		     chip_rev; diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index b89c36dbf5b..c2df6c35860 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -581,6 +581,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud  		 * Packet is OK - process it.  		 */  		length = be32_to_cpu(cqe->byte_cnt); +		length -= ring->fcs_del;  		ring->bytes += length;  		ring->packets++; @@ -813,8 +814,11 @@ static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv, int qpn,  	context->db_rec_addr = cpu_to_be64(ring->wqres.db.dma);  	/* Cancel FCS removal if FW allows */ -	if (mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_FCS_KEEP) +	if (mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_FCS_KEEP) {  		context->param3 |= cpu_to_be32(1 << 29); +		ring->fcs_del = ETH_FCS_LEN; +	} else +		ring->fcs_del = 0;  	err = mlx4_qp_to_ready(mdev->dev, &ring->wqres.mtt, context, qp, state);  	if (err) { diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 8fda331c65d..207b5add3ca 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -272,6 +272,7 @@ struct mlx4_en_rx_ring {  	u32 prod;  	u32 cons;  	u32 buf_size; +	u8  fcs_del;  	void *buf;  	void *rx_info;  	unsigned long bytes; diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c index 1dca57013cb..1c61d36e657 100644 --- a/drivers/net/ethernet/nvidia/forcedeth.c +++ b/drivers/net/ethernet/nvidia/forcedeth.c @@ -609,7 +609,7 @@ struct nv_ethtool_str {  };  static const struct nv_ethtool_str nv_estats_str[] = { -	{ "tx_bytes" }, +	{ "tx_bytes" }, /* includes Ethernet FCS CRC */  	{ "tx_zero_rexmt" },  	{ "tx_one_rexmt" },  	{ "tx_many_rexmt" }, @@ -637,7 +637,7 @@ static const struct nv_ethtool_str nv_estats_str[] = {  	/* version 2 stats */  	{ "tx_deferral" },  	{ "tx_packets" }, -	{ "rx_bytes" }, +	{ "rx_bytes" }, /* includes Ethernet FCS CRC */  	{ "tx_pause" },  	{ "rx_pause" },  	{ "rx_drop_frame" }, @@ -649,7 +649,7 @@ static const struct nv_ethtool_str nv_estats_str[] = {  };  struct nv_ethtool_stats { -	u64 tx_bytes; +	u64 tx_bytes; /* should be ifconfig->tx_bytes + 4*tx_packets */  	u64 tx_zero_rexmt;  	u64 tx_one_rexmt;  	u64 tx_many_rexmt; @@ -670,14 +670,14 @@ struct nv_ethtool_stats {  	u64 rx_unicast;  	u64 rx_multicast;  	u64 rx_broadcast; -	u64 rx_packets; +	u64 rx_packets; /* should be ifconfig->rx_packets */  	u64 rx_errors_total;  	u64 tx_errors_total;  	/* version 2 stats */  	u64 tx_deferral; -	u64 tx_packets; -	u64 rx_bytes; +	u64 tx_packets; /* should be ifconfig->tx_packets */ +	u64 rx_bytes;   /* should be ifconfig->rx_bytes + 4*rx_packets */  	u64 tx_pause;  	u64 rx_pause;  	u64 rx_drop_frame; @@ -1706,10 +1706,17 @@ static struct net_device_stats *nv_get_stats(struct net_device *dev)  	if (np->driver_data & (DEV_HAS_STATISTICS_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_STATISTICS_V3)) {  		nv_get_hw_stats(dev); +		/* +		 * Note: because HW stats are not always available and +		 * for consistency reasons, the following ifconfig +		 * stats are managed by software: rx_bytes, tx_bytes, +		 * rx_packets and tx_packets. The related hardware +		 * stats reported by ethtool should be equivalent to +		 * these ifconfig stats, with 4 additional bytes per +		 * packet (Ethernet FCS CRC). +		 */ +  		/* copy to net_device stats */ -		dev->stats.tx_packets = np->estats.tx_packets; -		dev->stats.rx_bytes = np->estats.rx_bytes; -		dev->stats.tx_bytes = np->estats.tx_bytes;  		dev->stats.tx_fifo_errors = np->estats.tx_fifo_errors;  		dev->stats.tx_carrier_errors = np->estats.tx_carrier_errors;  		dev->stats.rx_crc_errors = np->estats.rx_crc_errors; @@ -2380,6 +2387,9 @@ static int nv_tx_done(struct net_device *dev, int limit)  				if (flags & NV_TX_ERROR) {  					if ((flags & NV_TX_RETRYERROR) && !(flags & NV_TX_RETRYCOUNT_MASK))  						nv_legacybackoff_reseed(dev); +				} else { +					dev->stats.tx_packets++; +					dev->stats.tx_bytes += np->get_tx_ctx->skb->len;  				}  				dev_kfree_skb_any(np->get_tx_ctx->skb);  				np->get_tx_ctx->skb = NULL; @@ -2390,6 +2400,9 @@ static int nv_tx_done(struct net_device *dev, int limit)  				if (flags & NV_TX2_ERROR) {  					if ((flags & NV_TX2_RETRYERROR) && !(flags & NV_TX2_RETRYCOUNT_MASK))  						nv_legacybackoff_reseed(dev); +				} else { +					dev->stats.tx_packets++; +					dev->stats.tx_bytes += np->get_tx_ctx->skb->len;  				}  				dev_kfree_skb_any(np->get_tx_ctx->skb);  				np->get_tx_ctx->skb = NULL; @@ -2429,6 +2442,9 @@ static int nv_tx_done_optimized(struct net_device *dev, int limit)  					else  						nv_legacybackoff_reseed(dev);  				} +			} else { +				dev->stats.tx_packets++; +				dev->stats.tx_bytes += np->get_tx_ctx->skb->len;  			}  			dev_kfree_skb_any(np->get_tx_ctx->skb); @@ -2678,6 +2694,7 @@ static int nv_rx_process(struct net_device *dev, int limit)  		skb->protocol = eth_type_trans(skb, dev);  		napi_gro_receive(&np->napi, skb);  		dev->stats.rx_packets++; +		dev->stats.rx_bytes += len;  next_pkt:  		if (unlikely(np->get_rx.orig++ == np->last_rx.orig))  			np->get_rx.orig = np->first_rx.orig; @@ -2761,6 +2778,7 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit)  			}  			napi_gro_receive(&np->napi, skb);  			dev->stats.rx_packets++; +			dev->stats.rx_bytes += len;  		} else {  			dev_kfree_skb(skb);  		} diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c index 9c075ea2682..9cb5f912e48 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c @@ -18,8 +18,8 @@   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.   */ -#include <linux/module.h>	/* for __MODULE_STRING */  #include "pch_gbe.h" +#include <linux/module.h>	/* for __MODULE_STRING */  #define OPTION_UNSET   -1  #define OPTION_DISABLED 0 diff --git a/drivers/net/ethernet/rdc/r6040.c b/drivers/net/ethernet/rdc/r6040.c index 1fc01ca72b4..4bf68cfef39 100644 --- a/drivers/net/ethernet/rdc/r6040.c +++ b/drivers/net/ethernet/rdc/r6040.c @@ -940,7 +940,7 @@ static void r6040_multicast_list(struct net_device *dev)  	iowrite16(lp->mcr0, ioaddr + MCR0);  	/* Fill the MAC hash tables with their values */ -	if (lp->mcr0 && MCR0_HASH_EN) { +	if (lp->mcr0 & MCR0_HASH_EN) {  		iowrite16(hash_table[0], ioaddr + MAR0);  		iowrite16(hash_table[1], ioaddr + MAR1);  		iowrite16(hash_table[2], ioaddr + MAR2); diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 92b45f08858..6f06aa10f0d 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -1292,7 +1292,7 @@ static void __rtl8169_check_link_status(struct net_device *dev,  		netif_carrier_off(dev);  		netif_info(tp, ifdown, dev, "link down\n");  		if (pm) -			pm_schedule_suspend(&tp->pci_dev->dev, 100); +			pm_schedule_suspend(&tp->pci_dev->dev, 5000);  	}  	spin_unlock_irqrestore(&tp->lock, flags);  } diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index d2be42aafbe..8843071fe98 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c @@ -1937,6 +1937,7 @@ static int __devinit smsc911x_init(struct net_device *dev)  {  	struct smsc911x_data *pdata = netdev_priv(dev);  	unsigned int byte_test; +	unsigned int to = 100;  	SMSC_TRACE(pdata, probe, "Driver Parameters:");  	SMSC_TRACE(pdata, probe, "LAN base: 0x%08lX", @@ -1952,6 +1953,17 @@ static int __devinit smsc911x_init(struct net_device *dev)  		return -ENODEV;  	} +	/* +	 * poll the READY bit in PMT_CTRL. Any other access to the device is +	 * forbidden while this bit isn't set. Try for 100ms +	 */ +	while (!(smsc911x_reg_read(pdata, PMT_CTRL) & PMT_CTRL_READY_) && --to) +		udelay(1000); +	if (to == 0) { +		pr_err("Device not READY in 100ms aborting\n"); +		return -ENODEV; +	} +  	/* Check byte ordering */  	byte_test = smsc911x_reg_read(pdata, BYTE_TEST);  	SMSC_TRACE(pdata, probe, "BYTE_TEST: 0x%08X", byte_test); diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c index da66ac511c4..4d5402a1d26 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c @@ -39,10 +39,11 @@ static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx,  	/* DMA SW reset */  	value |= DMA_BUS_MODE_SFT_RESET;  	writel(value, ioaddr + DMA_BUS_MODE); -	limit = 15000; +	limit = 10;  	while (limit--) {  		if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET))  			break; +		mdelay(10);  	}  	if (limit < 0)  		return -EBUSY; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c index 627f656b0f3..bc17fd08b55 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c @@ -41,10 +41,11 @@ static int dwmac100_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx,  	/* DMA SW reset */  	value |= DMA_BUS_MODE_SFT_RESET;  	writel(value, ioaddr + DMA_BUS_MODE); -	limit = 15000; +	limit = 10;  	while (limit--) {  		if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET))  			break; +		mdelay(10);  	}  	if (limit < 0)  		return -EBUSY; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index 9bafa6cf9e8..a140a8fbf05 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -72,7 +72,6 @@ struct stmmac_priv {  	spinlock_t lock;  	spinlock_t tx_lock;  	int wolopts; -	int wolenabled;  	int wol_irq;  #ifdef CONFIG_STMMAC_TIMER  	struct stmmac_timer *tm; @@ -80,6 +79,7 @@ struct stmmac_priv {  	struct plat_stmmacenet_data *plat;  	struct stmmac_counters mmc;  	struct dma_features dma_cap; +	int hw_cap_support;  };  extern int stmmac_mdio_unregister(struct net_device *ndev); diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c index e8eff09bbbd..0395f9eba80 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c @@ -430,6 +430,12 @@ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)  	struct stmmac_priv *priv = netdev_priv(dev);  	u32 support = WAKE_MAGIC | WAKE_UCAST; +	/* By default almost all GMAC devices support the WoL via +	 * magic frame but we can disable it if the HW capability +	 * register shows no support for pmt_magic_frame. */ +	if ((priv->hw_cap_support) && (!priv->dma_cap.pmt_magic_frame)) +		wol->wolopts &= ~WAKE_MAGIC; +  	if (!device_can_wakeup(priv->device))  		return -EINVAL; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 20546bbbb8d..8ea770a89f2 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -321,12 +321,10 @@ static int stmmac_init_phy(struct net_device *dev)  	}  	/* Stop Advertising 1000BASE Capability if interface is not GMII */ -	if ((interface) && ((interface == PHY_INTERFACE_MODE_MII) || -	    (interface == PHY_INTERFACE_MODE_RMII))) { -		phydev->supported &= (PHY_BASIC_FEATURES | SUPPORTED_Pause | -				      SUPPORTED_Asym_Pause); -		phydev->advertising = phydev->supported; -	} +	if ((interface == PHY_INTERFACE_MODE_MII) || +	    (interface == PHY_INTERFACE_MODE_RMII)) +		phydev->advertising &= ~(SUPPORTED_1000baseT_Half | +					 SUPPORTED_1000baseT_Full);  	/*  	 * Broken HW is sometimes missing the pull-up resistor on the @@ -807,8 +805,29 @@ static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv)  	return 0;  } -/* New GMAC chips support a new register to indicate the - * presence of the optional feature/functions. +/** + * stmmac_selec_desc_mode + * @dev : device pointer + * Description: select the Enhanced/Alternate or Normal descriptors */ +static void stmmac_selec_desc_mode(struct stmmac_priv *priv) +{ +	if (priv->plat->enh_desc) { +		pr_info(" Enhanced/Alternate descriptors\n"); +		priv->hw->desc = &enh_desc_ops; +	} else { +		pr_info(" Normal descriptors\n"); +		priv->hw->desc = &ndesc_ops; +	} +} + +/** + * stmmac_get_hw_features + * @priv : private device pointer + * Description: + *  new GMAC chip generations have a new register to indicate the + *  presence of the optional feature/functions. + *  This can be also used to override the value passed through the + *  platform and necessary for old MAC10/100 and GMAC chips.   */  static int stmmac_get_hw_features(struct stmmac_priv *priv)  { @@ -829,7 +848,7 @@ static int stmmac_get_hw_features(struct stmmac_priv *priv)  			(hw_cap & DMA_HW_FEAT_RWKSEL) >> 9;  		priv->dma_cap.pmt_magic_frame =  			(hw_cap & DMA_HW_FEAT_MGKSEL) >> 10; -		/*MMC*/ +		/* MMC */  		priv->dma_cap.rmon = (hw_cap & DMA_HW_FEAT_MMCSEL) >> 11;  		/* IEEE 1588-2002*/  		priv->dma_cap.time_stamp = @@ -857,8 +876,7 @@ static int stmmac_get_hw_features(struct stmmac_priv *priv)  		priv->dma_cap.enh_desc =  			(hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24; -	} else -		pr_debug("\tNo HW DMA feature register supported"); +	}  	return hw_cap;  } @@ -913,6 +931,44 @@ static int stmmac_open(struct net_device *dev)  		goto open_error;  	} +	stmmac_get_synopsys_id(priv); + +	priv->hw_cap_support = stmmac_get_hw_features(priv); + +	if (priv->hw_cap_support) { +		pr_info(" Support DMA HW capability register"); + +		/* We can override some gmac/dma configuration fields: e.g. +		 * enh_desc, tx_coe (e.g. that are passed through the +		 * platform) with the values from the HW capability +		 * register (if supported). +		 */ +		priv->plat->enh_desc = priv->dma_cap.enh_desc; +		priv->plat->tx_coe = priv->dma_cap.tx_coe; +		priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up; + +		/* By default disable wol on magic frame if not supported */ +		if (!priv->dma_cap.pmt_magic_frame) +			priv->wolopts &= ~WAKE_MAGIC; + +	} else +		pr_info(" No HW DMA feature register supported"); + +	/* Select the enhnaced/normal descriptor structures */ +	stmmac_selec_desc_mode(priv); + +	/* PMT module is not integrated in all the MAC devices. */ +	if (priv->plat->pmt) { +		pr_info(" Remote wake-up capable\n"); +		device_set_wakeup_capable(priv->device, 1); +	} + +	priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr); +	if (priv->rx_coe) +		pr_info(" Checksum Offload Engine supported\n"); +	if (priv->plat->tx_coe) +		pr_info(" Checksum insertion supported\n"); +  	/* Create and initialize the TX/RX descriptors chains. */  	priv->dma_tx_size = STMMAC_ALIGN(dma_txsize);  	priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize); @@ -935,15 +991,6 @@ static int stmmac_open(struct net_device *dev)  	/* Initialize the MAC Core */  	priv->hw->mac->core_init(priv->ioaddr); -	stmmac_get_synopsys_id(priv); - -	stmmac_get_hw_features(priv); - -	priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr); -	if (priv->rx_coe) -		pr_info("stmmac: Rx Checksum Offload Engine supported\n"); -	if (priv->plat->tx_coe) -		pr_info("\tTX Checksum insertion supported\n");  	netdev_update_features(dev);  	/* Request the IRQ lines */ @@ -1489,9 +1536,7 @@ static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)  	if (!priv->phydev)  		return -EINVAL; -	spin_lock(&priv->lock);  	ret = phy_mii_ioctl(priv->phydev, rq, cmd); -	spin_unlock(&priv->lock);  	return ret;  } @@ -1558,7 +1603,7 @@ static int stmmac_sysfs_dma_cap_read(struct seq_file *seq, void *v)  	struct net_device *dev = seq->private;  	struct stmmac_priv *priv = netdev_priv(dev); -	if (!stmmac_get_hw_features(priv)) { +	if (!priv->hw_cap_support) {  		seq_printf(seq, "DMA HW features not supported\n");  		return 0;  	} @@ -1766,12 +1811,6 @@ static int stmmac_mac_device_setup(struct net_device *dev)  	if (!device)  		return -ENOMEM; -	if (priv->plat->enh_desc) { -		device->desc = &enh_desc_ops; -		pr_info("\tEnhanced descriptor structure\n"); -	} else -		device->desc = &ndesc_ops; -  	priv->hw = device;  	priv->hw->ring = &ring_mode_ops; @@ -1845,11 +1884,6 @@ static int stmmac_dvr_probe(struct platform_device *pdev)  	priv->ioaddr = addr; -	/* PMT module is not integrated in all the MAC devices. */ -	if (plat_dat->pmt) { -		pr_info("\tPMT module supported\n"); -		device_set_wakeup_capable(&pdev->dev, 1); -	}  	/*  	 * On some platforms e.g. SPEAr the wake up irq differs from the mac irq  	 * The external wake up irq can be passed through the platform code @@ -1862,7 +1896,6 @@ static int stmmac_dvr_probe(struct platform_device *pdev)  	if (priv->wol_irq == -ENXIO)  		priv->wol_irq = ndev->irq; -  	platform_set_drvdata(pdev, ndev);  	/* Set the I/O base addr */ @@ -1875,7 +1908,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev)  			goto out_free_ndev;  	} -	/* MAC HW revice detection */ +	/* MAC HW device detection */  	ret = stmmac_mac_device_setup(ndev);  	if (ret < 0)  		goto out_plat_exit; @@ -1978,12 +2011,13 @@ static int stmmac_suspend(struct device *dev)  	if (!ndev || !netif_running(ndev))  		return 0; +	if (priv->phydev) +		phy_stop(priv->phydev); +  	spin_lock(&priv->lock);  	netif_device_detach(ndev);  	netif_stop_queue(ndev); -	if (priv->phydev) -		phy_stop(priv->phydev);  #ifdef CONFIG_STMMAC_TIMER  	priv->tm->timer_stop(); @@ -2041,12 +2075,13 @@ static int stmmac_resume(struct device *dev)  #endif  	napi_enable(&priv->napi); -	if (priv->phydev) -		phy_start(priv->phydev); -  	netif_start_queue(ndev);  	spin_unlock(&priv->lock); + +	if (priv->phydev) +		phy_start(priv->phydev); +  	return 0;  } diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c index c517dac02ae..cf14ab9db57 100644 --- a/drivers/net/ethernet/sun/sunhme.c +++ b/drivers/net/ethernet/sun/sunhme.c @@ -2637,7 +2637,7 @@ static int __devinit happy_meal_sbus_probe_one(struct platform_device *op, int i  	sbus_dp = op->dev.parent->of_node;  	/* We can match PCI devices too, do not accept those here. */ -	if (strcmp(sbus_dp->name, "sbus")) +	if (strcmp(sbus_dp->name, "sbus") && strcmp(sbus_dp->name, "sbi"))  		return err;  	if (is_qfe) { diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c index caf3659e173..2681b53820e 100644 --- a/drivers/net/ethernet/xilinx/ll_temac_main.c +++ b/drivers/net/ethernet/xilinx/ll_temac_main.c @@ -114,6 +114,7 @@ void temac_indirect_out32(struct temac_local *lp, int reg, u32 value)  		return;  	temac_iow(lp, XTE_LSW0_OFFSET, value);  	temac_iow(lp, XTE_CTL0_OFFSET, CNTLREG_WRITE_ENABLE_MASK | reg); +	temac_indirect_busywait(lp);  }  /** @@ -203,6 +204,9 @@ static void temac_dma_bd_release(struct net_device *ndev)  	struct temac_local *lp = netdev_priv(ndev);  	int i; +	/* Reset Local Link (DMA) */ +	lp->dma_out(lp, DMA_CONTROL_REG, DMA_CONTROL_RST); +  	for (i = 0; i < RX_BD_NUM; i++) {  		if (!lp->rx_skb[i])  			break; @@ -860,6 +864,8 @@ static int temac_open(struct net_device *ndev)  		phy_start(lp->phy_dev);  	} +	temac_device_reset(ndev); +  	rc = request_irq(lp->tx_irq, ll_temac_tx_irq, 0, ndev->name, ndev);  	if (rc)  		goto err_tx_irq; @@ -867,7 +873,6 @@ static int temac_open(struct net_device *ndev)  	if (rc)  		goto err_rx_irq; -	temac_device_reset(ndev);  	return 0;   err_rx_irq: diff --git a/drivers/net/hippi/Kconfig b/drivers/net/hippi/Kconfig index 7393eb732ee..95eb34fdbba 100644 --- a/drivers/net/hippi/Kconfig +++ b/drivers/net/hippi/Kconfig @@ -36,4 +36,4 @@ config ROADRUNNER_LARGE_RINGS  	  kernel code or by user space programs. Say Y here only if you have  	  the memory. -endif /* HIPPI */ +endif # HIPPI diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index e81e22e3d1d..e6fed4d4cb7 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -36,7 +36,7 @@  #include <linux/usb/usbnet.h>  #include <linux/slab.h> -#define DRIVER_VERSION "26-Sep-2011" +#define DRIVER_VERSION "08-Nov-2011"  #define DRIVER_NAME "asix"  /* ASIX AX8817X based USB 2.0 Ethernet Devices */ @@ -163,7 +163,7 @@  #define MARVELL_CTRL_TXDELAY	0x0002  #define MARVELL_CTRL_RXDELAY	0x0080 -#define	PHY_MODE_RTL8211CL	0x0004 +#define	PHY_MODE_RTL8211CL	0x000C  /* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */  struct asix_data { @@ -652,9 +652,17 @@ static u32 asix_get_phyid(struct usbnet *dev)  {  	int phy_reg;  	u32 phy_id; +	int i; -	phy_reg = asix_mdio_read(dev->net, dev->mii.phy_id, MII_PHYSID1); -	if (phy_reg < 0) +	/* Poll for the rare case the FW or phy isn't ready yet.  */ +	for (i = 0; i < 100; i++) { +		phy_reg = asix_mdio_read(dev->net, dev->mii.phy_id, MII_PHYSID1); +		if (phy_reg != 0 && phy_reg != 0xFFFF) +			break; +		mdelay(1); +	} + +	if (phy_reg <= 0 || phy_reg == 0xFFFF)  		return 0;  	phy_id = (phy_reg & 0xffff) << 16; @@ -1075,7 +1083,7 @@ static const struct net_device_ops ax88772_netdev_ops = {  static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)  { -	int ret; +	int ret, embd_phy;  	struct asix_data *data = (struct asix_data *)&dev->data;  	u8 buf[ETH_ALEN];  	u32 phyid; @@ -1100,16 +1108,36 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)  	dev->mii.reg_num_mask = 0x1f;  	dev->mii.phy_id = asix_get_phy_addr(dev); -	phyid = asix_get_phyid(dev); -	dbg("PHYID=0x%08x", phyid); -  	dev->net->netdev_ops = &ax88772_netdev_ops;  	dev->net->ethtool_ops = &ax88772_ethtool_ops; -	ret = ax88772_reset(dev); +	embd_phy = ((dev->mii.phy_id & 0x1f) == 0x10 ? 1 : 0); + +	/* Reset the PHY to normal operation mode */ +	ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, embd_phy, 0, 0, NULL); +	if (ret < 0) { +		dbg("Select PHY #1 failed: %d", ret); +		return ret; +	} + +	ret = asix_sw_reset(dev, AX_SWRESET_IPPD | AX_SWRESET_PRL); +	if (ret < 0) +		return ret; + +	msleep(150); + +	ret = asix_sw_reset(dev, AX_SWRESET_CLEAR);  	if (ret < 0)  		return ret; +	msleep(150); + +	ret = asix_sw_reset(dev, embd_phy ? AX_SWRESET_IPRL : AX_SWRESET_PRTE); + +	/* Read PHYID register *AFTER* the PHY was reset properly */ +	phyid = asix_get_phyid(dev); +	dbg("PHYID=0x%08x", phyid); +  	/* Asix framing packs multiple eth frames into a 2K usb bulk transfer */  	if (dev->driver_info->flags & FLAG_FRAMING_AX) {  		/* hard_mtu  is still the default - the device does not support @@ -1220,6 +1248,7 @@ static int ax88178_reset(struct usbnet *dev)  	__le16 eeprom;  	u8 status;  	int gpio0 = 0; +	u32 phyid;  	asix_read_cmd(dev, AX_CMD_READ_GPIOS, 0, 0, 1, &status);  	dbg("GPIO Status: 0x%04x", status); @@ -1235,12 +1264,13 @@ static int ax88178_reset(struct usbnet *dev)  		data->ledmode = 0;  		gpio0 = 1;  	} else { -		data->phymode = le16_to_cpu(eeprom) & 7; +		data->phymode = le16_to_cpu(eeprom) & 0x7F;  		data->ledmode = le16_to_cpu(eeprom) >> 8;  		gpio0 = (le16_to_cpu(eeprom) & 0x80) ? 0 : 1;  	}  	dbg("GPIO0: %d, PhyMode: %d", gpio0, data->phymode); +	/* Power up external GigaPHY through AX88178 GPIO pin */  	asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_1 | AX_GPIO_GPO1EN, 40);  	if ((le16_to_cpu(eeprom) >> 8) != 1) {  		asix_write_gpio(dev, 0x003c, 30); @@ -1252,6 +1282,13 @@ static int ax88178_reset(struct usbnet *dev)  		asix_write_gpio(dev, AX_GPIO_GPO1EN | AX_GPIO_GPO_1, 30);  	} +	/* Read PHYID register *AFTER* powering up PHY */ +	phyid = asix_get_phyid(dev); +	dbg("PHYID=0x%08x", phyid); + +	/* Set AX88178 to enable MII/GMII/RGMII interface for external PHY */ +	asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, 0, 0, 0, NULL); +  	asix_sw_reset(dev, 0);  	msleep(150); @@ -1396,7 +1433,6 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf)  {  	int ret;  	u8 buf[ETH_ALEN]; -	u32 phyid;  	struct asix_data *data = (struct asix_data *)&dev->data;  	data->eeprom_len = AX88772_EEPROM_LEN; @@ -1423,12 +1459,12 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf)  	dev->net->netdev_ops = &ax88178_netdev_ops;  	dev->net->ethtool_ops = &ax88178_ethtool_ops; -	phyid = asix_get_phyid(dev); -	dbg("PHYID=0x%08x", phyid); +	/* Blink LEDS so users know driver saw dongle */ +	asix_sw_reset(dev, 0); +	msleep(150); -	ret = ax88178_reset(dev); -	if (ret < 0) -		return ret; +	asix_sw_reset(dev, AX_SWRESET_PRL | AX_SWRESET_IPPD); +	msleep(150);  	/* Asix framing packs multiple eth frames into a 2K usb bulk transfer */  	if (dev->driver_info->flags & FLAG_FRAMING_AX) { diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index c924ea2bce0..99ed6eb4dfa 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -567,7 +567,7 @@ static const struct usb_device_id	products [] = {  {  	USB_DEVICE_AND_INTERFACE_INFO(0x1004, 0x61aa, USB_CLASS_COMM,  			USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -	.driver_info = (unsigned long)&wwan_info, +	.driver_info = 0,  },  /* diff --git a/drivers/net/usb/lg-vl600.c b/drivers/net/usb/lg-vl600.c index d43db32f947..9c26c6390d6 100644 --- a/drivers/net/usb/lg-vl600.c +++ b/drivers/net/usb/lg-vl600.c @@ -144,10 +144,11 @@ static int vl600_rx_fixup(struct usbnet *dev, struct sk_buff *skb)  	}  	frame = (struct vl600_frame_hdr *) buf->data; -	/* NOTE: Should check that frame->magic == 0x53544448? -	 * Otherwise if we receive garbage at the beginning of the frame -	 * we may end up allocating a huge buffer and saving all the -	 * future incoming data into it.  */ +	/* Yes, check that frame->magic == 0x53544448 (or 0x44544d48), +	 * otherwise we may run out of memory w/a bad packet */ +	if (ntohl(frame->magic) != 0x53544448 && +			ntohl(frame->magic) != 0x44544d48) +		goto error;  	if (buf->len < sizeof(*frame) ||  			buf->len != le32_to_cpup(&frame->len)) { @@ -296,6 +297,11 @@ encapsulate:  	 * overwrite the remaining fields.  	 */  	packet = (struct vl600_pkt_hdr *) skb->data; +	/* The VL600 wants IPv6 packets to have an IPv4 ethertype +	 * Since this modem only supports IPv4 and IPv6, just set all +	 * frames to 0x0800 (ETH_P_IP) +	 */ +	packet->h_proto = htons(ETH_P_IP);  	memset(&packet->dummy, 0, sizeof(packet->dummy));  	packet->len = cpu_to_le32(orig_len); @@ -308,21 +314,12 @@ encapsulate:  	if (skb->len < full_len) /* Pad */  		skb_put(skb, full_len - skb->len); -	/* The VL600 wants IPv6 packets to have an IPv4 ethertype -	 * Check if this is an IPv6 packet, and set the ethertype -	 * to 0x800 -	 */ -	if ((skb->data[sizeof(struct vl600_pkt_hdr *) + 0x22] & 0xf0) == 0x60) { -		skb->data[sizeof(struct vl600_pkt_hdr *) + 0x20] = 0x08; -		skb->data[sizeof(struct vl600_pkt_hdr *) + 0x21] = 0; -	} -  	return skb;  }  static const struct driver_info	vl600_info = {  	.description	= "LG VL600 modem", -	.flags		= FLAG_ETHER | FLAG_RX_ASSEMBLE, +	.flags		= FLAG_RX_ASSEMBLE | FLAG_WWAN,  	.bind		= vl600_bind,  	.unbind		= vl600_unbind,  	.status		= usbnet_cdc_status, diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index 22a7cf951e7..a5b9b12ef26 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c @@ -51,6 +51,7 @@  #define USB_VENDOR_ID_SMSC		(0x0424)  #define USB_PRODUCT_ID_LAN7500		(0x7500)  #define USB_PRODUCT_ID_LAN7505		(0x7505) +#define RXW_PADDING			2  #define check_warn(ret, fmt, args...) \  	({ if (ret < 0) netdev_warn(dev->net, fmt, ##args); }) @@ -1088,13 +1089,13 @@ static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)  		memcpy(&rx_cmd_b, skb->data, sizeof(rx_cmd_b));  		le32_to_cpus(&rx_cmd_b); -		skb_pull(skb, 4 + NET_IP_ALIGN); +		skb_pull(skb, 4 + RXW_PADDING);  		packet = skb->data;  		/* get the packet length */ -		size = (rx_cmd_a & RX_CMD_A_LEN) - NET_IP_ALIGN; -		align_count = (4 - ((size + NET_IP_ALIGN) % 4)) % 4; +		size = (rx_cmd_a & RX_CMD_A_LEN) - RXW_PADDING; +		align_count = (4 - ((size + RXW_PADDING) % 4)) % 4;  		if (unlikely(rx_cmd_a & RX_CMD_A_RED)) {  			netif_dbg(dev, rx_err, dev->net, diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index 85fa9cc7350..65ecb5bab25 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c @@ -254,6 +254,8 @@ ath_reg_apply_active_scan_flags(struct wiphy *wiphy,  	int r;  	sband = wiphy->bands[IEEE80211_BAND_2GHZ]; +	if (!sband) +		return;  	/*  	 * If no country IE has been received always enable active scan diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index 58ea0e5fabf..5f77cbe0b6a 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c @@ -175,6 +175,7 @@ void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp,  	}  } +/* TODO: verify if needed for SSLPN or LCN  */  static u16 b43_generate_tx_phy_ctl1(struct b43_wldev *dev, u8 bitrate)  {  	const struct b43_phy *phy = &dev->phy; @@ -256,6 +257,9 @@ int b43_generate_txhdr(struct b43_wldev *dev,  	unsigned int plcp_fragment_len;  	u32 mac_ctl = 0;  	u16 phy_ctl = 0; +	bool fill_phy_ctl1 = (phy->type == B43_PHYTYPE_LP || +			      phy->type == B43_PHYTYPE_N || +			      phy->type == B43_PHYTYPE_HT);  	u8 extra_ft = 0;  	struct ieee80211_rate *txrate;  	struct ieee80211_tx_rate *rates; @@ -531,7 +535,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,  			extra_ft |= B43_TXH_EFT_RTSFB_CCK;  		if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS && -		    phy->type == B43_PHYTYPE_N) { +		    fill_phy_ctl1) {  			txhdr->phy_ctl1_rts = cpu_to_le16(  				b43_generate_tx_phy_ctl1(dev, rts_rate));  			txhdr->phy_ctl1_rts_fb = cpu_to_le16( @@ -552,7 +556,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,  		break;  	} -	if (phy->type == B43_PHYTYPE_N) { +	if (fill_phy_ctl1) {  		txhdr->phy_ctl1 =  			cpu_to_le16(b43_generate_tx_phy_ctl1(dev, rate));  		txhdr->phy_ctl1_fb = @@ -736,7 +740,14 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)  	/* Link quality statistics */  	switch (chanstat & B43_RX_CHAN_PHYTYPE) { +	case B43_PHYTYPE_HT: +		/* TODO: is max the right choice? */ +		status.signal = max_t(__s8, +			max(rxhdr->phy_ht_power0, rxhdr->phy_ht_power1), +			rxhdr->phy_ht_power2); +		break;  	case B43_PHYTYPE_N: +		/* Broadcom has code for min and avg, but always uses max */  		if (rxhdr->power0 == 16 || rxhdr->power0 == 32)  			status.signal = max(rxhdr->power1, rxhdr->power2);  		else diff --git a/drivers/net/wireless/b43/xmit.h b/drivers/net/wireless/b43/xmit.h index 16c514d54af..98d90747836 100644 --- a/drivers/net/wireless/b43/xmit.h +++ b/drivers/net/wireless/b43/xmit.h @@ -249,6 +249,12 @@ struct b43_rxhdr_fw4 {  		} __packed;  	} __packed;  	union { +		/* HT-PHY */ +		struct { +			PAD_BYTES(1); +			__s8 phy_ht_power0; +		} __packed; +  		/* RSSI for N-PHYs */  		struct {  			__s8 power2; @@ -257,7 +263,15 @@ struct b43_rxhdr_fw4 {  		__le16 phy_status2;	/* PHY RX Status 2 */  	} __packed; -	__le16 phy_status3;	/* PHY RX Status 3 */ +	union { +		/* HT-PHY */ +		struct { +			__s8 phy_ht_power1; +			__s8 phy_ht_power2; +		} __packed; + +		__le16 phy_status3;	/* PHY RX Status 3 */ +	} __packed;  	union {  		/* Tested with 598.314, 644.1001 and 666.2 */  		struct { diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c index b56a30297c2..6ebec8f4284 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c @@ -358,13 +358,14 @@ static uint nrxdactive(struct dma_info *di, uint h, uint t)  static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags)  { -	uint dmactrlflags = di->dma.dmactrlflags; +	uint dmactrlflags;  	if (di == NULL) { -		DMA_ERROR(("%s: _dma_ctrlflags: NULL dma handle\n", di->name)); +		DMA_ERROR(("_dma_ctrlflags: NULL dma handle\n"));  		return 0;  	} +	dmactrlflags = di->dma.dmactrlflags;  	dmactrlflags &= ~mask;  	dmactrlflags |= flags; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index da3411057af..ce918980e97 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -990,29 +990,16 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans)  	return 0;  } -static void iwl_trans_pcie_disable_sync_irq(struct iwl_trans *trans) +static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)  {  	unsigned long flags; -	struct iwl_trans_pcie *trans_pcie = -		IWL_TRANS_GET_PCIE_TRANS(trans); +	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); +	/* tell the device to stop sending interrupts */  	spin_lock_irqsave(&trans->shrd->lock, flags);  	iwl_disable_interrupts(trans);  	spin_unlock_irqrestore(&trans->shrd->lock, flags); -	/* wait to make sure we flush pending tasklet*/ -	synchronize_irq(bus(trans)->irq); -	tasklet_kill(&trans_pcie->irq_tasklet); -} - -static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) -{ -	/* stop and reset the on-board processor */ -	iwl_write32(bus(trans), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); - -	/* tell the device to stop sending interrupts */ -	iwl_trans_pcie_disable_sync_irq(trans); -  	/* device going down, Stop using ICT table */  	iwl_disable_ict(trans); @@ -1039,6 +1026,20 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)  	/* Stop the device, and put it in low power state */  	iwl_apm_stop(priv(trans)); + +	/* Upon stop, the APM issues an interrupt if HW RF kill is set. +	 * Clean again the interrupt here +	 */ +	spin_lock_irqsave(&trans->shrd->lock, flags); +	iwl_disable_interrupts(trans); +	spin_unlock_irqrestore(&trans->shrd->lock, flags); + +	/* wait to make sure we flush pending tasklet*/ +	synchronize_irq(bus(trans)->irq); +	tasklet_kill(&trans_pcie->irq_tasklet); + +	/* stop and reset the on-board processor */ +	iwl_write32(bus(trans), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);  }  static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 4fcd653bddc..a7f1ab28940 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -634,7 +634,7 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,  			if (channel &&  			    !(channel->flags & IEEE80211_CHAN_DISABLED))  				cfg80211_inform_bss(wiphy, channel, -					bssid, le64_to_cpu(*(__le64 *)tsfdesc), +					bssid, get_unaligned_le64(tsfdesc),  					capa, intvl, ie, ielen,  					LBS_SCAN_RSSI_TO_MBM(rssi),  					GFP_KERNEL); diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index 11b69b300dc..728baa44525 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c @@ -995,6 +995,7 @@ static int if_spi_host_to_card(struct lbs_private *priv,  		spin_unlock_irqrestore(&card->buffer_lock, flags);  		break;  	default: +		kfree(packet);  		netdev_err(priv->dev, "can't transfer buffer of type %d\n",  			   type);  		err = -EINVAL; diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index dae8dbb24a0..8d3ab378662 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -819,8 +819,10 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv,  			wildcard_ssid_tlv->header.len = cpu_to_le16(  				(u16) (ssid_len + sizeof(wildcard_ssid_tlv->  							 max_ssid_length))); -			wildcard_ssid_tlv->max_ssid_length = -				user_scan_in->ssid_list[ssid_idx].max_len; + +			/* max_ssid_length = 0 tells firmware to perform +			   specific scan for the SSID filled */ +			wildcard_ssid_tlv->max_ssid_length = 0;  			memcpy(wildcard_ssid_tlv->ssid,  			       user_scan_in->ssid_list[ssid_idx].ssid, @@ -1469,7 +1471,7 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv, u8 *bssid,  			       s32 rssi, const u8 *ie_buf, size_t ie_len,  			       u16 beacon_period, u16 cap_info_bitmap, u8 band)  { -	struct mwifiex_bssdescriptor *bss_desc = NULL; +	struct mwifiex_bssdescriptor *bss_desc;  	int ret;  	unsigned long flags;  	u8 *beacon_ie; @@ -1484,6 +1486,7 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv, u8 *bssid,  	beacon_ie = kmemdup(ie_buf, ie_len, GFP_KERNEL);  	if (!beacon_ie) { +		kfree(bss_desc);  		dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n");  		return -ENOMEM;  	} diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index f1565792f27..377876315b8 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -919,6 +919,7 @@ static struct usb_device_id rt2800usb_device_table[] = {  	{ USB_DEVICE(0x050d, 0x935b) },  	/* Buffalo */  	{ USB_DEVICE(0x0411, 0x00e8) }, +	{ USB_DEVICE(0x0411, 0x0158) },  	{ USB_DEVICE(0x0411, 0x016f) },  	{ USB_DEVICE(0x0411, 0x01a2) },  	/* Corega */ diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 2ec5c00235e..99ff12d0c29 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -943,6 +943,7 @@ struct rt2x00_dev {  	 * Powersaving work  	 */  	struct delayed_work autowakeup_work; +	struct work_struct sleep_work;  	/*  	 * Data queue arrays for RX, TX, Beacon and ATIM. diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index e1fb2a8569b..edd317fa7c0 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -465,6 +465,23 @@ static u8 *rt2x00lib_find_ie(u8 *data, unsigned int len, u8 ie)  	return NULL;  } +static void rt2x00lib_sleep(struct work_struct *work) +{ +	struct rt2x00_dev *rt2x00dev = +	    container_of(work, struct rt2x00_dev, sleep_work); + +	if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) +		return; + +	/* +	 * Check again is powersaving is enabled, to prevent races from delayed +	 * work execution. +	 */ +	if (!test_bit(CONFIG_POWERSAVING, &rt2x00dev->flags)) +		rt2x00lib_config(rt2x00dev, &rt2x00dev->hw->conf, +				 IEEE80211_CONF_CHANGE_PS); +} +  static void rt2x00lib_rxdone_check_ps(struct rt2x00_dev *rt2x00dev,  				      struct sk_buff *skb,  				      struct rxdone_entry_desc *rxdesc) @@ -512,8 +529,7 @@ static void rt2x00lib_rxdone_check_ps(struct rt2x00_dev *rt2x00dev,  	cam |= (tim_ie->bitmap_ctrl & 0x01);  	if (!cam && !test_bit(CONFIG_POWERSAVING, &rt2x00dev->flags)) -		rt2x00lib_config(rt2x00dev, &rt2x00dev->hw->conf, -				 IEEE80211_CONF_CHANGE_PS); +		queue_work(rt2x00dev->workqueue, &rt2x00dev->sleep_work);  }  static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev, @@ -1141,6 +1157,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)  	INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled);  	INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup); +	INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep);  	/*  	 * Let the driver probe the device to detect the capabilities. @@ -1197,6 +1214,7 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)  	 */  	cancel_work_sync(&rt2x00dev->intf_work);  	cancel_delayed_work_sync(&rt2x00dev->autowakeup_work); +	cancel_work_sync(&rt2x00dev->sleep_work);  	if (rt2x00_is_usb(rt2x00dev)) {  		del_timer_sync(&rt2x00dev->txstatus_timer);  		cancel_work_sync(&rt2x00dev->rxdone_work); diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c index 128ccb79318..fc29c671cf3 100644 --- a/drivers/net/wireless/wl12xx/scan.c +++ b/drivers/net/wireless/wl12xx/scan.c @@ -559,7 +559,7 @@ wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl,  						break;  					}  				/* Fail if SSID isn't present in the filters */ -				if (j == req->n_ssids) { +				if (j == cmd->n_ssids) {  					ret = -EINVAL;  					goto out_free;  				} diff --git a/drivers/s390/net/Kconfig b/drivers/s390/net/Kconfig index fa80ba1f034..9b66d2d1809 100644 --- a/drivers/s390/net/Kconfig +++ b/drivers/s390/net/Kconfig @@ -4,7 +4,7 @@ menu "S/390 network device drivers"  config LCS  	def_tristate m  	prompt "Lan Channel Station Interface" -	depends on CCW && NETDEVICES && (NET_ETHERNET || TR || FDDI) +	depends on CCW && NETDEVICES && (ETHERNET || TR || FDDI)  	help  	   Select this option if you want to use LCS networking on IBM System z.  	   This device driver supports Token Ring (IEEE 802.5), diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index c28713da1ec..863fc219715 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c @@ -50,7 +50,7 @@  #include "lcs.h" -#if !defined(CONFIG_NET_ETHERNET) && \ +#if !defined(CONFIG_ETHERNET) && \      !defined(CONFIG_TR) && !defined(CONFIG_FDDI)  #error Cannot compile lcs.c without some net devices switched on.  #endif @@ -1634,7 +1634,7 @@ lcs_startlan_auto(struct lcs_card *card)  	int rc;  	LCS_DBF_TEXT(2, trace, "strtauto"); -#ifdef CONFIG_NET_ETHERNET +#ifdef CONFIG_ETHERNET  	card->lan_type = LCS_FRAME_TYPE_ENET;  	rc = lcs_send_startlan(card, LCS_INITIATOR_TCPIP);  	if (rc == 0) @@ -2166,7 +2166,7 @@ lcs_new_device(struct ccwgroup_device *ccwgdev)  		goto netdev_out;  	}  	switch (card->lan_type) { -#ifdef CONFIG_NET_ETHERNET +#ifdef CONFIG_ETHERNET  	case LCS_FRAME_TYPE_ENET:  		card->lan_type_trans = eth_type_trans;  		dev = alloc_etherdev(0); diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c index 3251333a23d..b6a6356d09b 100644 --- a/drivers/s390/net/netiucv.c +++ b/drivers/s390/net/netiucv.c @@ -1994,6 +1994,8 @@ static struct net_device *netiucv_init_netdevice(char *username)  			   netiucv_setup_netdevice);  	if (!dev)  		return NULL; +	if (dev_alloc_name(dev, dev->name) < 0) +		goto out_netdev;  	privptr = netdev_priv(dev);  	privptr->fsm = init_fsm("netiucvdev", dev_state_names, diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index b77c65ed138..4abc79d3963 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -236,8 +236,7 @@ static inline int qeth_is_ipa_enabled(struct qeth_ipa_info *ipa,  #define QETH_IN_BUF_COUNT_MAX 128  #define QETH_MAX_BUFFER_ELEMENTS(card) ((card)->qdio.in_buf_size >> 12)  #define QETH_IN_BUF_REQUEUE_THRESHOLD(card) \ -		((card)->ssqd.qdioac1 & AC1_SIGA_INPUT_NEEDED ? 1 : \ -		 ((card)->qdio.in_buf_pool.buf_count / 2)) +		 ((card)->qdio.in_buf_pool.buf_count / 2)  /* buffers we have to be behind before we get a PCI */  #define QETH_PCI_THRESHOLD_A(card) ((card)->qdio.in_buf_pool.buf_count+1) diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 81534437373..fff57de7894 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -881,7 +881,6 @@ EXPORT_SYMBOL_GPL(qeth_do_run_thread);  void qeth_schedule_recovery(struct qeth_card *card)  {  	QETH_CARD_TEXT(card, 2, "startrec"); -	WARN_ON(1);  	if (qeth_set_thread_start_bit(card, QETH_RECOVER_THREAD) == 0)  		schedule_work(&card->kernel_thread_starter);  } diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index e4c1176ee25..4d5307ddbe5 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2756,11 +2756,13 @@ int inline qeth_l3_get_cast_type(struct qeth_card *card, struct sk_buff *skb)  	struct neighbour *n = NULL;  	struct dst_entry *dst; +	rcu_read_lock();  	dst = skb_dst(skb);  	if (dst)  		n = dst_get_neighbour(dst);  	if (n) {  		cast_type = n->type; +		rcu_read_unlock();  		if ((cast_type == RTN_BROADCAST) ||  		    (cast_type == RTN_MULTICAST) ||  		    (cast_type == RTN_ANYCAST)) @@ -2768,6 +2770,8 @@ int inline qeth_l3_get_cast_type(struct qeth_card *card, struct sk_buff *skb)  		else  			return RTN_UNSPEC;  	} +	rcu_read_unlock(); +  	/* try something else */  	if (skb->protocol == ETH_P_IPV6)  		return (skb_network_header(skb)[24] == 0xff) ? @@ -2847,6 +2851,8 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,  	}  	hdr->hdr.l3.length = skb->len - sizeof(struct qeth_hdr); + +	rcu_read_lock();  	dst = skb_dst(skb);  	if (dst)  		n = dst_get_neighbour(dst); @@ -2893,6 +2899,7 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,  				QETH_CAST_UNICAST | QETH_HDR_PASSTHRU;  		}  	} +	rcu_read_unlock();  }  static inline void qeth_l3_hdr_csum(struct qeth_card *card, diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c index 0ea2fbfe0e9..d979bb26522 100644 --- a/drivers/s390/net/qeth_l3_sys.c +++ b/drivers/s390/net/qeth_l3_sys.c @@ -335,10 +335,10 @@ static ssize_t qeth_l3_dev_sniffer_store(struct device *dev,  					QETH_IN_BUF_COUNT_MAX)  				qeth_realloc_buffer_pool(card,  					QETH_IN_BUF_COUNT_MAX); -			break;  		} else  			rc = -EPERM; -	default:   /* fall through */ +		break; +	default:  		rc = -EINVAL;  	}  out: diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c index 34907703333..16a509ae517 100644 --- a/drivers/usb/gadget/f_phonet.c +++ b/drivers/usb/gadget/f_phonet.c @@ -346,7 +346,7 @@ static void pn_rx_complete(struct usb_ep *ep, struct usb_request *req)  		}  		skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, -				skb->len == 0, req->actual); +				skb->len <= 1, req->actual);  		page = NULL;  		if (req->actual < req->length) { /* Last fragment */ diff --git a/include/linux/inet_diag.h b/include/linux/inet_diag.h index 80b480c9753..abf5028db98 100644 --- a/include/linux/inet_diag.h +++ b/include/linux/inet_diag.h @@ -98,9 +98,10 @@ enum {  	INET_DIAG_VEGASINFO,  	INET_DIAG_CONG,  	INET_DIAG_TOS, +	INET_DIAG_TCLASS,  }; -#define INET_DIAG_MAX INET_DIAG_TOS +#define INET_DIAG_MAX INET_DIAG_TCLASS  /* INET_DIAG_MEM */ diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index ab90ae0970a..6cc18f37167 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -39,8 +39,11 @@  #define L2CAP_DEFAULT_ACK_TO		200  #define L2CAP_LE_DEFAULT_MTU		23 -#define L2CAP_CONN_TIMEOUT	(40000) /* 40 seconds */ -#define L2CAP_INFO_TIMEOUT	(4000)  /*  4 seconds */ +#define L2CAP_DISC_TIMEOUT             (100) +#define L2CAP_DISC_REJ_TIMEOUT         (5000)  /*  5 seconds */ +#define L2CAP_ENC_TIMEOUT              (5000)  /*  5 seconds */ +#define L2CAP_CONN_TIMEOUT             (40000) /* 40 seconds */ +#define L2CAP_INFO_TIMEOUT             (4000)  /*  4 seconds */  /* L2CAP socket address */  struct sockaddr_l2 { diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 92cf1c2c30c..95852e36713 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -456,6 +456,9 @@ enum station_parameters_apply_mask {   *	as the AC bitmap in the QoS info field   * @max_sp: max Service Period. same format as the MAX_SP in the   *	QoS info field (but already shifted down) + * @sta_modify_mask: bitmap indicating which parameters changed + *	(for those that don't have a natural "no change" value), + *	see &enum station_parameters_apply_mask   */  struct station_parameters {  	u8 *supported_rates; @@ -615,6 +618,7 @@ struct sta_bss_parameters {   *	user space MLME/SME implementation. The information is provided for   *	the cfg80211_new_sta() calls to notify user space of the IEs.   * @assoc_req_ies_len: Length of assoc_req_ies buffer in octets. + * @sta_flags: station flags mask & values   */  struct station_info {  	u32 filled; diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index c1c597e3e19..e0af7237cd9 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -673,7 +673,7 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)  		goto encrypt;  auth: -	if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) +	if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))  		return 0;  	if (!hci_conn_auth(conn, sec_level, auth_type)) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 8cd12917733..5ea94a1eecf 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -251,7 +251,7 @@ static void l2cap_chan_timeout(unsigned long arg)  	if (sock_owned_by_user(sk)) {  		/* sk is owned by user. Try again later */ -		__set_chan_timer(chan, HZ / 5); +		__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);  		bh_unlock_sock(sk);  		chan_put(chan);  		return; @@ -2488,7 +2488,7 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd  		if (sock_owned_by_user(sk)) {  			l2cap_state_change(chan, BT_DISCONN);  			__clear_chan_timer(chan); -			__set_chan_timer(chan, HZ / 5); +			__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);  			break;  		} @@ -2661,7 +2661,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr  	default:  		sk->sk_err = ECONNRESET; -		__set_chan_timer(chan, HZ * 5); +		__set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);  		l2cap_send_disconn_req(conn, chan, ECONNRESET);  		goto done;  	} @@ -2718,7 +2718,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd  	if (sock_owned_by_user(sk)) {  		l2cap_state_change(chan, BT_DISCONN);  		__clear_chan_timer(chan); -		__set_chan_timer(chan, HZ / 5); +		__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);  		bh_unlock_sock(sk);  		return 0;  	} @@ -2752,7 +2752,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd  	if (sock_owned_by_user(sk)) {  		l2cap_state_change(chan,BT_DISCONN);  		__clear_chan_timer(chan); -		__set_chan_timer(chan, HZ / 5); +		__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);  		bh_unlock_sock(sk);  		return 0;  	} @@ -3998,7 +3998,7 @@ static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)  	if (encrypt == 0x00) {  		if (chan->sec_level == BT_SECURITY_MEDIUM) {  			__clear_chan_timer(chan); -			__set_chan_timer(chan, HZ * 5); +			__set_chan_timer(chan, L2CAP_ENC_TIMEOUT);  		} else if (chan->sec_level == BT_SECURITY_HIGH)  			l2cap_chan_close(chan, ECONNREFUSED);  	} else { @@ -4066,7 +4066,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)  					L2CAP_CONN_REQ, sizeof(req), &req);  			} else {  				__clear_chan_timer(chan); -				__set_chan_timer(chan, HZ / 10); +				__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);  			}  		} else if (chan->state == BT_CONNECT2) {  			struct l2cap_conn_rsp rsp; @@ -4086,7 +4086,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)  				}  			} else {  				l2cap_state_change(chan, BT_DISCONN); -				__set_chan_timer(chan, HZ / 10); +				__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);  				res = L2CAP_CR_SEC_BLOCK;  				stat = L2CAP_CS_NO_INFO;  			} diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 995cbe0ac0b..a5f4e576980 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -1501,6 +1501,8 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,  	__skb_pull(skb2, offset);  	skb_reset_transport_header(skb2); +	skb_postpull_rcsum(skb2, skb_network_header(skb2), +			   skb_network_header_len(skb2));  	icmp6_type = icmp6_hdr(skb2)->icmp6_type; @@ -1770,7 +1772,7 @@ int br_multicast_toggle(struct net_bridge *br, unsigned long val)  	int err = 0;  	struct net_bridge_mdb_htable *mdb; -	spin_lock(&br->multicast_lock); +	spin_lock_bh(&br->multicast_lock);  	if (br->multicast_disabled == !val)  		goto unlock; @@ -1806,7 +1808,7 @@ rollback:  	}  unlock: -	spin_unlock(&br->multicast_lock); +	spin_unlock_bh(&br->multicast_lock);  	return err;  } diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c index c1f4154552f..36d14406261 100644 --- a/net/ipv4/ah4.c +++ b/net/ipv4/ah4.c @@ -136,8 +136,6 @@ static void ah_output_done(struct crypto_async_request *base, int err)  		memcpy(top_iph+1, iph+1, top_iph->ihl*4 - sizeof(struct iphdr));  	} -	err = ah->nexthdr; -  	kfree(AH_SKB_CB(skb)->tmp);  	xfrm_output_resume(skb, err);  } @@ -264,12 +262,12 @@ static void ah_input_done(struct crypto_async_request *base, int err)  	if (err)  		goto out; +	err = ah->nexthdr; +  	skb->network_header += ah_hlen;  	memcpy(skb_network_header(skb), work_iph, ihl);  	__skb_pull(skb, ah_hlen + ihl);  	skb_set_transport_header(skb, -ihl); - -	err = ah->nexthdr;  out:  	kfree(AH_SKB_CB(skb)->tmp);  	xfrm_input_resume(skb, err); @@ -371,8 +369,6 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)  		if (err == -EINPROGRESS)  			goto out; -		if (err == -EBUSY) -			err = NET_XMIT_DROP;  		goto out_free;  	} diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index f5e2bdaef94..68e8ac51438 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c @@ -133,8 +133,8 @@ static int inet_csk_diag_fill(struct sock *sk,  			       &np->rcv_saddr);  		ipv6_addr_copy((struct in6_addr *)r->id.idiag_dst,  			       &np->daddr); -		if (ext & (1 << (INET_DIAG_TOS - 1))) -			RTA_PUT_U8(skb, INET_DIAG_TOS, np->tclass); +		if (ext & (1 << (INET_DIAG_TCLASS - 1))) +			RTA_PUT_U8(skb, INET_DIAG_TCLASS, np->tclass);  	}  #endif diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c index ec93335901d..05d20cca9d6 100644 --- a/net/ipv4/ip_options.c +++ b/net/ipv4/ip_options.c @@ -640,6 +640,7 @@ int ip_options_rcv_srr(struct sk_buff *skb)  	}  	if (srrptr <= srrspace) {  		opt->srr_is_hit = 1; +		iph->daddr = nexthop;  		opt->is_changed = 1;  	}  	return 0; diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index a06f73fdb3c..43d4c3b2236 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c @@ -339,7 +339,6 @@ void ping_err(struct sk_buff *skb, u32 info)  	sk = ping_v4_lookup(net, iph->daddr, iph->saddr,  			    ntohs(icmph->un.echo.id), skb->dev->ifindex);  	if (sk == NULL) { -		ICMP_INC_STATS_BH(net, ICMP_MIB_INERRORS);  		pr_debug("no socket, dropping\n");  		return;	/* No socket for error */  	} @@ -679,7 +678,6 @@ static int ping_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)  	pr_debug("ping_queue_rcv_skb(sk=%p,sk->num=%d,skb=%p)\n",  		inet_sk(sk), inet_sk(sk)->inet_num, skb);  	if (sock_queue_rcv_skb(sk, skb) < 0) { -		ICMP_INC_STATS_BH(sock_net(sk), ICMP_MIB_INERRORS);  		kfree_skb(skb);  		pr_debug("ping_queue_rcv_skb -> failed\n");  		return -1; diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 155138d8ec8..0c74da8a047 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1304,16 +1304,42 @@ static void rt_del(unsigned hash, struct rtable *rt)  	spin_unlock_bh(rt_hash_lock_addr(hash));  } +static int check_peer_redir(struct dst_entry *dst, struct inet_peer *peer) +{ +	struct rtable *rt = (struct rtable *) dst; +	__be32 orig_gw = rt->rt_gateway; +	struct neighbour *n, *old_n; + +	dst_confirm(&rt->dst); + +	rt->rt_gateway = peer->redirect_learned.a4; + +	n = ipv4_neigh_lookup(&rt->dst, &rt->rt_gateway); +	if (IS_ERR(n)) +		return PTR_ERR(n); +	old_n = xchg(&rt->dst._neighbour, n); +	if (old_n) +		neigh_release(old_n); +	if (!n || !(n->nud_state & NUD_VALID)) { +		if (n) +			neigh_event_send(n, NULL); +		rt->rt_gateway = orig_gw; +		return -EAGAIN; +	} else { +		rt->rt_flags |= RTCF_REDIRECTED; +		call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n); +	} +	return 0; +} +  /* called in rcu_read_lock() section */  void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,  		    __be32 saddr, struct net_device *dev)  {  	int s, i;  	struct in_device *in_dev = __in_dev_get_rcu(dev); -	struct rtable *rt;  	__be32 skeys[2] = { saddr, 0 };  	int    ikeys[2] = { dev->ifindex, 0 }; -	struct flowi4 fl4;  	struct inet_peer *peer;  	struct net *net; @@ -1336,33 +1362,42 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,  			goto reject_redirect;  	} -	memset(&fl4, 0, sizeof(fl4)); -	fl4.daddr = daddr;  	for (s = 0; s < 2; s++) {  		for (i = 0; i < 2; i++) { -			fl4.flowi4_oif = ikeys[i]; -			fl4.saddr = skeys[s]; -			rt = __ip_route_output_key(net, &fl4); -			if (IS_ERR(rt)) -				continue; +			unsigned int hash; +			struct rtable __rcu **rthp; +			struct rtable *rt; -			if (rt->dst.error || rt->dst.dev != dev || -			    rt->rt_gateway != old_gw) { -				ip_rt_put(rt); -				continue; -			} +			hash = rt_hash(daddr, skeys[s], ikeys[i], rt_genid(net)); -			if (!rt->peer) -				rt_bind_peer(rt, rt->rt_dst, 1); +			rthp = &rt_hash_table[hash].chain; -			peer = rt->peer; -			if (peer) { -				peer->redirect_learned.a4 = new_gw; -				atomic_inc(&__rt_peer_genid); -			} +			while ((rt = rcu_dereference(*rthp)) != NULL) { +				rthp = &rt->dst.rt_next; -			ip_rt_put(rt); -			return; +				if (rt->rt_key_dst != daddr || +				    rt->rt_key_src != skeys[s] || +				    rt->rt_oif != ikeys[i] || +				    rt_is_input_route(rt) || +				    rt_is_expired(rt) || +				    !net_eq(dev_net(rt->dst.dev), net) || +				    rt->dst.error || +				    rt->dst.dev != dev || +				    rt->rt_gateway != old_gw) +					continue; + +				if (!rt->peer) +					rt_bind_peer(rt, rt->rt_dst, 1); + +				peer = rt->peer; +				if (peer) { +					if (peer->redirect_learned.a4 != new_gw) { +						peer->redirect_learned.a4 = new_gw; +						atomic_inc(&__rt_peer_genid); +					} +					check_peer_redir(&rt->dst, peer); +				} +			}  		}  	}  	return; @@ -1649,33 +1684,6 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu)  	}  } -static int check_peer_redir(struct dst_entry *dst, struct inet_peer *peer) -{ -	struct rtable *rt = (struct rtable *) dst; -	__be32 orig_gw = rt->rt_gateway; -	struct neighbour *n, *old_n; - -	dst_confirm(&rt->dst); - -	rt->rt_gateway = peer->redirect_learned.a4; - -	n = ipv4_neigh_lookup(&rt->dst, &rt->rt_gateway); -	if (IS_ERR(n)) -		return PTR_ERR(n); -	old_n = xchg(&rt->dst._neighbour, n); -	if (old_n) -		neigh_release(old_n); -	if (!n || !(n->nud_state & NUD_VALID)) { -		if (n) -			neigh_event_send(n, NULL); -		rt->rt_gateway = orig_gw; -		return -EAGAIN; -	} else { -		rt->rt_flags |= RTCF_REDIRECTED; -		call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n); -	} -	return 0; -}  static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie)  { @@ -2845,7 +2853,7 @@ static int rt_fill_info(struct net *net,  	struct rtable *rt = skb_rtable(skb);  	struct rtmsg *r;  	struct nlmsghdr *nlh; -	long expires = 0; +	unsigned long expires = 0;  	const struct inet_peer *peer = rt->peer;  	u32 id = 0, ts = 0, tsage = 0, error; @@ -2902,8 +2910,12 @@ static int rt_fill_info(struct net *net,  			tsage = get_seconds() - peer->tcp_ts_stamp;  		}  		expires = ACCESS_ONCE(peer->pmtu_expires); -		if (expires) -			expires -= jiffies; +		if (expires) { +			if (time_before(jiffies, expires)) +				expires -= jiffies; +			else +				expires = 0; +		}  	}  	if (rt_is_input_route(rt)) { diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index a7443159c40..a9db4b1a221 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1510,6 +1510,7 @@ exit:  	NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);  	return NULL;  put_and_exit: +	tcp_clear_xmit_timers(newsk);  	bh_unlock_sock(newsk);  	sock_put(newsk);  	goto exit; diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 980b98f6288..63170e29754 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1382,7 +1382,7 @@ static inline int tcp_minshall_check(const struct tcp_sock *tp)  /* Return 0, if packet can be sent now without violation Nagle's rules:   * 1. It is full sized.   * 2. Or it contains FIN. (already checked by caller) - * 3. Or TCP_NODELAY was set. + * 3. Or TCP_CORK is not set, and TCP_NODELAY is set.   * 4. Or TCP_CORK is not set, and all sent packets are ACKed.   *    With Minshall's modification: all sent small packets are ACKed.   */ diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index 2195ae65192..4c0f894d084 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c @@ -324,8 +324,6 @@ static void ah6_output_done(struct crypto_async_request *base, int err)  #endif  	} -	err = ah->nexthdr; -  	kfree(AH_SKB_CB(skb)->tmp);  	xfrm_output_resume(skb, err);  } @@ -466,12 +464,12 @@ static void ah6_input_done(struct crypto_async_request *base, int err)  	if (err)  		goto out; +	err = ah->nexthdr; +  	skb->network_header += ah_hlen;  	memcpy(skb_network_header(skb), work_iph, hdr_len);  	__skb_pull(skb, ah_hlen + hdr_len);  	skb_set_transport_header(skb, -hdr_len); - -	err = ah->nexthdr;  out:  	kfree(AH_SKB_CB(skb)->tmp);  	xfrm_input_resume(skb, err); @@ -583,8 +581,6 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)  		if (err == -EINPROGRESS)  			goto out; -		if (err == -EBUSY) -			err = NET_XMIT_DROP;  		goto out_free;  	} diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index 027c7ff6f1e..a46c64eb0a6 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c @@ -111,6 +111,14 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt  	    ipv6_addr_loopback(&hdr->daddr))  		goto err; +	/* +	 * RFC4291 2.7 +	 * Multicast addresses must not be used as source addresses in IPv6 +	 * packets or appear in any Routing header. +	 */ +	if (ipv6_addr_is_multicast(&hdr->saddr)) +		goto err; +  	skb->transport_header = skb->network_header + sizeof(*hdr);  	IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr); diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index bdc15c9003d..4e2e9ff67ef 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -289,6 +289,8 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct ip6_tnl_parm *p)  	if ((err = register_netdevice(dev)) < 0)  		goto failed_free; +	strcpy(t->parms.name, dev->name); +  	dev_hold(dev);  	ip6_tnl_link(ip6n, t);  	return t; @@ -1407,7 +1409,6 @@ ip6_tnl_dev_init_gen(struct net_device *dev)  	struct ip6_tnl *t = netdev_priv(dev);  	t->dev = dev; -	strcpy(t->parms.name, dev->name);  	dev->tstats = alloc_percpu(struct pcpu_tstats);  	if (!dev->tstats)  		return -ENOMEM; @@ -1487,6 +1488,7 @@ static void __net_exit ip6_tnl_destroy_tunnels(struct ip6_tnl_net *ip6n)  static int __net_init ip6_tnl_init_net(struct net *net)  {  	struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); +	struct ip6_tnl *t = NULL;  	int err;  	ip6n->tnls[0] = ip6n->tnls_wc; @@ -1507,6 +1509,10 @@ static int __net_init ip6_tnl_init_net(struct net *net)  	err = register_netdev(ip6n->fb_tnl_dev);  	if (err < 0)  		goto err_register; + +	t = netdev_priv(ip6n->fb_tnl_dev); + +	strcpy(t->parms.name, ip6n->fb_tnl_dev->name);  	return 0;  err_register: diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index bf8d50c6793..cf0f308abf5 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -756,9 +756,6 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb,  		goto error;  	} -	/* Point to L2TP header */ -	optr = ptr = skb->data; -  	/* Trace packet contents, if enabled */  	if (tunnel->debug & L2TP_MSG_DATA) {  		length = min(32u, skb->len); @@ -769,12 +766,15 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb,  		offset = 0;  		do { -			printk(" %02X", ptr[offset]); +			printk(" %02X", skb->data[offset]);  		} while (++offset < length);  		printk("\n");  	} +	/* Point to L2TP header */ +	optr = ptr = skb->data; +  	/* Get L2TP header flags */  	hdrflags = ntohs(*(__be16 *) ptr); diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 72c8bea81a6..b1b1bb368f7 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1487,6 +1487,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,  	int i, j, err;  	bool have_higher_than_11mbit = false;  	u16 ap_ht_cap_flags; +	int min_rate = INT_MAX, min_rate_index = -1;  	/* AssocResp and ReassocResp have identical structure */ @@ -1553,6 +1554,10 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,  				rates |= BIT(j);  				if (is_basic)  					basic_rates |= BIT(j); +				if (rate < min_rate) { +					min_rate = rate; +					min_rate_index = j; +				}  				break;  			}  		} @@ -1570,11 +1575,25 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,  				rates |= BIT(j);  				if (is_basic)  					basic_rates |= BIT(j); +				if (rate < min_rate) { +					min_rate = rate; +					min_rate_index = j; +				}  				break;  			}  		}  	} +	/* +	 * some buggy APs don't advertise basic_rates. use the lowest +	 * supported rate instead. +	 */ +	if (unlikely(!basic_rates) && min_rate_index >= 0) { +		printk(KERN_DEBUG "%s: No basic rates in AssocResp. " +		       "Using min supported rate instead.\n", sdata->name); +		basic_rates = BIT(min_rate_index); +	} +  	sta->sta.supp_rates[wk->chan->band] = rates;  	sdata->vif.bss_conf.basic_rates = basic_rates; @@ -2269,6 +2288,7 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)  	cancel_work_sync(&ifmgd->request_smps_work); +	cancel_work_sync(&ifmgd->monitor_work);  	cancel_work_sync(&ifmgd->beacon_connection_loss_work);  	if (del_timer_sync(&ifmgd->timer))  		set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running); @@ -2277,7 +2297,6 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)  	if (del_timer_sync(&ifmgd->chswitch_timer))  		set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running); -	cancel_work_sync(&ifmgd->monitor_work);  	/* these will just be re-established on connection */  	del_timer_sync(&ifmgd->conn_mon_timer);  	del_timer_sync(&ifmgd->bcn_mon_timer); diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index bb53726cb04..fb123e2e081 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -141,8 +141,9 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,  	pos++;  	/* IEEE80211_RADIOTAP_RATE */ -	if (status->flag & RX_FLAG_HT) { +	if (!rate || status->flag & RX_FLAG_HT) {  		/* +		 * Without rate information don't add it. If we have,  		 * MCS information is a separate field in radiotap,  		 * added below. The byte here is needed as padding  		 * for the channel though, so initialise it to 0. @@ -163,12 +164,14 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,  	else if (status->flag & RX_FLAG_HT)  		put_unaligned_le16(IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ,  				   pos); -	else if (rate->flags & IEEE80211_RATE_ERP_G) +	else if (rate && rate->flags & IEEE80211_RATE_ERP_G)  		put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ,  				   pos); -	else +	else if (rate)  		put_unaligned_le16(IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ,  				   pos); +	else +		put_unaligned_le16(IEEE80211_CHAN_2GHZ, pos);  	pos += 2;  	/* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */ diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index ce962d2c878..8eaa746ec7a 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -1354,12 +1354,12 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta,  			 * Use MoreData flag to indicate whether there are  			 * more buffered frames for this STA  			 */ -			if (!more_data) -				hdr->frame_control &= -					cpu_to_le16(~IEEE80211_FCTL_MOREDATA); -			else +			if (more_data || !skb_queue_empty(&frames))  				hdr->frame_control |=  					cpu_to_le16(IEEE80211_FCTL_MOREDATA); +			else +				hdr->frame_control &= +					cpu_to_le16(~IEEE80211_FCTL_MOREDATA);  			if (ieee80211_is_data_qos(hdr->frame_control) ||  			    ieee80211_is_qos_nullfunc(hdr->frame_control)) diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 51e256c5fb7..eca0fad0970 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -881,6 +881,8 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,  	skb = ieee80211_probereq_get(&local->hw, &sdata->vif,  				     ssid, ssid_len,  				     buf, buf_len); +	if (!skb) +		goto out;  	if (dst) {  		mgmt = (struct ieee80211_mgmt *) skb->data; @@ -889,6 +891,8 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,  	}  	IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; + + out:  	kfree(buf);  	return skb; diff --git a/net/rds/Kconfig b/net/rds/Kconfig index 4cf6dc7910e..ec753b3ae72 100644 --- a/net/rds/Kconfig +++ b/net/rds/Kconfig @@ -9,7 +9,6 @@ config RDS  config RDS_RDMA  	tristate "RDS over Infiniband and iWARP" -	select LLIST  	depends on RDS && INFINIBAND && INFINIBAND_ADDR_TRANS  	---help---  	  Allow RDS to use Infiniband and iWARP as a transport. diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 48260c2d092..b3a476fe827 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -132,8 +132,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {  	[NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },  	[NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG }, -	[NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY, -					 .len = NL80211_HT_CAPABILITY_LEN }, +	[NL80211_ATTR_HT_CAPABILITY] = { .len = NL80211_HT_CAPABILITY_LEN },  	[NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },  	[NL80211_ATTR_IE] = { .type = NLA_BINARY, @@ -1253,6 +1252,12 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)  			goto bad_res;  		} +		if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && +		    netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { +			result = -EINVAL; +			goto bad_res; +		} +  		nla_for_each_nested(nl_txq_params,  				    info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],  				    rem_txq_params) { diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 6acba9d18cc..e71f5a66574 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -2265,6 +2265,9 @@ void /* __init_or_exit */ regulatory_exit(void)  	kfree(last_request); +	last_request = NULL; +	dev_set_uevent_suppress(®_pdev->dev, true); +  	platform_device_unregister(reg_pdev);  	spin_lock_bh(®_pending_beacons_lock); diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 0fb14241040..dc23b31594e 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -259,17 +259,20 @@ static int cmp_ies(u8 num, u8 *ies1, size_t len1, u8 *ies2, size_t len2)  {  	const u8 *ie1 = cfg80211_find_ie(num, ies1, len1);  	const u8 *ie2 = cfg80211_find_ie(num, ies2, len2); -	int r; +	/* equal if both missing */  	if (!ie1 && !ie2)  		return 0; -	if (!ie1 || !ie2) +	/* sort missing IE before (left of) present IE */ +	if (!ie1)  		return -1; +	if (!ie2) +		return 1; -	r = memcmp(ie1 + 2, ie2 + 2, min(ie1[1], ie2[1])); -	if (r == 0 && ie1[1] != ie2[1]) +	/* sort by length first, then by contents */ +	if (ie1[1] != ie2[1])  		return ie2[1] - ie1[1]; -	return r; +	return memcmp(ie1 + 2, ie2 + 2, ie1[1]);  }  static bool is_bss(struct cfg80211_bss *a,  |