Prechádzať zdrojové kódy

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (92 commits)
  gianfar: Revive VLAN support
  vlan: Export symbols as non GPL symbols.
  bnx2x: tx_has_work should not wait for FW
  netxen: reduce memory footprint
  netxen: fix vlan tso/checksum offload
  net: Fix linux/if_frad.h's suitability for userspace.
  net: Move config NET_NS to from net/Kconfig to init/Kconfig
  isdn: Fix missing ifdef in isdn_ppp
  networking: document "nc" in addition to "netcat" in netconsole.txt
  e1000e: workaround hw errata
  af_key: initialize xfrm encap_oa
  virtio_net: Fix MAX_PACKET_LEN to support 802.1Q VLANs
  lcs: fix compilation for !CONFIG_IP_MULTICAST
  rtl8187: Add termination packet to prevent stall
  iwlwifi: fix rs_get_rate WARN_ON()
  p54usb: fix packet loss with first generation devices
  sctp: Fix another socket race during accept/peeloff
  sctp: Properly timestamp outgoing data chunks for rtx purposes
  sctp: Correctly start rtx timer on new packet transmissions.
  sctp: Fix crc32c calculations on big-endian arhes.
  ...
Linus Torvalds 16 rokov pred
rodič
commit
924d26df6b
67 zmenil súbory, kde vykonal 801 pridanie a 464 odobranie
  1. 2 1
      Documentation/networking/netconsole.txt
  2. 2 0
      drivers/isdn/i4l/isdn_ppp.c
  3. 2 9
      drivers/net/bnx2x.h
  4. 46 18
      drivers/net/bnx2x_link.c
  5. 183 119
      drivers/net/bnx2x_main.c
  6. 1 1
      drivers/net/bnx2x_reg.h
  7. 1 0
      drivers/net/cxgb3/sge.c
  8. 5 1
      drivers/net/e1000e/82571.c
  9. 1 0
      drivers/net/e1000e/hw.h
  10. 1 5
      drivers/net/gianfar.c
  11. 33 29
      drivers/net/ixgbe/ixgbe_main.c
  12. 3 0
      drivers/net/ixgbe/ixgbe_type.h
  13. 9 6
      drivers/net/korina.c
  14. 8 0
      drivers/net/macb.c
  15. 10 7
      drivers/net/mv643xx_eth.c
  16. 9 6
      drivers/net/myri10ge/myri10ge.c
  17. 6 6
      drivers/net/netxen/netxen_nic.h
  18. 4 1
      drivers/net/netxen/netxen_nic_ethtool.c
  19. 20 11
      drivers/net/netxen/netxen_nic_main.c
  20. 3 5
      drivers/net/phy/mdio_bus.c
  21. 12 0
      drivers/net/phy/smsc.c
  22. 50 31
      drivers/net/tg3.c
  23. 1 0
      drivers/net/tg3.h
  24. 18 2
      drivers/net/usb/mcs7830.c
  25. 1 1
      drivers/net/via-velocity.c
  26. 2 1
      drivers/net/virtio_net.c
  27. 1 1
      drivers/net/wimax/i2400m/control.c
  28. 6 3
      drivers/net/wimax/i2400m/usb-rx.c
  29. 1 1
      drivers/net/wireless/ath9k/rc.c
  30. 1 1
      drivers/net/wireless/ath9k/regd_common.h
  31. 11 3
      drivers/net/wireless/iwlwifi/iwl-3945-rs.c
  32. 12 2
      drivers/net/wireless/iwlwifi/iwl-agn-rs.c
  33. 1 1
      drivers/net/wireless/iwlwifi/iwl-agn.c
  34. 1 1
      drivers/net/wireless/iwlwifi/iwl-hcmd.c
  35. 2 2
      drivers/net/wireless/iwlwifi/iwl3945-base.c
  36. 45 46
      drivers/net/wireless/libertas/hostcmd.h
  37. 14 18
      drivers/net/wireless/orinoco/orinoco.c
  38. 22 8
      drivers/net/wireless/p54/p54common.c
  39. 18 23
      drivers/net/wireless/p54/p54usb.c
  40. 0 2
      drivers/net/wireless/rndis_wlan.c
  41. 2 1
      drivers/net/wireless/rt2x00/rt2x00queue.c
  42. 1 1
      drivers/net/wireless/rt2x00/rt2x00rfkill.c
  43. 1 0
      drivers/net/wireless/rtl818x/rtl8187_dev.c
  44. 1 0
      drivers/net/wireless/zd1211rw/zd_usb.c
  45. 6 2
      drivers/s390/net/lcs.c
  46. 4 6
      include/linux/if_frad.h
  47. 3 1
      include/linux/usb/usbnet.h
  48. 0 1
      include/net/mac80211.h
  49. 1 1
      include/net/sctp/checksum.h
  50. 8 0
      init/Kconfig
  51. 2 2
      net/8021q/vlan_core.c
  52. 1 1
      net/9p/client.c
  53. 0 8
      net/Kconfig
  54. 14 1
      net/core/dev.c
  55. 1 1
      net/core/net_namespace.c
  56. 34 36
      net/core/skbuff.c
  57. 7 0
      net/ipv6/af_inet6.c
  58. 1 0
      net/key/af_key.c
  59. 2 2
      net/mac80211/mlme.c
  60. 0 1
      net/mac80211/sta_info.h
  61. 4 2
      net/mac80211/tx.c
  62. 3 0
      net/netfilter/nf_conntrack_netlink.c
  63. 13 0
      net/sctp/input.c
  64. 4 3
      net/sctp/output.c
  65. 1 2
      net/sctp/outqueue.c
  66. 117 11
      net/wireless/reg.c
  67. 2 9
      net/xfrm/xfrm_user.c

+ 2 - 1
Documentation/networking/netconsole.txt

@@ -51,7 +51,8 @@ Built-in netconsole starts immediately after the TCP stack is
 initialized and attempts to bring up the supplied dev at the supplied
 initialized and attempts to bring up the supplied dev at the supplied
 address.
 address.
 
 
-The remote host can run either 'netcat -u -l -p <port>' or syslogd.
+The remote host can run either 'netcat -u -l -p <port>',
+'nc -l -u <port>' or syslogd.
 
 
 Dynamic reconfiguration:
 Dynamic reconfiguration:
 ========================
 ========================

+ 2 - 0
drivers/isdn/i4l/isdn_ppp.c

@@ -431,6 +431,7 @@ set_arg(void __user *b, void *val,int len)
 	return 0;
 	return 0;
 }
 }
 
 
+#ifdef CONFIG_IPPP_FILTER
 static int get_filter(void __user *arg, struct sock_filter **p)
 static int get_filter(void __user *arg, struct sock_filter **p)
 {
 {
 	struct sock_fprog uprog;
 	struct sock_fprog uprog;
@@ -465,6 +466,7 @@ static int get_filter(void __user *arg, struct sock_filter **p)
 	*p = code;
 	*p = code;
 	return uprog.len;
 	return uprog.len;
 }
 }
+#endif /* CONFIG_IPPP_FILTER */
 
 
 /*
 /*
  * ippp device ioctl
  * ippp device ioctl

+ 2 - 9
drivers/net/bnx2x.h

@@ -1,6 +1,6 @@
 /* bnx2x.h: Broadcom Everest network driver.
 /* bnx2x.h: Broadcom Everest network driver.
  *
  *
- * Copyright (c) 2007-2008 Broadcom Corporation
+ * Copyright (c) 2007-2009 Broadcom Corporation
  *
  *
  * This program is free software; you can redistribute it and/or modify
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * it under the terms of the GNU General Public License as published by
@@ -271,14 +271,7 @@ struct bnx2x_fastpath {
 
 
 #define bnx2x_fp(bp, nr, var)		(bp->fp[nr].var)
 #define bnx2x_fp(bp, nr, var)		(bp->fp[nr].var)
 
 
-#define BNX2X_HAS_TX_WORK(fp) \
-			((fp->tx_pkt_prod != le16_to_cpu(*fp->tx_cons_sb)) || \
-			 (fp->tx_pkt_prod != fp->tx_pkt_cons))
-
-#define BNX2X_HAS_RX_WORK(fp) \
-			(fp->rx_comp_cons != rx_cons_sb)
-
-#define BNX2X_HAS_WORK(fp)	(BNX2X_HAS_RX_WORK(fp) || BNX2X_HAS_TX_WORK(fp))
+#define BNX2X_HAS_WORK(fp)	(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))
 
 
 
 
 /* MC hsi */
 /* MC hsi */

+ 46 - 18
drivers/net/bnx2x_link.c

@@ -1,4 +1,4 @@
-/* Copyright 2008 Broadcom Corporation
+/* Copyright 2008-2009 Broadcom Corporation
  *
  *
  * Unless you and Broadcom execute a separate written software license
  * Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
  * agreement governing use of this software, this software is licensed to you
@@ -317,6 +317,9 @@ static u8 bnx2x_emac_enable(struct link_params *params,
 		val &= ~0x810;
 		val &= ~0x810;
 	EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
 	EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
 
 
+	/* enable emac */
+	REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
+
 	/* enable emac for jumbo packets */
 	/* enable emac for jumbo packets */
 	EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
 	EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
 		(EMAC_RX_MTU_SIZE_JUMBO_ENA |
 		(EMAC_RX_MTU_SIZE_JUMBO_ENA |
@@ -1609,7 +1612,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
 				      u32 gp_status)
 				      u32 gp_status)
 {
 {
 	struct bnx2x *bp = params->bp;
 	struct bnx2x *bp = params->bp;
-
+	u16 new_line_speed;
 	u8 rc = 0;
 	u8 rc = 0;
 	vars->link_status = 0;
 	vars->link_status = 0;
 
 
@@ -1629,7 +1632,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
 
 
 		switch (gp_status & GP_STATUS_SPEED_MASK) {
 		switch (gp_status & GP_STATUS_SPEED_MASK) {
 		case GP_STATUS_10M:
 		case GP_STATUS_10M:
-			vars->line_speed = SPEED_10;
+			new_line_speed = SPEED_10;
 			if (vars->duplex == DUPLEX_FULL)
 			if (vars->duplex == DUPLEX_FULL)
 				vars->link_status |= LINK_10TFD;
 				vars->link_status |= LINK_10TFD;
 			else
 			else
@@ -1637,7 +1640,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
 			break;
 			break;
 
 
 		case GP_STATUS_100M:
 		case GP_STATUS_100M:
-			vars->line_speed = SPEED_100;
+			new_line_speed = SPEED_100;
 			if (vars->duplex == DUPLEX_FULL)
 			if (vars->duplex == DUPLEX_FULL)
 				vars->link_status |= LINK_100TXFD;
 				vars->link_status |= LINK_100TXFD;
 			else
 			else
@@ -1646,7 +1649,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
 
 
 		case GP_STATUS_1G:
 		case GP_STATUS_1G:
 		case GP_STATUS_1G_KX:
 		case GP_STATUS_1G_KX:
-			vars->line_speed = SPEED_1000;
+			new_line_speed = SPEED_1000;
 			if (vars->duplex == DUPLEX_FULL)
 			if (vars->duplex == DUPLEX_FULL)
 				vars->link_status |= LINK_1000TFD;
 				vars->link_status |= LINK_1000TFD;
 			else
 			else
@@ -1654,7 +1657,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
 			break;
 			break;
 
 
 		case GP_STATUS_2_5G:
 		case GP_STATUS_2_5G:
-			vars->line_speed = SPEED_2500;
+			new_line_speed = SPEED_2500;
 			if (vars->duplex == DUPLEX_FULL)
 			if (vars->duplex == DUPLEX_FULL)
 				vars->link_status |= LINK_2500TFD;
 				vars->link_status |= LINK_2500TFD;
 			else
 			else
@@ -1671,32 +1674,32 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
 		case GP_STATUS_10G_KX4:
 		case GP_STATUS_10G_KX4:
 		case GP_STATUS_10G_HIG:
 		case GP_STATUS_10G_HIG:
 		case GP_STATUS_10G_CX4:
 		case GP_STATUS_10G_CX4:
-			vars->line_speed = SPEED_10000;
+			new_line_speed = SPEED_10000;
 			vars->link_status |= LINK_10GTFD;
 			vars->link_status |= LINK_10GTFD;
 			break;
 			break;
 
 
 		case GP_STATUS_12G_HIG:
 		case GP_STATUS_12G_HIG:
-			vars->line_speed = SPEED_12000;
+			new_line_speed = SPEED_12000;
 			vars->link_status |= LINK_12GTFD;
 			vars->link_status |= LINK_12GTFD;
 			break;
 			break;
 
 
 		case GP_STATUS_12_5G:
 		case GP_STATUS_12_5G:
-			vars->line_speed = SPEED_12500;
+			new_line_speed = SPEED_12500;
 			vars->link_status |= LINK_12_5GTFD;
 			vars->link_status |= LINK_12_5GTFD;
 			break;
 			break;
 
 
 		case GP_STATUS_13G:
 		case GP_STATUS_13G:
-			vars->line_speed = SPEED_13000;
+			new_line_speed = SPEED_13000;
 			vars->link_status |= LINK_13GTFD;
 			vars->link_status |= LINK_13GTFD;
 			break;
 			break;
 
 
 		case GP_STATUS_15G:
 		case GP_STATUS_15G:
-			vars->line_speed = SPEED_15000;
+			new_line_speed = SPEED_15000;
 			vars->link_status |= LINK_15GTFD;
 			vars->link_status |= LINK_15GTFD;
 			break;
 			break;
 
 
 		case GP_STATUS_16G:
 		case GP_STATUS_16G:
-			vars->line_speed = SPEED_16000;
+			new_line_speed = SPEED_16000;
 			vars->link_status |= LINK_16GTFD;
 			vars->link_status |= LINK_16GTFD;
 			break;
 			break;
 
 
@@ -1708,6 +1711,15 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
 			break;
 			break;
 		}
 		}
 
 
+		/* Upon link speed change set the NIG into drain mode.
+		Comes to deals with possible FIFO glitch due to clk change
+		when speed is decreased without link down indicator */
+		if (new_line_speed != vars->line_speed) {
+			REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
+				    + params->port*4, 0);
+			msleep(1);
+		}
+		vars->line_speed = new_line_speed;
 		vars->link_status |= LINK_STATUS_SERDES_LINK;
 		vars->link_status |= LINK_STATUS_SERDES_LINK;
 
 
 		if ((params->req_line_speed == SPEED_AUTO_NEG) &&
 		if ((params->req_line_speed == SPEED_AUTO_NEG) &&
@@ -3571,7 +3583,7 @@ static void bnx2x_set_xgxs_loopback(struct link_params *params,
 			       (MDIO_REG_BANK_CL73_IEEEB0 +
 			       (MDIO_REG_BANK_CL73_IEEEB0 +
 				(MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
 				(MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
 			       0x6041);
 			       0x6041);
-
+		msleep(200);
 		/* set aer mmd back */
 		/* set aer mmd back */
 		bnx2x_set_aer_mmd(params, vars);
 		bnx2x_set_aer_mmd(params, vars);
 
 
@@ -3870,9 +3882,15 @@ static u8 bnx2x_link_initialize(struct link_params *params,
 	}
 	}
 
 
 	if (vars->phy_flags & PHY_XGXS_FLAG) {
 	if (vars->phy_flags & PHY_XGXS_FLAG) {
-		if (params->req_line_speed &&
+		if ((params->req_line_speed &&
 		    ((params->req_line_speed == SPEED_100) ||
 		    ((params->req_line_speed == SPEED_100) ||
-		     (params->req_line_speed == SPEED_10))) {
+		     (params->req_line_speed == SPEED_10))) ||
+		    (!params->req_line_speed &&
+		     (params->speed_cap_mask >=
+		       PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
+		     (params->speed_cap_mask <
+		       PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
+		     ))  {
 			vars->phy_flags |= PHY_SGMII_FLAG;
 			vars->phy_flags |= PHY_SGMII_FLAG;
 		} else {
 		} else {
 			vars->phy_flags &= ~PHY_SGMII_FLAG;
 			vars->phy_flags &= ~PHY_SGMII_FLAG;
@@ -4194,6 +4212,11 @@ static u8 bnx2x_update_link_down(struct link_params *params,
 	/* activate nig drain */
 	/* activate nig drain */
 	REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
 	REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
 
 
+	/* disable emac */
+	REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
+
+	msleep(10);
+
 	/* reset BigMac */
 	/* reset BigMac */
 	bnx2x_bmac_rx_disable(bp, params->port);
 	bnx2x_bmac_rx_disable(bp, params->port);
 	REG_WR(bp, GRCBASE_MISC +
 	REG_WR(bp, GRCBASE_MISC +
@@ -4238,6 +4261,7 @@ static u8 bnx2x_update_link_up(struct link_params *params,
 
 
 	/* update shared memory */
 	/* update shared memory */
 	bnx2x_update_mng(params, vars->link_status);
 	bnx2x_update_mng(params, vars->link_status);
+	msleep(20);
 	return rc;
 	return rc;
 }
 }
 /* This function should called upon link interrupt */
 /* This function should called upon link interrupt */
@@ -4276,6 +4300,9 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
 	  REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
 	  REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
 	  REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
 	  REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
 
 
+	/* disable emac */
+	REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
+
 	ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
 	ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
 
 
 	/* Check external link change only for non-direct */
 	/* Check external link change only for non-direct */
@@ -4377,10 +4404,11 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
 			      ext_phy_addr[port],
 			      ext_phy_addr[port],
 			      MDIO_PMA_DEVAD,
 			      MDIO_PMA_DEVAD,
 			      MDIO_PMA_REG_ROM_VER1, &fw_ver1);
 			      MDIO_PMA_REG_ROM_VER1, &fw_ver1);
-		if (fw_ver1 == 0) {
+		if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
 			DP(NETIF_MSG_LINK,
 			DP(NETIF_MSG_LINK,
-				 "bnx2x_8073_common_init_phy port %x "
-				 "fw Download failed\n", port);
+				 "bnx2x_8073_common_init_phy port %x:"
+				 "Download failed. fw version = 0x%x\n",
+				 port, fw_ver1);
 			return -EINVAL;
 			return -EINVAL;
 		}
 		}
 
 

+ 183 - 119
drivers/net/bnx2x_main.c

@@ -1,6 +1,6 @@
 /* bnx2x_main.c: Broadcom Everest network driver.
 /* bnx2x_main.c: Broadcom Everest network driver.
  *
  *
- * Copyright (c) 2007-2008 Broadcom Corporation
+ * Copyright (c) 2007-2009 Broadcom Corporation
  *
  *
  * This program is free software; you can redistribute it and/or modify
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * it under the terms of the GNU General Public License as published by
@@ -57,8 +57,8 @@
 #include "bnx2x.h"
 #include "bnx2x.h"
 #include "bnx2x_init.h"
 #include "bnx2x_init.h"
 
 
-#define DRV_MODULE_VERSION	"1.45.23"
-#define DRV_MODULE_RELDATE	"2008/11/03"
+#define DRV_MODULE_VERSION	"1.45.26"
+#define DRV_MODULE_RELDATE	"2009/01/26"
 #define BNX2X_BC_VER		0x040200
 #define BNX2X_BC_VER		0x040200
 
 
 /* Time in jiffies before concluding the transmitter is hung */
 /* Time in jiffies before concluding the transmitter is hung */
@@ -69,7 +69,7 @@ static char version[] __devinitdata =
 	DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
 	DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
 
 
 MODULE_AUTHOR("Eliezer Tamir");
 MODULE_AUTHOR("Eliezer Tamir");
-MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710 Driver");
+MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710/57711/57711E Driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_MODULE_VERSION);
 MODULE_VERSION(DRV_MODULE_VERSION);
 
 
@@ -733,6 +733,24 @@ static u16 bnx2x_ack_int(struct bnx2x *bp)
  * fast path service functions
  * fast path service functions
  */
  */
 
 
+static inline int bnx2x_has_tx_work(struct bnx2x_fastpath *fp)
+{
+	u16 tx_cons_sb;
+
+	/* Tell compiler that status block fields can change */
+	barrier();
+	tx_cons_sb = le16_to_cpu(*fp->tx_cons_sb);
+	return (fp->tx_pkt_cons != tx_cons_sb);
+}
+
+static inline int bnx2x_has_tx_work_unload(struct bnx2x_fastpath *fp)
+{
+	/* Tell compiler that consumer and producer can change */
+	barrier();
+	return (fp->tx_pkt_prod != fp->tx_pkt_cons);
+
+}
+
 /* free skb in the packet ring at pos idx
 /* free skb in the packet ring at pos idx
  * return idx of last bd freed
  * return idx of last bd freed
  */
  */
@@ -5137,12 +5155,21 @@ static void enable_blocks_attention(struct bnx2x *bp)
 }
 }
 
 
 
 
+static void bnx2x_reset_common(struct bnx2x *bp)
+{
+	/* reset_common */
+	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR,
+	       0xd3ffff7f);
+	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, 0x1403);
+}
+
 static int bnx2x_init_common(struct bnx2x *bp)
 static int bnx2x_init_common(struct bnx2x *bp)
 {
 {
 	u32 val, i;
 	u32 val, i;
 
 
 	DP(BNX2X_MSG_MCP, "starting common init  func %d\n", BP_FUNC(bp));
 	DP(BNX2X_MSG_MCP, "starting common init  func %d\n", BP_FUNC(bp));
 
 
+	bnx2x_reset_common(bp);
 	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0xffffffff);
 	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0xffffffff);
 	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, 0xfffc);
 	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, 0xfffc);
 
 
@@ -6123,8 +6150,8 @@ static void bnx2x_netif_start(struct bnx2x *bp)
 static void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw)
 static void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw)
 {
 {
 	bnx2x_int_disable_sync(bp, disable_hw);
 	bnx2x_int_disable_sync(bp, disable_hw);
+	bnx2x_napi_disable(bp);
 	if (netif_running(bp->dev)) {
 	if (netif_running(bp->dev)) {
-		bnx2x_napi_disable(bp);
 		netif_tx_disable(bp->dev);
 		netif_tx_disable(bp->dev);
 		bp->dev->trans_start = jiffies;	/* prevent tx timeout */
 		bp->dev->trans_start = jiffies;	/* prevent tx timeout */
 	}
 	}
@@ -6144,7 +6171,7 @@ static void bnx2x_set_mac_addr_e1(struct bnx2x *bp, int set)
 	 * multicast 64-127:port0 128-191:port1
 	 * multicast 64-127:port0 128-191:port1
 	 */
 	 */
 	config->hdr.length_6b = 2;
 	config->hdr.length_6b = 2;
-	config->hdr.offset = port ? 31 : 0;
+	config->hdr.offset = port ? 32 : 0;
 	config->hdr.client_id = BP_CL_ID(bp);
 	config->hdr.client_id = BP_CL_ID(bp);
 	config->hdr.reserved1 = 0;
 	config->hdr.reserved1 = 0;
 
 
@@ -6308,7 +6335,7 @@ static void bnx2x_set_rx_mode(struct net_device *dev);
 static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
 static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
 {
 {
 	u32 load_code;
 	u32 load_code;
-	int i, rc;
+	int i, rc = 0;
 #ifdef BNX2X_STOP_ON_ERROR
 #ifdef BNX2X_STOP_ON_ERROR
 	if (unlikely(bp->panic))
 	if (unlikely(bp->panic))
 		return -EPERM;
 		return -EPERM;
@@ -6316,48 +6343,6 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
 
 
 	bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD;
 	bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD;
 
 
-	/* Send LOAD_REQUEST command to MCP
-	   Returns the type of LOAD command:
-	   if it is the first port to be initialized
-	   common blocks should be initialized, otherwise - not
-	*/
-	if (!BP_NOMCP(bp)) {
-		load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ);
-		if (!load_code) {
-			BNX2X_ERR("MCP response failure, aborting\n");
-			return -EBUSY;
-		}
-		if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED)
-			return -EBUSY; /* other port in diagnostic mode */
-
-	} else {
-		int port = BP_PORT(bp);
-
-		DP(NETIF_MSG_IFUP, "NO MCP load counts before us %d, %d, %d\n",
-		   load_count[0], load_count[1], load_count[2]);
-		load_count[0]++;
-		load_count[1 + port]++;
-		DP(NETIF_MSG_IFUP, "NO MCP new load counts       %d, %d, %d\n",
-		   load_count[0], load_count[1], load_count[2]);
-		if (load_count[0] == 1)
-			load_code = FW_MSG_CODE_DRV_LOAD_COMMON;
-		else if (load_count[1 + port] == 1)
-			load_code = FW_MSG_CODE_DRV_LOAD_PORT;
-		else
-			load_code = FW_MSG_CODE_DRV_LOAD_FUNCTION;
-	}
-
-	if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) ||
-	    (load_code == FW_MSG_CODE_DRV_LOAD_PORT))
-		bp->port.pmf = 1;
-	else
-		bp->port.pmf = 0;
-	DP(NETIF_MSG_LINK, "pmf %d\n", bp->port.pmf);
-
-	/* if we can't use MSI-X we only need one fp,
-	 * so try to enable MSI-X with the requested number of fp's
-	 * and fallback to inta with one fp
-	 */
 	if (use_inta) {
 	if (use_inta) {
 		bp->num_queues = 1;
 		bp->num_queues = 1;
 
 
@@ -6372,7 +6357,15 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
 		else
 		else
 			bp->num_queues = 1;
 			bp->num_queues = 1;
 
 
-		if (bnx2x_enable_msix(bp)) {
+		DP(NETIF_MSG_IFUP,
+		   "set number of queues to %d\n", bp->num_queues);
+
+		/* if we can't use MSI-X we only need one fp,
+		 * so try to enable MSI-X with the requested number of fp's
+		 * and fallback to MSI or legacy INTx with one fp
+		 */
+		rc = bnx2x_enable_msix(bp);
+		if (rc) {
 			/* failed to enable MSI-X */
 			/* failed to enable MSI-X */
 			bp->num_queues = 1;
 			bp->num_queues = 1;
 			if (use_multi)
 			if (use_multi)
@@ -6380,8 +6373,6 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
 					  " to enable MSI-X\n");
 					  " to enable MSI-X\n");
 		}
 		}
 	}
 	}
-	DP(NETIF_MSG_IFUP,
-	   "set number of queues to %d\n", bp->num_queues);
 
 
 	if (bnx2x_alloc_mem(bp))
 	if (bnx2x_alloc_mem(bp))
 		return -ENOMEM;
 		return -ENOMEM;
@@ -6390,30 +6381,85 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
 		bnx2x_fp(bp, i, disable_tpa) =
 		bnx2x_fp(bp, i, disable_tpa) =
 					((bp->flags & TPA_ENABLE_FLAG) == 0);
 					((bp->flags & TPA_ENABLE_FLAG) == 0);
 
 
+	for_each_queue(bp, i)
+		netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
+			       bnx2x_poll, 128);
+
+#ifdef BNX2X_STOP_ON_ERROR
+	for_each_queue(bp, i) {
+		struct bnx2x_fastpath *fp = &bp->fp[i];
+
+		fp->poll_no_work = 0;
+		fp->poll_calls = 0;
+		fp->poll_max_calls = 0;
+		fp->poll_complete = 0;
+		fp->poll_exit = 0;
+	}
+#endif
+	bnx2x_napi_enable(bp);
+
 	if (bp->flags & USING_MSIX_FLAG) {
 	if (bp->flags & USING_MSIX_FLAG) {
 		rc = bnx2x_req_msix_irqs(bp);
 		rc = bnx2x_req_msix_irqs(bp);
 		if (rc) {
 		if (rc) {
 			pci_disable_msix(bp->pdev);
 			pci_disable_msix(bp->pdev);
-			goto load_error;
+			goto load_error1;
 		}
 		}
+		printk(KERN_INFO PFX "%s: using MSI-X\n", bp->dev->name);
 	} else {
 	} else {
 		bnx2x_ack_int(bp);
 		bnx2x_ack_int(bp);
 		rc = bnx2x_req_irq(bp);
 		rc = bnx2x_req_irq(bp);
 		if (rc) {
 		if (rc) {
-			BNX2X_ERR("IRQ request failed, aborting\n");
-			goto load_error;
+			BNX2X_ERR("IRQ request failed  rc %d, aborting\n", rc);
+			goto load_error1;
 		}
 		}
 	}
 	}
 
 
-	for_each_queue(bp, i)
-		netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
-			       bnx2x_poll, 128);
+	/* Send LOAD_REQUEST command to MCP
+	   Returns the type of LOAD command:
+	   if it is the first port to be initialized
+	   common blocks should be initialized, otherwise - not
+	*/
+	if (!BP_NOMCP(bp)) {
+		load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ);
+		if (!load_code) {
+			BNX2X_ERR("MCP response failure, aborting\n");
+			rc = -EBUSY;
+			goto load_error2;
+		}
+		if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED) {
+			rc = -EBUSY; /* other port in diagnostic mode */
+			goto load_error2;
+		}
+
+	} else {
+		int port = BP_PORT(bp);
+
+		DP(NETIF_MSG_IFUP, "NO MCP load counts before us %d, %d, %d\n",
+		   load_count[0], load_count[1], load_count[2]);
+		load_count[0]++;
+		load_count[1 + port]++;
+		DP(NETIF_MSG_IFUP, "NO MCP new load counts       %d, %d, %d\n",
+		   load_count[0], load_count[1], load_count[2]);
+		if (load_count[0] == 1)
+			load_code = FW_MSG_CODE_DRV_LOAD_COMMON;
+		else if (load_count[1 + port] == 1)
+			load_code = FW_MSG_CODE_DRV_LOAD_PORT;
+		else
+			load_code = FW_MSG_CODE_DRV_LOAD_FUNCTION;
+	}
+
+	if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) ||
+	    (load_code == FW_MSG_CODE_DRV_LOAD_PORT))
+		bp->port.pmf = 1;
+	else
+		bp->port.pmf = 0;
+	DP(NETIF_MSG_LINK, "pmf %d\n", bp->port.pmf);
 
 
 	/* Initialize HW */
 	/* Initialize HW */
 	rc = bnx2x_init_hw(bp, load_code);
 	rc = bnx2x_init_hw(bp, load_code);
 	if (rc) {
 	if (rc) {
 		BNX2X_ERR("HW init failed, aborting\n");
 		BNX2X_ERR("HW init failed, aborting\n");
-		goto load_int_disable;
+		goto load_error2;
 	}
 	}
 
 
 	/* Setup NIC internals and enable interrupts */
 	/* Setup NIC internals and enable interrupts */
@@ -6425,7 +6471,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
 		if (!load_code) {
 		if (!load_code) {
 			BNX2X_ERR("MCP response failure, aborting\n");
 			BNX2X_ERR("MCP response failure, aborting\n");
 			rc = -EBUSY;
 			rc = -EBUSY;
-			goto load_rings_free;
+			goto load_error3;
 		}
 		}
 	}
 	}
 
 
@@ -6434,7 +6480,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
 	rc = bnx2x_setup_leading(bp);
 	rc = bnx2x_setup_leading(bp);
 	if (rc) {
 	if (rc) {
 		BNX2X_ERR("Setup leading failed!\n");
 		BNX2X_ERR("Setup leading failed!\n");
-		goto load_netif_stop;
+		goto load_error3;
 	}
 	}
 
 
 	if (CHIP_IS_E1H(bp))
 	if (CHIP_IS_E1H(bp))
@@ -6447,7 +6493,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
 		for_each_nondefault_queue(bp, i) {
 		for_each_nondefault_queue(bp, i) {
 			rc = bnx2x_setup_multi(bp, i);
 			rc = bnx2x_setup_multi(bp, i);
 			if (rc)
 			if (rc)
-				goto load_netif_stop;
+				goto load_error3;
 		}
 		}
 
 
 	if (CHIP_IS_E1(bp))
 	if (CHIP_IS_E1(bp))
@@ -6463,18 +6509,18 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
 	case LOAD_NORMAL:
 	case LOAD_NORMAL:
 		/* Tx queue should be only reenabled */
 		/* Tx queue should be only reenabled */
 		netif_wake_queue(bp->dev);
 		netif_wake_queue(bp->dev);
+		/* Initialize the receive filter. */
 		bnx2x_set_rx_mode(bp->dev);
 		bnx2x_set_rx_mode(bp->dev);
 		break;
 		break;
 
 
 	case LOAD_OPEN:
 	case LOAD_OPEN:
 		netif_start_queue(bp->dev);
 		netif_start_queue(bp->dev);
+		/* Initialize the receive filter. */
 		bnx2x_set_rx_mode(bp->dev);
 		bnx2x_set_rx_mode(bp->dev);
-		if (bp->flags & USING_MSIX_FLAG)
-			printk(KERN_INFO PFX "%s: using MSI-X\n",
-			       bp->dev->name);
 		break;
 		break;
 
 
 	case LOAD_DIAG:
 	case LOAD_DIAG:
+		/* Initialize the receive filter. */
 		bnx2x_set_rx_mode(bp->dev);
 		bnx2x_set_rx_mode(bp->dev);
 		bp->state = BNX2X_STATE_DIAG;
 		bp->state = BNX2X_STATE_DIAG;
 		break;
 		break;
@@ -6492,20 +6538,25 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
 
 
 	return 0;
 	return 0;
 
 
-load_netif_stop:
-	bnx2x_napi_disable(bp);
-load_rings_free:
+load_error3:
+	bnx2x_int_disable_sync(bp, 1);
+	if (!BP_NOMCP(bp)) {
+		bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP);
+		bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
+	}
+	bp->port.pmf = 0;
 	/* Free SKBs, SGEs, TPA pool and driver internals */
 	/* Free SKBs, SGEs, TPA pool and driver internals */
 	bnx2x_free_skbs(bp);
 	bnx2x_free_skbs(bp);
 	for_each_queue(bp, i)
 	for_each_queue(bp, i)
 		bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
 		bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
-load_int_disable:
-	bnx2x_int_disable_sync(bp, 1);
+load_error2:
 	/* Release IRQs */
 	/* Release IRQs */
 	bnx2x_free_irq(bp);
 	bnx2x_free_irq(bp);
-load_error:
+load_error1:
+	bnx2x_napi_disable(bp);
+	for_each_queue(bp, i)
+		netif_napi_del(&bnx2x_fp(bp, i, napi));
 	bnx2x_free_mem(bp);
 	bnx2x_free_mem(bp);
-	bp->port.pmf = 0;
 
 
 	/* TBD we really need to reset the chip
 	/* TBD we really need to reset the chip
 	   if we want to recover from this */
 	   if we want to recover from this */
@@ -6578,6 +6629,7 @@ static int bnx2x_stop_leading(struct bnx2x *bp)
 		}
 		}
 		cnt--;
 		cnt--;
 		msleep(1);
 		msleep(1);
+		rmb(); /* Refresh the dsb_sp_prod */
 	}
 	}
 	bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD;
 	bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD;
 	bp->fp[0].state = BNX2X_FP_STATE_CLOSED;
 	bp->fp[0].state = BNX2X_FP_STATE_CLOSED;
@@ -6629,14 +6681,6 @@ static void bnx2x_reset_port(struct bnx2x *bp)
 	/* TODO: Close Doorbell port? */
 	/* TODO: Close Doorbell port? */
 }
 }
 
 
-static void bnx2x_reset_common(struct bnx2x *bp)
-{
-	/* reset_common */
-	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR,
-	       0xd3ffff7f);
-	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, 0x1403);
-}
-
 static void bnx2x_reset_chip(struct bnx2x *bp, u32 reset_code)
 static void bnx2x_reset_chip(struct bnx2x *bp, u32 reset_code)
 {
 {
 	DP(BNX2X_MSG_MCP, "function %d  reset_code %x\n",
 	DP(BNX2X_MSG_MCP, "function %d  reset_code %x\n",
@@ -6677,20 +6721,22 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
 	bnx2x_set_storm_rx_mode(bp);
 	bnx2x_set_storm_rx_mode(bp);
 
 
 	bnx2x_netif_stop(bp, 1);
 	bnx2x_netif_stop(bp, 1);
-	if (!netif_running(bp->dev))
-		bnx2x_napi_disable(bp);
+
 	del_timer_sync(&bp->timer);
 	del_timer_sync(&bp->timer);
 	SHMEM_WR(bp, func_mb[BP_FUNC(bp)].drv_pulse_mb,
 	SHMEM_WR(bp, func_mb[BP_FUNC(bp)].drv_pulse_mb,
 		 (DRV_PULSE_ALWAYS_ALIVE | bp->fw_drv_pulse_wr_seq));
 		 (DRV_PULSE_ALWAYS_ALIVE | bp->fw_drv_pulse_wr_seq));
 	bnx2x_stats_handle(bp, STATS_EVENT_STOP);
 	bnx2x_stats_handle(bp, STATS_EVENT_STOP);
 
 
+	/* Release IRQs */
+	bnx2x_free_irq(bp);
+
 	/* Wait until tx fast path tasks complete */
 	/* Wait until tx fast path tasks complete */
 	for_each_queue(bp, i) {
 	for_each_queue(bp, i) {
 		struct bnx2x_fastpath *fp = &bp->fp[i];
 		struct bnx2x_fastpath *fp = &bp->fp[i];
 
 
 		cnt = 1000;
 		cnt = 1000;
 		smp_rmb();
 		smp_rmb();
-		while (BNX2X_HAS_TX_WORK(fp)) {
+		while (bnx2x_has_tx_work_unload(fp)) {
 
 
 			bnx2x_tx_int(fp, 1000);
 			bnx2x_tx_int(fp, 1000);
 			if (!cnt) {
 			if (!cnt) {
@@ -6711,9 +6757,6 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
 	/* Give HW time to discard old tx messages */
 	/* Give HW time to discard old tx messages */
 	msleep(1);
 	msleep(1);
 
 
-	/* Release IRQs */
-	bnx2x_free_irq(bp);
-
 	if (CHIP_IS_E1(bp)) {
 	if (CHIP_IS_E1(bp)) {
 		struct mac_configuration_cmd *config =
 		struct mac_configuration_cmd *config =
 						bnx2x_sp(bp, mcast_config);
 						bnx2x_sp(bp, mcast_config);
@@ -6822,6 +6865,8 @@ unload_error:
 	bnx2x_free_skbs(bp);
 	bnx2x_free_skbs(bp);
 	for_each_queue(bp, i)
 	for_each_queue(bp, i)
 		bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
 		bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
+	for_each_queue(bp, i)
+		netif_napi_del(&bnx2x_fp(bp, i, napi));
 	bnx2x_free_mem(bp);
 	bnx2x_free_mem(bp);
 
 
 	bp->state = BNX2X_STATE_CLOSED;
 	bp->state = BNX2X_STATE_CLOSED;
@@ -6874,10 +6919,6 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
 		 */
 		 */
 		bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_UNDI);
 		bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_UNDI);
 		val = REG_RD(bp, DORQ_REG_NORM_CID_OFST);
 		val = REG_RD(bp, DORQ_REG_NORM_CID_OFST);
-		if (val == 0x7)
-			REG_WR(bp, DORQ_REG_NORM_CID_OFST, 0);
-		bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI);
-
 		if (val == 0x7) {
 		if (val == 0x7) {
 			u32 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;
 			u32 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;
 			/* save our func */
 			/* save our func */
@@ -6885,6 +6926,9 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
 			u32 swap_en;
 			u32 swap_en;
 			u32 swap_val;
 			u32 swap_val;
 
 
+			/* clear the UNDI indication */
+			REG_WR(bp, DORQ_REG_NORM_CID_OFST, 0);
+
 			BNX2X_DEV_INFO("UNDI is active! reset device\n");
 			BNX2X_DEV_INFO("UNDI is active! reset device\n");
 
 
 			/* try unload UNDI on port 0 */
 			/* try unload UNDI on port 0 */
@@ -6910,6 +6954,9 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
 				bnx2x_fw_command(bp, reset_code);
 				bnx2x_fw_command(bp, reset_code);
 			}
 			}
 
 
+			/* now it's safe to release the lock */
+			bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI);
+
 			REG_WR(bp, (BP_PORT(bp) ? HC_REG_CONFIG_1 :
 			REG_WR(bp, (BP_PORT(bp) ? HC_REG_CONFIG_1 :
 				    HC_REG_CONFIG_0), 0x1000);
 				    HC_REG_CONFIG_0), 0x1000);
 
 
@@ -6954,7 +7001,9 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
 			bp->fw_seq =
 			bp->fw_seq =
 			       (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) &
 			       (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) &
 				DRV_MSG_SEQ_NUMBER_MASK);
 				DRV_MSG_SEQ_NUMBER_MASK);
-		}
+
+		} else
+			bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI);
 	}
 	}
 }
 }
 
 
@@ -6971,7 +7020,7 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
 	id |= ((val & 0xf) << 12);
 	id |= ((val & 0xf) << 12);
 	val = REG_RD(bp, MISC_REG_CHIP_METAL);
 	val = REG_RD(bp, MISC_REG_CHIP_METAL);
 	id |= ((val & 0xff) << 4);
 	id |= ((val & 0xff) << 4);
-	REG_RD(bp, MISC_REG_BOND_ID);
+	val = REG_RD(bp, MISC_REG_BOND_ID);
 	id |= (val & 0xf);
 	id |= (val & 0xf);
 	bp->common.chip_id = id;
 	bp->common.chip_id = id;
 	bp->link_params.chip_id = bp->common.chip_id;
 	bp->link_params.chip_id = bp->common.chip_id;
@@ -8103,6 +8152,9 @@ static int bnx2x_get_eeprom(struct net_device *dev,
 	struct bnx2x *bp = netdev_priv(dev);
 	struct bnx2x *bp = netdev_priv(dev);
 	int rc;
 	int rc;
 
 
+	if (!netif_running(dev))
+		return -EAGAIN;
+
 	DP(BNX2X_MSG_NVM, "ethtool_eeprom: cmd %d\n"
 	DP(BNX2X_MSG_NVM, "ethtool_eeprom: cmd %d\n"
 	   DP_LEVEL "  magic 0x%x  offset 0x%x (%d)  len 0x%x (%d)\n",
 	   DP_LEVEL "  magic 0x%x  offset 0x%x (%d)  len 0x%x (%d)\n",
 	   eeprom->cmd, eeprom->magic, eeprom->offset, eeprom->offset,
 	   eeprom->cmd, eeprom->magic, eeprom->offset, eeprom->offset,
@@ -8705,18 +8757,17 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
 
 
 	if (loopback_mode == BNX2X_MAC_LOOPBACK) {
 	if (loopback_mode == BNX2X_MAC_LOOPBACK) {
 		bp->link_params.loopback_mode = LOOPBACK_BMAC;
 		bp->link_params.loopback_mode = LOOPBACK_BMAC;
-		bnx2x_acquire_phy_lock(bp);
 		bnx2x_phy_init(&bp->link_params, &bp->link_vars);
 		bnx2x_phy_init(&bp->link_params, &bp->link_vars);
-		bnx2x_release_phy_lock(bp);
 
 
 	} else if (loopback_mode == BNX2X_PHY_LOOPBACK) {
 	} else if (loopback_mode == BNX2X_PHY_LOOPBACK) {
+		u16 cnt = 1000;
 		bp->link_params.loopback_mode = LOOPBACK_XGXS_10;
 		bp->link_params.loopback_mode = LOOPBACK_XGXS_10;
-		bnx2x_acquire_phy_lock(bp);
 		bnx2x_phy_init(&bp->link_params, &bp->link_vars);
 		bnx2x_phy_init(&bp->link_params, &bp->link_vars);
-		bnx2x_release_phy_lock(bp);
 		/* wait until link state is restored */
 		/* wait until link state is restored */
-		bnx2x_wait_for_link(bp, link_up);
-
+		if (link_up)
+			while (cnt-- && bnx2x_test_link(&bp->link_params,
+							&bp->link_vars))
+				msleep(10);
 	} else
 	} else
 		return -EINVAL;
 		return -EINVAL;
 
 
@@ -8822,6 +8873,7 @@ static int bnx2x_test_loopback(struct bnx2x *bp, u8 link_up)
 		return BNX2X_LOOPBACK_FAILED;
 		return BNX2X_LOOPBACK_FAILED;
 
 
 	bnx2x_netif_stop(bp, 1);
 	bnx2x_netif_stop(bp, 1);
+	bnx2x_acquire_phy_lock(bp);
 
 
 	if (bnx2x_run_loopback(bp, BNX2X_MAC_LOOPBACK, link_up)) {
 	if (bnx2x_run_loopback(bp, BNX2X_MAC_LOOPBACK, link_up)) {
 		DP(NETIF_MSG_PROBE, "MAC loopback failed\n");
 		DP(NETIF_MSG_PROBE, "MAC loopback failed\n");
@@ -8833,6 +8885,7 @@ static int bnx2x_test_loopback(struct bnx2x *bp, u8 link_up)
 		rc |= BNX2X_PHY_LOOPBACK_FAILED;
 		rc |= BNX2X_PHY_LOOPBACK_FAILED;
 	}
 	}
 
 
+	bnx2x_release_phy_lock(bp);
 	bnx2x_netif_start(bp);
 	bnx2x_netif_start(bp);
 
 
 	return rc;
 	return rc;
@@ -8906,7 +8959,10 @@ static int bnx2x_test_intr(struct bnx2x *bp)
 		return -ENODEV;
 		return -ENODEV;
 
 
 	config->hdr.length_6b = 0;
 	config->hdr.length_6b = 0;
-	config->hdr.offset = 0;
+	if (CHIP_IS_E1(bp))
+		config->hdr.offset = (BP_PORT(bp) ? 32 : 0);
+	else
+		config->hdr.offset = BP_FUNC(bp);
 	config->hdr.client_id = BP_CL_ID(bp);
 	config->hdr.client_id = BP_CL_ID(bp);
 	config->hdr.reserved1 = 0;
 	config->hdr.reserved1 = 0;
 
 
@@ -9271,6 +9327,18 @@ static int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state)
 	return 0;
 	return 0;
 }
 }
 
 
+static inline int bnx2x_has_rx_work(struct bnx2x_fastpath *fp)
+{
+	u16 rx_cons_sb;
+
+	/* Tell compiler that status block fields can change */
+	barrier();
+	rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb);
+	if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
+		rx_cons_sb++;
+	return (fp->rx_comp_cons != rx_cons_sb);
+}
+
 /*
 /*
  * net_device service functions
  * net_device service functions
  */
  */
@@ -9281,7 +9349,6 @@ static int bnx2x_poll(struct napi_struct *napi, int budget)
 						 napi);
 						 napi);
 	struct bnx2x *bp = fp->bp;
 	struct bnx2x *bp = fp->bp;
 	int work_done = 0;
 	int work_done = 0;
-	u16 rx_cons_sb;
 
 
 #ifdef BNX2X_STOP_ON_ERROR
 #ifdef BNX2X_STOP_ON_ERROR
 	if (unlikely(bp->panic))
 	if (unlikely(bp->panic))
@@ -9294,19 +9361,12 @@ static int bnx2x_poll(struct napi_struct *napi, int budget)
 
 
 	bnx2x_update_fpsb_idx(fp);
 	bnx2x_update_fpsb_idx(fp);
 
 
-	if (BNX2X_HAS_TX_WORK(fp))
+	if (bnx2x_has_tx_work(fp))
 		bnx2x_tx_int(fp, budget);
 		bnx2x_tx_int(fp, budget);
 
 
-	rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb);
-	if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
-		rx_cons_sb++;
-	if (BNX2X_HAS_RX_WORK(fp))
+	if (bnx2x_has_rx_work(fp))
 		work_done = bnx2x_rx_int(fp, budget);
 		work_done = bnx2x_rx_int(fp, budget);
-
 	rmb(); /* BNX2X_HAS_WORK() reads the status block */
 	rmb(); /* BNX2X_HAS_WORK() reads the status block */
-	rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb);
-	if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
-		rx_cons_sb++;
 
 
 	/* must not complete if we consumed full budget */
 	/* must not complete if we consumed full budget */
 	if ((work_done < budget) && !BNX2X_HAS_WORK(fp)) {
 	if ((work_done < budget) && !BNX2X_HAS_WORK(fp)) {
@@ -9417,6 +9477,7 @@ static inline u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb)
 	return rc;
 	return rc;
 }
 }
 
 
+#if (MAX_SKB_FRAGS >= MAX_FETCH_BD - 3)
 /* check if packet requires linearization (packet is too fragmented) */
 /* check if packet requires linearization (packet is too fragmented) */
 static int bnx2x_pkt_req_lin(struct bnx2x *bp, struct sk_buff *skb,
 static int bnx2x_pkt_req_lin(struct bnx2x *bp, struct sk_buff *skb,
 			     u32 xmit_type)
 			     u32 xmit_type)
@@ -9494,6 +9555,7 @@ exit_lbl:
 
 
 	return to_copy;
 	return to_copy;
 }
 }
+#endif
 
 
 /* called with netif_tx_lock
 /* called with netif_tx_lock
  * bnx2x_tx_int() runs without netif_tx_lock unless it needs to call
  * bnx2x_tx_int() runs without netif_tx_lock unless it needs to call
@@ -9534,6 +9596,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	   skb->ip_summed, skb->protocol, ipv6_hdr(skb)->nexthdr,
 	   skb->ip_summed, skb->protocol, ipv6_hdr(skb)->nexthdr,
 	   ip_hdr(skb)->protocol, skb_shinfo(skb)->gso_type, xmit_type);
 	   ip_hdr(skb)->protocol, skb_shinfo(skb)->gso_type, xmit_type);
 
 
+#if (MAX_SKB_FRAGS >= MAX_FETCH_BD - 3)
 	/* First, check if we need to linearize the skb
 	/* First, check if we need to linearize the skb
 	   (due to FW restrictions) */
 	   (due to FW restrictions) */
 	if (bnx2x_pkt_req_lin(bp, skb, xmit_type)) {
 	if (bnx2x_pkt_req_lin(bp, skb, xmit_type)) {
@@ -9546,6 +9609,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
 			return NETDEV_TX_OK;
 			return NETDEV_TX_OK;
 		}
 		}
 	}
 	}
+#endif
 
 
 	/*
 	/*
 	Please read carefully. First we use one BD which we mark as start,
 	Please read carefully. First we use one BD which we mark as start,
@@ -9776,6 +9840,8 @@ static int bnx2x_open(struct net_device *dev)
 {
 {
 	struct bnx2x *bp = netdev_priv(dev);
 	struct bnx2x *bp = netdev_priv(dev);
 
 
+	netif_carrier_off(dev);
+
 	bnx2x_set_power_state(bp, PCI_D0);
 	bnx2x_set_power_state(bp, PCI_D0);
 
 
 	return bnx2x_nic_load(bp, LOAD_OPEN);
 	return bnx2x_nic_load(bp, LOAD_OPEN);
@@ -9859,7 +9925,7 @@ static void bnx2x_set_rx_mode(struct net_device *dev)
 				for (; i < old; i++) {
 				for (; i < old; i++) {
 					if (CAM_IS_INVALID(config->
 					if (CAM_IS_INVALID(config->
 							   config_table[i])) {
 							   config_table[i])) {
-						i--; /* already invalidated */
+						/* already invalidated */
 						break;
 						break;
 					}
 					}
 					/* invalidate */
 					/* invalidate */
@@ -10269,22 +10335,18 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
 		return rc;
 		return rc;
 	}
 	}
 
 
-	rc = register_netdev(dev);
-	if (rc) {
-		dev_err(&pdev->dev, "Cannot register net device\n");
-		goto init_one_exit;
-	}
-
 	pci_set_drvdata(pdev, dev);
 	pci_set_drvdata(pdev, dev);
 
 
 	rc = bnx2x_init_bp(bp);
 	rc = bnx2x_init_bp(bp);
+	if (rc)
+		goto init_one_exit;
+
+	rc = register_netdev(dev);
 	if (rc) {
 	if (rc) {
-		unregister_netdev(dev);
+		dev_err(&pdev->dev, "Cannot register net device\n");
 		goto init_one_exit;
 		goto init_one_exit;
 	}
 	}
 
 
-	netif_carrier_off(dev);
-
 	bp->common.name = board_info[ent->driver_data].name;
 	bp->common.name = board_info[ent->driver_data].name;
 	printk(KERN_INFO "%s: %s (%c%d) PCI-E x%d %s found at mem %lx,"
 	printk(KERN_INFO "%s: %s (%c%d) PCI-E x%d %s found at mem %lx,"
 	       " IRQ %d, ", dev->name, bp->common.name,
 	       " IRQ %d, ", dev->name, bp->common.name,
@@ -10432,6 +10494,8 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp)
 	bnx2x_free_skbs(bp);
 	bnx2x_free_skbs(bp);
 	for_each_queue(bp, i)
 	for_each_queue(bp, i)
 		bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
 		bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
+	for_each_queue(bp, i)
+		netif_napi_del(&bnx2x_fp(bp, i, napi));
 	bnx2x_free_mem(bp);
 	bnx2x_free_mem(bp);
 
 
 	bp->state = BNX2X_STATE_CLOSED;
 	bp->state = BNX2X_STATE_CLOSED;

+ 1 - 1
drivers/net/bnx2x_reg.h

@@ -1,6 +1,6 @@
 /* bnx2x_reg.h: Broadcom Everest network driver.
 /* bnx2x_reg.h: Broadcom Everest network driver.
  *
  *
- * Copyright (c) 2007-2008 Broadcom Corporation
+ * Copyright (c) 2007-2009 Broadcom Corporation
  *
  *
  * This program is free software; you can redistribute it and/or modify
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * it under the terms of the GNU General Public License as published by

+ 1 - 0
drivers/net/cxgb3/sge.c

@@ -2104,6 +2104,7 @@ static void init_lro_mgr(struct sge_qset *qs, struct net_lro_mgr *lro_mgr)
 {
 {
 	lro_mgr->dev = qs->netdev;
 	lro_mgr->dev = qs->netdev;
 	lro_mgr->features = LRO_F_NAPI;
 	lro_mgr->features = LRO_F_NAPI;
+	lro_mgr->frag_align_pad = NET_IP_ALIGN;
 	lro_mgr->ip_summed = CHECKSUM_UNNECESSARY;
 	lro_mgr->ip_summed = CHECKSUM_UNNECESSARY;
 	lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY;
 	lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY;
 	lro_mgr->max_desc = T3_MAX_LRO_SES;
 	lro_mgr->max_desc = T3_MAX_LRO_SES;

+ 5 - 1
drivers/net/e1000e/82571.c

@@ -981,11 +981,15 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw)
 		ew32(PBA_ECC, reg);
 		ew32(PBA_ECC, reg);
 	}
 	}
 
 
-	/* PCI-Ex Control Register */
+	/* PCI-Ex Control Registers */
 	if (hw->mac.type == e1000_82574) {
 	if (hw->mac.type == e1000_82574) {
 		reg = er32(GCR);
 		reg = er32(GCR);
 		reg |= (1 << 22);
 		reg |= (1 << 22);
 		ew32(GCR, reg);
 		ew32(GCR, reg);
+
+		reg = er32(GCR2);
+		reg |= 1;
+		ew32(GCR2, reg);
 	}
 	}
 
 
 	return;
 	return;

+ 1 - 0
drivers/net/e1000e/hw.h

@@ -206,6 +206,7 @@ enum e1e_registers {
 	E1000_MANC2H    = 0x05860, /* Management Control To Host - RW */
 	E1000_MANC2H    = 0x05860, /* Management Control To Host - RW */
 	E1000_SW_FW_SYNC = 0x05B5C, /* Software-Firmware Synchronization - RW */
 	E1000_SW_FW_SYNC = 0x05B5C, /* Software-Firmware Synchronization - RW */
 	E1000_GCR	= 0x05B00, /* PCI-Ex Control */
 	E1000_GCR	= 0x05B00, /* PCI-Ex Control */
+	E1000_GCR2      = 0x05B64, /* PCI-Ex Control #2 */
 	E1000_FACTPS    = 0x05B30, /* Function Active and Power State to MNG */
 	E1000_FACTPS    = 0x05B30, /* Function Active and Power State to MNG */
 	E1000_SWSM      = 0x05B50, /* SW Semaphore */
 	E1000_SWSM      = 0x05B50, /* SW Semaphore */
 	E1000_FWSM      = 0x05B54, /* FW Semaphore */
 	E1000_FWSM      = 0x05B54, /* FW Semaphore */

+ 1 - 5
drivers/net/gianfar.c

@@ -1423,15 +1423,11 @@ static void gfar_vlan_rx_register(struct net_device *dev,
 {
 {
 	struct gfar_private *priv = netdev_priv(dev);
 	struct gfar_private *priv = netdev_priv(dev);
 	unsigned long flags;
 	unsigned long flags;
-	struct vlan_group *old_grp;
 	u32 tempval;
 	u32 tempval;
 
 
 	spin_lock_irqsave(&priv->rxlock, flags);
 	spin_lock_irqsave(&priv->rxlock, flags);
 
 
-	old_grp = priv->vlgrp;
-
-	if (old_grp == grp)
-		return;
+	priv->vlgrp = grp;
 
 
 	if (grp) {
 	if (grp) {
 		/* Enable VLAN tag insertion */
 		/* Enable VLAN tag insertion */

+ 33 - 29
drivers/net/ixgbe/ixgbe_main.c

@@ -318,6 +318,9 @@ static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter,
 		rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
 		rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
 		rxctrl |= IXGBE_DCA_RXCTRL_DESC_DCA_EN;
 		rxctrl |= IXGBE_DCA_RXCTRL_DESC_DCA_EN;
 		rxctrl |= IXGBE_DCA_RXCTRL_HEAD_DCA_EN;
 		rxctrl |= IXGBE_DCA_RXCTRL_HEAD_DCA_EN;
+		rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_RRO_EN);
+		rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN |
+			    IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
 		IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_RXCTRL(q), rxctrl);
 		IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_RXCTRL(q), rxctrl);
 		rx_ring->cpu = cpu;
 		rx_ring->cpu = cpu;
 	}
 	}
@@ -1741,6 +1744,32 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
 	IXGBE_WRITE_REG(hw, IXGBE_RXCSUM, rxcsum);
 	IXGBE_WRITE_REG(hw, IXGBE_RXCSUM, rxcsum);
 }
 }
 
 
+static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
+{
+	struct ixgbe_adapter *adapter = netdev_priv(netdev);
+	struct ixgbe_hw *hw = &adapter->hw;
+
+	/* add VID to filter table */
+	hw->mac.ops.set_vfta(&adapter->hw, vid, 0, true);
+}
+
+static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
+{
+	struct ixgbe_adapter *adapter = netdev_priv(netdev);
+	struct ixgbe_hw *hw = &adapter->hw;
+
+	if (!test_bit(__IXGBE_DOWN, &adapter->state))
+		ixgbe_irq_disable(adapter);
+
+	vlan_group_set_device(adapter->vlgrp, vid, NULL);
+
+	if (!test_bit(__IXGBE_DOWN, &adapter->state))
+		ixgbe_irq_enable(adapter);
+
+	/* remove VID from filter table */
+	hw->mac.ops.set_vfta(&adapter->hw, vid, 0, false);
+}
+
 static void ixgbe_vlan_rx_register(struct net_device *netdev,
 static void ixgbe_vlan_rx_register(struct net_device *netdev,
                                    struct vlan_group *grp)
                                    struct vlan_group *grp)
 {
 {
@@ -1760,6 +1789,7 @@ static void ixgbe_vlan_rx_register(struct net_device *netdev,
 	ctrl |= IXGBE_VLNCTRL_VME;
 	ctrl |= IXGBE_VLNCTRL_VME;
 	ctrl &= ~IXGBE_VLNCTRL_CFIEN;
 	ctrl &= ~IXGBE_VLNCTRL_CFIEN;
 	IXGBE_WRITE_REG(&adapter->hw, IXGBE_VLNCTRL, ctrl);
 	IXGBE_WRITE_REG(&adapter->hw, IXGBE_VLNCTRL, ctrl);
+	ixgbe_vlan_rx_add_vid(netdev, 0);
 
 
 	if (grp) {
 	if (grp) {
 		/* enable VLAN tag insert/strip */
 		/* enable VLAN tag insert/strip */
@@ -1773,32 +1803,6 @@ static void ixgbe_vlan_rx_register(struct net_device *netdev,
 		ixgbe_irq_enable(adapter);
 		ixgbe_irq_enable(adapter);
 }
 }
 
 
-static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
-{
-	struct ixgbe_adapter *adapter = netdev_priv(netdev);
-	struct ixgbe_hw *hw = &adapter->hw;
-
-	/* add VID to filter table */
-	hw->mac.ops.set_vfta(&adapter->hw, vid, 0, true);
-}
-
-static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
-{
-	struct ixgbe_adapter *adapter = netdev_priv(netdev);
-	struct ixgbe_hw *hw = &adapter->hw;
-
-	if (!test_bit(__IXGBE_DOWN, &adapter->state))
-		ixgbe_irq_disable(adapter);
-
-	vlan_group_set_device(adapter->vlgrp, vid, NULL);
-
-	if (!test_bit(__IXGBE_DOWN, &adapter->state))
-		ixgbe_irq_enable(adapter);
-
-	/* remove VID from filter table */
-	hw->mac.ops.set_vfta(&adapter->hw, vid, 0, false);
-}
-
 static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter)
 static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter)
 {
 {
 	ixgbe_vlan_rx_register(adapter->netdev, adapter->vlgrp);
 	ixgbe_vlan_rx_register(adapter->netdev, adapter->vlgrp);
@@ -2074,6 +2078,9 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
 
 
 	ixgbe_irq_enable(adapter);
 	ixgbe_irq_enable(adapter);
 
 
+	/* enable transmits */
+	netif_tx_start_all_queues(netdev);
+
 	/* bring the link up in the watchdog, this could race with our first
 	/* bring the link up in the watchdog, this could race with our first
 	 * link up interrupt but shouldn't be a problem */
 	 * link up interrupt but shouldn't be a problem */
 	adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
 	adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
@@ -3475,7 +3482,6 @@ static void ixgbe_watchdog_task(struct work_struct *work)
 			        (FLOW_TX ? "TX" : "None"))));
 			        (FLOW_TX ? "TX" : "None"))));
 
 
 			netif_carrier_on(netdev);
 			netif_carrier_on(netdev);
-			netif_tx_wake_all_queues(netdev);
 		} else {
 		} else {
 			/* Force detection of hung controller */
 			/* Force detection of hung controller */
 			adapter->detect_tx_hung = true;
 			adapter->detect_tx_hung = true;
@@ -3487,7 +3493,6 @@ static void ixgbe_watchdog_task(struct work_struct *work)
 			printk(KERN_INFO "ixgbe: %s NIC Link is Down\n",
 			printk(KERN_INFO "ixgbe: %s NIC Link is Down\n",
 			       netdev->name);
 			       netdev->name);
 			netif_carrier_off(netdev);
 			netif_carrier_off(netdev);
-			netif_tx_stop_all_queues(netdev);
 		}
 		}
 	}
 	}
 
 
@@ -4218,7 +4223,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
 	}
 	}
 
 
 	netif_carrier_off(netdev);
 	netif_carrier_off(netdev);
-	netif_tx_stop_all_queues(netdev);
 
 
 	strcpy(netdev->name, "eth%d");
 	strcpy(netdev->name, "eth%d");
 	err = register_netdev(netdev);
 	err = register_netdev(netdev);

+ 3 - 0
drivers/net/ixgbe/ixgbe_type.h

@@ -404,6 +404,9 @@
 #define IXGBE_DCA_RXCTRL_DESC_DCA_EN (1 << 5) /* DCA Rx Desc enable */
 #define IXGBE_DCA_RXCTRL_DESC_DCA_EN (1 << 5) /* DCA Rx Desc enable */
 #define IXGBE_DCA_RXCTRL_HEAD_DCA_EN (1 << 6) /* DCA Rx Desc header enable */
 #define IXGBE_DCA_RXCTRL_HEAD_DCA_EN (1 << 6) /* DCA Rx Desc header enable */
 #define IXGBE_DCA_RXCTRL_DATA_DCA_EN (1 << 7) /* DCA Rx Desc payload enable */
 #define IXGBE_DCA_RXCTRL_DATA_DCA_EN (1 << 7) /* DCA Rx Desc payload enable */
+#define IXGBE_DCA_RXCTRL_DESC_RRO_EN (1 << 9) /* DCA Rx rd Desc Relax Order */
+#define IXGBE_DCA_RXCTRL_DESC_WRO_EN (1 << 13) /* DCA Rx wr Desc Relax Order */
+#define IXGBE_DCA_RXCTRL_DESC_HSRO_EN (1 << 15) /* DCA Rx Split Header RO */
 
 
 #define IXGBE_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */
 #define IXGBE_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */
 #define IXGBE_DCA_TXCTRL_DESC_DCA_EN (1 << 5) /* DCA Tx Desc enable */
 #define IXGBE_DCA_TXCTRL_DESC_DCA_EN (1 << 5) /* DCA Tx Desc enable */

+ 9 - 6
drivers/net/korina.c

@@ -416,6 +416,9 @@ static int korina_rx(struct net_device *dev, int limit)
 			if (devcs & ETH_RX_MP)
 			if (devcs & ETH_RX_MP)
 				dev->stats.multicast++;
 				dev->stats.multicast++;
 
 
+			/* 16 bit align */
+			skb_reserve(skb_new, 2);
+
 			lp->rx_skb[lp->rx_next_done] = skb_new;
 			lp->rx_skb[lp->rx_next_done] = skb_new;
 		}
 		}
 
 
@@ -740,6 +743,7 @@ static struct ethtool_ops netdev_ethtool_ops = {
 static void korina_alloc_ring(struct net_device *dev)
 static void korina_alloc_ring(struct net_device *dev)
 {
 {
 	struct korina_private *lp = netdev_priv(dev);
 	struct korina_private *lp = netdev_priv(dev);
+	struct sk_buff *skb;
 	int i;
 	int i;
 
 
 	/* Initialize the transmit descriptors */
 	/* Initialize the transmit descriptors */
@@ -755,8 +759,6 @@ static void korina_alloc_ring(struct net_device *dev)
 
 
 	/* Initialize the receive descriptors */
 	/* Initialize the receive descriptors */
 	for (i = 0; i < KORINA_NUM_RDS; i++) {
 	for (i = 0; i < KORINA_NUM_RDS; i++) {
-		struct sk_buff *skb = lp->rx_skb[i];
-
 		skb = dev_alloc_skb(KORINA_RBSIZE + 2);
 		skb = dev_alloc_skb(KORINA_RBSIZE + 2);
 		if (!skb)
 		if (!skb)
 			break;
 			break;
@@ -769,11 +771,12 @@ static void korina_alloc_ring(struct net_device *dev)
 		lp->rd_ring[i].link = CPHYSADDR(&lp->rd_ring[i+1]);
 		lp->rd_ring[i].link = CPHYSADDR(&lp->rd_ring[i+1]);
 	}
 	}
 
 
-	/* loop back */
-	lp->rd_ring[i].link = CPHYSADDR(&lp->rd_ring[0]);
-	lp->rx_next_done  = 0;
+	/* loop back receive descriptors, so the last
+	 * descriptor points to the first one */
+	lp->rd_ring[i - 1].link = CPHYSADDR(&lp->rd_ring[0]);
+	lp->rd_ring[i - 1].control |= DMA_DESC_COD;
 
 
-	lp->rd_ring[i].control |= DMA_DESC_COD;
+	lp->rx_next_done  = 0;
 	lp->rx_chain_head = 0;
 	lp->rx_chain_head = 0;
 	lp->rx_chain_tail = 0;
 	lp->rx_chain_tail = 0;
 	lp->rx_chain_status = desc_empty;
 	lp->rx_chain_status = desc_empty;

+ 8 - 0
drivers/net/macb.c

@@ -321,6 +321,10 @@ static void macb_tx(struct macb *bp)
 		printk(KERN_ERR "%s: TX underrun, resetting buffers\n",
 		printk(KERN_ERR "%s: TX underrun, resetting buffers\n",
 			bp->dev->name);
 			bp->dev->name);
 
 
+		/* Transfer ongoing, disable transmitter, to avoid confusion */
+		if (status & MACB_BIT(TGO))
+			macb_writel(bp, NCR, macb_readl(bp, NCR) & ~MACB_BIT(TE));
+
 		head = bp->tx_head;
 		head = bp->tx_head;
 
 
 		/*Mark all the buffer as used to avoid sending a lost buffer*/
 		/*Mark all the buffer as used to avoid sending a lost buffer*/
@@ -343,6 +347,10 @@ static void macb_tx(struct macb *bp)
 		}
 		}
 
 
 		bp->tx_head = bp->tx_tail = 0;
 		bp->tx_head = bp->tx_tail = 0;
+
+		/* Enable the transmitter again */
+		if (status & MACB_BIT(TGO))
+			macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TE));
 	}
 	}
 
 
 	if (!(status & MACB_BIT(COMP)))
 	if (!(status & MACB_BIT(COMP)))

+ 10 - 7
drivers/net/mv643xx_eth.c

@@ -136,21 +136,23 @@ static char mv643xx_eth_driver_version[] = "1.4";
 /*
 /*
  * SDMA configuration register.
  * SDMA configuration register.
  */
  */
+#define RX_BURST_SIZE_4_64BIT		(2 << 1)
 #define RX_BURST_SIZE_16_64BIT		(4 << 1)
 #define RX_BURST_SIZE_16_64BIT		(4 << 1)
 #define BLM_RX_NO_SWAP			(1 << 4)
 #define BLM_RX_NO_SWAP			(1 << 4)
 #define BLM_TX_NO_SWAP			(1 << 5)
 #define BLM_TX_NO_SWAP			(1 << 5)
+#define TX_BURST_SIZE_4_64BIT		(2 << 22)
 #define TX_BURST_SIZE_16_64BIT		(4 << 22)
 #define TX_BURST_SIZE_16_64BIT		(4 << 22)
 
 
 #if defined(__BIG_ENDIAN)
 #if defined(__BIG_ENDIAN)
 #define PORT_SDMA_CONFIG_DEFAULT_VALUE		\
 #define PORT_SDMA_CONFIG_DEFAULT_VALUE		\
-		(RX_BURST_SIZE_16_64BIT	|	\
-		TX_BURST_SIZE_16_64BIT)
+		(RX_BURST_SIZE_4_64BIT	|	\
+		 TX_BURST_SIZE_4_64BIT)
 #elif defined(__LITTLE_ENDIAN)
 #elif defined(__LITTLE_ENDIAN)
 #define PORT_SDMA_CONFIG_DEFAULT_VALUE		\
 #define PORT_SDMA_CONFIG_DEFAULT_VALUE		\
-		(RX_BURST_SIZE_16_64BIT	|	\
-		BLM_RX_NO_SWAP		|	\
-		BLM_TX_NO_SWAP		|	\
-		TX_BURST_SIZE_16_64BIT)
+		(RX_BURST_SIZE_4_64BIT	|	\
+		 BLM_RX_NO_SWAP		|	\
+		 BLM_TX_NO_SWAP		|	\
+		 TX_BURST_SIZE_4_64BIT)
 #else
 #else
 #error One of __BIG_ENDIAN or __LITTLE_ENDIAN must be defined
 #error One of __BIG_ENDIAN or __LITTLE_ENDIAN must be defined
 #endif
 #endif
@@ -1594,7 +1596,7 @@ oom:
 			entry = addr_crc(a);
 			entry = addr_crc(a);
 		}
 		}
 
 
-		table[entry >> 2] |= 1 << (entry & 3);
+		table[entry >> 2] |= 1 << (8 * (entry & 3));
 	}
 	}
 
 
 	for (i = 0; i < 0x100; i += 4) {
 	for (i = 0; i < 0x100; i += 4) {
@@ -2210,6 +2212,7 @@ static int mv643xx_eth_stop(struct net_device *dev)
 	struct mv643xx_eth_private *mp = netdev_priv(dev);
 	struct mv643xx_eth_private *mp = netdev_priv(dev);
 	int i;
 	int i;
 
 
+	wrlp(mp, INT_MASK_EXT, 0x00000000);
 	wrlp(mp, INT_MASK, 0x00000000);
 	wrlp(mp, INT_MASK, 0x00000000);
 	rdlp(mp, INT_MASK);
 	rdlp(mp, INT_MASK);
 
 

+ 9 - 6
drivers/net/myri10ge/myri10ge.c

@@ -1,7 +1,7 @@
 /*************************************************************************
 /*************************************************************************
  * myri10ge.c: Myricom Myri-10G Ethernet driver.
  * myri10ge.c: Myricom Myri-10G Ethernet driver.
  *
  *
- * Copyright (C) 2005 - 2007 Myricom, Inc.
+ * Copyright (C) 2005 - 2009 Myricom, Inc.
  * All rights reserved.
  * All rights reserved.
  *
  *
  * Redistribution and use in source and binary forms, with or without
  * Redistribution and use in source and binary forms, with or without
@@ -75,7 +75,7 @@
 #include "myri10ge_mcp.h"
 #include "myri10ge_mcp.h"
 #include "myri10ge_mcp_gen_header.h"
 #include "myri10ge_mcp_gen_header.h"
 
 
-#define MYRI10GE_VERSION_STR "1.4.4-1.398"
+#define MYRI10GE_VERSION_STR "1.4.4-1.401"
 
 
 MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
 MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
 MODULE_AUTHOR("Maintainer: help@myri.com");
 MODULE_AUTHOR("Maintainer: help@myri.com");
@@ -3786,7 +3786,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	if (status != 0) {
 	if (status != 0) {
 		dev_err(&pdev->dev, "Error %d writing PCI_EXP_DEVCTL\n",
 		dev_err(&pdev->dev, "Error %d writing PCI_EXP_DEVCTL\n",
 			status);
 			status);
-		goto abort_with_netdev;
+		goto abort_with_enabled;
 	}
 	}
 
 
 	pci_set_master(pdev);
 	pci_set_master(pdev);
@@ -3801,13 +3801,13 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	}
 	}
 	if (status != 0) {
 	if (status != 0) {
 		dev_err(&pdev->dev, "Error %d setting DMA mask\n", status);
 		dev_err(&pdev->dev, "Error %d setting DMA mask\n", status);
-		goto abort_with_netdev;
+		goto abort_with_enabled;
 	}
 	}
 	(void)pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
 	(void)pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
 	mgp->cmd = dma_alloc_coherent(&pdev->dev, sizeof(*mgp->cmd),
 	mgp->cmd = dma_alloc_coherent(&pdev->dev, sizeof(*mgp->cmd),
 				      &mgp->cmd_bus, GFP_KERNEL);
 				      &mgp->cmd_bus, GFP_KERNEL);
 	if (mgp->cmd == NULL)
 	if (mgp->cmd == NULL)
-		goto abort_with_netdev;
+		goto abort_with_enabled;
 
 
 	mgp->board_span = pci_resource_len(pdev, 0);
 	mgp->board_span = pci_resource_len(pdev, 0);
 	mgp->iomem_base = pci_resource_start(pdev, 0);
 	mgp->iomem_base = pci_resource_start(pdev, 0);
@@ -3943,8 +3943,10 @@ abort_with_mtrr:
 	dma_free_coherent(&pdev->dev, sizeof(*mgp->cmd),
 	dma_free_coherent(&pdev->dev, sizeof(*mgp->cmd),
 			  mgp->cmd, mgp->cmd_bus);
 			  mgp->cmd, mgp->cmd_bus);
 
 
-abort_with_netdev:
+abort_with_enabled:
+	pci_disable_device(pdev);
 
 
+abort_with_netdev:
 	free_netdev(netdev);
 	free_netdev(netdev);
 	return status;
 	return status;
 }
 }
@@ -3990,6 +3992,7 @@ static void myri10ge_remove(struct pci_dev *pdev)
 			  mgp->cmd, mgp->cmd_bus);
 			  mgp->cmd, mgp->cmd_bus);
 
 
 	free_netdev(netdev);
 	free_netdev(netdev);
+	pci_disable_device(pdev);
 	pci_set_drvdata(pdev, NULL);
 	pci_set_drvdata(pdev, NULL);
 }
 }
 
 

+ 6 - 6
drivers/net/netxen/netxen_nic.h

@@ -146,7 +146,7 @@
 
 
 #define MAX_RX_BUFFER_LENGTH		1760
 #define MAX_RX_BUFFER_LENGTH		1760
 #define MAX_RX_JUMBO_BUFFER_LENGTH 	8062
 #define MAX_RX_JUMBO_BUFFER_LENGTH 	8062
-#define MAX_RX_LRO_BUFFER_LENGTH	((48*1024)-512)
+#define MAX_RX_LRO_BUFFER_LENGTH	(8062)
 #define RX_DMA_MAP_LEN			(MAX_RX_BUFFER_LENGTH - 2)
 #define RX_DMA_MAP_LEN			(MAX_RX_BUFFER_LENGTH - 2)
 #define RX_JUMBO_DMA_MAP_LEN	\
 #define RX_JUMBO_DMA_MAP_LEN	\
 	(MAX_RX_JUMBO_BUFFER_LENGTH - 2)
 	(MAX_RX_JUMBO_BUFFER_LENGTH - 2)
@@ -207,11 +207,11 @@
 
 
 #define MAX_CMD_DESCRIPTORS		4096
 #define MAX_CMD_DESCRIPTORS		4096
 #define MAX_RCV_DESCRIPTORS		16384
 #define MAX_RCV_DESCRIPTORS		16384
-#define MAX_CMD_DESCRIPTORS_HOST	(MAX_CMD_DESCRIPTORS / 4)
-#define MAX_RCV_DESCRIPTORS_1G		(MAX_RCV_DESCRIPTORS / 4)
-#define MAX_RCV_DESCRIPTORS_10G		8192
-#define MAX_JUMBO_RCV_DESCRIPTORS	1024
-#define MAX_LRO_RCV_DESCRIPTORS		64
+#define MAX_CMD_DESCRIPTORS_HOST	1024
+#define MAX_RCV_DESCRIPTORS_1G		2048
+#define MAX_RCV_DESCRIPTORS_10G		4096
+#define MAX_JUMBO_RCV_DESCRIPTORS	512
+#define MAX_LRO_RCV_DESCRIPTORS		8
 #define MAX_RCVSTATUS_DESCRIPTORS	MAX_RCV_DESCRIPTORS
 #define MAX_RCVSTATUS_DESCRIPTORS	MAX_RCV_DESCRIPTORS
 #define MAX_JUMBO_RCV_DESC	MAX_JUMBO_RCV_DESCRIPTORS
 #define MAX_JUMBO_RCV_DESC	MAX_JUMBO_RCV_DESCRIPTORS
 #define MAX_RCV_DESC		MAX_RCV_DESCRIPTORS
 #define MAX_RCV_DESC		MAX_RCV_DESCRIPTORS

+ 4 - 1
drivers/net/netxen/netxen_nic_ethtool.c

@@ -561,7 +561,10 @@ netxen_nic_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring)
 	}
 	}
 	ring->tx_pending = adapter->max_tx_desc_count;
 	ring->tx_pending = adapter->max_tx_desc_count;
 
 
-	ring->rx_max_pending = MAX_RCV_DESCRIPTORS;
+	if (adapter->ahw.board_type == NETXEN_NIC_GBE)
+		ring->rx_max_pending = MAX_RCV_DESCRIPTORS_1G;
+	else
+		ring->rx_max_pending = MAX_RCV_DESCRIPTORS_10G;
 	ring->tx_max_pending = MAX_CMD_DESCRIPTORS_HOST;
 	ring->tx_max_pending = MAX_CMD_DESCRIPTORS_HOST;
 	ring->rx_jumbo_max_pending = MAX_JUMBO_RCV_DESCRIPTORS;
 	ring->rx_jumbo_max_pending = MAX_JUMBO_RCV_DESCRIPTORS;
 	ring->rx_mini_max_pending = 0;
 	ring->rx_mini_max_pending = 0;

+ 20 - 11
drivers/net/netxen/netxen_nic_main.c

@@ -735,17 +735,18 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 
 	SET_ETHTOOL_OPS(netdev, &netxen_nic_ethtool_ops);
 	SET_ETHTOOL_OPS(netdev, &netxen_nic_ethtool_ops);
 
 
-	/* ScatterGather support */
-	netdev->features = NETIF_F_SG;
-	netdev->features |= NETIF_F_IP_CSUM;
-	netdev->features |= NETIF_F_TSO;
+	netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
+	netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
+
 	if (NX_IS_REVISION_P3(revision_id)) {
 	if (NX_IS_REVISION_P3(revision_id)) {
-		netdev->features |= NETIF_F_IPV6_CSUM;
-		netdev->features |= NETIF_F_TSO6;
+		netdev->features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
+		netdev->vlan_features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
 	}
 	}
 
 
-	if (adapter->pci_using_dac)
+	if (adapter->pci_using_dac) {
 		netdev->features |= NETIF_F_HIGHDMA;
 		netdev->features |= NETIF_F_HIGHDMA;
+		netdev->vlan_features |= NETIF_F_HIGHDMA;
+	}
 
 
 	/*
 	/*
 	 * Set the CRB window to invalid. If any register in window 0 is
 	 * Set the CRB window to invalid. If any register in window 0 is
@@ -1166,6 +1167,14 @@ static bool netxen_tso_check(struct net_device *netdev,
 {
 {
 	bool tso = false;
 	bool tso = false;
 	u8 opcode = TX_ETHER_PKT;
 	u8 opcode = TX_ETHER_PKT;
+	__be16 protocol = skb->protocol;
+	u16 flags = 0;
+
+	if (protocol == __constant_htons(ETH_P_8021Q)) {
+		struct vlan_ethhdr *vh = (struct vlan_ethhdr *)skb->data;
+		protocol = vh->h_vlan_encapsulated_proto;
+		flags = FLAGS_VLAN_TAGGED;
+	}
 
 
 	if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) &&
 	if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) &&
 			skb_shinfo(skb)->gso_size > 0) {
 			skb_shinfo(skb)->gso_size > 0) {
@@ -1174,21 +1183,21 @@ static bool netxen_tso_check(struct net_device *netdev,
 		desc->total_hdr_length =
 		desc->total_hdr_length =
 			skb_transport_offset(skb) + tcp_hdrlen(skb);
 			skb_transport_offset(skb) + tcp_hdrlen(skb);
 
 
-		opcode = (skb->protocol == htons(ETH_P_IPV6)) ?
+		opcode = (protocol == __constant_htons(ETH_P_IPV6)) ?
 				TX_TCP_LSO6 : TX_TCP_LSO;
 				TX_TCP_LSO6 : TX_TCP_LSO;
 		tso = true;
 		tso = true;
 
 
 	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
 	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
 		u8 l4proto;
 		u8 l4proto;
 
 
-		if (skb->protocol == htons(ETH_P_IP)) {
+		if (protocol == __constant_htons(ETH_P_IP)) {
 			l4proto = ip_hdr(skb)->protocol;
 			l4proto = ip_hdr(skb)->protocol;
 
 
 			if (l4proto == IPPROTO_TCP)
 			if (l4proto == IPPROTO_TCP)
 				opcode = TX_TCP_PKT;
 				opcode = TX_TCP_PKT;
 			else if(l4proto == IPPROTO_UDP)
 			else if(l4proto == IPPROTO_UDP)
 				opcode = TX_UDP_PKT;
 				opcode = TX_UDP_PKT;
-		} else if (skb->protocol == htons(ETH_P_IPV6)) {
+		} else if (protocol == __constant_htons(ETH_P_IPV6)) {
 			l4proto = ipv6_hdr(skb)->nexthdr;
 			l4proto = ipv6_hdr(skb)->nexthdr;
 
 
 			if (l4proto == IPPROTO_TCP)
 			if (l4proto == IPPROTO_TCP)
@@ -1199,7 +1208,7 @@ static bool netxen_tso_check(struct net_device *netdev,
 	}
 	}
 	desc->tcp_hdr_offset = skb_transport_offset(skb);
 	desc->tcp_hdr_offset = skb_transport_offset(skb);
 	desc->ip_hdr_offset = skb_network_offset(skb);
 	desc->ip_hdr_offset = skb_network_offset(skb);
-	netxen_set_tx_flags_opcode(desc, 0, opcode);
+	netxen_set_tx_flags_opcode(desc, flags, opcode);
 	return tso;
 	return tso;
 }
 }
 
 

+ 3 - 5
drivers/net/phy/mdio_bus.c

@@ -296,9 +296,8 @@ static int mdio_bus_suspend(struct device * dev, pm_message_t state)
 	struct phy_driver *phydrv = to_phy_driver(drv);
 	struct phy_driver *phydrv = to_phy_driver(drv);
 	struct phy_device *phydev = to_phy_device(dev);
 	struct phy_device *phydev = to_phy_device(dev);
 
 
-	if ((!device_may_wakeup(phydev->dev.parent)) &&
-		(phydrv && phydrv->suspend))
-			ret = phydrv->suspend(phydev);
+	if (drv && phydrv->suspend && !device_may_wakeup(phydev->dev.parent))
+		ret = phydrv->suspend(phydev);
 
 
 	return ret;
 	return ret;
 }
 }
@@ -310,8 +309,7 @@ static int mdio_bus_resume(struct device * dev)
 	struct phy_driver *phydrv = to_phy_driver(drv);
 	struct phy_driver *phydrv = to_phy_driver(drv);
 	struct phy_device *phydev = to_phy_device(dev);
 	struct phy_device *phydev = to_phy_device(dev);
 
 
-	if ((!device_may_wakeup(phydev->dev.parent)) &&
-		(phydrv && phydrv->resume))
+	if (drv && phydrv->resume && !device_may_wakeup(phydev->dev.parent))
 		ret = phydrv->resume(phydev);
 		ret = phydrv->resume(phydev);
 
 
 	return ret;
 	return ret;

+ 12 - 0
drivers/net/phy/smsc.c

@@ -81,6 +81,9 @@ static struct phy_driver lan83c185_driver = {
 	.ack_interrupt	= smsc_phy_ack_interrupt,
 	.ack_interrupt	= smsc_phy_ack_interrupt,
 	.config_intr	= smsc_phy_config_intr,
 	.config_intr	= smsc_phy_config_intr,
 
 
+	.suspend	= genphy_suspend,
+	.resume		= genphy_resume,
+
 	.driver		= { .owner = THIS_MODULE, }
 	.driver		= { .owner = THIS_MODULE, }
 };
 };
 
 
@@ -102,6 +105,9 @@ static struct phy_driver lan8187_driver = {
 	.ack_interrupt	= smsc_phy_ack_interrupt,
 	.ack_interrupt	= smsc_phy_ack_interrupt,
 	.config_intr	= smsc_phy_config_intr,
 	.config_intr	= smsc_phy_config_intr,
 
 
+	.suspend	= genphy_suspend,
+	.resume		= genphy_resume,
+
 	.driver		= { .owner = THIS_MODULE, }
 	.driver		= { .owner = THIS_MODULE, }
 };
 };
 
 
@@ -123,6 +129,9 @@ static struct phy_driver lan8700_driver = {
 	.ack_interrupt	= smsc_phy_ack_interrupt,
 	.ack_interrupt	= smsc_phy_ack_interrupt,
 	.config_intr	= smsc_phy_config_intr,
 	.config_intr	= smsc_phy_config_intr,
 
 
+	.suspend	= genphy_suspend,
+	.resume		= genphy_resume,
+
 	.driver		= { .owner = THIS_MODULE, }
 	.driver		= { .owner = THIS_MODULE, }
 };
 };
 
 
@@ -144,6 +153,9 @@ static struct phy_driver lan911x_int_driver = {
 	.ack_interrupt	= smsc_phy_ack_interrupt,
 	.ack_interrupt	= smsc_phy_ack_interrupt,
 	.config_intr	= smsc_phy_config_intr,
 	.config_intr	= smsc_phy_config_intr,
 
 
+	.suspend	= genphy_suspend,
+	.resume		= genphy_resume,
+
 	.driver		= { .owner = THIS_MODULE, }
 	.driver		= { .owner = THIS_MODULE, }
 };
 };
 
 

+ 50 - 31
drivers/net/tg3.c

@@ -7535,11 +7535,58 @@ static int tg3_test_msi(struct tg3 *tp)
 	return err;
 	return err;
 }
 }
 
 
+static int tg3_request_firmware(struct tg3 *tp)
+{
+	const __be32 *fw_data;
+
+	if (request_firmware(&tp->fw, tp->fw_needed, &tp->pdev->dev)) {
+		printk(KERN_ERR "%s: Failed to load firmware \"%s\"\n",
+		       tp->dev->name, tp->fw_needed);
+		return -ENOENT;
+	}
+
+	fw_data = (void *)tp->fw->data;
+
+	/* Firmware blob starts with version numbers, followed by
+	 * start address and _full_ length including BSS sections
+	 * (which must be longer than the actual data, of course
+	 */
+
+	tp->fw_len = be32_to_cpu(fw_data[2]);	/* includes bss */
+	if (tp->fw_len < (tp->fw->size - 12)) {
+		printk(KERN_ERR "%s: bogus length %d in \"%s\"\n",
+		       tp->dev->name, tp->fw_len, tp->fw_needed);
+		release_firmware(tp->fw);
+		tp->fw = NULL;
+		return -EINVAL;
+	}
+
+	/* We no longer need firmware; we have it. */
+	tp->fw_needed = NULL;
+	return 0;
+}
+
 static int tg3_open(struct net_device *dev)
 static int tg3_open(struct net_device *dev)
 {
 {
 	struct tg3 *tp = netdev_priv(dev);
 	struct tg3 *tp = netdev_priv(dev);
 	int err;
 	int err;
 
 
+	if (tp->fw_needed) {
+		err = tg3_request_firmware(tp);
+		if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0) {
+			if (err)
+				return err;
+		} else if (err) {
+			printk(KERN_WARNING "%s: TSO capability disabled.\n",
+			       tp->dev->name);
+			tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE;
+		} else if (!(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE)) {
+			printk(KERN_NOTICE "%s: TSO capability restored.\n",
+			       tp->dev->name);
+			tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
+		}
+	}
+
 	netif_carrier_off(tp->dev);
 	netif_carrier_off(tp->dev);
 
 
 	err = tg3_set_power_state(tp, PCI_D0);
 	err = tg3_set_power_state(tp, PCI_D0);
@@ -12934,7 +12981,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 	struct net_device *dev;
 	struct net_device *dev;
 	struct tg3 *tp;
 	struct tg3 *tp;
 	int err, pm_cap;
 	int err, pm_cap;
-	const char *fw_name = NULL;
 	char str[40];
 	char str[40];
 	u64 dma_mask, persist_dma_mask;
 	u64 dma_mask, persist_dma_mask;
 
 
@@ -13091,7 +13137,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 	tg3_init_bufmgr_config(tp);
 	tg3_init_bufmgr_config(tp);
 
 
 	if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0)
 	if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0)
-		fw_name = FIRMWARE_TG3;
+		tp->fw_needed = FIRMWARE_TG3;
 
 
 	if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) {
 	if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) {
 		tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
 		tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
@@ -13104,37 +13150,10 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 		tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE;
 		tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE;
 	} else {
 	} else {
 		tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE | TG3_FLG2_TSO_BUG;
 		tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE | TG3_FLG2_TSO_BUG;
-	}
-	if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) {
 		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)
 		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)
-			fw_name = FIRMWARE_TG3TSO5;
+			tp->fw_needed = FIRMWARE_TG3TSO5;
 		else
 		else
-			fw_name = FIRMWARE_TG3TSO;
-	}
-
-	if (fw_name) {
-		const __be32 *fw_data;
-
-		err = request_firmware(&tp->fw, fw_name, &tp->pdev->dev);
-		if (err) {
-			printk(KERN_ERR "tg3: Failed to load firmware \"%s\"\n",
-			       fw_name);
-			goto err_out_iounmap;
-		}
-
-		fw_data = (void *)tp->fw->data;
-
-		/* Firmware blob starts with version numbers, followed by
-		   start address and _full_ length including BSS sections
-		   (which must be longer than the actual data, of course */
-
-		tp->fw_len = be32_to_cpu(fw_data[2]);	/* includes bss */
-		if (tp->fw_len < (tp->fw->size - 12)) {
-			printk(KERN_ERR "tg3: bogus length %d in \"%s\"\n",
-			       tp->fw_len, fw_name);
-			err = -EINVAL;
-			goto err_out_fw;
-		}
+			tp->fw_needed = FIRMWARE_TG3TSO;
 	}
 	}
 
 
 	/* TSO is on by default on chips that support hardware TSO.
 	/* TSO is on by default on chips that support hardware TSO.

+ 1 - 0
drivers/net/tg3.h

@@ -2764,6 +2764,7 @@ struct tg3 {
 	struct ethtool_coalesce		coal;
 	struct ethtool_coalesce		coal;
 
 
 	/* firmware info */
 	/* firmware info */
+	const char			*fw_needed;
 	const struct firmware		*fw;
 	const struct firmware		*fw;
 	u32				fw_len; /* includes BSS */
 	u32				fw_len; /* includes BSS */
 };
 };

+ 18 - 2
drivers/net/usb/mcs7830.c

@@ -94,10 +94,18 @@ static int mcs7830_get_reg(struct usbnet *dev, u16 index, u16 size, void *data)
 {
 {
 	struct usb_device *xdev = dev->udev;
 	struct usb_device *xdev = dev->udev;
 	int ret;
 	int ret;
+	void *buffer;
+
+	buffer = kmalloc(size, GFP_NOIO);
+	if (buffer == NULL)
+		return -ENOMEM;
 
 
 	ret = usb_control_msg(xdev, usb_rcvctrlpipe(xdev, 0), MCS7830_RD_BREQ,
 	ret = usb_control_msg(xdev, usb_rcvctrlpipe(xdev, 0), MCS7830_RD_BREQ,
-			      MCS7830_RD_BMREQ, 0x0000, index, data,
+			      MCS7830_RD_BMREQ, 0x0000, index, buffer,
 			      size, MCS7830_CTRL_TIMEOUT);
 			      size, MCS7830_CTRL_TIMEOUT);
+	memcpy(data, buffer, size);
+	kfree(buffer);
+
 	return ret;
 	return ret;
 }
 }
 
 
@@ -105,10 +113,18 @@ static int mcs7830_set_reg(struct usbnet *dev, u16 index, u16 size, void *data)
 {
 {
 	struct usb_device *xdev = dev->udev;
 	struct usb_device *xdev = dev->udev;
 	int ret;
 	int ret;
+	void *buffer;
+
+	buffer = kmalloc(size, GFP_NOIO);
+	if (buffer == NULL)
+		return -ENOMEM;
+
+	memcpy(buffer, data, size);
 
 
 	ret = usb_control_msg(xdev, usb_sndctrlpipe(xdev, 0), MCS7830_WR_BREQ,
 	ret = usb_control_msg(xdev, usb_sndctrlpipe(xdev, 0), MCS7830_WR_BREQ,
-			      MCS7830_WR_BMREQ, 0x0000, index, data,
+			      MCS7830_WR_BMREQ, 0x0000, index, buffer,
 			      size, MCS7830_CTRL_TIMEOUT);
 			      size, MCS7830_CTRL_TIMEOUT);
+	kfree(buffer);
 	return ret;
 	return ret;
 }
 }
 
 

+ 1 - 1
drivers/net/via-velocity.c

@@ -1302,7 +1302,7 @@ static void velocity_free_rd_ring(struct velocity_info *vptr)
 static int velocity_init_td_ring(struct velocity_info *vptr)
 static int velocity_init_td_ring(struct velocity_info *vptr)
 {
 {
 	dma_addr_t curr;
 	dma_addr_t curr;
-	unsigned int j;
+	int j;
 
 
 	/* Init the TD ring entries */
 	/* Init the TD ring entries */
 	for (j = 0; j < vptr->tx.numq; j++) {
 	for (j = 0; j < vptr->tx.numq; j++) {

+ 2 - 1
drivers/net/virtio_net.c

@@ -24,6 +24,7 @@
 #include <linux/virtio.h>
 #include <linux/virtio.h>
 #include <linux/virtio_net.h>
 #include <linux/virtio_net.h>
 #include <linux/scatterlist.h>
 #include <linux/scatterlist.h>
+#include <linux/if_vlan.h>
 
 
 static int napi_weight = 128;
 static int napi_weight = 128;
 module_param(napi_weight, int, 0444);
 module_param(napi_weight, int, 0444);
@@ -33,7 +34,7 @@ module_param(csum, bool, 0444);
 module_param(gso, bool, 0444);
 module_param(gso, bool, 0444);
 
 
 /* FIXME: MTU in config. */
 /* FIXME: MTU in config. */
-#define MAX_PACKET_LEN (ETH_HLEN+ETH_DATA_LEN)
+#define MAX_PACKET_LEN (ETH_HLEN + VLAN_HLEN + ETH_DATA_LEN)
 #define GOOD_COPY_LEN	128
 #define GOOD_COPY_LEN	128
 
 
 struct virtnet_info
 struct virtnet_info

+ 1 - 1
drivers/net/wimax/i2400m/control.c

@@ -609,7 +609,7 @@ void i2400m_msg_to_dev_cancel_wait(struct i2400m *i2400m, int code)
 	spin_lock_irqsave(&i2400m->rx_lock, flags);
 	spin_lock_irqsave(&i2400m->rx_lock, flags);
 	ack_skb = i2400m->ack_skb;
 	ack_skb = i2400m->ack_skb;
 	if (ack_skb && !IS_ERR(ack_skb))
 	if (ack_skb && !IS_ERR(ack_skb))
-		kfree(ack_skb);
+		kfree_skb(ack_skb);
 	i2400m->ack_skb = ERR_PTR(code);
 	i2400m->ack_skb = ERR_PTR(code);
 	spin_unlock_irqrestore(&i2400m->rx_lock, flags);
 	spin_unlock_irqrestore(&i2400m->rx_lock, flags);
 }
 }

+ 6 - 3
drivers/net/wimax/i2400m/usb-rx.c

@@ -184,6 +184,8 @@ void i2400mu_rx_size_maybe_shrink(struct i2400mu *i2400mu)
  *   NOTE: this function might realloc the skb (if it is too small),
  *   NOTE: this function might realloc the skb (if it is too small),
  *   so always update with the one returned.
  *   so always update with the one returned.
  *   ERR_PTR() is < 0 on error.
  *   ERR_PTR() is < 0 on error.
+ *   Will return NULL if it cannot reallocate -- this can be
+ *   considered a transient retryable error.
  */
  */
 static
 static
 struct sk_buff *i2400mu_rx(struct i2400mu *i2400mu, struct sk_buff *rx_skb)
 struct sk_buff *i2400mu_rx(struct i2400mu *i2400mu, struct sk_buff *rx_skb)
@@ -243,8 +245,8 @@ retry:
 			if (printk_ratelimit())
 			if (printk_ratelimit())
 				dev_err(dev, "RX: Can't reallocate skb to %d; "
 				dev_err(dev, "RX: Can't reallocate skb to %d; "
 					"RX dropped\n", rx_size);
 					"RX dropped\n", rx_size);
-			kfree(rx_skb);
-			result = 0;
+			kfree_skb(rx_skb);
+			rx_skb = NULL;
 			goto out;	/* drop it...*/
 			goto out;	/* drop it...*/
 		}
 		}
 		kfree_skb(rx_skb);
 		kfree_skb(rx_skb);
@@ -344,7 +346,8 @@ int i2400mu_rxd(void *_i2400mu)
 		if (IS_ERR(rx_skb))
 		if (IS_ERR(rx_skb))
 			goto out;
 			goto out;
 		atomic_dec(&i2400mu->rx_pending_count);
 		atomic_dec(&i2400mu->rx_pending_count);
-		if (rx_skb->len == 0) {	/* some ignorable condition */
+		if (rx_skb == NULL || rx_skb->len == 0) {
+			/* some "ignorable" condition */
 			kfree_skb(rx_skb);
 			kfree_skb(rx_skb);
 			continue;
 			continue;
 		}
 		}

+ 1 - 1
drivers/net/wireless/ath9k/rc.c

@@ -490,7 +490,7 @@ static inline int ath_rc_get_nextvalid_txrate(struct ath_rate_table *rate_table,
 
 
 static int ath_rc_valid_phyrate(u32 phy, u32 capflag, int ignore_cw)
 static int ath_rc_valid_phyrate(u32 phy, u32 capflag, int ignore_cw)
 {
 {
-	if (WLAN_RC_PHY_HT(phy) & !(capflag & WLAN_RC_HT_FLAG))
+	if (WLAN_RC_PHY_HT(phy) && !(capflag & WLAN_RC_HT_FLAG))
 		return 0;
 		return 0;
 	if (WLAN_RC_PHY_DS(phy) && !(capflag & WLAN_RC_DS_FLAG))
 	if (WLAN_RC_PHY_DS(phy) && !(capflag & WLAN_RC_DS_FLAG))
 		return 0;
 		return 0;

+ 1 - 1
drivers/net/wireless/ath9k/regd_common.h

@@ -228,7 +228,7 @@ enum {
 };
 };
 
 
 #define REG_DOMAIN_2GHZ_MASK    (REQ_MASK & \
 #define REG_DOMAIN_2GHZ_MASK    (REQ_MASK & \
-	(!(ADHOC_NO_11A | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB)))
+	(~(ADHOC_NO_11A | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB)))
 #define REG_DOMAIN_5GHZ_MASK    REQ_MASK
 #define REG_DOMAIN_5GHZ_MASK    REQ_MASK
 
 
 static struct reg_dmn_pair_mapping regDomainPairs[] = {
 static struct reg_dmn_pair_mapping regDomainPairs[] = {

+ 11 - 3
drivers/net/wireless/iwlwifi/iwl-3945-rs.c

@@ -638,12 +638,16 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
 	s8 scale_action = 0;
 	s8 scale_action = 0;
 	unsigned long flags;
 	unsigned long flags;
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-	u16 fc, rate_mask;
+	u16 fc;
+	u16 rate_mask = 0;
 	struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_r;
 	struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_r;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 
 
 	IWL_DEBUG_RATE("enter\n");
 	IWL_DEBUG_RATE("enter\n");
 
 
+	if (sta)
+		rate_mask = sta->supp_rates[sband->band];
+
 	/* Send management frames and broadcast/multicast data using lowest
 	/* Send management frames and broadcast/multicast data using lowest
 	 * rate. */
 	 * rate. */
 	fc = le16_to_cpu(hdr->frame_control);
 	fc = le16_to_cpu(hdr->frame_control);
@@ -651,11 +655,15 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
 	    is_multicast_ether_addr(hdr->addr1) ||
 	    is_multicast_ether_addr(hdr->addr1) ||
 	    !sta || !priv_sta) {
 	    !sta || !priv_sta) {
 		IWL_DEBUG_RATE("leave: No STA priv data to update!\n");
 		IWL_DEBUG_RATE("leave: No STA priv data to update!\n");
-		info->control.rates[0].idx = rate_lowest_index(sband, sta);
+		if (!rate_mask)
+			info->control.rates[0].idx =
+					rate_lowest_index(sband, NULL);
+		else
+			info->control.rates[0].idx =
+					rate_lowest_index(sband, sta);
 		return;
 		return;
 	}
 	}
 
 
-	rate_mask = sta->supp_rates[sband->band];
 	index = min(rs_sta->last_txrate_idx & 0xffff, IWL_RATE_COUNT - 1);
 	index = min(rs_sta->last_txrate_idx & 0xffff, IWL_RATE_COUNT - 1);
 
 
 	if (sband->band == IEEE80211_BAND_5GHZ)
 	if (sband->band == IEEE80211_BAND_5GHZ)

+ 12 - 2
drivers/net/wireless/iwlwifi/iwl-agn-rs.c

@@ -944,7 +944,8 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
 	}
 	}
 
 
 	/* See if there's a better rate or modulation mode to try. */
 	/* See if there's a better rate or modulation mode to try. */
-	rs_rate_scale_perform(priv, hdr, sta, lq_sta);
+	if (sta && sta->supp_rates[sband->band])
+		rs_rate_scale_perform(priv, hdr, sta, lq_sta);
 out:
 out:
 	return;
 	return;
 }
 }
@@ -2101,14 +2102,23 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct iwl_lq_sta *lq_sta = priv_sta;
 	struct iwl_lq_sta *lq_sta = priv_sta;
 	int rate_idx;
 	int rate_idx;
+	u64 mask_bit = 0;
 
 
 	IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n");
 	IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n");
 
 
+	if (sta)
+		mask_bit = sta->supp_rates[sband->band];
+
 	/* Send management frames and broadcast/multicast data using lowest
 	/* Send management frames and broadcast/multicast data using lowest
 	 * rate. */
 	 * rate. */
 	if (!ieee80211_is_data(hdr->frame_control) ||
 	if (!ieee80211_is_data(hdr->frame_control) ||
 	    is_multicast_ether_addr(hdr->addr1) || !sta || !lq_sta) {
 	    is_multicast_ether_addr(hdr->addr1) || !sta || !lq_sta) {
-		info->control.rates[0].idx = rate_lowest_index(sband, sta);
+		if (!mask_bit)
+			info->control.rates[0].idx =
+					rate_lowest_index(sband, NULL);
+		else
+			info->control.rates[0].idx =
+					rate_lowest_index(sband, sta);
 		return;
 		return;
 	}
 	}
 
 

+ 1 - 1
drivers/net/wireless/iwlwifi/iwl-agn.c

@@ -2482,7 +2482,7 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 		dev_kfree_skb_any(skb);
 		dev_kfree_skb_any(skb);
 
 
 	IWL_DEBUG_MACDUMP("leave\n");
 	IWL_DEBUG_MACDUMP("leave\n");
-	return 0;
+	return NETDEV_TX_OK;
 }
 }
 
 
 static int iwl_mac_add_interface(struct ieee80211_hw *hw,
 static int iwl_mac_add_interface(struct ieee80211_hw *hw,

+ 1 - 1
drivers/net/wireless/iwlwifi/iwl-hcmd.c

@@ -224,7 +224,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 		IWL_ERROR("Error: Response NULL in '%s'\n",
 		IWL_ERROR("Error: Response NULL in '%s'\n",
 			  get_cmd_string(cmd->id));
 			  get_cmd_string(cmd->id));
 		ret = -EIO;
 		ret = -EIO;
-		goto out;
+		goto cancel;
 	}
 	}
 
 
 	ret = 0;
 	ret = 0;

+ 2 - 2
drivers/net/wireless/iwlwifi/iwl3945-base.c

@@ -745,7 +745,7 @@ static int iwl3945_send_cmd_sync(struct iwl3945_priv *priv, struct iwl3945_host_
 		IWL_ERROR("Error: Response NULL in '%s'\n",
 		IWL_ERROR("Error: Response NULL in '%s'\n",
 			  get_cmd_string(cmd->id));
 			  get_cmd_string(cmd->id));
 		ret = -EIO;
 		ret = -EIO;
-		goto out;
+		goto cancel;
 	}
 	}
 
 
 	ret = 0;
 	ret = 0;
@@ -6538,7 +6538,7 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 		dev_kfree_skb_any(skb);
 		dev_kfree_skb_any(skb);
 
 
 	IWL_DEBUG_MAC80211("leave\n");
 	IWL_DEBUG_MAC80211("leave\n");
-	return 0;
+	return NETDEV_TX_OK;
 }
 }
 
 
 static int iwl3945_mac_add_interface(struct ieee80211_hw *hw,
 static int iwl3945_mac_add_interface(struct ieee80211_hw *hw,

+ 45 - 46
drivers/net/wireless/libertas/hostcmd.h

@@ -32,7 +32,7 @@ struct txpd {
 	u8 pktdelay_2ms;
 	u8 pktdelay_2ms;
 	/* reserved */
 	/* reserved */
 	u8 reserved1;
 	u8 reserved1;
-};
+} __attribute__ ((packed));
 
 
 /* RxPD Descriptor */
 /* RxPD Descriptor */
 struct rxpd {
 struct rxpd {
@@ -63,7 +63,7 @@ struct rxpd {
 	/* Pkt Priority */
 	/* Pkt Priority */
 	u8 priority;
 	u8 priority;
 	u8 reserved[3];
 	u8 reserved[3];
-};
+} __attribute__ ((packed));
 
 
 struct cmd_header {
 struct cmd_header {
 	__le16 command;
 	__le16 command;
@@ -97,7 +97,7 @@ struct enc_key {
 struct lbs_offset_value {
 struct lbs_offset_value {
 	u32 offset;
 	u32 offset;
 	u32 value;
 	u32 value;
-};
+} __attribute__ ((packed));
 
 
 /* Define general data structure */
 /* Define general data structure */
 /* cmd_DS_GEN */
 /* cmd_DS_GEN */
@@ -107,7 +107,7 @@ struct cmd_ds_gen {
 	__le16 seqnum;
 	__le16 seqnum;
 	__le16 result;
 	__le16 result;
 	void *cmdresp[0];
 	void *cmdresp[0];
-};
+} __attribute__ ((packed));
 
 
 #define S_DS_GEN sizeof(struct cmd_ds_gen)
 #define S_DS_GEN sizeof(struct cmd_ds_gen)
 
 
@@ -163,7 +163,7 @@ struct cmd_ds_802_11_subscribe_event {
 	 * bump this up a bit.
 	 * bump this up a bit.
 	 */
 	 */
 	uint8_t tlv[128];
 	uint8_t tlv[128];
-};
+} __attribute__ ((packed));
 
 
 /*
 /*
  * This scan handle Country Information IE(802.11d compliant)
  * This scan handle Country Information IE(802.11d compliant)
@@ -180,7 +180,7 @@ struct cmd_ds_802_11_scan {
 	mrvlietypes_chanlistparamset_t ChanListParamSet;
 	mrvlietypes_chanlistparamset_t ChanListParamSet;
 	mrvlietypes_ratesparamset_t OpRateSet;
 	mrvlietypes_ratesparamset_t OpRateSet;
 #endif
 #endif
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_802_11_scan_rsp {
 struct cmd_ds_802_11_scan_rsp {
 	struct cmd_header hdr;
 	struct cmd_header hdr;
@@ -188,7 +188,7 @@ struct cmd_ds_802_11_scan_rsp {
 	__le16 bssdescriptsize;
 	__le16 bssdescriptsize;
 	uint8_t nr_sets;
 	uint8_t nr_sets;
 	uint8_t bssdesc_and_tlvbuffer[0];
 	uint8_t bssdesc_and_tlvbuffer[0];
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_802_11_get_log {
 struct cmd_ds_802_11_get_log {
 	struct cmd_header hdr;
 	struct cmd_header hdr;
@@ -206,33 +206,33 @@ struct cmd_ds_802_11_get_log {
 	__le32 fcserror;
 	__le32 fcserror;
 	__le32 txframe;
 	__le32 txframe;
 	__le32 wepundecryptable;
 	__le32 wepundecryptable;
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_mac_control {
 struct cmd_ds_mac_control {
 	struct cmd_header hdr;
 	struct cmd_header hdr;
 	__le16 action;
 	__le16 action;
 	u16 reserved;
 	u16 reserved;
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_mac_multicast_adr {
 struct cmd_ds_mac_multicast_adr {
 	struct cmd_header hdr;
 	struct cmd_header hdr;
 	__le16 action;
 	__le16 action;
 	__le16 nr_of_adrs;
 	__le16 nr_of_adrs;
 	u8 maclist[ETH_ALEN * MRVDRV_MAX_MULTICAST_LIST_SIZE];
 	u8 maclist[ETH_ALEN * MRVDRV_MAX_MULTICAST_LIST_SIZE];
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_802_11_authenticate {
 struct cmd_ds_802_11_authenticate {
 	u8 macaddr[ETH_ALEN];
 	u8 macaddr[ETH_ALEN];
 	u8 authtype;
 	u8 authtype;
 	u8 reserved[10];
 	u8 reserved[10];
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_802_11_deauthenticate {
 struct cmd_ds_802_11_deauthenticate {
 	struct cmd_header hdr;
 	struct cmd_header hdr;
 
 
 	u8 macaddr[ETH_ALEN];
 	u8 macaddr[ETH_ALEN];
 	__le16 reasoncode;
 	__le16 reasoncode;
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_802_11_associate {
 struct cmd_ds_802_11_associate {
 	u8 peerstaaddr[6];
 	u8 peerstaaddr[6];
@@ -251,7 +251,7 @@ struct cmd_ds_802_11_associate {
 
 
 struct cmd_ds_802_11_associate_rsp {
 struct cmd_ds_802_11_associate_rsp {
 	struct ieeetypes_assocrsp assocRsp;
 	struct ieeetypes_assocrsp assocRsp;
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_802_11_set_wep {
 struct cmd_ds_802_11_set_wep {
 	struct cmd_header hdr;
 	struct cmd_header hdr;
@@ -265,7 +265,7 @@ struct cmd_ds_802_11_set_wep {
 	/* 40, 128bit or TXWEP */
 	/* 40, 128bit or TXWEP */
 	uint8_t keytype[4];
 	uint8_t keytype[4];
 	uint8_t keymaterial[4][16];
 	uint8_t keymaterial[4][16];
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_802_3_get_stat {
 struct cmd_ds_802_3_get_stat {
 	__le32 xmitok;
 	__le32 xmitok;
@@ -274,7 +274,7 @@ struct cmd_ds_802_3_get_stat {
 	__le32 rcverror;
 	__le32 rcverror;
 	__le32 rcvnobuffer;
 	__le32 rcvnobuffer;
 	__le32 rcvcrcerror;
 	__le32 rcvcrcerror;
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_802_11_get_stat {
 struct cmd_ds_802_11_get_stat {
 	__le32 txfragmentcnt;
 	__le32 txfragmentcnt;
@@ -294,7 +294,7 @@ struct cmd_ds_802_11_get_stat {
 	__le32 txbeacon;
 	__le32 txbeacon;
 	__le32 rxbeacon;
 	__le32 rxbeacon;
 	__le32 wepundecryptable;
 	__le32 wepundecryptable;
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_802_11_snmp_mib {
 struct cmd_ds_802_11_snmp_mib {
 	struct cmd_header hdr;
 	struct cmd_header hdr;
@@ -303,58 +303,58 @@ struct cmd_ds_802_11_snmp_mib {
 	__le16 oid;
 	__le16 oid;
 	__le16 bufsize;
 	__le16 bufsize;
 	u8 value[128];
 	u8 value[128];
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_mac_reg_map {
 struct cmd_ds_mac_reg_map {
 	__le16 buffersize;
 	__le16 buffersize;
 	u8 regmap[128];
 	u8 regmap[128];
 	__le16 reserved;
 	__le16 reserved;
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_bbp_reg_map {
 struct cmd_ds_bbp_reg_map {
 	__le16 buffersize;
 	__le16 buffersize;
 	u8 regmap[128];
 	u8 regmap[128];
 	__le16 reserved;
 	__le16 reserved;
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_rf_reg_map {
 struct cmd_ds_rf_reg_map {
 	__le16 buffersize;
 	__le16 buffersize;
 	u8 regmap[64];
 	u8 regmap[64];
 	__le16 reserved;
 	__le16 reserved;
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_mac_reg_access {
 struct cmd_ds_mac_reg_access {
 	__le16 action;
 	__le16 action;
 	__le16 offset;
 	__le16 offset;
 	__le32 value;
 	__le32 value;
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_bbp_reg_access {
 struct cmd_ds_bbp_reg_access {
 	__le16 action;
 	__le16 action;
 	__le16 offset;
 	__le16 offset;
 	u8 value;
 	u8 value;
 	u8 reserved[3];
 	u8 reserved[3];
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_rf_reg_access {
 struct cmd_ds_rf_reg_access {
 	__le16 action;
 	__le16 action;
 	__le16 offset;
 	__le16 offset;
 	u8 value;
 	u8 value;
 	u8 reserved[3];
 	u8 reserved[3];
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_802_11_radio_control {
 struct cmd_ds_802_11_radio_control {
 	struct cmd_header hdr;
 	struct cmd_header hdr;
 
 
 	__le16 action;
 	__le16 action;
 	__le16 control;
 	__le16 control;
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_802_11_beacon_control {
 struct cmd_ds_802_11_beacon_control {
 	__le16 action;
 	__le16 action;
 	__le16 beacon_enable;
 	__le16 beacon_enable;
 	__le16 beacon_period;
 	__le16 beacon_period;
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_802_11_sleep_params {
 struct cmd_ds_802_11_sleep_params {
 	struct cmd_header hdr;
 	struct cmd_header hdr;
@@ -379,7 +379,7 @@ struct cmd_ds_802_11_sleep_params {
 
 
 	/* reserved field, should be set to zero */
 	/* reserved field, should be set to zero */
 	__le16 reserved;
 	__le16 reserved;
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_802_11_inactivity_timeout {
 struct cmd_ds_802_11_inactivity_timeout {
 	struct cmd_header hdr;
 	struct cmd_header hdr;
@@ -389,7 +389,7 @@ struct cmd_ds_802_11_inactivity_timeout {
 
 
 	/* Inactivity timeout in msec */
 	/* Inactivity timeout in msec */
 	__le16 timeout;
 	__le16 timeout;
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_802_11_rf_channel {
 struct cmd_ds_802_11_rf_channel {
 	struct cmd_header hdr;
 	struct cmd_header hdr;
@@ -399,7 +399,7 @@ struct cmd_ds_802_11_rf_channel {
 	__le16 rftype;      /* unused */
 	__le16 rftype;      /* unused */
 	__le16 reserved;    /* unused */
 	__le16 reserved;    /* unused */
 	u8 channellist[32]; /* unused */
 	u8 channellist[32]; /* unused */
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_802_11_rssi {
 struct cmd_ds_802_11_rssi {
 	/* weighting factor */
 	/* weighting factor */
@@ -408,21 +408,21 @@ struct cmd_ds_802_11_rssi {
 	__le16 reserved_0;
 	__le16 reserved_0;
 	__le16 reserved_1;
 	__le16 reserved_1;
 	__le16 reserved_2;
 	__le16 reserved_2;
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_802_11_rssi_rsp {
 struct cmd_ds_802_11_rssi_rsp {
 	__le16 SNR;
 	__le16 SNR;
 	__le16 noisefloor;
 	__le16 noisefloor;
 	__le16 avgSNR;
 	__le16 avgSNR;
 	__le16 avgnoisefloor;
 	__le16 avgnoisefloor;
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_802_11_mac_address {
 struct cmd_ds_802_11_mac_address {
 	struct cmd_header hdr;
 	struct cmd_header hdr;
 
 
 	__le16 action;
 	__le16 action;
 	u8 macadd[ETH_ALEN];
 	u8 macadd[ETH_ALEN];
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_802_11_rf_tx_power {
 struct cmd_ds_802_11_rf_tx_power {
 	struct cmd_header hdr;
 	struct cmd_header hdr;
@@ -431,7 +431,7 @@ struct cmd_ds_802_11_rf_tx_power {
 	__le16 curlevel;
 	__le16 curlevel;
 	s8 maxlevel;
 	s8 maxlevel;
 	s8 minlevel;
 	s8 minlevel;
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_802_11_rf_antenna {
 struct cmd_ds_802_11_rf_antenna {
 	__le16 action;
 	__le16 action;
@@ -439,33 +439,33 @@ struct cmd_ds_802_11_rf_antenna {
 	/* Number of antennas or 0xffff(diversity) */
 	/* Number of antennas or 0xffff(diversity) */
 	__le16 antennamode;
 	__le16 antennamode;
 
 
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_802_11_monitor_mode {
 struct cmd_ds_802_11_monitor_mode {
 	__le16 action;
 	__le16 action;
 	__le16 mode;
 	__le16 mode;
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_set_boot2_ver {
 struct cmd_ds_set_boot2_ver {
 	struct cmd_header hdr;
 	struct cmd_header hdr;
 
 
 	__le16 action;
 	__le16 action;
 	__le16 version;
 	__le16 version;
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_802_11_fw_wake_method {
 struct cmd_ds_802_11_fw_wake_method {
 	struct cmd_header hdr;
 	struct cmd_header hdr;
 
 
 	__le16 action;
 	__le16 action;
 	__le16 method;
 	__le16 method;
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_802_11_sleep_period {
 struct cmd_ds_802_11_sleep_period {
 	struct cmd_header hdr;
 	struct cmd_header hdr;
 
 
 	__le16 action;
 	__le16 action;
 	__le16 period;
 	__le16 period;
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_802_11_ps_mode {
 struct cmd_ds_802_11_ps_mode {
 	__le16 action;
 	__le16 action;
@@ -473,7 +473,7 @@ struct cmd_ds_802_11_ps_mode {
 	__le16 multipledtim;
 	__le16 multipledtim;
 	__le16 reserved;
 	__le16 reserved;
 	__le16 locallisteninterval;
 	__le16 locallisteninterval;
-};
+} __attribute__ ((packed));
 
 
 struct cmd_confirm_sleep {
 struct cmd_confirm_sleep {
 	struct cmd_header hdr;
 	struct cmd_header hdr;
@@ -483,7 +483,7 @@ struct cmd_confirm_sleep {
 	__le16 multipledtim;
 	__le16 multipledtim;
 	__le16 reserved;
 	__le16 reserved;
 	__le16 locallisteninterval;
 	__le16 locallisteninterval;
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_802_11_data_rate {
 struct cmd_ds_802_11_data_rate {
 	struct cmd_header hdr;
 	struct cmd_header hdr;
@@ -491,14 +491,14 @@ struct cmd_ds_802_11_data_rate {
 	__le16 action;
 	__le16 action;
 	__le16 reserved;
 	__le16 reserved;
 	u8 rates[MAX_RATES];
 	u8 rates[MAX_RATES];
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_802_11_rate_adapt_rateset {
 struct cmd_ds_802_11_rate_adapt_rateset {
 	struct cmd_header hdr;
 	struct cmd_header hdr;
 	__le16 action;
 	__le16 action;
 	__le16 enablehwauto;
 	__le16 enablehwauto;
 	__le16 bitmap;
 	__le16 bitmap;
-};
+} __attribute__ ((packed));
 
 
 struct cmd_ds_802_11_ad_hoc_start {
 struct cmd_ds_802_11_ad_hoc_start {
 	struct cmd_header hdr;
 	struct cmd_header hdr;
@@ -520,7 +520,7 @@ struct cmd_ds_802_11_ad_hoc_result {
 
 
 	u8 pad[3];
 	u8 pad[3];
 	u8 bssid[ETH_ALEN];
 	u8 bssid[ETH_ALEN];
-};
+} __attribute__ ((packed));
 
 
 struct adhoc_bssdesc {
 struct adhoc_bssdesc {
 	u8 bssid[ETH_ALEN];
 	u8 bssid[ETH_ALEN];
@@ -578,7 +578,7 @@ struct MrvlIEtype_keyParamSet {
 
 
 	/* key material of size keylen */
 	/* key material of size keylen */
 	u8 key[32];
 	u8 key[32];
-};
+} __attribute__ ((packed));
 
 
 #define MAX_WOL_RULES 		16
 #define MAX_WOL_RULES 		16
 
 
@@ -590,7 +590,7 @@ struct host_wol_rule {
 	__le16 reserve;
 	__le16 reserve;
 	__be32 sig_mask;
 	__be32 sig_mask;
 	__be32 signature;
 	__be32 signature;
-};
+} __attribute__ ((packed));
 
 
 struct wol_config {
 struct wol_config {
 	uint8_t action;
 	uint8_t action;
@@ -598,8 +598,7 @@ struct wol_config {
 	uint8_t no_rules_in_cmd;
 	uint8_t no_rules_in_cmd;
 	uint8_t result;
 	uint8_t result;
 	struct host_wol_rule rule[MAX_WOL_RULES];
 	struct host_wol_rule rule[MAX_WOL_RULES];
-};
-
+} __attribute__ ((packed));
 
 
 struct cmd_ds_host_sleep {
 struct cmd_ds_host_sleep {
 	struct cmd_header hdr;
 	struct cmd_header hdr;

+ 14 - 18
drivers/net/wireless/orinoco/orinoco.c

@@ -1673,7 +1673,7 @@ static void print_linkstatus(struct net_device *dev, u16 status)
 		s = "UNKNOWN";
 		s = "UNKNOWN";
 	}
 	}
 	
 	
-	printk(KERN_INFO "%s: New link status: %s (%04x)\n",
+	printk(KERN_DEBUG "%s: New link status: %s (%04x)\n",
 	       dev->name, s, status);
 	       dev->name, s, status);
 }
 }
 
 
@@ -5068,33 +5068,30 @@ static int orinoco_ioctl_set_genie(struct net_device *dev,
 	struct orinoco_private *priv = netdev_priv(dev);
 	struct orinoco_private *priv = netdev_priv(dev);
 	u8 *buf;
 	u8 *buf;
 	unsigned long flags;
 	unsigned long flags;
-	int err = 0;
 
 
 	/* cut off at IEEE80211_MAX_DATA_LEN */
 	/* cut off at IEEE80211_MAX_DATA_LEN */
 	if ((wrqu->data.length > IEEE80211_MAX_DATA_LEN) ||
 	if ((wrqu->data.length > IEEE80211_MAX_DATA_LEN) ||
 	    (wrqu->data.length && (extra == NULL)))
 	    (wrqu->data.length && (extra == NULL)))
 		return -EINVAL;
 		return -EINVAL;
 
 
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
 	if (wrqu->data.length) {
 	if (wrqu->data.length) {
 		buf = kmalloc(wrqu->data.length, GFP_KERNEL);
 		buf = kmalloc(wrqu->data.length, GFP_KERNEL);
-		if (buf == NULL) {
-			err = -ENOMEM;
-			goto out;
-		}
+		if (buf == NULL)
+			return -ENOMEM;
 
 
 		memcpy(buf, extra, wrqu->data.length);
 		memcpy(buf, extra, wrqu->data.length);
-		kfree(priv->wpa_ie);
-		priv->wpa_ie = buf;
-		priv->wpa_ie_len = wrqu->data.length;
-	} else {
-		kfree(priv->wpa_ie);
-		priv->wpa_ie = NULL;
-		priv->wpa_ie_len = 0;
+	} else
+		buf = NULL;
+
+	if (orinoco_lock(priv, &flags) != 0) {
+		kfree(buf);
+		return -EBUSY;
 	}
 	}
 
 
+	kfree(priv->wpa_ie);
+	priv->wpa_ie = buf;
+	priv->wpa_ie_len = wrqu->data.length;
+
 	if (priv->wpa_ie) {
 	if (priv->wpa_ie) {
 		/* Looks like wl_lkm wants to check the auth alg, and
 		/* Looks like wl_lkm wants to check the auth alg, and
 		 * somehow pass it to the firmware.
 		 * somehow pass it to the firmware.
@@ -5103,9 +5100,8 @@ static int orinoco_ioctl_set_genie(struct net_device *dev,
 		 */
 		 */
 	}
 	}
 
 
-out:
 	orinoco_unlock(priv, &flags);
 	orinoco_unlock(priv, &flags);
-	return err;
+	return 0;
 }
 }
 
 
 static int orinoco_ioctl_get_genie(struct net_device *dev,
 static int orinoco_ioctl_get_genie(struct net_device *dev,

+ 22 - 8
drivers/net/wireless/p54/p54common.c

@@ -451,8 +451,8 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
 			}
 			}
 			if (err)
 			if (err)
 				goto err;
 				goto err;
-
-		}
+			}
+			break;
 		case PDR_PRISM_ZIF_TX_IQ_CALIBRATION:
 		case PDR_PRISM_ZIF_TX_IQ_CALIBRATION:
 			priv->iq_autocal = kmalloc(data_len, GFP_KERNEL);
 			priv->iq_autocal = kmalloc(data_len, GFP_KERNEL);
 			if (!priv->iq_autocal) {
 			if (!priv->iq_autocal) {
@@ -745,7 +745,7 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
 		struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry);
 		struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry);
 		struct p54_hdr *entry_hdr;
 		struct p54_hdr *entry_hdr;
 		struct p54_tx_data *entry_data;
 		struct p54_tx_data *entry_data;
-		int pad = 0;
+		unsigned int pad = 0, frame_len;
 
 
 		range = (void *)info->rate_driver_data;
 		range = (void *)info->rate_driver_data;
 		if (range->start_addr != addr) {
 		if (range->start_addr != addr) {
@@ -768,6 +768,7 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
 		__skb_unlink(entry, &priv->tx_queue);
 		__skb_unlink(entry, &priv->tx_queue);
 		spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
 		spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
 
 
+		frame_len = entry->len;
 		entry_hdr = (struct p54_hdr *) entry->data;
 		entry_hdr = (struct p54_hdr *) entry->data;
 		entry_data = (struct p54_tx_data *) entry_hdr->data;
 		entry_data = (struct p54_tx_data *) entry_hdr->data;
 		priv->tx_stats[entry_data->hw_queue].len--;
 		priv->tx_stats[entry_data->hw_queue].len--;
@@ -814,15 +815,28 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
 		info->status.ack_signal = p54_rssi_to_dbm(dev,
 		info->status.ack_signal = p54_rssi_to_dbm(dev,
 				(int)payload->ack_rssi);
 				(int)payload->ack_rssi);
 
 
-		if (entry_data->key_type == P54_CRYPTO_TKIPMICHAEL) {
+		/* Undo all changes to the frame. */
+		switch (entry_data->key_type) {
+		case P54_CRYPTO_TKIPMICHAEL: {
 			u8 *iv = (u8 *)(entry_data->align + pad +
 			u8 *iv = (u8 *)(entry_data->align + pad +
-				        entry_data->crypt_offset);
+					entry_data->crypt_offset);
 
 
 			/* Restore the original TKIP IV. */
 			/* Restore the original TKIP IV. */
 			iv[2] = iv[0];
 			iv[2] = iv[0];
 			iv[0] = iv[1];
 			iv[0] = iv[1];
 			iv[1] = (iv[0] | 0x20) & 0x7f;	/* WEPSeed - 8.3.2.2 */
 			iv[1] = (iv[0] | 0x20) & 0x7f;	/* WEPSeed - 8.3.2.2 */
+
+			frame_len -= 12; /* remove TKIP_MMIC + TKIP_ICV */
+			break;
+			}
+		case P54_CRYPTO_AESCCMP:
+			frame_len -= 8; /* remove CCMP_MIC */
+			break;
+		case P54_CRYPTO_WEP:
+			frame_len -= 4; /* remove WEP_ICV */
+			break;
 		}
 		}
+		skb_trim(entry, frame_len);
 		skb_pull(entry, sizeof(*hdr) + pad + sizeof(*entry_data));
 		skb_pull(entry, sizeof(*hdr) + pad + sizeof(*entry_data));
 		ieee80211_tx_status_irqsafe(dev, entry);
 		ieee80211_tx_status_irqsafe(dev, entry);
 		goto out;
 		goto out;
@@ -1147,7 +1161,7 @@ static int p54_set_tim(struct ieee80211_hw *dev, struct ieee80211_sta *sta,
 
 
 	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET,
 	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET,
 		      sizeof(struct p54_hdr) + sizeof(*tim),
 		      sizeof(struct p54_hdr) + sizeof(*tim),
-		      P54_CONTROL_TYPE_TIM, GFP_KERNEL);
+		      P54_CONTROL_TYPE_TIM, GFP_ATOMIC);
 	if (!skb)
 	if (!skb)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
@@ -1610,7 +1624,7 @@ static int p54_scan(struct ieee80211_hw *dev, u16 mode, u16 dwell)
 
 
  err:
  err:
 	printk(KERN_ERR "%s: frequency change failed\n", wiphy_name(dev->wiphy));
 	printk(KERN_ERR "%s: frequency change failed\n", wiphy_name(dev->wiphy));
-	kfree_skb(skb);
+	p54_free_skb(dev, skb);
 	return -EINVAL;
 	return -EINVAL;
 }
 }
 
 
@@ -2077,7 +2091,7 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
 			algo = P54_CRYPTO_AESCCMP;
 			algo = P54_CRYPTO_AESCCMP;
 			break;
 			break;
 		default:
 		default:
-			return -EINVAL;
+			return -EOPNOTSUPP;
 		}
 		}
 	}
 	}
 
 

+ 18 - 23
drivers/net/wireless/p54/p54usb.c

@@ -144,11 +144,8 @@ static void p54u_tx_cb(struct urb *urb)
 	struct sk_buff *skb = urb->context;
 	struct sk_buff *skb = urb->context;
 	struct ieee80211_hw *dev = (struct ieee80211_hw *)
 	struct ieee80211_hw *dev = (struct ieee80211_hw *)
 		usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
 		usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
-	struct p54u_priv *priv = dev->priv;
 
 
-	skb_pull(skb, priv->common.tx_hdr_len);
-	if (FREE_AFTER_TX(skb))
-		p54_free_skb(dev, skb);
+	p54_free_skb(dev, skb);
 }
 }
 
 
 static void p54u_tx_dummy_cb(struct urb *urb) { }
 static void p54u_tx_dummy_cb(struct urb *urb) { }
@@ -230,7 +227,10 @@ static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb)
 			  p54u_tx_dummy_cb, dev);
 			  p54u_tx_dummy_cb, dev);
 	usb_fill_bulk_urb(data_urb, priv->udev,
 	usb_fill_bulk_urb(data_urb, priv->udev,
 			  usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
 			  usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
-			  skb->data, skb->len, p54u_tx_cb, skb);
+			  skb->data, skb->len, FREE_AFTER_TX(skb) ?
+			  p54u_tx_cb : p54u_tx_dummy_cb, skb);
+	addr_urb->transfer_flags |= URB_ZERO_PACKET;
+	data_urb->transfer_flags |= URB_ZERO_PACKET;
 
 
 	usb_anchor_urb(addr_urb, &priv->submitted);
 	usb_anchor_urb(addr_urb, &priv->submitted);
 	err = usb_submit_urb(addr_urb, GFP_ATOMIC);
 	err = usb_submit_urb(addr_urb, GFP_ATOMIC);
@@ -239,7 +239,7 @@ static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb)
 		goto out;
 		goto out;
 	}
 	}
 
 
-	usb_anchor_urb(addr_urb, &priv->submitted);
+	usb_anchor_urb(data_urb, &priv->submitted);
 	err = usb_submit_urb(data_urb, GFP_ATOMIC);
 	err = usb_submit_urb(data_urb, GFP_ATOMIC);
 	if (err)
 	if (err)
 		usb_unanchor_urb(data_urb);
 		usb_unanchor_urb(data_urb);
@@ -269,28 +269,24 @@ static void p54u_tx_lm87(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
 {
 	struct p54u_priv *priv = dev->priv;
 	struct p54u_priv *priv = dev->priv;
 	struct urb *data_urb;
 	struct urb *data_urb;
-	struct lm87_tx_hdr *hdr;
-	__le32 checksum;
-	__le32 addr = ((struct p54_hdr *)skb->data)->req_id;
+	struct lm87_tx_hdr *hdr = (void *)skb->data - sizeof(*hdr);
 
 
 	data_urb = usb_alloc_urb(0, GFP_ATOMIC);
 	data_urb = usb_alloc_urb(0, GFP_ATOMIC);
 	if (!data_urb)
 	if (!data_urb)
 		return;
 		return;
 
 
-	checksum = p54u_lm87_chksum((__le32 *)skb->data, skb->len);
-	hdr = (struct lm87_tx_hdr *)skb_push(skb, sizeof(*hdr));
-	hdr->chksum = checksum;
-	hdr->device_addr = addr;
+	hdr->chksum = p54u_lm87_chksum((__le32 *)skb->data, skb->len);
+	hdr->device_addr = ((struct p54_hdr *)skb->data)->req_id;
 
 
 	usb_fill_bulk_urb(data_urb, priv->udev,
 	usb_fill_bulk_urb(data_urb, priv->udev,
 			  usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
 			  usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
-			  skb->data, skb->len, p54u_tx_cb, skb);
+			  hdr, skb->len + sizeof(*hdr),  FREE_AFTER_TX(skb) ?
+			  p54u_tx_cb : p54u_tx_dummy_cb, skb);
 	data_urb->transfer_flags |= URB_ZERO_PACKET;
 	data_urb->transfer_flags |= URB_ZERO_PACKET;
 
 
 	usb_anchor_urb(data_urb, &priv->submitted);
 	usb_anchor_urb(data_urb, &priv->submitted);
 	if (usb_submit_urb(data_urb, GFP_ATOMIC)) {
 	if (usb_submit_urb(data_urb, GFP_ATOMIC)) {
 		usb_unanchor_urb(data_urb);
 		usb_unanchor_urb(data_urb);
-		skb_pull(skb, sizeof(*hdr));
 		p54_free_skb(dev, skb);
 		p54_free_skb(dev, skb);
 	}
 	}
 	usb_free_urb(data_urb);
 	usb_free_urb(data_urb);
@@ -300,11 +296,9 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
 {
 	struct p54u_priv *priv = dev->priv;
 	struct p54u_priv *priv = dev->priv;
 	struct urb *int_urb, *data_urb;
 	struct urb *int_urb, *data_urb;
-	struct net2280_tx_hdr *hdr;
+	struct net2280_tx_hdr *hdr = (void *)skb->data - sizeof(*hdr);
 	struct net2280_reg_write *reg;
 	struct net2280_reg_write *reg;
 	int err = 0;
 	int err = 0;
-	__le32 addr = ((struct p54_hdr *) skb->data)->req_id;
-	__le16 len = cpu_to_le16(skb->len);
 
 
 	reg = kmalloc(sizeof(*reg), GFP_ATOMIC);
 	reg = kmalloc(sizeof(*reg), GFP_ATOMIC);
 	if (!reg)
 	if (!reg)
@@ -327,10 +321,9 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb)
 	reg->addr = cpu_to_le32(P54U_DEV_BASE);
 	reg->addr = cpu_to_le32(P54U_DEV_BASE);
 	reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA);
 	reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA);
 
 
-	hdr = (void *)skb_push(skb, sizeof(*hdr));
 	memset(hdr, 0, sizeof(*hdr));
 	memset(hdr, 0, sizeof(*hdr));
-	hdr->len = len;
-	hdr->device_addr = addr;
+	hdr->len = cpu_to_le16(skb->len);
+	hdr->device_addr = ((struct p54_hdr *) skb->data)->req_id;
 
 
 	usb_fill_bulk_urb(int_urb, priv->udev,
 	usb_fill_bulk_urb(int_urb, priv->udev,
 		usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), reg, sizeof(*reg),
 		usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), reg, sizeof(*reg),
@@ -341,11 +334,13 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb)
 	 * free what's inside the transfer_buffer after the callback routine
 	 * free what's inside the transfer_buffer after the callback routine
 	 * has completed.
 	 * has completed.
 	 */
 	 */
-	int_urb->transfer_flags |= URB_FREE_BUFFER;
+	int_urb->transfer_flags |= URB_FREE_BUFFER | URB_ZERO_PACKET;
 
 
 	usb_fill_bulk_urb(data_urb, priv->udev,
 	usb_fill_bulk_urb(data_urb, priv->udev,
 			  usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
 			  usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
-			  skb->data, skb->len, p54u_tx_cb, skb);
+			  hdr, skb->len + sizeof(*hdr), FREE_AFTER_TX(skb) ?
+			  p54u_tx_cb : p54u_tx_dummy_cb, skb);
+	data_urb->transfer_flags |= URB_ZERO_PACKET;
 
 
 	usb_anchor_urb(int_urb, &priv->submitted);
 	usb_anchor_urb(int_urb, &priv->submitted);
 	err = usb_submit_urb(int_urb, GFP_ATOMIC);
 	err = usb_submit_urb(int_urb, GFP_ATOMIC);

+ 0 - 2
drivers/net/wireless/rndis_wlan.c

@@ -1649,9 +1649,7 @@ static char *rndis_translate_scan(struct net_device *dev,
 				  char *end_buf,
 				  char *end_buf,
 				  struct ndis_80211_bssid_ex *bssid)
 				  struct ndis_80211_bssid_ex *bssid)
 {
 {
-#ifdef DEBUG
 	struct usbnet *usbdev = netdev_priv(dev);
 	struct usbnet *usbdev = netdev_priv(dev);
-#endif
 	u8 *ie;
 	u8 *ie;
 	char *current_val;
 	char *current_val;
 	int bssid_len, ie_len, i;
 	int bssid_len, ie_len, i;

+ 2 - 1
drivers/net/wireless/rt2x00/rt2x00queue.c

@@ -154,6 +154,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
+	struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0];
 	struct ieee80211_rate *rate =
 	struct ieee80211_rate *rate =
 	    ieee80211_get_tx_rate(rt2x00dev->hw, tx_info);
 	    ieee80211_get_tx_rate(rt2x00dev->hw, tx_info);
 	const struct rt2x00_rate *hwrate;
 	const struct rt2x00_rate *hwrate;
@@ -313,7 +314,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
 		 * When preamble is enabled we should set the
 		 * When preamble is enabled we should set the
 		 * preamble bit for the signal.
 		 * preamble bit for the signal.
 		 */
 		 */
-		if (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
+		if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
 			txdesc->signal |= 0x08;
 			txdesc->signal |= 0x08;
 	}
 	}
 }
 }

+ 1 - 1
drivers/net/wireless/rt2x00/rt2x00rfkill.c

@@ -162,7 +162,7 @@ void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
 
 
 void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
 void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
 {
 {
-	if (!test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->flags))
+	if (!test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state))
 		return;
 		return;
 
 
 	cancel_delayed_work_sync(&rt2x00dev->rfkill_work);
 	cancel_delayed_work_sync(&rt2x00dev->rfkill_work);

+ 1 - 0
drivers/net/wireless/rtl818x/rtl8187_dev.c

@@ -273,6 +273,7 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
 
 
 	usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, ep),
 	usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, ep),
 			  buf, skb->len, rtl8187_tx_cb, skb);
 			  buf, skb->len, rtl8187_tx_cb, skb);
+	urb->transfer_flags |= URB_ZERO_PACKET;
 	usb_anchor_urb(urb, &priv->anchored);
 	usb_anchor_urb(urb, &priv->anchored);
 	rc = usb_submit_urb(urb, GFP_ATOMIC);
 	rc = usb_submit_urb(urb, GFP_ATOMIC);
 	if (rc < 0) {
 	if (rc < 0) {

+ 1 - 0
drivers/net/wireless/zd1211rw/zd_usb.c

@@ -84,6 +84,7 @@ static struct usb_device_id usb_ids[] = {
 	{ USB_DEVICE(0x0586, 0x340a), .driver_info = DEVICE_ZD1211B },
 	{ USB_DEVICE(0x0586, 0x340a), .driver_info = DEVICE_ZD1211B },
 	{ USB_DEVICE(0x0471, 0x1237), .driver_info = DEVICE_ZD1211B },
 	{ USB_DEVICE(0x0471, 0x1237), .driver_info = DEVICE_ZD1211B },
 	{ USB_DEVICE(0x07fa, 0x1196), .driver_info = DEVICE_ZD1211B },
 	{ USB_DEVICE(0x07fa, 0x1196), .driver_info = DEVICE_ZD1211B },
+	{ USB_DEVICE(0x0df6, 0x0036), .driver_info = DEVICE_ZD1211B },
 	/* "Driverless" devices that need ejecting */
 	/* "Driverless" devices that need ejecting */
 	{ USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER },
 	{ USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER },
 	{ USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER },
 	{ USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER },

+ 6 - 2
drivers/s390/net/lcs.c

@@ -70,7 +70,9 @@ static char debug_buffer[255];
 static void lcs_tasklet(unsigned long);
 static void lcs_tasklet(unsigned long);
 static void lcs_start_kernel_thread(struct work_struct *);
 static void lcs_start_kernel_thread(struct work_struct *);
 static void lcs_get_frames_cb(struct lcs_channel *, struct lcs_buffer *);
 static void lcs_get_frames_cb(struct lcs_channel *, struct lcs_buffer *);
+#ifdef CONFIG_IP_MULTICAST
 static int lcs_send_delipm(struct lcs_card *, struct lcs_ipm_list *);
 static int lcs_send_delipm(struct lcs_card *, struct lcs_ipm_list *);
+#endif /* CONFIG_IP_MULTICAST */
 static int lcs_recovery(void *ptr);
 static int lcs_recovery(void *ptr);
 
 
 /**
 /**
@@ -1285,6 +1287,8 @@ out:
 	lcs_clear_thread_running_bit(card, LCS_SET_MC_THREAD);
 	lcs_clear_thread_running_bit(card, LCS_SET_MC_THREAD);
 	return 0;
 	return 0;
 }
 }
+#endif /* CONFIG_IP_MULTICAST */
+
 /**
 /**
  * function called by net device to
  * function called by net device to
  * handle multicast address relevant things
  * handle multicast address relevant things
@@ -1292,6 +1296,7 @@ out:
 static void
 static void
 lcs_set_multicast_list(struct net_device *dev)
 lcs_set_multicast_list(struct net_device *dev)
 {
 {
+#ifdef CONFIG_IP_MULTICAST
         struct lcs_card *card;
         struct lcs_card *card;
 
 
         LCS_DBF_TEXT(4, trace, "setmulti");
         LCS_DBF_TEXT(4, trace, "setmulti");
@@ -1299,9 +1304,8 @@ lcs_set_multicast_list(struct net_device *dev)
 
 
         if (!lcs_set_thread_start_bit(card, LCS_SET_MC_THREAD))
         if (!lcs_set_thread_start_bit(card, LCS_SET_MC_THREAD))
 		schedule_work(&card->kernel_thread_starter);
 		schedule_work(&card->kernel_thread_starter);
-}
-
 #endif /* CONFIG_IP_MULTICAST */
 #endif /* CONFIG_IP_MULTICAST */
+}
 
 
 static long
 static long
 lcs_check_irb_error(struct ccw_device *cdev, struct irb *irb)
 lcs_check_irb_error(struct ccw_device *cdev, struct irb *irb)

+ 4 - 6
include/linux/if_frad.h

@@ -26,8 +26,6 @@
 
 
 #include <linux/if.h>
 #include <linux/if.h>
 
 
-#if defined(CONFIG_DLCI) || defined(CONFIG_DLCI_MODULE)
-
 /* Structures and constants associated with the DLCI device driver */
 /* Structures and constants associated with the DLCI device driver */
 
 
 struct dlci_add
 struct dlci_add
@@ -127,6 +125,8 @@ struct frad_conf
 
 
 #ifdef __KERNEL__
 #ifdef __KERNEL__
 
 
+#if defined(CONFIG_DLCI) || defined(CONFIG_DLCI_MODULE)
+
 /* these are the fields of an RFC 1490 header */
 /* these are the fields of an RFC 1490 header */
 struct frhdr
 struct frhdr
 {
 {
@@ -190,12 +190,10 @@ struct frad_local
    int               buffer;		/* current buffer for S508 firmware */
    int               buffer;		/* current buffer for S508 firmware */
 };
 };
 
 
-#endif /* __KERNEL__ */
-
 #endif /* CONFIG_DLCI || CONFIG_DLCI_MODULE */
 #endif /* CONFIG_DLCI || CONFIG_DLCI_MODULE */
 
 
-#ifdef __KERNEL__
 extern void dlci_ioctl_set(int (*hook)(unsigned int, void __user *));
 extern void dlci_ioctl_set(int (*hook)(unsigned int, void __user *));
-#endif
+
+#endif /* __KERNEL__ */
 
 
 #endif
 #endif

+ 3 - 1
include/linux/usb/usbnet.h

@@ -197,7 +197,9 @@ extern int usbnet_nway_reset(struct net_device *net);
 #define devdbg(usbnet, fmt, arg...) \
 #define devdbg(usbnet, fmt, arg...) \
 	printk(KERN_DEBUG "%s: " fmt "\n" , (usbnet)->net->name , ## arg)
 	printk(KERN_DEBUG "%s: " fmt "\n" , (usbnet)->net->name , ## arg)
 #else
 #else
-#define devdbg(usbnet, fmt, arg...) do {} while(0)
+#define devdbg(usbnet, fmt, arg...) \
+	({ if (0) printk(KERN_DEBUG "%s: " fmt "\n" , (usbnet)->net->name , \
+		## arg); 0; })
 #endif
 #endif
 
 
 #define deverr(usbnet, fmt, arg...) \
 #define deverr(usbnet, fmt, arg...) \

+ 0 - 1
include/net/mac80211.h

@@ -322,7 +322,6 @@ struct ieee80211_tx_rate {
  * @control: union for control data
  * @control: union for control data
  * @status: union for status data
  * @status: union for status data
  * @driver_data: array of driver_data pointers
  * @driver_data: array of driver_data pointers
- * @retry_count: number of retries
  * @ampdu_ack_len: number of aggregated frames.
  * @ampdu_ack_len: number of aggregated frames.
  * 	relevant only if IEEE80211_TX_STATUS_AMPDU was set.
  * 	relevant only if IEEE80211_TX_STATUS_AMPDU was set.
  * @ampdu_ack_map: block ack bit map for the aggregation.
  * @ampdu_ack_map: block ack bit map for the aggregation.

+ 1 - 1
include/net/sctp/checksum.h

@@ -79,5 +79,5 @@ static inline __be32 sctp_update_cksum(__u8 *buffer, __u16 length, __be32 crc32)
 
 
 static inline __be32 sctp_end_cksum(__be32 crc32)
 static inline __be32 sctp_end_cksum(__be32 crc32)
 {
 {
-	return ~crc32;
+	return (__force __be32)~cpu_to_le32((__force u32)crc32);
 }
 }

+ 8 - 0
init/Kconfig

@@ -633,6 +633,14 @@ config PID_NS
 	  Unless you want to work with an experimental feature
 	  Unless you want to work with an experimental feature
 	  say N here.
 	  say N here.
 
 
+config NET_NS
+	bool "Network namespace"
+	default n
+	depends on NAMESPACES && EXPERIMENTAL && NET
+	help
+	  Allow user space to create what appear to be multiple instances
+	  of the network stack.
+
 config BLK_DEV_INITRD
 config BLK_DEV_INITRD
 	bool "Initial RAM filesystem and RAM disk (initramfs/initrd) support"
 	bool "Initial RAM filesystem and RAM disk (initramfs/initrd) support"
 	depends on BROKEN || !FRV
 	depends on BROKEN || !FRV

+ 2 - 2
net/8021q/vlan_core.c

@@ -62,13 +62,13 @@ struct net_device *vlan_dev_real_dev(const struct net_device *dev)
 {
 {
 	return vlan_dev_info(dev)->real_dev;
 	return vlan_dev_info(dev)->real_dev;
 }
 }
-EXPORT_SYMBOL_GPL(vlan_dev_real_dev);
+EXPORT_SYMBOL(vlan_dev_real_dev);
 
 
 u16 vlan_dev_vlan_id(const struct net_device *dev)
 u16 vlan_dev_vlan_id(const struct net_device *dev)
 {
 {
 	return vlan_dev_info(dev)->vlan_id;
 	return vlan_dev_info(dev)->vlan_id;
 }
 }
-EXPORT_SYMBOL_GPL(vlan_dev_vlan_id);
+EXPORT_SYMBOL(vlan_dev_vlan_id);
 
 
 static int vlan_gro_common(struct napi_struct *napi, struct vlan_group *grp,
 static int vlan_gro_common(struct napi_struct *napi, struct vlan_group *grp,
 			   unsigned int vlan_tci, struct sk_buff *skb)
 			   unsigned int vlan_tci, struct sk_buff *skb)

+ 1 - 1
net/9p/client.c

@@ -618,7 +618,7 @@ static struct p9_fid *p9_fid_create(struct p9_client *clnt)
 		return ERR_PTR(-ENOMEM);
 		return ERR_PTR(-ENOMEM);
 
 
 	ret = p9_idpool_get(clnt->fidpool);
 	ret = p9_idpool_get(clnt->fidpool);
-	if (fid->fid < 0) {
+	if (ret < 0) {
 		ret = -ENOSPC;
 		ret = -ENOSPC;
 		goto error;
 		goto error;
 	}
 	}

+ 0 - 8
net/Kconfig

@@ -24,14 +24,6 @@ if NET
 
 
 menu "Networking options"
 menu "Networking options"
 
 
-config NET_NS
-	bool "Network namespace support"
-	default n
-	depends on EXPERIMENTAL && NAMESPACES
-	help
-	  Allow user space to create what appear to be multiple instances
-	  of the network stack.
-
 config COMPAT_NET_DEV_OPS
 config COMPAT_NET_DEV_OPS
        def_bool y
        def_bool y
 
 

+ 14 - 1
net/core/dev.c

@@ -1534,7 +1534,19 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features)
 	skb->mac_len = skb->network_header - skb->mac_header;
 	skb->mac_len = skb->network_header - skb->mac_header;
 	__skb_pull(skb, skb->mac_len);
 	__skb_pull(skb, skb->mac_len);
 
 
-	if (WARN_ON(skb->ip_summed != CHECKSUM_PARTIAL)) {
+	if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) {
+		struct net_device *dev = skb->dev;
+		struct ethtool_drvinfo info = {};
+
+		if (dev && dev->ethtool_ops && dev->ethtool_ops->get_drvinfo)
+			dev->ethtool_ops->get_drvinfo(dev, &info);
+
+		WARN(1, "%s: caps=(0x%lx, 0x%lx) len=%d data_len=%d "
+			"ip_summed=%d",
+		     info.driver, dev ? dev->features : 0L,
+		     skb->sk ? skb->sk->sk_route_caps : 0L,
+		     skb->len, skb->data_len, skb->ip_summed);
+
 		if (skb_header_cloned(skb) &&
 		if (skb_header_cloned(skb) &&
 		    (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
 		    (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
 			return ERR_PTR(err);
 			return ERR_PTR(err);
@@ -2524,6 +2536,7 @@ struct sk_buff *napi_fraginfo_skb(struct napi_struct *napi,
 
 
 	if (!pskb_may_pull(skb, ETH_HLEN)) {
 	if (!pskb_may_pull(skb, ETH_HLEN)) {
 		napi_reuse_skb(napi, skb);
 		napi_reuse_skb(napi, skb);
+		skb = NULL;
 		goto out;
 		goto out;
 	}
 	}
 
 

+ 1 - 1
net/core/net_namespace.c

@@ -341,8 +341,8 @@ again:
 	rv = register_pernet_operations(first_device, ops);
 	rv = register_pernet_operations(first_device, ops);
 	if (rv < 0)
 	if (rv < 0)
 		ida_remove(&net_generic_ids, *id);
 		ida_remove(&net_generic_ids, *id);
-	mutex_unlock(&net_mutex);
 out:
 out:
+	mutex_unlock(&net_mutex);
 	return rv;
 	return rv;
 }
 }
 EXPORT_SYMBOL_GPL(register_pernet_gen_subsys);
 EXPORT_SYMBOL_GPL(register_pernet_gen_subsys);

+ 34 - 36
net/core/skbuff.c

@@ -73,17 +73,13 @@ static struct kmem_cache *skbuff_fclone_cache __read_mostly;
 static void sock_pipe_buf_release(struct pipe_inode_info *pipe,
 static void sock_pipe_buf_release(struct pipe_inode_info *pipe,
 				  struct pipe_buffer *buf)
 				  struct pipe_buffer *buf)
 {
 {
-	struct sk_buff *skb = (struct sk_buff *) buf->private;
-
-	kfree_skb(skb);
+	put_page(buf->page);
 }
 }
 
 
 static void sock_pipe_buf_get(struct pipe_inode_info *pipe,
 static void sock_pipe_buf_get(struct pipe_inode_info *pipe,
 				struct pipe_buffer *buf)
 				struct pipe_buffer *buf)
 {
 {
-	struct sk_buff *skb = (struct sk_buff *) buf->private;
-
-	skb_get(skb);
+	get_page(buf->page);
 }
 }
 
 
 static int sock_pipe_buf_steal(struct pipe_inode_info *pipe,
 static int sock_pipe_buf_steal(struct pipe_inode_info *pipe,
@@ -1334,9 +1330,19 @@ fault:
  */
  */
 static void sock_spd_release(struct splice_pipe_desc *spd, unsigned int i)
 static void sock_spd_release(struct splice_pipe_desc *spd, unsigned int i)
 {
 {
-	struct sk_buff *skb = (struct sk_buff *) spd->partial[i].private;
+	put_page(spd->pages[i]);
+}
 
 
-	kfree_skb(skb);
+static inline struct page *linear_to_page(struct page *page, unsigned int len,
+					  unsigned int offset)
+{
+	struct page *p = alloc_pages(GFP_KERNEL, 0);
+
+	if (!p)
+		return NULL;
+	memcpy(page_address(p) + offset, page_address(page) + offset, len);
+
+	return p;
 }
 }
 
 
 /*
 /*
@@ -1344,16 +1350,23 @@ static void sock_spd_release(struct splice_pipe_desc *spd, unsigned int i)
  */
  */
 static inline int spd_fill_page(struct splice_pipe_desc *spd, struct page *page,
 static inline int spd_fill_page(struct splice_pipe_desc *spd, struct page *page,
 				unsigned int len, unsigned int offset,
 				unsigned int len, unsigned int offset,
-				struct sk_buff *skb)
+				struct sk_buff *skb, int linear)
 {
 {
 	if (unlikely(spd->nr_pages == PIPE_BUFFERS))
 	if (unlikely(spd->nr_pages == PIPE_BUFFERS))
 		return 1;
 		return 1;
 
 
+	if (linear) {
+		page = linear_to_page(page, len, offset);
+		if (!page)
+			return 1;
+	} else
+		get_page(page);
+
 	spd->pages[spd->nr_pages] = page;
 	spd->pages[spd->nr_pages] = page;
 	spd->partial[spd->nr_pages].len = len;
 	spd->partial[spd->nr_pages].len = len;
 	spd->partial[spd->nr_pages].offset = offset;
 	spd->partial[spd->nr_pages].offset = offset;
-	spd->partial[spd->nr_pages].private = (unsigned long) skb_get(skb);
 	spd->nr_pages++;
 	spd->nr_pages++;
+
 	return 0;
 	return 0;
 }
 }
 
 
@@ -1369,7 +1382,7 @@ static inline void __segment_seek(struct page **page, unsigned int *poff,
 static inline int __splice_segment(struct page *page, unsigned int poff,
 static inline int __splice_segment(struct page *page, unsigned int poff,
 				   unsigned int plen, unsigned int *off,
 				   unsigned int plen, unsigned int *off,
 				   unsigned int *len, struct sk_buff *skb,
 				   unsigned int *len, struct sk_buff *skb,
-				   struct splice_pipe_desc *spd)
+				   struct splice_pipe_desc *spd, int linear)
 {
 {
 	if (!*len)
 	if (!*len)
 		return 1;
 		return 1;
@@ -1392,7 +1405,7 @@ static inline int __splice_segment(struct page *page, unsigned int poff,
 		/* the linear region may spread across several pages  */
 		/* the linear region may spread across several pages  */
 		flen = min_t(unsigned int, flen, PAGE_SIZE - poff);
 		flen = min_t(unsigned int, flen, PAGE_SIZE - poff);
 
 
-		if (spd_fill_page(spd, page, flen, poff, skb))
+		if (spd_fill_page(spd, page, flen, poff, skb, linear))
 			return 1;
 			return 1;
 
 
 		__segment_seek(&page, &poff, &plen, flen);
 		__segment_seek(&page, &poff, &plen, flen);
@@ -1419,7 +1432,7 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset,
 	if (__splice_segment(virt_to_page(skb->data),
 	if (__splice_segment(virt_to_page(skb->data),
 			     (unsigned long) skb->data & (PAGE_SIZE - 1),
 			     (unsigned long) skb->data & (PAGE_SIZE - 1),
 			     skb_headlen(skb),
 			     skb_headlen(skb),
-			     offset, len, skb, spd))
+			     offset, len, skb, spd, 1))
 		return 1;
 		return 1;
 
 
 	/*
 	/*
@@ -1429,7 +1442,7 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset,
 		const skb_frag_t *f = &skb_shinfo(skb)->frags[seg];
 		const skb_frag_t *f = &skb_shinfo(skb)->frags[seg];
 
 
 		if (__splice_segment(f->page, f->page_offset, f->size,
 		if (__splice_segment(f->page, f->page_offset, f->size,
-				     offset, len, skb, spd))
+				     offset, len, skb, spd, 0))
 			return 1;
 			return 1;
 	}
 	}
 
 
@@ -1442,7 +1455,7 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset,
  * the frag list, if such a thing exists. We'd probably need to recurse to
  * the frag list, if such a thing exists. We'd probably need to recurse to
  * handle that cleanly.
  * handle that cleanly.
  */
  */
-int skb_splice_bits(struct sk_buff *__skb, unsigned int offset,
+int skb_splice_bits(struct sk_buff *skb, unsigned int offset,
 		    struct pipe_inode_info *pipe, unsigned int tlen,
 		    struct pipe_inode_info *pipe, unsigned int tlen,
 		    unsigned int flags)
 		    unsigned int flags)
 {
 {
@@ -1455,16 +1468,6 @@ int skb_splice_bits(struct sk_buff *__skb, unsigned int offset,
 		.ops = &sock_pipe_buf_ops,
 		.ops = &sock_pipe_buf_ops,
 		.spd_release = sock_spd_release,
 		.spd_release = sock_spd_release,
 	};
 	};
-	struct sk_buff *skb;
-
-	/*
-	 * I'd love to avoid the clone here, but tcp_read_sock()
-	 * ignores reference counts and unconditonally kills the sk_buff
-	 * on return from the actor.
-	 */
-	skb = skb_clone(__skb, GFP_KERNEL);
-	if (unlikely(!skb))
-		return -ENOMEM;
 
 
 	/*
 	/*
 	 * __skb_splice_bits() only fails if the output has no room left,
 	 * __skb_splice_bits() only fails if the output has no room left,
@@ -1488,15 +1491,9 @@ int skb_splice_bits(struct sk_buff *__skb, unsigned int offset,
 	}
 	}
 
 
 done:
 done:
-	/*
-	 * drop our reference to the clone, the pipe consumption will
-	 * drop the rest.
-	 */
-	kfree_skb(skb);
-
 	if (spd.nr_pages) {
 	if (spd.nr_pages) {
+		struct sock *sk = skb->sk;
 		int ret;
 		int ret;
-		struct sock *sk = __skb->sk;
 
 
 		/*
 		/*
 		 * Drop the socket lock, otherwise we have reverse
 		 * Drop the socket lock, otherwise we have reverse
@@ -2588,8 +2585,9 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)
 	struct sk_buff *nskb;
 	struct sk_buff *nskb;
 	unsigned int headroom;
 	unsigned int headroom;
 	unsigned int hlen = p->data - skb_mac_header(p);
 	unsigned int hlen = p->data - skb_mac_header(p);
+	unsigned int len = skb->len;
 
 
-	if (hlen + p->len + skb->len >= 65536)
+	if (hlen + p->len + len >= 65536)
 		return -E2BIG;
 		return -E2BIG;
 
 
 	if (skb_shinfo(p)->frag_list)
 	if (skb_shinfo(p)->frag_list)
@@ -2651,9 +2649,9 @@ merge:
 
 
 done:
 done:
 	NAPI_GRO_CB(p)->count++;
 	NAPI_GRO_CB(p)->count++;
-	p->data_len += skb->len;
-	p->truesize += skb->len;
-	p->len += skb->len;
+	p->data_len += len;
+	p->truesize += len;
+	p->len += len;
 
 
 	NAPI_GRO_CB(skb)->same_flow = 1;
 	NAPI_GRO_CB(skb)->same_flow = 1;
 	return 0;
 	return 0;

+ 7 - 0
net/ipv6/af_inet6.c

@@ -797,6 +797,7 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,
 	unsigned int nlen;
 	unsigned int nlen;
 	int flush = 1;
 	int flush = 1;
 	int proto;
 	int proto;
+	__wsum csum;
 
 
 	if (unlikely(!pskb_may_pull(skb, sizeof(*iph))))
 	if (unlikely(!pskb_may_pull(skb, sizeof(*iph))))
 		goto out;
 		goto out;
@@ -808,6 +809,7 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,
 
 
 	rcu_read_lock();
 	rcu_read_lock();
 	proto = ipv6_gso_pull_exthdrs(skb, iph->nexthdr);
 	proto = ipv6_gso_pull_exthdrs(skb, iph->nexthdr);
+	iph = ipv6_hdr(skb);
 	IPV6_GRO_CB(skb)->proto = proto;
 	IPV6_GRO_CB(skb)->proto = proto;
 	ops = rcu_dereference(inet6_protos[proto]);
 	ops = rcu_dereference(inet6_protos[proto]);
 	if (!ops || !ops->gro_receive)
 	if (!ops || !ops->gro_receive)
@@ -839,8 +841,13 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,
 
 
 	NAPI_GRO_CB(skb)->flush |= flush;
 	NAPI_GRO_CB(skb)->flush |= flush;
 
 
+	csum = skb->csum;
+	skb_postpull_rcsum(skb, iph, skb_network_header_len(skb));
+
 	pp = ops->gro_receive(head, skb);
 	pp = ops->gro_receive(head, skb);
 
 
+	skb->csum = csum;
+
 out_unlock:
 out_unlock:
 	rcu_read_unlock();
 	rcu_read_unlock();
 
 

+ 1 - 0
net/key/af_key.c

@@ -1285,6 +1285,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
 				ext_hdrs[SADB_X_EXT_NAT_T_DPORT-1];
 				ext_hdrs[SADB_X_EXT_NAT_T_DPORT-1];
 			natt->encap_dport = n_port->sadb_x_nat_t_port_port;
 			natt->encap_dport = n_port->sadb_x_nat_t_port_port;
 		}
 		}
+		memset(&natt->encap_oa, 0, sizeof(natt->encap_oa));
 	}
 	}
 
 
 	err = xfrm_init_state(x);
 	err = xfrm_init_state(x);

+ 2 - 2
net/mac80211/mlme.c

@@ -620,8 +620,8 @@ static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
 	if (use_short_slot != bss_conf->use_short_slot) {
 	if (use_short_slot != bss_conf->use_short_slot) {
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
 		if (net_ratelimit()) {
 		if (net_ratelimit()) {
-			printk(KERN_DEBUG "%s: switched to %s slot"
-			       " (BSSID=%s)\n",
+			printk(KERN_DEBUG "%s: switched to %s slot time"
+			       " (BSSID=%pM)\n",
 			       sdata->dev->name,
 			       sdata->dev->name,
 			       use_short_slot ? "short" : "long",
 			       use_short_slot ? "short" : "long",
 			       ifsta->bssid);
 			       ifsta->bssid);

+ 0 - 1
net/mac80211/sta_info.h

@@ -195,7 +195,6 @@ struct sta_ampdu_mlme {
  * @tx_packets: number of RX/TX MSDUs
  * @tx_packets: number of RX/TX MSDUs
  * @tx_bytes: number of bytes transmitted to this STA
  * @tx_bytes: number of bytes transmitted to this STA
  * @tx_fragments: number of transmitted MPDUs
  * @tx_fragments: number of transmitted MPDUs
- * @last_txrate: description of the last used transmit rate
  * @tid_seq: per-TID sequence numbers for sending to this STA
  * @tid_seq: per-TID sequence numbers for sending to this STA
  * @ampdu_mlme: A-MPDU state machine state
  * @ampdu_mlme: A-MPDU state machine state
  * @timer_to_tid: identity mapping to ID timers
  * @timer_to_tid: identity mapping to ID timers

+ 4 - 2
net/mac80211/tx.c

@@ -1307,8 +1307,10 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		if (is_multicast_ether_addr(hdr->addr3))
 		if (is_multicast_ether_addr(hdr->addr3))
 			memcpy(hdr->addr1, hdr->addr3, ETH_ALEN);
 			memcpy(hdr->addr1, hdr->addr3, ETH_ALEN);
 		else
 		else
-			if (mesh_nexthop_lookup(skb, osdata))
-				return  0;
+			if (mesh_nexthop_lookup(skb, osdata)) {
+				dev_put(odev);
+				return 0;
+			}
 		if (memcmp(odev->dev_addr, hdr->addr4, ETH_ALEN) != 0)
 		if (memcmp(odev->dev_addr, hdr->addr4, ETH_ALEN) != 0)
 			IEEE80211_IFSTA_MESH_CTR_INC(&osdata->u.mesh,
 			IEEE80211_IFSTA_MESH_CTR_INC(&osdata->u.mesh,
 							    fwded_frames);
 							    fwded_frames);

+ 3 - 0
net/netfilter/nf_conntrack_netlink.c

@@ -831,13 +831,16 @@ ctnetlink_parse_nat_setup(struct nf_conn *ct,
 	if (!parse_nat_setup) {
 	if (!parse_nat_setup) {
 #ifdef CONFIG_MODULES
 #ifdef CONFIG_MODULES
 		rcu_read_unlock();
 		rcu_read_unlock();
+		spin_unlock_bh(&nf_conntrack_lock);
 		nfnl_unlock();
 		nfnl_unlock();
 		if (request_module("nf-nat-ipv4") < 0) {
 		if (request_module("nf-nat-ipv4") < 0) {
 			nfnl_lock();
 			nfnl_lock();
+			spin_lock_bh(&nf_conntrack_lock);
 			rcu_read_lock();
 			rcu_read_lock();
 			return -EOPNOTSUPP;
 			return -EOPNOTSUPP;
 		}
 		}
 		nfnl_lock();
 		nfnl_lock();
+		spin_lock_bh(&nf_conntrack_lock);
 		rcu_read_lock();
 		rcu_read_lock();
 		if (nfnetlink_parse_nat_setup_hook)
 		if (nfnetlink_parse_nat_setup_hook)
 			return -EAGAIN;
 			return -EAGAIN;

+ 13 - 0
net/sctp/input.c

@@ -249,6 +249,19 @@ int sctp_rcv(struct sk_buff *skb)
 	 */
 	 */
 	sctp_bh_lock_sock(sk);
 	sctp_bh_lock_sock(sk);
 
 
+	if (sk != rcvr->sk) {
+		/* Our cached sk is different from the rcvr->sk.  This is
+		 * because migrate()/accept() may have moved the association
+		 * to a new socket and released all the sockets.  So now we
+		 * are holding a lock on the old socket while the user may
+		 * be doing something with the new socket.  Switch our veiw
+		 * of the current sk.
+		 */
+		sctp_bh_unlock_sock(sk);
+		sk = rcvr->sk;
+		sctp_bh_lock_sock(sk);
+	}
+
 	if (sock_owned_by_user(sk)) {
 	if (sock_owned_by_user(sk)) {
 		SCTP_INC_STATS_BH(SCTP_MIB_IN_PKT_BACKLOG);
 		SCTP_INC_STATS_BH(SCTP_MIB_IN_PKT_BACKLOG);
 		sctp_add_backlog(sk, skb);
 		sctp_add_backlog(sk, skb);

+ 4 - 3
net/sctp/output.c

@@ -324,14 +324,16 @@ append:
 	switch (chunk->chunk_hdr->type) {
 	switch (chunk->chunk_hdr->type) {
 	    case SCTP_CID_DATA:
 	    case SCTP_CID_DATA:
 		retval = sctp_packet_append_data(packet, chunk);
 		retval = sctp_packet_append_data(packet, chunk);
+		if (SCTP_XMIT_OK != retval)
+			goto finish;
 		/* Disallow SACK bundling after DATA. */
 		/* Disallow SACK bundling after DATA. */
 		packet->has_sack = 1;
 		packet->has_sack = 1;
 		/* Disallow AUTH bundling after DATA */
 		/* Disallow AUTH bundling after DATA */
 		packet->has_auth = 1;
 		packet->has_auth = 1;
 		/* Let it be knows that packet has DATA in it */
 		/* Let it be knows that packet has DATA in it */
 		packet->has_data = 1;
 		packet->has_data = 1;
-		if (SCTP_XMIT_OK != retval)
-			goto finish;
+		/* timestamp the chunk for rtx purposes */
+		chunk->sent_at = jiffies;
 		break;
 		break;
 	    case SCTP_CID_COOKIE_ECHO:
 	    case SCTP_CID_COOKIE_ECHO:
 		packet->has_cookie_echo = 1;
 		packet->has_cookie_echo = 1;
@@ -470,7 +472,6 @@ int sctp_packet_transmit(struct sctp_packet *packet)
 			} else
 			} else
 				chunk->resent = 1;
 				chunk->resent = 1;
 
 
-			chunk->sent_at = jiffies;
 			has_data = 1;
 			has_data = 1;
 		}
 		}
 
 

+ 1 - 2
net/sctp/outqueue.c

@@ -929,7 +929,6 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
 		}
 		}
 
 
 		/* Finally, transmit new packets.  */
 		/* Finally, transmit new packets.  */
-		start_timer = 0;
 		while ((chunk = sctp_outq_dequeue_data(q)) != NULL) {
 		while ((chunk = sctp_outq_dequeue_data(q)) != NULL) {
 			/* RFC 2960 6.5 Every DATA chunk MUST carry a valid
 			/* RFC 2960 6.5 Every DATA chunk MUST carry a valid
 			 * stream identifier.
 			 * stream identifier.
@@ -1028,7 +1027,7 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
 			list_add_tail(&chunk->transmitted_list,
 			list_add_tail(&chunk->transmitted_list,
 				      &transport->transmitted);
 				      &transport->transmitted);
 
 
-			sctp_transport_reset_timers(transport, start_timer-1);
+			sctp_transport_reset_timers(transport, 0);
 
 
 			q->empty = 0;
 			q->empty = 0;
 
 

+ 117 - 11
net/wireless/reg.c

@@ -421,6 +421,31 @@ static u32 freq_max_bandwidth(const struct ieee80211_freq_range *freq_range,
 	return 0;
 	return 0;
 }
 }
 
 
+/**
+ * freq_in_rule_band - tells us if a frequency is in a frequency band
+ * @freq_range: frequency rule we want to query
+ * @freq_khz: frequency we are inquiring about
+ *
+ * This lets us know if a specific frequency rule is or is not relevant to
+ * a specific frequency's band. Bands are device specific and artificial
+ * definitions (the "2.4 GHz band" and the "5 GHz band"), however it is
+ * safe for now to assume that a frequency rule should not be part of a
+ * frequency's band if the start freq or end freq are off by more than 2 GHz.
+ * This resolution can be lowered and should be considered as we add
+ * regulatory rule support for other "bands".
+ **/
+static bool freq_in_rule_band(const struct ieee80211_freq_range *freq_range,
+	u32 freq_khz)
+{
+#define ONE_GHZ_IN_KHZ	1000000
+	if (abs(freq_khz - freq_range->start_freq_khz) <= (2 * ONE_GHZ_IN_KHZ))
+		return true;
+	if (abs(freq_khz - freq_range->end_freq_khz) <= (2 * ONE_GHZ_IN_KHZ))
+		return true;
+	return false;
+#undef ONE_GHZ_IN_KHZ
+}
+
 /* Converts a country IE to a regulatory domain. A regulatory domain
 /* Converts a country IE to a regulatory domain. A regulatory domain
  * structure has a lot of information which the IE doesn't yet have,
  * structure has a lot of information which the IE doesn't yet have,
  * so for the other values we use upper max values as we will intersect
  * so for the other values we use upper max values as we will intersect
@@ -538,6 +563,7 @@ static struct ieee80211_regdomain *country_ie_2_rd(
 
 
 	/* This time around we fill in the rd */
 	/* This time around we fill in the rd */
 	while (country_ie_len >= 3) {
 	while (country_ie_len >= 3) {
+		int end_channel = 0;
 		struct ieee80211_country_ie_triplet *triplet =
 		struct ieee80211_country_ie_triplet *triplet =
 			(struct ieee80211_country_ie_triplet *) country_ie;
 			(struct ieee80211_country_ie_triplet *) country_ie;
 		struct ieee80211_reg_rule *reg_rule = NULL;
 		struct ieee80211_reg_rule *reg_rule = NULL;
@@ -559,6 +585,23 @@ static struct ieee80211_regdomain *country_ie_2_rd(
 
 
 		reg_rule->flags = flags;
 		reg_rule->flags = flags;
 
 
+		/* 2 GHz */
+		if (triplet->chans.first_channel <= 14)
+			end_channel = triplet->chans.first_channel +
+				triplet->chans.num_channels;
+		else
+			/*
+			 * 5 GHz -- For example in country IEs if the first
+			 * channel given is 36 and the number of channels is 4
+			 * then the individual channel numbers defined for the
+			 * 5 GHz PHY by these parameters are: 36, 40, 44, and 48
+			 * and not 36, 37, 38, 39.
+			 *
+			 * See: http://tinyurl.com/11d-clarification
+			 */
+			end_channel =  triplet->chans.first_channel +
+				(4 * (triplet->chans.num_channels - 1));
+
 		/* The +10 is since the regulatory domain expects
 		/* The +10 is since the regulatory domain expects
 		 * the actual band edge, not the center of freq for
 		 * the actual band edge, not the center of freq for
 		 * its start and end freqs, assuming 20 MHz bandwidth on
 		 * its start and end freqs, assuming 20 MHz bandwidth on
@@ -568,8 +611,7 @@ static struct ieee80211_regdomain *country_ie_2_rd(
 				triplet->chans.first_channel) - 10);
 				triplet->chans.first_channel) - 10);
 		freq_range->end_freq_khz =
 		freq_range->end_freq_khz =
 			MHZ_TO_KHZ(ieee80211_channel_to_frequency(
 			MHZ_TO_KHZ(ieee80211_channel_to_frequency(
-				triplet->chans.first_channel +
-					triplet->chans.num_channels) + 10);
+				end_channel) + 10);
 
 
 		/* Large arbitrary values, we intersect later */
 		/* Large arbitrary values, we intersect later */
 		/* Increment this if we ever support >= 40 MHz channels
 		/* Increment this if we ever support >= 40 MHz channels
@@ -748,12 +790,23 @@ static u32 map_regdom_flags(u32 rd_flags)
  * 	this value to the maximum allowed bandwidth.
  * 	this value to the maximum allowed bandwidth.
  * @reg_rule: the regulatory rule which we have for this frequency
  * @reg_rule: the regulatory rule which we have for this frequency
  *
  *
- * Use this function to get the regulatory rule for a specific frequency.
+ * Use this function to get the regulatory rule for a specific frequency on
+ * a given wireless device. If the device has a specific regulatory domain
+ * it wants to follow we respect that unless a country IE has been received
+ * and processed already.
+ *
+ * Returns 0 if it was able to find a valid regulatory rule which does
+ * apply to the given center_freq otherwise it returns non-zero. It will
+ * also return -ERANGE if we determine the given center_freq does not even have
+ * a regulatory rule for a frequency range in the center_freq's band. See
+ * freq_in_rule_band() for our current definition of a band -- this is purely
+ * subjective and right now its 802.11 specific.
  */
  */
 static int freq_reg_info(u32 center_freq, u32 *bandwidth,
 static int freq_reg_info(u32 center_freq, u32 *bandwidth,
 			 const struct ieee80211_reg_rule **reg_rule)
 			 const struct ieee80211_reg_rule **reg_rule)
 {
 {
 	int i;
 	int i;
+	bool band_rule_found = false;
 	u32 max_bandwidth = 0;
 	u32 max_bandwidth = 0;
 
 
 	if (!cfg80211_regdomain)
 	if (!cfg80211_regdomain)
@@ -767,7 +820,15 @@ static int freq_reg_info(u32 center_freq, u32 *bandwidth,
 		rr = &cfg80211_regdomain->reg_rules[i];
 		rr = &cfg80211_regdomain->reg_rules[i];
 		fr = &rr->freq_range;
 		fr = &rr->freq_range;
 		pr = &rr->power_rule;
 		pr = &rr->power_rule;
+
+		/* We only need to know if one frequency rule was
+		 * was in center_freq's band, that's enough, so lets
+		 * not overwrite it once found */
+		if (!band_rule_found)
+			band_rule_found = freq_in_rule_band(fr, center_freq);
+
 		max_bandwidth = freq_max_bandwidth(fr, center_freq);
 		max_bandwidth = freq_max_bandwidth(fr, center_freq);
+
 		if (max_bandwidth && *bandwidth <= max_bandwidth) {
 		if (max_bandwidth && *bandwidth <= max_bandwidth) {
 			*reg_rule = rr;
 			*reg_rule = rr;
 			*bandwidth = max_bandwidth;
 			*bandwidth = max_bandwidth;
@@ -775,23 +836,64 @@ static int freq_reg_info(u32 center_freq, u32 *bandwidth,
 		}
 		}
 	}
 	}
 
 
+	if (!band_rule_found)
+		return -ERANGE;
+
 	return !max_bandwidth;
 	return !max_bandwidth;
 }
 }
 
 
-static void handle_channel(struct ieee80211_channel *chan)
+static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
+			   unsigned int chan_idx)
 {
 {
 	int r;
 	int r;
-	u32 flags = chan->orig_flags;
+	u32 flags;
 	u32 max_bandwidth = 0;
 	u32 max_bandwidth = 0;
 	const struct ieee80211_reg_rule *reg_rule = NULL;
 	const struct ieee80211_reg_rule *reg_rule = NULL;
 	const struct ieee80211_power_rule *power_rule = NULL;
 	const struct ieee80211_power_rule *power_rule = NULL;
+	struct ieee80211_supported_band *sband;
+	struct ieee80211_channel *chan;
+
+	sband = wiphy->bands[band];
+	BUG_ON(chan_idx >= sband->n_channels);
+	chan = &sband->channels[chan_idx];
+
+	flags = chan->orig_flags;
 
 
 	r = freq_reg_info(MHZ_TO_KHZ(chan->center_freq),
 	r = freq_reg_info(MHZ_TO_KHZ(chan->center_freq),
 		&max_bandwidth, &reg_rule);
 		&max_bandwidth, &reg_rule);
 
 
 	if (r) {
 	if (r) {
-		flags |= IEEE80211_CHAN_DISABLED;
-		chan->flags = flags;
+		/* This means no regulatory rule was found in the country IE
+		 * with a frequency range on the center_freq's band, since
+		 * IEEE-802.11 allows for a country IE to have a subset of the
+		 * regulatory information provided in a country we ignore
+		 * disabling the channel unless at least one reg rule was
+		 * found on the center_freq's band. For details see this
+		 * clarification:
+		 *
+		 * http://tinyurl.com/11d-clarification
+		 */
+		if (r == -ERANGE &&
+		    last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) {
+#ifdef CONFIG_CFG80211_REG_DEBUG
+			printk(KERN_DEBUG "cfg80211: Leaving channel %d MHz "
+				"intact on %s - no rule found in band on "
+				"Country IE\n",
+				chan->center_freq, wiphy_name(wiphy));
+#endif
+		} else {
+		/* In this case we know the country IE has at least one reg rule
+		 * for the band so we respect its band definitions */
+#ifdef CONFIG_CFG80211_REG_DEBUG
+			if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE)
+				printk(KERN_DEBUG "cfg80211: Disabling "
+					"channel %d MHz on %s due to "
+					"Country IE\n",
+					chan->center_freq, wiphy_name(wiphy));
+#endif
+			flags |= IEEE80211_CHAN_DISABLED;
+			chan->flags = flags;
+		}
 		return;
 		return;
 	}
 	}
 
 
@@ -808,12 +910,16 @@ static void handle_channel(struct ieee80211_channel *chan)
 		chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp);
 		chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp);
 }
 }
 
 
-static void handle_band(struct ieee80211_supported_band *sband)
+static void handle_band(struct wiphy *wiphy, enum ieee80211_band band)
 {
 {
-	int i;
+	unsigned int i;
+	struct ieee80211_supported_band *sband;
+
+	BUG_ON(!wiphy->bands[band]);
+	sband = wiphy->bands[band];
 
 
 	for (i = 0; i < sband->n_channels; i++)
 	for (i = 0; i < sband->n_channels; i++)
-		handle_channel(&sband->channels[i]);
+		handle_channel(wiphy, band, i);
 }
 }
 
 
 static bool ignore_reg_update(struct wiphy *wiphy, enum reg_set_by setby)
 static bool ignore_reg_update(struct wiphy *wiphy, enum reg_set_by setby)
@@ -840,7 +946,7 @@ void wiphy_update_regulatory(struct wiphy *wiphy, enum reg_set_by setby)
 	enum ieee80211_band band;
 	enum ieee80211_band band;
 	for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
 	for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
 		if (wiphy->bands[band])
 		if (wiphy->bands[band])
-			handle_band(wiphy->bands[band]);
+			handle_band(wiphy, band);
 		if (wiphy->reg_notifier)
 		if (wiphy->reg_notifier)
 			wiphy->reg_notifier(wiphy, setby);
 			wiphy->reg_notifier(wiphy, setby);
 	}
 	}

+ 2 - 9
net/xfrm/xfrm_user.c

@@ -1914,17 +1914,10 @@ static int xfrm_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
 }
 }
 #endif
 #endif
 
 
-/* For the xfrm_usersa_info cases we have to work around some 32-bit vs.
- * 64-bit compatability issues.  On 32-bit the structure is 220 bytes, but
- * for 64-bit it gets padded out to 224 bytes.  Those bytes are just
- * padding and don't have any content we care about.  Therefore as long
- * as we have enough bytes for the content we can make both cases work.
- */
-
 #define XMSGSIZE(type) sizeof(struct type)
 #define XMSGSIZE(type) sizeof(struct type)
 
 
 static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = {
 static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = {
-	[XFRM_MSG_NEWSA       - XFRM_MSG_BASE] = 220, /* see above */
+	[XFRM_MSG_NEWSA       - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_info),
 	[XFRM_MSG_DELSA       - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_id),
 	[XFRM_MSG_DELSA       - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_id),
 	[XFRM_MSG_GETSA       - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_id),
 	[XFRM_MSG_GETSA       - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_id),
 	[XFRM_MSG_NEWPOLICY   - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_info),
 	[XFRM_MSG_NEWPOLICY   - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_info),
@@ -1934,7 +1927,7 @@ static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = {
 	[XFRM_MSG_ACQUIRE     - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_acquire),
 	[XFRM_MSG_ACQUIRE     - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_acquire),
 	[XFRM_MSG_EXPIRE      - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_expire),
 	[XFRM_MSG_EXPIRE      - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_expire),
 	[XFRM_MSG_UPDPOLICY   - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_info),
 	[XFRM_MSG_UPDPOLICY   - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_info),
-	[XFRM_MSG_UPDSA       - XFRM_MSG_BASE] = 220, /* see above */
+	[XFRM_MSG_UPDSA       - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_info),
 	[XFRM_MSG_POLEXPIRE   - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_polexpire),
 	[XFRM_MSG_POLEXPIRE   - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_polexpire),
 	[XFRM_MSG_FLUSHSA     - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_flush),
 	[XFRM_MSG_FLUSHSA     - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_flush),
 	[XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = 0,
 	[XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = 0,