Преглед изворни кода

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: (94 commits)
  pkt_sched: Prevent livelock in TX queue running.
  Revert "pkt_sched: Add BH protection for qdisc_stab_lock."
  Revert "pkt_sched: Protect gen estimators under est_lock."
  pkt_sched: remove bogus block (cleanup)
  nf_nat: use secure_ipv4_port_ephemeral() for NAT port randomization
  netfilter: ctnetlink: sleepable allocation with spin lock bh
  netfilter: ctnetlink: fix sleep in read-side lock section
  netfilter: ctnetlink: fix double helper assignation for NAT'ed conntracks
  netfilter: ipt_addrtype: Fix matching of inverted destination address type
  dccp: Fix panic caused by too early termination of retransmission mechanism
  pkt_sched: Don't hold qdisc lock over qdisc_destroy().
  pkt_sched: Add lockdep annotation for qdisc locks
  pkt_sched: Never schedule non-root qdiscs.
  removed unused #include <version.h>
  rt2x00: Fix txdone_entry_desc_flags
  b43: Fix for another Bluetooth Coexistence SPROM Programming error for BCM4306
  mac80211: remove kdoc references to IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE
  p54u: reset skb's data/tail pointer on requeue
  p54: move p54_vdcf_init to the right place.
  iwlwifi: fix printk newlines
  ...
Linus Torvalds пре 17 година
родитељ
комит
4309e09242
100 измењених фајлова са 1439 додато и 781 уклоњено
  1. 5 0
      Documentation/rfkill.txt
  2. 6 81
      MAINTAINERS
  3. 4 6
      drivers/bluetooth/Kconfig
  4. 1 1
      drivers/bluetooth/bt3c_cs.c
  5. 268 14
      drivers/bluetooth/btusb.c
  6. 1 1
      drivers/bluetooth/hci_ldisc.c
  7. 1 1
      drivers/bluetooth/hci_usb.c
  8. 1 1
      drivers/bluetooth/hci_vhci.c
  9. 1 0
      drivers/char/random.c
  10. 1 1
      drivers/net/Kconfig
  11. 0 1
      drivers/net/acenic.c
  12. 3 3
      drivers/net/arm/ixp4xx_eth.c
  13. 1 1
      drivers/net/atl1e/atl1e_ethtool.c
  14. 1 1
      drivers/net/au1000_eth.c
  15. 2 2
      drivers/net/ax88796.c
  16. 34 13
      drivers/net/bnx2.c
  17. 0 1
      drivers/net/bnx2x_link.c
  18. 0 1
      drivers/net/bnx2x_main.c
  19. 0 1
      drivers/net/cpmac.c
  20. 1 1
      drivers/net/e1000e/defines.h
  21. 1 0
      drivers/net/e1000e/e1000.h
  22. 1 1
      drivers/net/e1000e/ethtool.c
  23. 170 15
      drivers/net/e1000e/netdev.c
  24. 19 6
      drivers/net/e1000e/param.c
  25. 2 4
      drivers/net/gianfar.c
  26. 0 1
      drivers/net/gianfar_sysfs.c
  27. 0 2
      drivers/net/ipg.h
  28. 1 0
      drivers/net/ixgbe/ixgbe_82598.c
  29. 3 1
      drivers/net/ixgbe/ixgbe_main.c
  30. 1 0
      drivers/net/ixgbe/ixgbe_type.h
  31. 0 67
      drivers/net/loopback.c
  32. 5 1
      drivers/net/myri10ge/myri10ge.c
  33. 2 2
      drivers/net/ne.c
  34. 4 3
      drivers/net/netxen/netxen_nic.h
  35. 42 17
      drivers/net/netxen/netxen_nic_hw.c
  36. 15 13
      drivers/net/netxen/netxen_nic_init.c
  37. 96 114
      drivers/net/netxen/netxen_nic_main.c
  38. 2 0
      drivers/net/netxen/netxen_nic_phan_reg.h
  39. 0 1
      drivers/net/ppp_mppe.c
  40. 0 1
      drivers/net/pppol2tp.c
  41. 0 1
      drivers/net/r6040.c
  42. 0 1
      drivers/net/sh_eth.c
  43. 6 2
      drivers/net/sky2.c
  44. 0 1
      drivers/net/tehuti.h
  45. 78 23
      drivers/net/tg3.c
  46. 6 0
      drivers/net/tg3.h
  47. 4 4
      drivers/net/tlan.c
  48. 101 4
      drivers/net/tun.c
  49. 0 1
      drivers/net/typhoon.c
  50. 10 11
      drivers/net/usb/Kconfig
  51. 30 23
      drivers/net/usb/hso.c
  52. 2 7
      drivers/net/wireless/ath5k/base.c
  53. 5 1
      drivers/net/wireless/ath9k/hw.c
  54. 2 1
      drivers/net/wireless/b43/main.c
  55. 0 1
      drivers/net/wireless/ipw2100.c
  56. 0 1
      drivers/net/wireless/ipw2200.c
  57. 0 1
      drivers/net/wireless/iwlwifi/iwl-3945.c
  58. 1 2
      drivers/net/wireless/iwlwifi/iwl-4965.c
  59. 0 1
      drivers/net/wireless/iwlwifi/iwl-5000.c
  60. 0 1
      drivers/net/wireless/iwlwifi/iwl-agn.c
  61. 0 1
      drivers/net/wireless/iwlwifi/iwl-core.c
  62. 3 4
      drivers/net/wireless/iwlwifi/iwl-eeprom.c
  63. 0 1
      drivers/net/wireless/iwlwifi/iwl-hcmd.c
  64. 0 1
      drivers/net/wireless/iwlwifi/iwl-power.c
  65. 2 2
      drivers/net/wireless/iwlwifi/iwl-sta.c
  66. 2 2
      drivers/net/wireless/iwlwifi/iwl-tx.c
  67. 3 4
      drivers/net/wireless/iwlwifi/iwl3945-base.c
  68. 27 24
      drivers/net/wireless/p54/p54common.c
  69. 9 9
      drivers/net/wireless/p54/p54common.h
  70. 10 0
      drivers/net/wireless/p54/p54usb.c
  71. 4 4
      drivers/net/wireless/rt2x00/rt2x00queue.h
  72. 1 0
      drivers/net/wireless/rt2x00/rt2x00usb.c
  73. 1 0
      drivers/net/wireless/rtl8187_dev.c
  74. 8 0
      drivers/ssb/main.c
  75. 1 0
      include/linux/if_tun.h
  76. 4 0
      include/linux/skbuff.h
  77. 2 1
      include/net/addrconf.h
  78. 1 0
      include/net/ip6_route.h
  79. 3 8
      include/net/mac80211.h
  80. 1 1
      include/net/sch_generic.h
  81. 1 1
      net/bluetooth/af_bluetooth.c
  82. 1 1
      net/bluetooth/bnep/core.c
  83. 189 187
      net/bluetooth/hci_sysfs.c
  84. 1 1
      net/bluetooth/l2cap.c
  85. 1 1
      net/bluetooth/rfcomm/core.c
  86. 1 1
      net/bluetooth/sco.c
  87. 10 5
      net/bridge/br_device.c
  88. 87 0
      net/core/datagram.c
  89. 30 19
      net/core/dev.c
  90. 4 5
      net/core/gen_estimator.c
  91. 2 10
      net/core/skbuff.c
  92. 6 6
      net/dccp/input.c
  93. 1 1
      net/ipv4/netfilter/ipt_addrtype.c
  94. 6 2
      net/ipv4/netfilter/nf_nat_proto_common.c
  95. 70 6
      net/ipv4/route.c
  96. 1 2
      net/ipv6/addrconf.c
  97. 2 1
      net/ipv6/fib6_rules.c
  98. 1 0
      net/ipv6/ip6_fib.c
  99. 1 1
      net/ipv6/ip6_output.c
  100. 2 2
      net/ipv6/ipv6_sockglue.c

+ 5 - 0
Documentation/rfkill.txt

@@ -363,6 +363,11 @@ This rule exists because users of the rfkill subsystem expect to get (and set,
 when possible) the overall transmitter rfkill state, not of a particular rfkill
 when possible) the overall transmitter rfkill state, not of a particular rfkill
 line.
 line.
 
 
+5. During suspend, the rfkill class will attempt to soft-block the radio
+through a call to rfkill->toggle_radio, and will try to restore its previous
+state during resume.  After a rfkill class is suspended, it will *not* call
+rfkill->toggle_radio until it is resumed.
+
 Example of a WLAN wireless driver connected to the rfkill subsystem:
 Example of a WLAN wireless driver connected to the rfkill subsystem:
 --------------------------------------------------------------------
 --------------------------------------------------------------------
 
 

+ 6 - 81
MAINTAINERS

@@ -942,94 +942,19 @@ M:	joern@lazybastard.org
 L:	linux-mtd@lists.infradead.org
 L:	linux-mtd@lists.infradead.org
 S:	Maintained
 S:	Maintained
 
 
-BLUETOOTH SUBSYSTEM
+BLUETOOTH DRIVERS
 P:	Marcel Holtmann
 P:	Marcel Holtmann
 M:	marcel@holtmann.org
 M:	marcel@holtmann.org
-P:	Maxim Krasnyansky
-M:	maxk@qualcomm.com
 L:	linux-bluetooth@vger.kernel.org
 L:	linux-bluetooth@vger.kernel.org
-W:	http://bluez.sf.net
-W:	http://www.bluez.org
-W:	http://www.holtmann.org/linux/bluetooth/
-T:	git kernel.org:/pub/scm/linux/kernel/git/holtmann/bluetooth-2.6.git
-S:	Maintained
-
-BLUETOOTH RFCOMM LAYER
-P:	Marcel Holtmann
-M:	marcel@holtmann.org
-P:	Maxim Krasnyansky
-M:	maxk@qualcomm.com
-S:	Maintained
-
-BLUETOOTH BNEP LAYER
-P:	Marcel Holtmann
-M:	marcel@holtmann.org
-P:	Maxim Krasnyansky
-M:	maxk@qualcomm.com
-S:	Maintained
-
-BLUETOOTH CMTP LAYER
-P:	Marcel Holtmann
-M:	marcel@holtmann.org
+W:	http://www.bluez.org/
 S:	Maintained
 S:	Maintained
 
 
-BLUETOOTH HIDP LAYER
-P:	Marcel Holtmann
-M:	marcel@holtmann.org
-S:	Maintained
-
-BLUETOOTH HCI UART DRIVER
-P:	Marcel Holtmann
-M:	marcel@holtmann.org
-P:	Maxim Krasnyansky
-M:	maxk@qualcomm.com
-S:	Maintained
-
-BLUETOOTH HCI USB DRIVER
-P:	Marcel Holtmann
-M:	marcel@holtmann.org
-P:	Maxim Krasnyansky
-M:	maxk@qualcomm.com
-S:	Maintained
-
-BLUETOOTH HCI BCM203X DRIVER
-P:	Marcel Holtmann
-M:	marcel@holtmann.org
-S:	Maintained
-
-BLUETOOTH HCI BPA10X DRIVER
-P:	Marcel Holtmann
-M:	marcel@holtmann.org
-S:	Maintained
-
-BLUETOOTH HCI BFUSB DRIVER
-P:	Marcel Holtmann
-M:	marcel@holtmann.org
-S:	Maintained
-
-BLUETOOTH HCI DTL1 DRIVER
-P:	Marcel Holtmann
-M:	marcel@holtmann.org
-S:	Maintained
-
-BLUETOOTH HCI BLUECARD DRIVER
-P:	Marcel Holtmann
-M:	marcel@holtmann.org
-S:	Maintained
-
-BLUETOOTH HCI BT3C DRIVER
-P:	Marcel Holtmann
-M:	marcel@holtmann.org
-S:	Maintained
-
-BLUETOOTH HCI BTUART DRIVER
+BLUETOOTH SUBSYSTEM
 P:	Marcel Holtmann
 P:	Marcel Holtmann
 M:	marcel@holtmann.org
 M:	marcel@holtmann.org
-S:	Maintained
-
-BLUETOOTH HCI VHCI DRIVER
-P:	Maxim Krasnyansky
-M:	maxk@qualcomm.com
+L:	linux-bluetooth@vger.kernel.org
+W:	http://www.bluez.org/
+T:	git kernel.org:/pub/scm/linux/kernel/git/holtmann/bluetooth-2.6.git
 S:	Maintained
 S:	Maintained
 
 
 BONDING DRIVER
 BONDING DRIVER

+ 4 - 6
drivers/bluetooth/Kconfig

@@ -3,8 +3,8 @@ menu "Bluetooth device drivers"
 	depends on BT
 	depends on BT
 
 
 config BT_HCIUSB
 config BT_HCIUSB
-	tristate "HCI USB driver"
-	depends on USB
+	tristate "HCI USB driver (old version)"
+	depends on USB && BT_HCIBTUSB=n
 	help
 	help
 	  Bluetooth HCI USB driver.
 	  Bluetooth HCI USB driver.
 	  This driver is required if you want to use Bluetooth devices with
 	  This driver is required if you want to use Bluetooth devices with
@@ -23,15 +23,13 @@ config BT_HCIUSB_SCO
 	  Say Y here to compile support for SCO over HCI USB.
 	  Say Y here to compile support for SCO over HCI USB.
 
 
 config BT_HCIBTUSB
 config BT_HCIBTUSB
-	tristate "HCI USB driver (alternate version)"
-	depends on USB && EXPERIMENTAL && BT_HCIUSB=n
+	tristate "HCI USB driver"
+	depends on USB
 	help
 	help
 	  Bluetooth HCI USB driver.
 	  Bluetooth HCI USB driver.
 	  This driver is required if you want to use Bluetooth devices with
 	  This driver is required if you want to use Bluetooth devices with
 	  USB interface.
 	  USB interface.
 
 
-          This driver is still experimental and has no SCO support.
-
 	  Say Y here to compile support for Bluetooth USB devices into the
 	  Say Y here to compile support for Bluetooth USB devices into the
 	  kernel or say M to compile it as module (btusb).
 	  kernel or say M to compile it as module (btusb).
 
 

+ 1 - 1
drivers/bluetooth/bt3c_cs.c

@@ -60,7 +60,7 @@
 /* ======================== Module parameters ======================== */
 /* ======================== Module parameters ======================== */
 
 
 
 
-MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>, Jose Orlando Pereira <jop@di.uminho.pt>");
+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth driver for the 3Com Bluetooth PCMCIA card");
 MODULE_DESCRIPTION("Bluetooth driver for the 3Com Bluetooth PCMCIA card");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
 MODULE_FIRMWARE("BT3CPCC.bin");
 MODULE_FIRMWARE("BT3CPCC.bin");

+ 268 - 14
drivers/bluetooth/btusb.c

@@ -2,7 +2,7 @@
  *
  *
  *  Generic Bluetooth USB driver
  *  Generic Bluetooth USB driver
  *
  *
- *  Copyright (C) 2005-2007  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (C) 2005-2008  Marcel Holtmann <marcel@holtmann.org>
  *
  *
  *
  *
  *  This program is free software; you can redistribute it and/or modify
  *  This program is free software; you can redistribute it and/or modify
@@ -41,7 +41,7 @@
 #define BT_DBG(D...)
 #define BT_DBG(D...)
 #endif
 #endif
 
 
-#define VERSION "0.2"
+#define VERSION "0.3"
 
 
 static int ignore_dga;
 static int ignore_dga;
 static int ignore_csr;
 static int ignore_csr;
@@ -160,12 +160,16 @@ static struct usb_device_id blacklist_table[] = {
 	{ }	/* Terminating entry */
 	{ }	/* Terminating entry */
 };
 };
 
 
+#define BTUSB_MAX_ISOC_FRAMES	10
+
 #define BTUSB_INTR_RUNNING	0
 #define BTUSB_INTR_RUNNING	0
 #define BTUSB_BULK_RUNNING	1
 #define BTUSB_BULK_RUNNING	1
+#define BTUSB_ISOC_RUNNING	2
 
 
 struct btusb_data {
 struct btusb_data {
 	struct hci_dev       *hdev;
 	struct hci_dev       *hdev;
 	struct usb_device    *udev;
 	struct usb_device    *udev;
+	struct usb_interface *isoc;
 
 
 	spinlock_t lock;
 	spinlock_t lock;
 
 
@@ -176,10 +180,15 @@ struct btusb_data {
 	struct usb_anchor tx_anchor;
 	struct usb_anchor tx_anchor;
 	struct usb_anchor intr_anchor;
 	struct usb_anchor intr_anchor;
 	struct usb_anchor bulk_anchor;
 	struct usb_anchor bulk_anchor;
+	struct usb_anchor isoc_anchor;
 
 
 	struct usb_endpoint_descriptor *intr_ep;
 	struct usb_endpoint_descriptor *intr_ep;
 	struct usb_endpoint_descriptor *bulk_tx_ep;
 	struct usb_endpoint_descriptor *bulk_tx_ep;
 	struct usb_endpoint_descriptor *bulk_rx_ep;
 	struct usb_endpoint_descriptor *bulk_rx_ep;
+	struct usb_endpoint_descriptor *isoc_tx_ep;
+	struct usb_endpoint_descriptor *isoc_rx_ep;
+
+	int isoc_altsetting;
 };
 };
 
 
 static void btusb_intr_complete(struct urb *urb)
 static void btusb_intr_complete(struct urb *urb)
@@ -195,6 +204,8 @@ static void btusb_intr_complete(struct urb *urb)
 		return;
 		return;
 
 
 	if (urb->status == 0) {
 	if (urb->status == 0) {
+		hdev->stat.byte_rx += urb->actual_length;
+
 		if (hci_recv_fragment(hdev, HCI_EVENT_PKT,
 		if (hci_recv_fragment(hdev, HCI_EVENT_PKT,
 						urb->transfer_buffer,
 						urb->transfer_buffer,
 						urb->actual_length) < 0) {
 						urb->actual_length) < 0) {
@@ -216,7 +227,7 @@ static void btusb_intr_complete(struct urb *urb)
 	}
 	}
 }
 }
 
 
-static inline int btusb_submit_intr_urb(struct hci_dev *hdev)
+static int btusb_submit_intr_urb(struct hci_dev *hdev)
 {
 {
 	struct btusb_data *data = hdev->driver_data;
 	struct btusb_data *data = hdev->driver_data;
 	struct urb *urb;
 	struct urb *urb;
@@ -226,6 +237,9 @@ static inline int btusb_submit_intr_urb(struct hci_dev *hdev)
 
 
 	BT_DBG("%s", hdev->name);
 	BT_DBG("%s", hdev->name);
 
 
+	if (!data->intr_ep)
+		return -ENODEV;
+
 	urb = usb_alloc_urb(0, GFP_ATOMIC);
 	urb = usb_alloc_urb(0, GFP_ATOMIC);
 	if (!urb)
 	if (!urb)
 		return -ENOMEM;
 		return -ENOMEM;
@@ -274,6 +288,8 @@ static void btusb_bulk_complete(struct urb *urb)
 		return;
 		return;
 
 
 	if (urb->status == 0) {
 	if (urb->status == 0) {
+		hdev->stat.byte_rx += urb->actual_length;
+
 		if (hci_recv_fragment(hdev, HCI_ACLDATA_PKT,
 		if (hci_recv_fragment(hdev, HCI_ACLDATA_PKT,
 						urb->transfer_buffer,
 						urb->transfer_buffer,
 						urb->actual_length) < 0) {
 						urb->actual_length) < 0) {
@@ -295,7 +311,7 @@ static void btusb_bulk_complete(struct urb *urb)
 	}
 	}
 }
 }
 
 
-static inline int btusb_submit_bulk_urb(struct hci_dev *hdev)
+static int btusb_submit_bulk_urb(struct hci_dev *hdev)
 {
 {
 	struct btusb_data *data = hdev->driver_data;
 	struct btusb_data *data = hdev->driver_data;
 	struct urb *urb;
 	struct urb *urb;
@@ -305,6 +321,9 @@ static inline int btusb_submit_bulk_urb(struct hci_dev *hdev)
 
 
 	BT_DBG("%s", hdev->name);
 	BT_DBG("%s", hdev->name);
 
 
+	if (!data->bulk_rx_ep)
+		return -ENODEV;
+
 	urb = usb_alloc_urb(0, GFP_KERNEL);
 	urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!urb)
 	if (!urb)
 		return -ENOMEM;
 		return -ENOMEM;
@@ -339,6 +358,127 @@ static inline int btusb_submit_bulk_urb(struct hci_dev *hdev)
 	return err;
 	return err;
 }
 }
 
 
+static void btusb_isoc_complete(struct urb *urb)
+{
+	struct hci_dev *hdev = urb->context;
+	struct btusb_data *data = hdev->driver_data;
+	int i, err;
+
+	BT_DBG("%s urb %p status %d count %d", hdev->name,
+					urb, urb->status, urb->actual_length);
+
+	if (!test_bit(HCI_RUNNING, &hdev->flags))
+		return;
+
+	if (urb->status == 0) {
+		for (i = 0; i < urb->number_of_packets; i++) {
+			unsigned int offset = urb->iso_frame_desc[i].offset;
+			unsigned int length = urb->iso_frame_desc[i].actual_length;
+
+			if (urb->iso_frame_desc[i].status)
+				continue;
+
+			hdev->stat.byte_rx += length;
+
+			if (hci_recv_fragment(hdev, HCI_SCODATA_PKT,
+						urb->transfer_buffer + offset,
+								length) < 0) {
+				BT_ERR("%s corrupted SCO packet", hdev->name);
+				hdev->stat.err_rx++;
+			}
+		}
+	}
+
+	if (!test_bit(BTUSB_ISOC_RUNNING, &data->flags))
+		return;
+
+	usb_anchor_urb(urb, &data->isoc_anchor);
+
+	err = usb_submit_urb(urb, GFP_ATOMIC);
+	if (err < 0) {
+		BT_ERR("%s urb %p failed to resubmit (%d)",
+						hdev->name, urb, -err);
+		usb_unanchor_urb(urb);
+	}
+}
+
+static void inline __fill_isoc_descriptor(struct urb *urb, int len, int mtu)
+{
+	int i, offset = 0;
+
+	BT_DBG("len %d mtu %d", len, mtu);
+
+	for (i = 0; i < BTUSB_MAX_ISOC_FRAMES && len >= mtu;
+					i++, offset += mtu, len -= mtu) {
+		urb->iso_frame_desc[i].offset = offset;
+		urb->iso_frame_desc[i].length = mtu;
+	}
+
+	if (len && i < BTUSB_MAX_ISOC_FRAMES) {
+		urb->iso_frame_desc[i].offset = offset;
+		urb->iso_frame_desc[i].length = len;
+		i++;
+	}
+
+	urb->number_of_packets = i;
+}
+
+static int btusb_submit_isoc_urb(struct hci_dev *hdev)
+{
+	struct btusb_data *data = hdev->driver_data;
+	struct urb *urb;
+	unsigned char *buf;
+	unsigned int pipe;
+	int err, size;
+
+	BT_DBG("%s", hdev->name);
+
+	if (!data->isoc_rx_ep)
+		return -ENODEV;
+
+	urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_KERNEL);
+	if (!urb)
+		return -ENOMEM;
+
+	size = le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize) *
+						BTUSB_MAX_ISOC_FRAMES;
+
+	buf = kmalloc(size, GFP_KERNEL);
+	if (!buf) {
+		usb_free_urb(urb);
+		return -ENOMEM;
+	}
+
+	pipe = usb_rcvisocpipe(data->udev, data->isoc_rx_ep->bEndpointAddress);
+
+	urb->dev      = data->udev;
+	urb->pipe     = pipe;
+	urb->context  = hdev;
+	urb->complete = btusb_isoc_complete;
+	urb->interval = data->isoc_rx_ep->bInterval;
+
+	urb->transfer_flags  = URB_FREE_BUFFER | URB_ISO_ASAP;
+	urb->transfer_buffer = buf;
+	urb->transfer_buffer_length = size;
+
+	__fill_isoc_descriptor(urb, size,
+			le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize));
+
+	usb_anchor_urb(urb, &data->isoc_anchor);
+
+	err = usb_submit_urb(urb, GFP_KERNEL);
+	if (err < 0) {
+		BT_ERR("%s urb %p submission failed (%d)",
+						hdev->name, urb, -err);
+		usb_unanchor_urb(urb);
+		kfree(buf);
+	}
+
+	usb_free_urb(urb);
+
+	return err;
+}
+
 static void btusb_tx_complete(struct urb *urb)
 static void btusb_tx_complete(struct urb *urb)
 {
 {
 	struct sk_buff *skb = urb->context;
 	struct sk_buff *skb = urb->context;
@@ -392,6 +532,9 @@ static int btusb_close(struct hci_dev *hdev)
 	if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
 	if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
 		return 0;
 		return 0;
 
 
+	clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
+	usb_kill_anchored_urbs(&data->intr_anchor);
+
 	clear_bit(BTUSB_BULK_RUNNING, &data->flags);
 	clear_bit(BTUSB_BULK_RUNNING, &data->flags);
 	usb_kill_anchored_urbs(&data->bulk_anchor);
 	usb_kill_anchored_urbs(&data->bulk_anchor);
 
 
@@ -453,6 +596,9 @@ static int btusb_send_frame(struct sk_buff *skb)
 		break;
 		break;
 
 
 	case HCI_ACLDATA_PKT:
 	case HCI_ACLDATA_PKT:
+		if (!data->bulk_tx_ep || hdev->conn_hash.acl_num < 1)
+			return -ENODEV;
+
 		urb = usb_alloc_urb(0, GFP_ATOMIC);
 		urb = usb_alloc_urb(0, GFP_ATOMIC);
 		if (!urb)
 		if (!urb)
 			return -ENOMEM;
 			return -ENOMEM;
@@ -467,9 +613,31 @@ static int btusb_send_frame(struct sk_buff *skb)
 		break;
 		break;
 
 
 	case HCI_SCODATA_PKT:
 	case HCI_SCODATA_PKT:
+		if (!data->isoc_tx_ep || hdev->conn_hash.sco_num < 1)
+			return -ENODEV;
+
+		urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_ATOMIC);
+		if (!urb)
+			return -ENOMEM;
+
+		pipe = usb_sndisocpipe(data->udev,
+					data->isoc_tx_ep->bEndpointAddress);
+
+		urb->dev      = data->udev;
+		urb->pipe     = pipe;
+		urb->context  = skb;
+		urb->complete = btusb_tx_complete;
+		urb->interval = data->isoc_tx_ep->bInterval;
+
+		urb->transfer_flags  = URB_ISO_ASAP;
+		urb->transfer_buffer = skb->data;
+		urb->transfer_buffer_length = skb->len;
+
+		__fill_isoc_descriptor(urb, skb->len,
+				le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize));
+
 		hdev->stat.sco_tx++;
 		hdev->stat.sco_tx++;
-		kfree_skb(skb);
-		return 0;
+		break;
 
 
 	default:
 	default:
 		return -EILSEQ;
 		return -EILSEQ;
@@ -508,22 +676,86 @@ static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
 		schedule_work(&data->work);
 		schedule_work(&data->work);
 }
 }
 
 
+static int inline __set_isoc_interface(struct hci_dev *hdev, int altsetting)
+{
+	struct btusb_data *data = hdev->driver_data;
+	struct usb_interface *intf = data->isoc;
+	struct usb_endpoint_descriptor *ep_desc;
+	int i, err;
+
+	if (!data->isoc)
+		return -ENODEV;
+
+	err = usb_set_interface(data->udev, 1, altsetting);
+	if (err < 0) {
+		BT_ERR("%s setting interface failed (%d)", hdev->name, -err);
+		return err;
+	}
+
+	data->isoc_altsetting = altsetting;
+
+	data->isoc_tx_ep = NULL;
+	data->isoc_rx_ep = NULL;
+
+	for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
+		ep_desc = &intf->cur_altsetting->endpoint[i].desc;
+
+		if (!data->isoc_tx_ep && usb_endpoint_is_isoc_out(ep_desc)) {
+			data->isoc_tx_ep = ep_desc;
+			continue;
+		}
+
+		if (!data->isoc_rx_ep && usb_endpoint_is_isoc_in(ep_desc)) {
+			data->isoc_rx_ep = ep_desc;
+			continue;
+		}
+	}
+
+	if (!data->isoc_tx_ep || !data->isoc_rx_ep) {
+		BT_ERR("%s invalid SCO descriptors", hdev->name);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
 static void btusb_work(struct work_struct *work)
 static void btusb_work(struct work_struct *work)
 {
 {
 	struct btusb_data *data = container_of(work, struct btusb_data, work);
 	struct btusb_data *data = container_of(work, struct btusb_data, work);
 	struct hci_dev *hdev = data->hdev;
 	struct hci_dev *hdev = data->hdev;
 
 
-	if (hdev->conn_hash.acl_num == 0) {
+	if (hdev->conn_hash.acl_num > 0) {
+		if (!test_and_set_bit(BTUSB_BULK_RUNNING, &data->flags)) {
+			if (btusb_submit_bulk_urb(hdev) < 0)
+				clear_bit(BTUSB_BULK_RUNNING, &data->flags);
+			else
+				btusb_submit_bulk_urb(hdev);
+		}
+	} else {
 		clear_bit(BTUSB_BULK_RUNNING, &data->flags);
 		clear_bit(BTUSB_BULK_RUNNING, &data->flags);
 		usb_kill_anchored_urbs(&data->bulk_anchor);
 		usb_kill_anchored_urbs(&data->bulk_anchor);
-		return;
 	}
 	}
 
 
-	if (!test_and_set_bit(BTUSB_BULK_RUNNING, &data->flags)) {
-		if (btusb_submit_bulk_urb(hdev) < 0)
-			clear_bit(BTUSB_BULK_RUNNING, &data->flags);
-		else
-			btusb_submit_bulk_urb(hdev);
+	if (hdev->conn_hash.sco_num > 0) {
+		if (data->isoc_altsetting != 2) {
+			clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
+			usb_kill_anchored_urbs(&data->isoc_anchor);
+
+			if (__set_isoc_interface(hdev, 2) < 0)
+				return;
+		}
+
+		if (!test_and_set_bit(BTUSB_ISOC_RUNNING, &data->flags)) {
+			if (btusb_submit_isoc_urb(hdev) < 0)
+				clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
+			else
+				btusb_submit_isoc_urb(hdev);
+		}
+	} else {
+		clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
+		usb_kill_anchored_urbs(&data->isoc_anchor);
+
+		__set_isoc_interface(hdev, 0);
 	}
 	}
 }
 }
 
 
@@ -597,6 +829,7 @@ static int btusb_probe(struct usb_interface *intf,
 	init_usb_anchor(&data->tx_anchor);
 	init_usb_anchor(&data->tx_anchor);
 	init_usb_anchor(&data->intr_anchor);
 	init_usb_anchor(&data->intr_anchor);
 	init_usb_anchor(&data->bulk_anchor);
 	init_usb_anchor(&data->bulk_anchor);
+	init_usb_anchor(&data->isoc_anchor);
 
 
 	hdev = hci_alloc_dev();
 	hdev = hci_alloc_dev();
 	if (!hdev) {
 	if (!hdev) {
@@ -620,6 +853,9 @@ static int btusb_probe(struct usb_interface *intf,
 
 
 	hdev->owner = THIS_MODULE;
 	hdev->owner = THIS_MODULE;
 
 
+	/* interface numbers are hardcoded in the spec */
+	data->isoc = usb_ifnum_to_if(data->udev, 1);
+
 	if (reset || id->driver_info & BTUSB_RESET)
 	if (reset || id->driver_info & BTUSB_RESET)
 		set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks);
 		set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks);
 
 
@@ -628,11 +864,16 @@ static int btusb_probe(struct usb_interface *intf,
 			set_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks);
 			set_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks);
 	}
 	}
 
 
+	if (id->driver_info & BTUSB_BROKEN_ISOC)
+		data->isoc = NULL;
+
 	if (id->driver_info & BTUSB_SNIFFER) {
 	if (id->driver_info & BTUSB_SNIFFER) {
-		struct usb_device *udev = interface_to_usbdev(intf);
+		struct usb_device *udev = data->udev;
 
 
 		if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997)
 		if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997)
 			set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
 			set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
+
+		data->isoc = NULL;
 	}
 	}
 
 
 	if (id->driver_info & BTUSB_BCM92035) {
 	if (id->driver_info & BTUSB_BCM92035) {
@@ -646,6 +887,16 @@ static int btusb_probe(struct usb_interface *intf,
 		}
 		}
 	}
 	}
 
 
+	if (data->isoc) {
+		err = usb_driver_claim_interface(&btusb_driver,
+							data->isoc, NULL);
+		if (err < 0) {
+			hci_free_dev(hdev);
+			kfree(data);
+			return err;
+		}
+	}
+
 	err = hci_register_dev(hdev);
 	err = hci_register_dev(hdev);
 	if (err < 0) {
 	if (err < 0) {
 		hci_free_dev(hdev);
 		hci_free_dev(hdev);
@@ -670,6 +921,9 @@ static void btusb_disconnect(struct usb_interface *intf)
 
 
 	hdev = data->hdev;
 	hdev = data->hdev;
 
 
+	if (data->isoc)
+		usb_driver_release_interface(&btusb_driver, data->isoc);
+
 	usb_set_intfdata(intf, NULL);
 	usb_set_intfdata(intf, NULL);
 
 
 	hci_unregister_dev(hdev);
 	hci_unregister_dev(hdev);

+ 1 - 1
drivers/bluetooth/hci_ldisc.c

@@ -577,7 +577,7 @@ module_exit(hci_uart_exit);
 module_param(reset, bool, 0644);
 module_param(reset, bool, 0644);
 MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");
 MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");
 
 
-MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth HCI UART driver ver " VERSION);
 MODULE_DESCRIPTION("Bluetooth HCI UART driver ver " VERSION);
 MODULE_VERSION(VERSION);
 MODULE_VERSION(VERSION);
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");

+ 1 - 1
drivers/bluetooth/hci_usb.c

@@ -1130,7 +1130,7 @@ module_param(isoc, int, 0644);
 MODULE_PARM_DESC(isoc, "Set isochronous transfers for SCO over HCI support");
 MODULE_PARM_DESC(isoc, "Set isochronous transfers for SCO over HCI support");
 #endif
 #endif
 
 
-MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth HCI USB driver ver " VERSION);
 MODULE_DESCRIPTION("Bluetooth HCI USB driver ver " VERSION);
 MODULE_VERSION(VERSION);
 MODULE_VERSION(VERSION);
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");

+ 1 - 1
drivers/bluetooth/hci_vhci.c

@@ -377,7 +377,7 @@ module_exit(vhci_exit);
 module_param(minor, int, 0444);
 module_param(minor, int, 0444);
 MODULE_PARM_DESC(minor, "Miscellaneous minor device number");
 MODULE_PARM_DESC(minor, "Miscellaneous minor device number");
 
 
-MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth virtual HCI driver ver " VERSION);
 MODULE_DESCRIPTION("Bluetooth virtual HCI driver ver " VERSION);
 MODULE_VERSION(VERSION);
 MODULE_VERSION(VERSION);
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");

+ 1 - 0
drivers/char/random.c

@@ -1571,6 +1571,7 @@ u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
 
 
 	return half_md4_transform(hash, keyptr->secret);
 	return half_md4_transform(hash, keyptr->secret);
 }
 }
+EXPORT_SYMBOL_GPL(secure_ipv4_port_ephemeral);
 
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
 u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,

+ 1 - 1
drivers/net/Kconfig

@@ -1172,7 +1172,7 @@ config ETH16I
 
 
 config NE2000
 config NE2000
 	tristate "NE2000/NE1000 support"
 	tristate "NE2000/NE1000 support"
-	depends on NET_ISA || (Q40 && m) || M32R || TOSHIBA_RBTX4927 || TOSHIBA_RBTX4938
+	depends on NET_ISA || (Q40 && m) || M32R || MACH_TX49XX
 	select CRC32
 	select CRC32
 	---help---
 	---help---
 	  If you have a network (Ethernet) card of this type, say Y and read
 	  If you have a network (Ethernet) card of this type, say Y and read

+ 0 - 1
drivers/net/acenic.c

@@ -52,7 +52,6 @@
 
 
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/moduleparam.h>
-#include <linux/version.h>
 #include <linux/types.h>
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
 #include <linux/ioport.h>

+ 3 - 3
drivers/net/arm/ixp4xx_eth.c

@@ -551,7 +551,7 @@ static int eth_poll(struct napi_struct *napi, int budget)
 		if ((skb = netdev_alloc_skb(dev, RX_BUFF_SIZE))) {
 		if ((skb = netdev_alloc_skb(dev, RX_BUFF_SIZE))) {
 			phys = dma_map_single(&dev->dev, skb->data,
 			phys = dma_map_single(&dev->dev, skb->data,
 					      RX_BUFF_SIZE, DMA_FROM_DEVICE);
 					      RX_BUFF_SIZE, DMA_FROM_DEVICE);
-			if (dma_mapping_error(phys)) {
+			if (dma_mapping_error(&dev->dev, phys)) {
 				dev_kfree_skb(skb);
 				dev_kfree_skb(skb);
 				skb = NULL;
 				skb = NULL;
 			}
 			}
@@ -698,7 +698,7 @@ static int eth_xmit(struct sk_buff *skb, struct net_device *dev)
 #endif
 #endif
 
 
 	phys = dma_map_single(&dev->dev, mem, bytes, DMA_TO_DEVICE);
 	phys = dma_map_single(&dev->dev, mem, bytes, DMA_TO_DEVICE);
-	if (dma_mapping_error(phys)) {
+	if (dma_mapping_error(&dev->dev, phys)) {
 #ifdef __ARMEB__
 #ifdef __ARMEB__
 		dev_kfree_skb(skb);
 		dev_kfree_skb(skb);
 #else
 #else
@@ -883,7 +883,7 @@ static int init_queues(struct port *port)
 		desc->buf_len = MAX_MRU;
 		desc->buf_len = MAX_MRU;
 		desc->data = dma_map_single(&port->netdev->dev, data,
 		desc->data = dma_map_single(&port->netdev->dev, data,
 					    RX_BUFF_SIZE, DMA_FROM_DEVICE);
 					    RX_BUFF_SIZE, DMA_FROM_DEVICE);
-		if (dma_mapping_error(desc->data)) {
+		if (dma_mapping_error(&port->netdev->dev, desc->data)) {
 			free_buffer(buff);
 			free_buffer(buff);
 			return -EIO;
 			return -EIO;
 		}
 		}

+ 1 - 1
drivers/net/atl1e/atl1e_ethtool.c

@@ -355,7 +355,7 @@ static int atl1e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 	struct atl1e_adapter *adapter = netdev_priv(netdev);
 	struct atl1e_adapter *adapter = netdev_priv(netdev);
 
 
 	if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE |
 	if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE |
-			    WAKE_MCAST | WAKE_BCAST | WAKE_MCAST))
+			    WAKE_UCAST | WAKE_MCAST | WAKE_BCAST))
 		return -EOPNOTSUPP;
 		return -EOPNOTSUPP;
 	/* these settings will always override what we currently have */
 	/* these settings will always override what we currently have */
 	adapter->wol = 0;
 	adapter->wol = 0;

+ 1 - 1
drivers/net/au1000_eth.c

@@ -807,7 +807,7 @@ err_out:
 static int au1000_init(struct net_device *dev)
 static int au1000_init(struct net_device *dev)
 {
 {
 	struct au1000_private *aup = (struct au1000_private *) dev->priv;
 	struct au1000_private *aup = (struct au1000_private *) dev->priv;
-	u32 flags;
+	unsigned long flags;
 	int i;
 	int i;
 	u32 control;
 	u32 control;
 
 

+ 2 - 2
drivers/net/ax88796.c

@@ -554,7 +554,7 @@ static int ax_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 
 
 	spin_lock_irqsave(&ax->mii_lock, flags);
 	spin_lock_irqsave(&ax->mii_lock, flags);
 	mii_ethtool_gset(&ax->mii, cmd);
 	mii_ethtool_gset(&ax->mii, cmd);
-	spin_lock_irqsave(&ax->mii_lock, flags);
+	spin_unlock_irqrestore(&ax->mii_lock, flags);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -567,7 +567,7 @@ static int ax_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 
 
 	spin_lock_irqsave(&ax->mii_lock, flags);
 	spin_lock_irqsave(&ax->mii_lock, flags);
 	rc = mii_ethtool_sset(&ax->mii, cmd);
 	rc = mii_ethtool_sset(&ax->mii, cmd);
-	spin_lock_irqsave(&ax->mii_lock, flags);
+	spin_unlock_irqrestore(&ax->mii_lock, flags);
 
 
 	return rc;
 	return rc;
 }
 }

+ 34 - 13
drivers/net/bnx2.c

@@ -35,8 +35,8 @@
 #include <linux/time.h>
 #include <linux/time.h>
 #include <linux/ethtool.h>
 #include <linux/ethtool.h>
 #include <linux/mii.h>
 #include <linux/mii.h>
-#ifdef NETIF_F_HW_VLAN_TX
 #include <linux/if_vlan.h>
 #include <linux/if_vlan.h>
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
 #define BCM_VLAN 1
 #define BCM_VLAN 1
 #endif
 #endif
 #include <net/ip.h>
 #include <net/ip.h>
@@ -57,8 +57,8 @@
 
 
 #define DRV_MODULE_NAME		"bnx2"
 #define DRV_MODULE_NAME		"bnx2"
 #define PFX DRV_MODULE_NAME	": "
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"1.7.9"
-#define DRV_MODULE_RELDATE	"July 18, 2008"
+#define DRV_MODULE_VERSION	"1.8.0"
+#define DRV_MODULE_RELDATE	"Aug 14, 2008"
 
 
 #define RUN_AT(x) (jiffies + (x))
 #define RUN_AT(x) (jiffies + (x))
 
 
@@ -2876,6 +2876,8 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
 		struct sw_bd *rx_buf;
 		struct sw_bd *rx_buf;
 		struct sk_buff *skb;
 		struct sk_buff *skb;
 		dma_addr_t dma_addr;
 		dma_addr_t dma_addr;
+		u16 vtag = 0;
+		int hw_vlan __maybe_unused = 0;
 
 
 		sw_ring_cons = RX_RING_IDX(sw_cons);
 		sw_ring_cons = RX_RING_IDX(sw_cons);
 		sw_ring_prod = RX_RING_IDX(sw_prod);
 		sw_ring_prod = RX_RING_IDX(sw_prod);
@@ -2919,7 +2921,7 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
 		if (len <= bp->rx_copy_thresh) {
 		if (len <= bp->rx_copy_thresh) {
 			struct sk_buff *new_skb;
 			struct sk_buff *new_skb;
 
 
-			new_skb = netdev_alloc_skb(bp->dev, len + 2);
+			new_skb = netdev_alloc_skb(bp->dev, len + 6);
 			if (new_skb == NULL) {
 			if (new_skb == NULL) {
 				bnx2_reuse_rx_skb(bp, rxr, skb, sw_ring_cons,
 				bnx2_reuse_rx_skb(bp, rxr, skb, sw_ring_cons,
 						  sw_ring_prod);
 						  sw_ring_prod);
@@ -2928,9 +2930,9 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
 
 
 			/* aligned copy */
 			/* aligned copy */
 			skb_copy_from_linear_data_offset(skb,
 			skb_copy_from_linear_data_offset(skb,
-							 BNX2_RX_OFFSET - 2,
-				      new_skb->data, len + 2);
-			skb_reserve(new_skb, 2);
+							 BNX2_RX_OFFSET - 6,
+				      new_skb->data, len + 6);
+			skb_reserve(new_skb, 6);
 			skb_put(new_skb, len);
 			skb_put(new_skb, len);
 
 
 			bnx2_reuse_rx_skb(bp, rxr, skb,
 			bnx2_reuse_rx_skb(bp, rxr, skb,
@@ -2941,6 +2943,25 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
 			   dma_addr, (sw_ring_cons << 16) | sw_ring_prod)))
 			   dma_addr, (sw_ring_cons << 16) | sw_ring_prod)))
 			goto next_rx;
 			goto next_rx;
 
 
+		if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) &&
+		    !(bp->rx_mode & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG)) {
+			vtag = rx_hdr->l2_fhdr_vlan_tag;
+#ifdef BCM_VLAN
+			if (bp->vlgrp)
+				hw_vlan = 1;
+			else
+#endif
+			{
+				struct vlan_ethhdr *ve = (struct vlan_ethhdr *)
+					__skb_push(skb, 4);
+
+				memmove(ve, skb->data + 4, ETH_ALEN * 2);
+				ve->h_vlan_proto = htons(ETH_P_8021Q);
+				ve->h_vlan_TCI = htons(vtag);
+				len += 4;
+			}
+		}
+
 		skb->protocol = eth_type_trans(skb, bp->dev);
 		skb->protocol = eth_type_trans(skb, bp->dev);
 
 
 		if ((len > (bp->dev->mtu + ETH_HLEN)) &&
 		if ((len > (bp->dev->mtu + ETH_HLEN)) &&
@@ -2962,10 +2983,8 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
 		}
 		}
 
 
 #ifdef BCM_VLAN
 #ifdef BCM_VLAN
-		if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) && bp->vlgrp) {
-			vlan_hwaccel_receive_skb(skb, bp->vlgrp,
-				rx_hdr->l2_fhdr_vlan_tag);
-		}
+		if (hw_vlan)
+			vlan_hwaccel_receive_skb(skb, bp->vlgrp, vtag);
 		else
 		else
 #endif
 #endif
 			netif_receive_skb(skb);
 			netif_receive_skb(skb);
@@ -3237,10 +3256,10 @@ bnx2_set_rx_mode(struct net_device *dev)
 				  BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG);
 				  BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG);
 	sort_mode = 1 | BNX2_RPM_SORT_USER0_BC_EN;
 	sort_mode = 1 | BNX2_RPM_SORT_USER0_BC_EN;
 #ifdef BCM_VLAN
 #ifdef BCM_VLAN
-	if (!bp->vlgrp && !(bp->flags & BNX2_FLAG_ASF_ENABLE))
+	if (!bp->vlgrp && (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN))
 		rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG;
 		rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG;
 #else
 #else
-	if (!(bp->flags & BNX2_FLAG_ASF_ENABLE))
+	if (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN)
 		rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG;
 		rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG;
 #endif
 #endif
 	if (dev->flags & IFF_PROMISC) {
 	if (dev->flags & IFF_PROMISC) {
@@ -5963,10 +5982,12 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		vlan_tag_flags |= TX_BD_FLAGS_TCP_UDP_CKSUM;
 		vlan_tag_flags |= TX_BD_FLAGS_TCP_UDP_CKSUM;
 	}
 	}
 
 
+#ifdef BCM_VLAN
 	if (bp->vlgrp && vlan_tx_tag_present(skb)) {
 	if (bp->vlgrp && vlan_tx_tag_present(skb)) {
 		vlan_tag_flags |=
 		vlan_tag_flags |=
 			(TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16));
 			(TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16));
 	}
 	}
+#endif
 	if ((mss = skb_shinfo(skb)->gso_size)) {
 	if ((mss = skb_shinfo(skb)->gso_size)) {
 		u32 tcp_opt_len, ip_tcp_len;
 		u32 tcp_opt_len, ip_tcp_len;
 		struct iphdr *iph;
 		struct iphdr *iph;

+ 0 - 1
drivers/net/bnx2x_link.c

@@ -21,7 +21,6 @@
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/ethtool.h>
 #include <linux/ethtool.h>
 #include <linux/mutex.h>
 #include <linux/mutex.h>
-#include <linux/version.h>
 
 
 #include "bnx2x_reg.h"
 #include "bnx2x_reg.h"
 #include "bnx2x_fw_defs.h"
 #include "bnx2x_fw_defs.h"

+ 0 - 1
drivers/net/bnx2x_main.c

@@ -44,7 +44,6 @@
 #include <net/ip.h>
 #include <net/ip.h>
 #include <net/tcp.h>
 #include <net/tcp.h>
 #include <net/checksum.h>
 #include <net/checksum.h>
-#include <linux/version.h>
 #include <net/ip6_checksum.h>
 #include <net/ip6_checksum.h>
 #include <linux/workqueue.h>
 #include <linux/workqueue.h>
 #include <linux/crc32.h>
 #include <linux/crc32.h>

+ 0 - 1
drivers/net/cpmac.c

@@ -26,7 +26,6 @@
 #include <linux/errno.h>
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/types.h>
 #include <linux/delay.h>
 #include <linux/delay.h>
-#include <linux/version.h>
 
 
 #include <linux/netdevice.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/etherdevice.h>

+ 1 - 1
drivers/net/e1000e/defines.h

@@ -389,7 +389,7 @@
 
 
 /* Interrupt Cause Set */
 /* Interrupt Cause Set */
 #define E1000_ICS_LSC       E1000_ICR_LSC       /* Link Status Change */
 #define E1000_ICS_LSC       E1000_ICR_LSC       /* Link Status Change */
-#define E1000_ICS_RXDMT0    E1000_ICR_RXDMT0    /* rx desc min. threshold */
+#define E1000_ICS_RXSEQ     E1000_ICR_RXSEQ     /* Rx sequence error */
 #define E1000_ICS_RXDMT0    E1000_ICR_RXDMT0    /* Rx desc min. threshold */
 #define E1000_ICS_RXDMT0    E1000_ICR_RXDMT0    /* Rx desc min. threshold */
 
 
 /* Transmit Descriptor Control */
 /* Transmit Descriptor Control */

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

@@ -326,6 +326,7 @@ struct e1000_info {
 #define FLAG_RX_CSUM_ENABLED              (1 << 28)
 #define FLAG_RX_CSUM_ENABLED              (1 << 28)
 #define FLAG_TSO_FORCE                    (1 << 29)
 #define FLAG_TSO_FORCE                    (1 << 29)
 #define FLAG_RX_RESTART_NOW               (1 << 30)
 #define FLAG_RX_RESTART_NOW               (1 << 30)
+#define FLAG_MSI_TEST_FAILED              (1 << 31)
 
 
 #define E1000_RX_DESC_PS(R, i)	    \
 #define E1000_RX_DESC_PS(R, i)	    \
 	(&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
 	(&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))

+ 1 - 1
drivers/net/e1000e/ethtool.c

@@ -177,7 +177,7 @@ static u32 e1000_get_link(struct net_device *netdev)
 	u32 status;
 	u32 status;
 	
 	
 	status = er32(STATUS);
 	status = er32(STATUS);
-	return (status & E1000_STATUS_LU);
+	return (status & E1000_STATUS_LU) ? 1 : 0;
 }
 }
 
 
 static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
 static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)

+ 170 - 15
drivers/net/e1000e/netdev.c

@@ -510,9 +510,12 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
 			    netdev_alloc_skb(netdev, length + NET_IP_ALIGN);
 			    netdev_alloc_skb(netdev, length + NET_IP_ALIGN);
 			if (new_skb) {
 			if (new_skb) {
 				skb_reserve(new_skb, NET_IP_ALIGN);
 				skb_reserve(new_skb, NET_IP_ALIGN);
-				memcpy(new_skb->data - NET_IP_ALIGN,
-				       skb->data - NET_IP_ALIGN,
-				       length + NET_IP_ALIGN);
+				skb_copy_to_linear_data_offset(new_skb,
+							       -NET_IP_ALIGN,
+							       (skb->data -
+								NET_IP_ALIGN),
+							       (length +
+								NET_IP_ALIGN));
 				/* save the skb in buffer_info as good */
 				/* save the skb in buffer_info as good */
 				buffer_info->skb = skb;
 				buffer_info->skb = skb;
 				skb = new_skb;
 				skb = new_skb;
@@ -1233,26 +1236,36 @@ static irqreturn_t e1000_intr(int irq, void *data)
 	return IRQ_HANDLED;
 	return IRQ_HANDLED;
 }
 }
 
 
+/**
+ * e1000_request_irq - initialize interrupts
+ *
+ * Attempts to configure interrupts using the best available
+ * capabilities of the hardware and kernel.
+ **/
 static int e1000_request_irq(struct e1000_adapter *adapter)
 static int e1000_request_irq(struct e1000_adapter *adapter)
 {
 {
 	struct net_device *netdev = adapter->netdev;
 	struct net_device *netdev = adapter->netdev;
-	irq_handler_t handler = e1000_intr;
 	int irq_flags = IRQF_SHARED;
 	int irq_flags = IRQF_SHARED;
 	int err;
 	int err;
 
 
-	if (!pci_enable_msi(adapter->pdev)) {
-		adapter->flags |= FLAG_MSI_ENABLED;
-		handler = e1000_intr_msi;
-		irq_flags = 0;
+	if (!(adapter->flags & FLAG_MSI_TEST_FAILED)) {
+		err = pci_enable_msi(adapter->pdev);
+		if (!err) {
+			adapter->flags |= FLAG_MSI_ENABLED;
+			irq_flags = 0;
+		}
 	}
 	}
 
 
-	err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name,
-			  netdev);
+	err = request_irq(adapter->pdev->irq,
+			  ((adapter->flags & FLAG_MSI_ENABLED) ?
+				&e1000_intr_msi : &e1000_intr),
+			  irq_flags, netdev->name, netdev);
 	if (err) {
 	if (err) {
-		e_err("Unable to allocate %s interrupt (return: %d)\n",
-		      adapter->flags & FLAG_MSI_ENABLED ? "MSI":"INTx",	err);
-		if (adapter->flags & FLAG_MSI_ENABLED)
+		if (adapter->flags & FLAG_MSI_ENABLED) {
 			pci_disable_msi(adapter->pdev);
 			pci_disable_msi(adapter->pdev);
+			adapter->flags &= ~FLAG_MSI_ENABLED;
+		}
+		e_err("Unable to allocate interrupt, Error: %d\n", err);
 	}
 	}
 
 
 	return err;
 	return err;
@@ -2591,6 +2604,135 @@ err:
 	return -ENOMEM;
 	return -ENOMEM;
 }
 }
 
 
+/**
+ * e1000_intr_msi_test - Interrupt Handler
+ * @irq: interrupt number
+ * @data: pointer to a network interface device structure
+ **/
+static irqreturn_t e1000_intr_msi_test(int irq, void *data)
+{
+	struct net_device *netdev = data;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
+	u32 icr = er32(ICR);
+
+	e_dbg("%s: icr is %08X\n", netdev->name, icr);
+	if (icr & E1000_ICR_RXSEQ) {
+		adapter->flags &= ~FLAG_MSI_TEST_FAILED;
+		wmb();
+	}
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * e1000_test_msi_interrupt - Returns 0 for successful test
+ * @adapter: board private struct
+ *
+ * code flow taken from tg3.c
+ **/
+static int e1000_test_msi_interrupt(struct e1000_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+	struct e1000_hw *hw = &adapter->hw;
+	int err;
+
+	/* poll_enable hasn't been called yet, so don't need disable */
+	/* clear any pending events */
+	er32(ICR);
+
+	/* free the real vector and request a test handler */
+	e1000_free_irq(adapter);
+
+	/* Assume that the test fails, if it succeeds then the test
+	 * MSI irq handler will unset this flag */
+	adapter->flags |= FLAG_MSI_TEST_FAILED;
+
+	err = pci_enable_msi(adapter->pdev);
+	if (err)
+		goto msi_test_failed;
+
+	err = request_irq(adapter->pdev->irq, &e1000_intr_msi_test, 0,
+			  netdev->name, netdev);
+	if (err) {
+		pci_disable_msi(adapter->pdev);
+		goto msi_test_failed;
+	}
+
+	wmb();
+
+	e1000_irq_enable(adapter);
+
+	/* fire an unusual interrupt on the test handler */
+	ew32(ICS, E1000_ICS_RXSEQ);
+	e1e_flush();
+	msleep(50);
+
+	e1000_irq_disable(adapter);
+
+	rmb();
+
+	if (adapter->flags & FLAG_MSI_TEST_FAILED) {
+		err = -EIO;
+		e_info("MSI interrupt test failed!\n");
+	}
+
+	free_irq(adapter->pdev->irq, netdev);
+	pci_disable_msi(adapter->pdev);
+
+	if (err == -EIO)
+		goto msi_test_failed;
+
+	/* okay so the test worked, restore settings */
+	e_dbg("%s: MSI interrupt test succeeded!\n", netdev->name);
+msi_test_failed:
+	/* restore the original vector, even if it failed */
+	e1000_request_irq(adapter);
+	return err;
+}
+
+/**
+ * e1000_test_msi - Returns 0 if MSI test succeeds or INTx mode is restored
+ * @adapter: board private struct
+ *
+ * code flow taken from tg3.c, called with e1000 interrupts disabled.
+ **/
+static int e1000_test_msi(struct e1000_adapter *adapter)
+{
+	int err;
+	u16 pci_cmd;
+
+	if (!(adapter->flags & FLAG_MSI_ENABLED))
+		return 0;
+
+	/* disable SERR in case the MSI write causes a master abort */
+	pci_read_config_word(adapter->pdev, PCI_COMMAND, &pci_cmd);
+	pci_write_config_word(adapter->pdev, PCI_COMMAND,
+			      pci_cmd & ~PCI_COMMAND_SERR);
+
+	err = e1000_test_msi_interrupt(adapter);
+
+	/* restore previous setting of command word */
+	pci_write_config_word(adapter->pdev, PCI_COMMAND, pci_cmd);
+
+	/* success ! */
+	if (!err)
+		return 0;
+
+	/* EIO means MSI test failed */
+	if (err != -EIO)
+		return err;
+
+	/* back to INTx mode */
+	e_warn("MSI interrupt test failed, using legacy interrupt.\n");
+
+	e1000_free_irq(adapter);
+
+	err = e1000_request_irq(adapter);
+
+	return err;
+}
+
 /**
 /**
  * e1000_open - Called when a network interface is made active
  * e1000_open - Called when a network interface is made active
  * @netdev: network interface device structure
  * @netdev: network interface device structure
@@ -2649,6 +2791,19 @@ static int e1000_open(struct net_device *netdev)
 	if (err)
 	if (err)
 		goto err_req_irq;
 		goto err_req_irq;
 
 
+	/*
+	 * Work around PCIe errata with MSI interrupts causing some chipsets to
+	 * ignore e1000e MSI messages, which means we need to test our MSI
+	 * interrupt now
+	 */
+	{
+		err = e1000_test_msi(adapter);
+		if (err) {
+			e_err("Interrupt allocation failed\n");
+			goto err_req_irq;
+		}
+	}
+
 	/* From here on the code is the same as e1000e_up() */
 	/* From here on the code is the same as e1000e_up() */
 	clear_bit(__E1000_DOWN, &adapter->state);
 	clear_bit(__E1000_DOWN, &adapter->state);
 
 
@@ -3055,7 +3210,7 @@ static void e1000_watchdog_task(struct work_struct *work)
 			case SPEED_10:
 			case SPEED_10:
 				txb2b = 0;
 				txb2b = 0;
 				netdev->tx_queue_len = 10;
 				netdev->tx_queue_len = 10;
-				adapter->tx_timeout_factor = 14;
+				adapter->tx_timeout_factor = 16;
 				break;
 				break;
 			case SPEED_100:
 			case SPEED_100:
 				txb2b = 0;
 				txb2b = 0;
@@ -3721,7 +3876,7 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
 	int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
 
 
-	if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) ||
+	if ((new_mtu < ETH_ZLEN + ETH_FCS_LEN + VLAN_HLEN) ||
 	    (max_frame > MAX_JUMBO_FRAME_SIZE)) {
 	    (max_frame > MAX_JUMBO_FRAME_SIZE)) {
 		e_err("Invalid MTU setting\n");
 		e_err("Invalid MTU setting\n");
 		return -EINVAL;
 		return -EINVAL;

+ 19 - 6
drivers/net/e1000e/param.c

@@ -324,14 +324,27 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
 				adapter->itr = 20000;
 				adapter->itr = 20000;
 				break;
 				break;
 			default:
 			default:
-				e1000_validate_option(&adapter->itr, &opt,
-					adapter);
 				/*
 				/*
-				 * save the setting, because the dynamic bits
-				 * change itr. clear the lower two bits
-				 * because they are used as control
+				 * Save the setting, because the dynamic bits
+				 * change itr.
 				 */
 				 */
-				adapter->itr_setting = adapter->itr & ~3;
+				if (e1000_validate_option(&adapter->itr, &opt,
+							  adapter) &&
+				    (adapter->itr == 3)) {
+					/*
+					 * In case of invalid user value,
+					 * default to conservative mode.
+					 */
+					adapter->itr_setting = adapter->itr;
+					adapter->itr = 20000;
+				} else {
+					/*
+					 * Clear the lower two bits because
+					 * they are used as control.
+					 */
+					adapter->itr_setting =
+						adapter->itr & ~3;
+				}
 				break;
 				break;
 			}
 			}
 		} else {
 		} else {

+ 2 - 4
drivers/net/gianfar.c

@@ -134,9 +134,7 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int l
 static void gfar_vlan_rx_register(struct net_device *netdev,
 static void gfar_vlan_rx_register(struct net_device *netdev,
 		                struct vlan_group *grp);
 		                struct vlan_group *grp);
 void gfar_halt(struct net_device *dev);
 void gfar_halt(struct net_device *dev);
-#ifdef CONFIG_PM
 static void gfar_halt_nodisable(struct net_device *dev);
 static void gfar_halt_nodisable(struct net_device *dev);
-#endif
 void gfar_start(struct net_device *dev);
 void gfar_start(struct net_device *dev);
 static void gfar_clear_exact_match(struct net_device *dev);
 static void gfar_clear_exact_match(struct net_device *dev);
 static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr);
 static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr);
@@ -631,7 +629,6 @@ static void init_registers(struct net_device *dev)
 }
 }
 
 
 
 
-#ifdef CONFIG_PM
 /* Halt the receive and transmit queues */
 /* Halt the receive and transmit queues */
 static void gfar_halt_nodisable(struct net_device *dev)
 static void gfar_halt_nodisable(struct net_device *dev)
 {
 {
@@ -657,7 +654,6 @@ static void gfar_halt_nodisable(struct net_device *dev)
 			cpu_relax();
 			cpu_relax();
 	}
 	}
 }
 }
-#endif
 
 
 /* Halt the receive and transmit queues */
 /* Halt the receive and transmit queues */
 void gfar_halt(struct net_device *dev)
 void gfar_halt(struct net_device *dev)
@@ -666,6 +662,8 @@ void gfar_halt(struct net_device *dev)
 	struct gfar __iomem *regs = priv->regs;
 	struct gfar __iomem *regs = priv->regs;
 	u32 tempval;
 	u32 tempval;
 
 
+	gfar_halt_nodisable(dev);
+
 	/* Disable Rx and Tx */
 	/* Disable Rx and Tx */
 	tempval = gfar_read(&regs->maccfg1);
 	tempval = gfar_read(&regs->maccfg1);
 	tempval &= ~(MACCFG1_RX_EN | MACCFG1_TX_EN);
 	tempval &= ~(MACCFG1_RX_EN | MACCFG1_TX_EN);

+ 0 - 1
drivers/net/gianfar_sysfs.c

@@ -33,7 +33,6 @@
 
 
 #include <asm/uaccess.h>
 #include <asm/uaccess.h>
 #include <linux/module.h>
 #include <linux/module.h>
-#include <linux/version.h>
 
 
 #include "gianfar.h"
 #include "gianfar.h"
 
 

+ 0 - 2
drivers/net/ipg.h

@@ -7,7 +7,6 @@
 #ifndef __LINUX_IPG_H
 #ifndef __LINUX_IPG_H
 #define __LINUX_IPG_H
 #define __LINUX_IPG_H
 
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/module.h>
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
@@ -21,7 +20,6 @@
 #include <linux/etherdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/skbuff.h>
 #include <linux/skbuff.h>
-#include <linux/version.h>
 #include <asm/bitops.h>
 #include <asm/bitops.h>
 
 
 /*
 /*

+ 1 - 0
drivers/net/ixgbe/ixgbe_82598.c

@@ -190,6 +190,7 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
 	case IXGBE_DEV_ID_82598AF_DUAL_PORT:
 	case IXGBE_DEV_ID_82598AF_DUAL_PORT:
 	case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
 	case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
 	case IXGBE_DEV_ID_82598EB_CX4:
 	case IXGBE_DEV_ID_82598EB_CX4:
+	case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
 		media_type = ixgbe_media_type_fiber;
 		media_type = ixgbe_media_type_fiber;
 		break;
 		break;
 	case IXGBE_DEV_ID_82598AT_DUAL_PORT:
 	case IXGBE_DEV_ID_82598AT_DUAL_PORT:

+ 3 - 1
drivers/net/ixgbe/ixgbe_main.c

@@ -48,7 +48,7 @@ char ixgbe_driver_name[] = "ixgbe";
 static const char ixgbe_driver_string[] =
 static const char ixgbe_driver_string[] =
 	"Intel(R) 10 Gigabit PCI Express Network Driver";
 	"Intel(R) 10 Gigabit PCI Express Network Driver";
 
 
-#define DRV_VERSION "1.3.18-k2"
+#define DRV_VERSION "1.3.18-k4"
 const char ixgbe_driver_version[] = DRV_VERSION;
 const char ixgbe_driver_version[] = DRV_VERSION;
 static const char ixgbe_copyright[] =
 static const char ixgbe_copyright[] =
 	 "Copyright (c) 1999-2007 Intel Corporation.";
 	 "Copyright (c) 1999-2007 Intel Corporation.";
@@ -72,6 +72,8 @@ static struct pci_device_id ixgbe_pci_tbl[] = {
 	 board_82598 },
 	 board_82598 },
 	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_CX4),
 	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_CX4),
 	 board_82598 },
 	 board_82598 },
+	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_CX4_DUAL_PORT),
+	 board_82598 },
 
 
 	/* required last entry */
 	/* required last entry */
 	{0, }
 	{0, }

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

@@ -39,6 +39,7 @@
 #define IXGBE_DEV_ID_82598AF_SINGLE_PORT 0x10C7
 #define IXGBE_DEV_ID_82598AF_SINGLE_PORT 0x10C7
 #define IXGBE_DEV_ID_82598AT_DUAL_PORT   0x10C8
 #define IXGBE_DEV_ID_82598AT_DUAL_PORT   0x10C8
 #define IXGBE_DEV_ID_82598EB_CX4         0x10DD
 #define IXGBE_DEV_ID_82598EB_CX4         0x10DD
+#define IXGBE_DEV_ID_82598_CX4_DUAL_PORT 0x10EC
 
 
 /* General Registers */
 /* General Registers */
 #define IXGBE_CTRL      0x00000
 #define IXGBE_CTRL      0x00000

+ 0 - 67
drivers/net/loopback.c

@@ -64,68 +64,6 @@ struct pcpu_lstats {
 	unsigned long bytes;
 	unsigned long bytes;
 };
 };
 
 
-/* KISS: just allocate small chunks and copy bits.
- *
- * So, in fact, this is documentation, explaining what we expect
- * of largesending device modulo TCP checksum, which is ignored for loopback.
- */
-
-#ifdef LOOPBACK_TSO
-static void emulate_large_send_offload(struct sk_buff *skb)
-{
-	struct iphdr *iph = ip_hdr(skb);
-	struct tcphdr *th = (struct tcphdr *)(skb_network_header(skb) +
-					      (iph->ihl * 4));
-	unsigned int doffset = (iph->ihl + th->doff) * 4;
-	unsigned int mtu = skb_shinfo(skb)->gso_size + doffset;
-	unsigned int offset = 0;
-	u32 seq = ntohl(th->seq);
-	u16 id  = ntohs(iph->id);
-
-	while (offset + doffset < skb->len) {
-		unsigned int frag_size = min(mtu, skb->len - offset) - doffset;
-		struct sk_buff *nskb = alloc_skb(mtu + 32, GFP_ATOMIC);
-
-		if (!nskb)
-			break;
-		skb_reserve(nskb, 32);
-		skb_set_mac_header(nskb, -ETH_HLEN);
-		skb_reset_network_header(nskb);
-		iph = ip_hdr(nskb);
-		skb_copy_to_linear_data(nskb, skb_network_header(skb),
-					doffset);
-		if (skb_copy_bits(skb,
-				  doffset + offset,
-				  nskb->data + doffset,
-				  frag_size))
-			BUG();
-		skb_put(nskb, doffset + frag_size);
-		nskb->ip_summed = CHECKSUM_UNNECESSARY;
-		nskb->dev = skb->dev;
-		nskb->priority = skb->priority;
-		nskb->protocol = skb->protocol;
-		nskb->dst = dst_clone(skb->dst);
-		memcpy(nskb->cb, skb->cb, sizeof(skb->cb));
-		nskb->pkt_type = skb->pkt_type;
-
-		th = (struct tcphdr *)(skb_network_header(nskb) + iph->ihl * 4);
-		iph->tot_len = htons(frag_size + doffset);
-		iph->id = htons(id);
-		iph->check = 0;
-		iph->check = ip_fast_csum((unsigned char *) iph, iph->ihl);
-		th->seq = htonl(seq);
-		if (offset + doffset + frag_size < skb->len)
-			th->fin = th->psh = 0;
-		netif_rx(nskb);
-		offset += frag_size;
-		seq += frag_size;
-		id++;
-	}
-
-	dev_kfree_skb(skb);
-}
-#endif /* LOOPBACK_TSO */
-
 /*
 /*
  * The higher levels take care of making this non-reentrant (it's
  * The higher levels take care of making this non-reentrant (it's
  * called with bh's disabled).
  * called with bh's disabled).
@@ -137,9 +75,6 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
 	skb_orphan(skb);
 	skb_orphan(skb);
 
 
 	skb->protocol = eth_type_trans(skb,dev);
 	skb->protocol = eth_type_trans(skb,dev);
-#ifndef LOOPBACK_MUST_CHECKSUM
-	skb->ip_summed = CHECKSUM_UNNECESSARY;
-#endif
 
 
 #ifdef LOOPBACK_TSO
 #ifdef LOOPBACK_TSO
 	if (skb_is_gso(skb)) {
 	if (skb_is_gso(skb)) {
@@ -234,9 +169,7 @@ static void loopback_setup(struct net_device *dev)
 	dev->type		= ARPHRD_LOOPBACK;	/* 0x0001*/
 	dev->type		= ARPHRD_LOOPBACK;	/* 0x0001*/
 	dev->flags		= IFF_LOOPBACK;
 	dev->flags		= IFF_LOOPBACK;
 	dev->features 		= NETIF_F_SG | NETIF_F_FRAGLIST
 	dev->features 		= NETIF_F_SG | NETIF_F_FRAGLIST
-#ifdef LOOPBACK_TSO
 		| NETIF_F_TSO
 		| NETIF_F_TSO
-#endif
 		| NETIF_F_NO_CSUM
 		| NETIF_F_NO_CSUM
 		| NETIF_F_HIGHDMA
 		| NETIF_F_HIGHDMA
 		| NETIF_F_LLTX
 		| NETIF_F_LLTX

+ 5 - 1
drivers/net/myri10ge/myri10ge.c

@@ -3548,7 +3548,11 @@ static void myri10ge_probe_slices(struct myri10ge_priv *mgp)
 
 
 	/* try to load the slice aware rss firmware */
 	/* try to load the slice aware rss firmware */
 	old_fw = mgp->fw_name;
 	old_fw = mgp->fw_name;
-	if (old_fw == myri10ge_fw_aligned)
+	if (myri10ge_fw_name != NULL) {
+		dev_info(&mgp->pdev->dev, "overriding rss firmware to %s\n",
+			 myri10ge_fw_name);
+		mgp->fw_name = myri10ge_fw_name;
+	} else if (old_fw == myri10ge_fw_aligned)
 		mgp->fw_name = myri10ge_fw_rss_aligned;
 		mgp->fw_name = myri10ge_fw_rss_aligned;
 	else
 	else
 		mgp->fw_name = myri10ge_fw_rss_unaligned;
 		mgp->fw_name = myri10ge_fw_rss_unaligned;

+ 2 - 2
drivers/net/ne.c

@@ -118,7 +118,7 @@ bad_clone_list[] __initdata = {
     {"E-LAN100", "E-LAN200", {0x00, 0x00, 0x5d}}, /* Broken ne1000 clones */
     {"E-LAN100", "E-LAN200", {0x00, 0x00, 0x5d}}, /* Broken ne1000 clones */
     {"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */
     {"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */
     {"REALTEK", "RTL8019", {0x00, 0x00, 0xe8}}, /* no-name with Realtek chip */
     {"REALTEK", "RTL8019", {0x00, 0x00, 0xe8}}, /* no-name with Realtek chip */
-#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
+#ifdef CONFIG_MACH_TX49XX
     {"RBHMA4X00-RTL8019", "RBHMA4X00/RTL8019", {0x00, 0x60, 0x0a}},  /* Toshiba built-in */
     {"RBHMA4X00-RTL8019", "RBHMA4X00/RTL8019", {0x00, 0x60, 0x0a}},  /* Toshiba built-in */
 #endif
 #endif
     {"LCS-8834", "LCS-8836", {0x04, 0x04, 0x37}}, /* ShinyNet (SET) */
     {"LCS-8834", "LCS-8836", {0x04, 0x04, 0x37}}, /* ShinyNet (SET) */
@@ -142,7 +142,7 @@ bad_clone_list[] __initdata = {
 #if defined(CONFIG_PLAT_MAPPI)
 #if defined(CONFIG_PLAT_MAPPI)
 #  define DCR_VAL 0x4b
 #  define DCR_VAL 0x4b
 #elif defined(CONFIG_PLAT_OAKS32R)  || \
 #elif defined(CONFIG_PLAT_OAKS32R)  || \
-   defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
+   defined(CONFIG_MACH_TX49XX)
 #  define DCR_VAL 0x48		/* 8-bit mode */
 #  define DCR_VAL 0x48		/* 8-bit mode */
 #else
 #else
 #  define DCR_VAL 0x49
 #  define DCR_VAL 0x49

+ 4 - 3
drivers/net/netxen/netxen_nic.h

@@ -66,8 +66,8 @@
 
 
 #define _NETXEN_NIC_LINUX_MAJOR 4
 #define _NETXEN_NIC_LINUX_MAJOR 4
 #define _NETXEN_NIC_LINUX_MINOR 0
 #define _NETXEN_NIC_LINUX_MINOR 0
-#define _NETXEN_NIC_LINUX_SUBVERSION 0
-#define NETXEN_NIC_LINUX_VERSIONID  "4.0.0"
+#define _NETXEN_NIC_LINUX_SUBVERSION 11
+#define NETXEN_NIC_LINUX_VERSIONID  "4.0.11"
 
 
 #define NETXEN_VERSION_CODE(a, b, c)	(((a) << 16) + ((b) << 8) + (c))
 #define NETXEN_VERSION_CODE(a, b, c)	(((a) << 16) + ((b) << 8) + (c))
 
 
@@ -1615,7 +1615,8 @@ dma_watchdog_wakeup(struct netxen_adapter *adapter)
 
 
 
 
 int netxen_is_flash_supported(struct netxen_adapter *adapter);
 int netxen_is_flash_supported(struct netxen_adapter *adapter);
-int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 mac[]);
+int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac);
+int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac);
 extern void netxen_change_ringparam(struct netxen_adapter *adapter);
 extern void netxen_change_ringparam(struct netxen_adapter *adapter);
 extern int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr,
 extern int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr,
 				int *valp);
 				int *valp);

+ 42 - 17
drivers/net/netxen/netxen_nic_hw.c

@@ -733,31 +733,56 @@ static int netxen_get_flash_block(struct netxen_adapter *adapter, int base,
 	return 0;
 	return 0;
 }
 }
 
 
-int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 mac[])
+int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac)
 {
 {
-	__le32 *pmac = (__le32 *) & mac[0];
+	__le32 *pmac = (__le32 *) mac;
+	u32 offset;
 
 
-	if (netxen_get_flash_block(adapter,
-				   NETXEN_USER_START +
-				   offsetof(struct netxen_new_user_info,
-					    mac_addr),
-				   FLASH_NUM_PORTS * sizeof(u64), pmac) == -1) {
+	offset = NETXEN_USER_START +
+		offsetof(struct netxen_new_user_info, mac_addr) +
+		adapter->portnum * sizeof(u64);
+
+	if (netxen_get_flash_block(adapter, offset, sizeof(u64), pmac) == -1)
 		return -1;
 		return -1;
-	}
+
 	if (*mac == cpu_to_le64(~0ULL)) {
 	if (*mac == cpu_to_le64(~0ULL)) {
+
+		offset = NETXEN_USER_START_OLD +
+			offsetof(struct netxen_user_old_info, mac_addr) +
+			adapter->portnum * sizeof(u64);
+
 		if (netxen_get_flash_block(adapter,
 		if (netxen_get_flash_block(adapter,
-					   NETXEN_USER_START_OLD +
-					   offsetof(struct netxen_user_old_info,
-						    mac_addr),
-					   FLASH_NUM_PORTS * sizeof(u64),
-					   pmac) == -1)
+					offset, sizeof(u64), pmac) == -1)
 			return -1;
 			return -1;
+
 		if (*mac == cpu_to_le64(~0ULL))
 		if (*mac == cpu_to_le64(~0ULL))
 			return -1;
 			return -1;
 	}
 	}
 	return 0;
 	return 0;
 }
 }
 
 
+int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac)
+{
+	uint32_t crbaddr, mac_hi, mac_lo;
+	int pci_func = adapter->ahw.pci_func;
+
+	crbaddr = CRB_MAC_BLOCK_START +
+		(4 * ((pci_func/2) * 3)) + (4 * (pci_func & 1));
+
+	adapter->hw_read_wx(adapter, crbaddr, &mac_lo, 4);
+	adapter->hw_read_wx(adapter, crbaddr+4, &mac_hi, 4);
+
+	mac_hi = cpu_to_le32(mac_hi);
+	mac_lo = cpu_to_le32(mac_lo);
+
+	if (pci_func & 1)
+		*mac = ((mac_lo >> 16) | ((u64)mac_hi << 16));
+	else
+		*mac = ((mac_lo) | ((u64)mac_hi << 32));
+
+	return 0;
+}
+
 #define CRB_WIN_LOCK_TIMEOUT 100000000
 #define CRB_WIN_LOCK_TIMEOUT 100000000
 
 
 static int crb_win_lock(struct netxen_adapter *adapter)
 static int crb_win_lock(struct netxen_adapter *adapter)
@@ -2183,10 +2208,10 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter)
 	if (adapter->portnum == 0) {
 	if (adapter->portnum == 0) {
 		get_brd_name_by_type(board_info->board_type, brd_name);
 		get_brd_name_by_type(board_info->board_type, brd_name);
 
 
-		printk("NetXen %s Board S/N %s  Chip id 0x%x\n",
-				brd_name, serial_num, board_info->chip_id);
-		printk("NetXen Firmware version %d.%d.%d\n", fw_major,
-				fw_minor, fw_build);
+		printk(KERN_INFO "NetXen %s Board S/N %s  Chip rev 0x%x\n",
+				brd_name, serial_num, adapter->ahw.revision_id);
+		printk(KERN_INFO "NetXen Firmware version %d.%d.%d\n",
+				fw_major, fw_minor, fw_build);
 	}
 	}
 
 
 	if (NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build) <
 	if (NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build) <

+ 15 - 13
drivers/net/netxen/netxen_nic_init.c

@@ -1079,10 +1079,12 @@ int netxen_initialize_adapter_offload(struct netxen_adapter *adapter)
 
 
 void netxen_free_adapter_offload(struct netxen_adapter *adapter)
 void netxen_free_adapter_offload(struct netxen_adapter *adapter)
 {
 {
-	int i;
+	int i = 100;
+
+	if (!adapter->dummy_dma.addr)
+		return;
 
 
-	if (adapter->dummy_dma.addr) {
-		i = 100;
+	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
 		do {
 		do {
 			if (dma_watchdog_shutdown_request(adapter) == 1)
 			if (dma_watchdog_shutdown_request(adapter) == 1)
 				break;
 				break;
@@ -1090,17 +1092,17 @@ void netxen_free_adapter_offload(struct netxen_adapter *adapter)
 			if (dma_watchdog_shutdown_poll_result(adapter) == 1)
 			if (dma_watchdog_shutdown_poll_result(adapter) == 1)
 				break;
 				break;
 		} while (--i);
 		} while (--i);
+	}
 
 
-		if (i) {
-			pci_free_consistent(adapter->pdev,
-				    NETXEN_HOST_DUMMY_DMA_SIZE,
-				    adapter->dummy_dma.addr,
-				    adapter->dummy_dma.phys_addr);
-			adapter->dummy_dma.addr = NULL;
-		} else {
-			printk(KERN_ERR "%s: dma_watchdog_shutdown failed\n",
-					adapter->netdev->name);
-		}
+	if (i) {
+		pci_free_consistent(adapter->pdev,
+			    NETXEN_HOST_DUMMY_DMA_SIZE,
+			    adapter->dummy_dma.addr,
+			    adapter->dummy_dma.phys_addr);
+		adapter->dummy_dma.addr = NULL;
+	} else {
+		printk(KERN_ERR "%s: dma_watchdog_shutdown failed\n",
+				adapter->netdev->name);
 	}
 	}
 }
 }
 
 

+ 96 - 114
drivers/net/netxen/netxen_nic_main.c

@@ -149,76 +149,18 @@ static uint32_t msi_tgt_status[8] = {
 
 
 static struct netxen_legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG;
 static struct netxen_legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG;
 
 
-static void netxen_nic_disable_int(struct netxen_adapter *adapter)
+static inline void netxen_nic_disable_int(struct netxen_adapter *adapter)
 {
 {
-	u32 mask = 0x7ff;
-	int retries = 32;
-	int pci_fn = adapter->ahw.pci_func;
-
-	if (adapter->msi_mode != MSI_MODE_MULTIFUNC)
-		adapter->pci_write_normalize(adapter,
-				adapter->crb_intr_mask, 0);
-
-	if (adapter->intr_scheme != -1 &&
-	    adapter->intr_scheme != INTR_SCHEME_PERPORT)
-		adapter->pci_write_immediate(adapter, ISR_INT_MASK, mask);
-
-	if (!NETXEN_IS_MSI_FAMILY(adapter)) {
-		do {
-			adapter->pci_write_immediate(adapter,
-					adapter->legacy_intr.tgt_status_reg,
-					0xffffffff);
-			mask = adapter->pci_read_immediate(adapter,
-					ISR_INT_VECTOR);
-			if (!(mask & 0x80))
-				break;
-			udelay(10);
-		} while (--retries);
-
-		if (!retries) {
-			printk(KERN_NOTICE "%s: Failed to disable interrupt\n",
-					netxen_nic_driver_name);
-		}
-	} else {
-		if (adapter->msi_mode == MSI_MODE_MULTIFUNC) {
-			adapter->pci_write_immediate(adapter,
-					msi_tgt_status[pci_fn], 0xffffffff);
-		}
-	}
+	adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0);
 }
 }
 
 
-static void netxen_nic_enable_int(struct netxen_adapter *adapter)
+static inline void netxen_nic_enable_int(struct netxen_adapter *adapter)
 {
 {
-	u32 mask;
-
-	if (adapter->intr_scheme != -1 &&
-		adapter->intr_scheme != INTR_SCHEME_PERPORT) {
-		switch (adapter->ahw.board_type) {
-		case NETXEN_NIC_GBE:
-			mask  =  0x77b;
-			break;
-		case NETXEN_NIC_XGBE:
-			mask  =  0x77f;
-			break;
-		default:
-			mask  =  0x7ff;
-			break;
-		}
-
-		adapter->pci_write_immediate(adapter, ISR_INT_MASK, mask);
-	}
-
 	adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0x1);
 	adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0x1);
 
 
-	if (!NETXEN_IS_MSI_FAMILY(adapter)) {
-		mask = 0xbff;
-		if (adapter->intr_scheme == INTR_SCHEME_PERPORT)
-			adapter->pci_write_immediate(adapter,
-				adapter->legacy_intr.tgt_mask_reg, mask);
-		else
-			adapter->pci_write_normalize(adapter,
-					CRB_INT_VECTOR, 0);
-	}
+	if (!NETXEN_IS_MSI_FAMILY(adapter))
+		adapter->pci_write_immediate(adapter,
+				adapter->legacy_intr.tgt_mask_reg, 0xfbff);
 }
 }
 
 
 static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id)
 static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id)
@@ -501,6 +443,44 @@ static void netxen_init_msix_entries(struct netxen_adapter *adapter)
 		adapter->msix_entries[i].entry = i;
 		adapter->msix_entries[i].entry = i;
 }
 }
 
 
+static int
+netxen_read_mac_addr(struct netxen_adapter *adapter)
+{
+	int i;
+	unsigned char *p;
+	__le64 mac_addr;
+	DECLARE_MAC_BUF(mac);
+	struct net_device *netdev = adapter->netdev;
+	struct pci_dev *pdev = adapter->pdev;
+
+	if (netxen_is_flash_supported(adapter) != 0)
+		return -EIO;
+
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+		if (netxen_p3_get_mac_addr(adapter, &mac_addr) != 0)
+			return -EIO;
+	} else {
+		if (netxen_get_flash_mac_addr(adapter, &mac_addr) != 0)
+			return -EIO;
+	}
+
+	p = (unsigned char *)&mac_addr;
+	for (i = 0; i < 6; i++)
+		netdev->dev_addr[i] = *(p + 5 - i);
+
+	memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);
+
+	/* set station address */
+
+	if (!is_valid_ether_addr(netdev->perm_addr)) {
+		dev_warn(&pdev->dev, "Bad MAC address %s.\n",
+				print_mac(mac, netdev->dev_addr));
+	} else
+		adapter->macaddr_set(adapter, netdev->dev_addr);
+
+	return 0;
+}
+
 /*
 /*
  * netxen_nic_probe()
  * netxen_nic_probe()
  *
  *
@@ -529,10 +509,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	unsigned long mem_base, mem_len, db_base, db_len, pci_len0 = 0;
 	unsigned long mem_base, mem_len, db_base, db_len, pci_len0 = 0;
 	int i = 0, err;
 	int i = 0, err;
 	int first_driver, first_boot;
 	int first_driver, first_boot;
-	__le64 mac_addr[FLASH_NUM_PORTS + 1];
 	u32 val;
 	u32 val;
 	int pci_func_id = PCI_FUNC(pdev->devfn);
 	int pci_func_id = PCI_FUNC(pdev->devfn);
-	DECLARE_MAC_BUF(mac);
 	struct netxen_legacy_intr_set *legacy_intrp;
 	struct netxen_legacy_intr_set *legacy_intrp;
 	uint8_t revision_id;
 	uint8_t revision_id;
 
 
@@ -545,6 +523,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		return -ENODEV;
 		return -ENODEV;
 	}
 	}
 
 
+	if (pdev->revision >= NX_P3_A0 && pdev->revision < NX_P3_B1) {
+		printk(KERN_WARNING "NetXen chip revisions between 0x%x-0x%x"
+				"will not be enabled.\n",
+				NX_P3_A0, NX_P3_B1);
+		return -ENODEV;
+	}
+
 	if ((err = pci_enable_device(pdev)))
 	if ((err = pci_enable_device(pdev)))
 		return err;
 		return err;
 
 
@@ -898,34 +883,14 @@ request_msi:
 		goto err_out_disable_msi;
 		goto err_out_disable_msi;
 
 
 	init_timer(&adapter->watchdog_timer);
 	init_timer(&adapter->watchdog_timer);
-	adapter->ahw.linkup = 0;
 	adapter->watchdog_timer.function = &netxen_watchdog;
 	adapter->watchdog_timer.function = &netxen_watchdog;
 	adapter->watchdog_timer.data = (unsigned long)adapter;
 	adapter->watchdog_timer.data = (unsigned long)adapter;
 	INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task);
 	INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task);
 	INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task);
 	INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task);
 
 
-	if (netxen_is_flash_supported(adapter) == 0 &&
-			netxen_get_flash_mac_addr(adapter, mac_addr) == 0) {
-		unsigned char *p;
-
-		p = (unsigned char *)&mac_addr[adapter->portnum];
-		netdev->dev_addr[0] = *(p + 5);
-		netdev->dev_addr[1] = *(p + 4);
-		netdev->dev_addr[2] = *(p + 3);
-		netdev->dev_addr[3] = *(p + 2);
-		netdev->dev_addr[4] = *(p + 1);
-		netdev->dev_addr[5] = *(p + 0);
-
-		memcpy(netdev->perm_addr, netdev->dev_addr,
-			netdev->addr_len);
-		if (!is_valid_ether_addr(netdev->perm_addr)) {
-			printk(KERN_ERR "%s: Bad MAC address %s.\n",
-					netxen_nic_driver_name,
-					print_mac(mac, netdev->dev_addr));
-		} else {
-			adapter->macaddr_set(adapter, netdev->dev_addr);
-		}
-	}
+	err = netxen_read_mac_addr(adapter);
+	if (err)
+		dev_warn(&pdev->dev, "failed to read mac addr\n");
 
 
 	netif_carrier_off(netdev);
 	netif_carrier_off(netdev);
 	netif_stop_queue(netdev);
 	netif_stop_queue(netdev);
@@ -1000,6 +965,7 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
 
 
 	if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
 	if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
 		netxen_free_hw_resources(adapter);
 		netxen_free_hw_resources(adapter);
+		netxen_release_rx_buffers(adapter);
 		netxen_free_sw_resources(adapter);
 		netxen_free_sw_resources(adapter);
 	}
 	}
 
 
@@ -1069,6 +1035,15 @@ static int netxen_nic_open(struct net_device *netdev)
 			goto err_out_free_sw;
 			goto err_out_free_sw;
 		}
 		}
 
 
+		if ((adapter->msi_mode != MSI_MODE_MULTIFUNC) ||
+			(adapter->intr_scheme != INTR_SCHEME_PERPORT)) {
+			printk(KERN_ERR "%s: Firmware interrupt scheme is "
+					"incompatible with driver\n",
+					netdev->name);
+			adapter->driver_mismatch = 1;
+			goto err_out_free_hw;
+		}
+
 		if (adapter->fw_major < 4) {
 		if (adapter->fw_major < 4) {
 			adapter->crb_addr_cmd_producer =
 			adapter->crb_addr_cmd_producer =
 				crb_cmd_producer[adapter->portnum];
 				crb_cmd_producer[adapter->portnum];
@@ -1094,7 +1069,7 @@ static int netxen_nic_open(struct net_device *netdev)
 				  flags, netdev->name, adapter);
 				  flags, netdev->name, adapter);
 		if (err) {
 		if (err) {
 			printk(KERN_ERR "request_irq failed with: %d\n", err);
 			printk(KERN_ERR "request_irq failed with: %d\n", err);
-			goto err_out_free_hw;
+			goto err_out_free_rxbuf;
 		}
 		}
 
 
 		adapter->is_up = NETXEN_ADAPTER_UP_MAGIC;
 		adapter->is_up = NETXEN_ADAPTER_UP_MAGIC;
@@ -1116,6 +1091,7 @@ static int netxen_nic_open(struct net_device *netdev)
 	if (adapter->set_mtu)
 	if (adapter->set_mtu)
 		adapter->set_mtu(adapter, netdev->mtu);
 		adapter->set_mtu(adapter, netdev->mtu);
 
 
+	adapter->ahw.linkup = 0;
 	mod_timer(&adapter->watchdog_timer, jiffies);
 	mod_timer(&adapter->watchdog_timer, jiffies);
 
 
 	napi_enable(&adapter->napi);
 	napi_enable(&adapter->napi);
@@ -1127,6 +1103,8 @@ static int netxen_nic_open(struct net_device *netdev)
 
 
 err_out_free_irq:
 err_out_free_irq:
 	free_irq(adapter->irq, adapter);
 	free_irq(adapter->irq, adapter);
+err_out_free_rxbuf:
+	netxen_release_rx_buffers(adapter);
 err_out_free_hw:
 err_out_free_hw:
 	netxen_free_hw_resources(adapter);
 	netxen_free_hw_resources(adapter);
 err_out_free_sw:
 err_out_free_sw:
@@ -1152,10 +1130,8 @@ static int netxen_nic_close(struct net_device *netdev)
 
 
 	netxen_release_tx_buffers(adapter);
 	netxen_release_tx_buffers(adapter);
 
 
-	if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
-		FLUSH_SCHEDULED_WORK();
-		del_timer_sync(&adapter->watchdog_timer);
-	}
+	FLUSH_SCHEDULED_WORK();
+	del_timer_sync(&adapter->watchdog_timer);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -1458,7 +1434,8 @@ void netxen_watchdog_task(struct work_struct *work)
 
 
 	netxen_nic_handle_phy_intr(adapter);
 	netxen_nic_handle_phy_intr(adapter);
 
 
-	mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
+	if (netif_running(adapter->netdev))
+		mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
 }
 }
 
 
 static void netxen_tx_timeout(struct net_device *netdev)
 static void netxen_tx_timeout(struct net_device *netdev)
@@ -1518,18 +1495,9 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
 	return stats;
 	return stats;
 }
 }
 
 
-static inline void
-netxen_handle_int(struct netxen_adapter *adapter)
-{
-	netxen_nic_disable_int(adapter);
-	napi_schedule(&adapter->napi);
-}
-
 static irqreturn_t netxen_intr(int irq, void *data)
 static irqreturn_t netxen_intr(int irq, void *data)
 {
 {
 	struct netxen_adapter *adapter = data;
 	struct netxen_adapter *adapter = data;
-	u32 our_int = 0;
-
 	u32 status = 0;
 	u32 status = 0;
 
 
 	status = adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
 	status = adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
@@ -1544,22 +1512,32 @@ static irqreturn_t netxen_intr(int irq, void *data)
 		if (!ISR_LEGACY_INT_TRIGGERED(status))
 		if (!ISR_LEGACY_INT_TRIGGERED(status))
 			return IRQ_NONE;
 			return IRQ_NONE;
 
 
-	} else if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+	} else {
+		unsigned long our_int = 0;
 
 
 		our_int = adapter->pci_read_normalize(adapter, CRB_INT_VECTOR);
 		our_int = adapter->pci_read_normalize(adapter, CRB_INT_VECTOR);
+
 		/* not our interrupt */
 		/* not our interrupt */
-		if ((our_int & (0x80 << adapter->portnum)) == 0)
+		if (!test_and_clear_bit((7 + adapter->portnum), &our_int))
 			return IRQ_NONE;
 			return IRQ_NONE;
 
 
-		if (adapter->intr_scheme == INTR_SCHEME_PERPORT) {
-			/* claim interrupt */
-			adapter->pci_write_normalize(adapter,
-				CRB_INT_VECTOR,
-				our_int & ~((u32)(0x80 << adapter->portnum)));
-		}
+		/* claim interrupt */
+		adapter->pci_write_normalize(adapter,
+				CRB_INT_VECTOR, (our_int & 0xffffffff));
 	}
 	}
 
 
-	netxen_handle_int(adapter);
+	/* clear interrupt */
+	if (adapter->fw_major < 4)
+		netxen_nic_disable_int(adapter);
+
+	adapter->pci_write_immediate(adapter,
+			adapter->legacy_intr.tgt_status_reg,
+			0xffffffff);
+	/* read twice to ensure write is flushed */
+	adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
+	adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
+
+	napi_schedule(&adapter->napi);
 
 
 	return IRQ_HANDLED;
 	return IRQ_HANDLED;
 }
 }
@@ -1568,7 +1546,11 @@ static irqreturn_t netxen_msi_intr(int irq, void *data)
 {
 {
 	struct netxen_adapter *adapter = data;
 	struct netxen_adapter *adapter = data;
 
 
-	netxen_handle_int(adapter);
+	/* clear interrupt */
+	adapter->pci_write_immediate(adapter,
+			msi_tgt_status[adapter->ahw.pci_func], 0xffffffff);
+
+	napi_schedule(&adapter->napi);
 	return IRQ_HANDLED;
 	return IRQ_HANDLED;
 }
 }
 
 

+ 2 - 0
drivers/net/netxen/netxen_nic_phan_reg.h

@@ -125,6 +125,8 @@
 #define CRB_SW_INT_MASK_2	   NETXEN_NIC_REG(0x1e4)
 #define CRB_SW_INT_MASK_2	   NETXEN_NIC_REG(0x1e4)
 #define CRB_SW_INT_MASK_3	   NETXEN_NIC_REG(0x1e8)
 #define CRB_SW_INT_MASK_3	   NETXEN_NIC_REG(0x1e8)
 
 
+#define CRB_MAC_BLOCK_START        NETXEN_CAM_RAM(0x1c0)
+
 /*
 /*
  * capabilities register, can be used to selectively enable/disable features
  * capabilities register, can be used to selectively enable/disable features
  * for backward compability
  * for backward compability

+ 0 - 1
drivers/net/ppp_mppe.c

@@ -46,7 +46,6 @@
 #include <linux/err.h>
 #include <linux/err.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <linux/slab.h>

+ 0 - 1
drivers/net/pppol2tp.c

@@ -61,7 +61,6 @@
  */
  */
 
 
 #include <linux/module.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/string.h>
 #include <linux/string.h>
 #include <linux/list.h>
 #include <linux/list.h>
 #include <asm/uaccess.h>
 #include <asm/uaccess.h>

+ 0 - 1
drivers/net/r6040.c

@@ -24,7 +24,6 @@
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/moduleparam.h>
 #include <linux/moduleparam.h>
 #include <linux/string.h>
 #include <linux/string.h>
 #include <linux/timer.h>
 #include <linux/timer.h>

+ 0 - 1
drivers/net/sh_eth.c

@@ -20,7 +20,6 @@
  *  the file called "COPYING".
  *  the file called "COPYING".
  */
  */
 
 
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
 #include <linux/dma-mapping.h>
 #include <linux/etherdevice.h>
 #include <linux/etherdevice.h>

+ 6 - 2
drivers/net/sky2.c

@@ -24,7 +24,6 @@
 
 
 #include <linux/crc32.h>
 #include <linux/crc32.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/netdevice.h>
 #include <linux/dma-mapping.h>
 #include <linux/dma-mapping.h>
@@ -666,11 +665,16 @@ static void sky2_phy_power_down(struct sky2_hw *hw, unsigned port)
 
 
 	if (hw->chip_id != CHIP_ID_YUKON_EC) {
 	if (hw->chip_id != CHIP_ID_YUKON_EC) {
 		if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
 		if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
-			ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
+			/* select page 2 to access MAC control register */
+			gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 2);
 
 
+			ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
 			/* enable Power Down */
 			/* enable Power Down */
 			ctrl |= PHY_M_PC_POW_D_ENA;
 			ctrl |= PHY_M_PC_POW_D_ENA;
 			gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
 			gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
+
+			/* set page register back to 0 */
+			gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0);
 		}
 		}
 
 
 		/* set IEEE compatible Power Down Mode (dev. #4.99) */
 		/* set IEEE compatible Power Down Mode (dev. #4.99) */

+ 0 - 1
drivers/net/tehuti.h

@@ -27,7 +27,6 @@
 #include <linux/sched.h>
 #include <linux/sched.h>
 #include <linux/tty.h>
 #include <linux/tty.h>
 #include <linux/if_vlan.h>
 #include <linux/if_vlan.h>
-#include <linux/version.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/vmalloc.h>
 #include <linux/vmalloc.h>
 #include <asm/byteorder.h>
 #include <asm/byteorder.h>

+ 78 - 23
drivers/net/tg3.c

@@ -66,8 +66,8 @@
 
 
 #define DRV_MODULE_NAME		"tg3"
 #define DRV_MODULE_NAME		"tg3"
 #define PFX DRV_MODULE_NAME	": "
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"3.93"
-#define DRV_MODULE_RELDATE	"May 22, 2008"
+#define DRV_MODULE_VERSION	"3.94"
+#define DRV_MODULE_RELDATE	"August 14, 2008"
 
 
 #define TG3_DEF_MAC_MODE	0
 #define TG3_DEF_MAC_MODE	0
 #define TG3_DEF_RX_MODE		0
 #define TG3_DEF_RX_MODE		0
@@ -536,6 +536,7 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum)
 		return 0;
 		return 0;
 
 
 	switch (locknum) {
 	switch (locknum) {
+		case TG3_APE_LOCK_GRC:
 		case TG3_APE_LOCK_MEM:
 		case TG3_APE_LOCK_MEM:
 			break;
 			break;
 		default:
 		default:
@@ -573,6 +574,7 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum)
 		return;
 		return;
 
 
 	switch (locknum) {
 	switch (locknum) {
+		case TG3_APE_LOCK_GRC:
 		case TG3_APE_LOCK_MEM:
 		case TG3_APE_LOCK_MEM:
 			break;
 			break;
 		default:
 		default:
@@ -1017,16 +1019,44 @@ static void tg3_mdio_fini(struct tg3 *tp)
 	}
 	}
 }
 }
 
 
+/* tp->lock is held. */
+static inline void tg3_generate_fw_event(struct tg3 *tp)
+{
+	u32 val;
+
+	val = tr32(GRC_RX_CPU_EVENT);
+	val |= GRC_RX_CPU_DRIVER_EVENT;
+	tw32_f(GRC_RX_CPU_EVENT, val);
+
+	tp->last_event_jiffies = jiffies;
+}
+
+#define TG3_FW_EVENT_TIMEOUT_USEC 2500
+
 /* tp->lock is held. */
 /* tp->lock is held. */
 static void tg3_wait_for_event_ack(struct tg3 *tp)
 static void tg3_wait_for_event_ack(struct tg3 *tp)
 {
 {
 	int i;
 	int i;
+	unsigned int delay_cnt;
+	long time_remain;
+
+	/* If enough time has passed, no wait is necessary. */
+	time_remain = (long)(tp->last_event_jiffies + 1 +
+		      usecs_to_jiffies(TG3_FW_EVENT_TIMEOUT_USEC)) -
+		      (long)jiffies;
+	if (time_remain < 0)
+		return;
 
 
-	/* Wait for up to 2.5 milliseconds */
-	for (i = 0; i < 250000; i++) {
+	/* Check if we can shorten the wait time. */
+	delay_cnt = jiffies_to_usecs(time_remain);
+	if (delay_cnt > TG3_FW_EVENT_TIMEOUT_USEC)
+		delay_cnt = TG3_FW_EVENT_TIMEOUT_USEC;
+	delay_cnt = (delay_cnt >> 3) + 1;
+
+	for (i = 0; i < delay_cnt; i++) {
 		if (!(tr32(GRC_RX_CPU_EVENT) & GRC_RX_CPU_DRIVER_EVENT))
 		if (!(tr32(GRC_RX_CPU_EVENT) & GRC_RX_CPU_DRIVER_EVENT))
 			break;
 			break;
-		udelay(10);
+		udelay(8);
 	}
 	}
 }
 }
 
 
@@ -1075,9 +1105,7 @@ static void tg3_ump_link_report(struct tg3 *tp)
 		val = 0;
 		val = 0;
 	tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 12, val);
 	tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 12, val);
 
 
-	val = tr32(GRC_RX_CPU_EVENT);
-	val |= GRC_RX_CPU_DRIVER_EVENT;
-	tw32_f(GRC_RX_CPU_EVENT, val);
+	tg3_generate_fw_event(tp);
 }
 }
 
 
 static void tg3_link_report(struct tg3 *tp)
 static void tg3_link_report(struct tg3 *tp)
@@ -2124,6 +2152,13 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
 		     (tp->tg3_flags & TG3_FLAG_WOL_ENABLE))
 		     (tp->tg3_flags & TG3_FLAG_WOL_ENABLE))
 			mac_mode |= MAC_MODE_MAGIC_PKT_ENABLE;
 			mac_mode |= MAC_MODE_MAGIC_PKT_ENABLE;
 
 
+		if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
+			mac_mode |= tp->mac_mode &
+				    (MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN);
+			if (mac_mode & MAC_MODE_APE_TX_EN)
+				mac_mode |= MAC_MODE_TDE_ENABLE;
+		}
+
 		tw32_f(MAC_MODE, mac_mode);
 		tw32_f(MAC_MODE, mac_mode);
 		udelay(100);
 		udelay(100);
 
 
@@ -5493,7 +5528,7 @@ static void tg3_ape_send_event(struct tg3 *tp, u32 event)
 		return;
 		return;
 
 
 	apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS);
 	apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS);
-	if (apedata != APE_FW_STATUS_READY)
+	if (!(apedata & APE_FW_STATUS_READY))
 		return;
 		return;
 
 
 	/* Wait for up to 1 millisecond for APE to service previous event. */
 	/* Wait for up to 1 millisecond for APE to service previous event. */
@@ -5760,6 +5795,8 @@ static int tg3_chip_reset(struct tg3 *tp)
 
 
 	tg3_mdio_stop(tp);
 	tg3_mdio_stop(tp);
 
 
+	tg3_ape_lock(tp, TG3_APE_LOCK_GRC);
+
 	/* No matching tg3_nvram_unlock() after this because
 	/* No matching tg3_nvram_unlock() after this because
 	 * chip reset below will undo the nvram lock.
 	 * chip reset below will undo the nvram lock.
 	 */
 	 */
@@ -5908,12 +5945,19 @@ static int tg3_chip_reset(struct tg3 *tp)
 	} else if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) {
 	} else if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) {
 		tp->mac_mode = MAC_MODE_PORT_MODE_GMII;
 		tp->mac_mode = MAC_MODE_PORT_MODE_GMII;
 		tw32_f(MAC_MODE, tp->mac_mode);
 		tw32_f(MAC_MODE, tp->mac_mode);
+	} else if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
+		tp->mac_mode &= (MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN);
+		if (tp->mac_mode & MAC_MODE_APE_TX_EN)
+			tp->mac_mode |= MAC_MODE_TDE_ENABLE;
+		tw32_f(MAC_MODE, tp->mac_mode);
 	} else
 	} else
 		tw32_f(MAC_MODE, 0);
 		tw32_f(MAC_MODE, 0);
 	udelay(40);
 	udelay(40);
 
 
 	tg3_mdio_start(tp);
 	tg3_mdio_start(tp);
 
 
+	tg3_ape_unlock(tp, TG3_APE_LOCK_GRC);
+
 	err = tg3_poll_fw(tp);
 	err = tg3_poll_fw(tp);
 	if (err)
 	if (err)
 		return err;
 		return err;
@@ -5935,6 +5979,7 @@ static int tg3_chip_reset(struct tg3 *tp)
 		tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg);
 		tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg);
 		if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) {
 		if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) {
 			tp->tg3_flags |= TG3_FLAG_ENABLE_ASF;
 			tp->tg3_flags |= TG3_FLAG_ENABLE_ASF;
+			tp->last_event_jiffies = jiffies;
 			if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)
 			if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)
 				tp->tg3_flags2 |= TG3_FLG2_ASF_NEW_HANDSHAKE;
 				tp->tg3_flags2 |= TG3_FLG2_ASF_NEW_HANDSHAKE;
 		}
 		}
@@ -5948,15 +5993,12 @@ static void tg3_stop_fw(struct tg3 *tp)
 {
 {
 	if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) &&
 	if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) &&
 	   !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) {
 	   !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) {
-		u32 val;
-
 		/* Wait for RX cpu to ACK the previous event. */
 		/* Wait for RX cpu to ACK the previous event. */
 		tg3_wait_for_event_ack(tp);
 		tg3_wait_for_event_ack(tp);
 
 
 		tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_PAUSE_FW);
 		tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_PAUSE_FW);
-		val = tr32(GRC_RX_CPU_EVENT);
-		val |= GRC_RX_CPU_DRIVER_EVENT;
-		tw32(GRC_RX_CPU_EVENT, val);
+
+		tg3_generate_fw_event(tp);
 
 
 		/* Wait for RX cpu to ACK this event. */
 		/* Wait for RX cpu to ACK this event. */
 		tg3_wait_for_event_ack(tp);
 		tg3_wait_for_event_ack(tp);
@@ -7406,7 +7448,11 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 		udelay(10);
 		udelay(10);
 	}
 	}
 
 
-	tp->mac_mode = MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE |
+	if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
+		tp->mac_mode &= MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN;
+	else
+		tp->mac_mode = 0;
+	tp->mac_mode |= MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE |
 		MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | MAC_MODE_FHDE_ENABLE;
 		MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | MAC_MODE_FHDE_ENABLE;
 	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
 	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
 	    !(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) &&
 	    !(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) &&
@@ -7840,9 +7886,8 @@ static void tg3_timer(unsigned long __opaque)
 	 * resets.
 	 * resets.
 	 */
 	 */
 	if (!--tp->asf_counter) {
 	if (!--tp->asf_counter) {
-		if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
-			u32 val;
-
+		if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) &&
+		    !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) {
 			tg3_wait_for_event_ack(tp);
 			tg3_wait_for_event_ack(tp);
 
 
 			tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX,
 			tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX,
@@ -7850,9 +7895,8 @@ static void tg3_timer(unsigned long __opaque)
 			tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
 			tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
 			/* 5 seconds timeout */
 			/* 5 seconds timeout */
 			tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5);
 			tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5);
-			val = tr32(GRC_RX_CPU_EVENT);
-			val |= GRC_RX_CPU_DRIVER_EVENT;
-			tw32_f(GRC_RX_CPU_EVENT, val);
+
+			tg3_generate_fw_event(tp);
 		}
 		}
 		tp->asf_counter = tp->asf_multiplier;
 		tp->asf_counter = tp->asf_multiplier;
 	}
 	}
@@ -8422,6 +8466,11 @@ static inline unsigned long get_stat64(tg3_stat64_t *val)
 	return ret;
 	return ret;
 }
 }
 
 
+static inline u64 get_estat64(tg3_stat64_t *val)
+{
+       return ((u64)val->high << 32) | ((u64)val->low);
+}
+
 static unsigned long calc_crc_errors(struct tg3 *tp)
 static unsigned long calc_crc_errors(struct tg3 *tp)
 {
 {
 	struct tg3_hw_stats *hw_stats = tp->hw_stats;
 	struct tg3_hw_stats *hw_stats = tp->hw_stats;
@@ -8450,7 +8499,7 @@ static unsigned long calc_crc_errors(struct tg3 *tp)
 
 
 #define ESTAT_ADD(member) \
 #define ESTAT_ADD(member) \
 	estats->member =	old_estats->member + \
 	estats->member =	old_estats->member + \
-				get_stat64(&hw_stats->member)
+				get_estat64(&hw_stats->member)
 
 
 static struct tg3_ethtool_stats *tg3_get_estats(struct tg3 *tp)
 static struct tg3_ethtool_stats *tg3_get_estats(struct tg3 *tp)
 {
 {
@@ -12416,6 +12465,13 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 				       tp->misc_host_ctrl);
 				       tp->misc_host_ctrl);
 	}
 	}
 
 
+	/* Preserve the APE MAC_MODE bits */
+	if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
+		tp->mac_mode = tr32(MAC_MODE) |
+			       MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN;
+	else
+		tp->mac_mode = TG3_DEF_MAC_MODE;
+
 	/* these are limited to 10/100 only */
 	/* these are limited to 10/100 only */
 	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 &&
 	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 &&
 	     (grc_misc_cfg == 0x8000 || grc_misc_cfg == 0x4000)) ||
 	     (grc_misc_cfg == 0x8000 || grc_misc_cfg == 0x4000)) ||
@@ -13275,7 +13331,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 	tp->pdev = pdev;
 	tp->pdev = pdev;
 	tp->dev = dev;
 	tp->dev = dev;
 	tp->pm_cap = pm_cap;
 	tp->pm_cap = pm_cap;
-	tp->mac_mode = TG3_DEF_MAC_MODE;
 	tp->rx_mode = TG3_DEF_RX_MODE;
 	tp->rx_mode = TG3_DEF_RX_MODE;
 	tp->tx_mode = TG3_DEF_TX_MODE;
 	tp->tx_mode = TG3_DEF_TX_MODE;
 
 

+ 6 - 0
drivers/net/tg3.h

@@ -325,6 +325,8 @@
 #define  MAC_MODE_TDE_ENABLE		 0x00200000
 #define  MAC_MODE_TDE_ENABLE		 0x00200000
 #define  MAC_MODE_RDE_ENABLE		 0x00400000
 #define  MAC_MODE_RDE_ENABLE		 0x00400000
 #define  MAC_MODE_FHDE_ENABLE		 0x00800000
 #define  MAC_MODE_FHDE_ENABLE		 0x00800000
+#define  MAC_MODE_APE_RX_EN		 0x08000000
+#define  MAC_MODE_APE_TX_EN		 0x10000000
 #define MAC_STATUS			0x00000404
 #define MAC_STATUS			0x00000404
 #define  MAC_STATUS_PCS_SYNCED		 0x00000001
 #define  MAC_STATUS_PCS_SYNCED		 0x00000001
 #define  MAC_STATUS_SIGNAL_DET		 0x00000002
 #define  MAC_STATUS_SIGNAL_DET		 0x00000002
@@ -1889,6 +1891,7 @@
 #define  APE_EVENT_STATUS_EVENT_PENDING	 0x80000000
 #define  APE_EVENT_STATUS_EVENT_PENDING	 0x80000000
 
 
 /* APE convenience enumerations. */
 /* APE convenience enumerations. */
+#define TG3_APE_LOCK_GRC                1
 #define TG3_APE_LOCK_MEM                4
 #define TG3_APE_LOCK_MEM                4
 
 
 #define TG3_EEPROM_SB_F1R2_MBA_OFF	0x10
 #define TG3_EEPROM_SB_F1R2_MBA_OFF	0x10
@@ -2429,7 +2432,10 @@ struct tg3 {
 	struct tg3_ethtool_stats	estats;
 	struct tg3_ethtool_stats	estats;
 	struct tg3_ethtool_stats	estats_prev;
 	struct tg3_ethtool_stats	estats_prev;
 
 
+	union {
 	unsigned long			phy_crc_errors;
 	unsigned long			phy_crc_errors;
+	unsigned long			last_event_jiffies;
+	};
 
 
 	u32				rx_offset;
 	u32				rx_offset;
 	u32				tg3_flags;
 	u32				tg3_flags;

+ 4 - 4
drivers/net/tlan.c

@@ -360,8 +360,8 @@ TLan_GetSKB( const struct tlan_list_tag *tag)
 {
 {
 	unsigned long addr;
 	unsigned long addr;
 
 
-	addr = tag->buffer[8].address;
-	addr |= (tag->buffer[9].address << 16) << 16;
+	addr = tag->buffer[9].address;
+	addr |= (tag->buffer[8].address << 16) << 16;
 	return (struct sk_buff *) addr;
 	return (struct sk_buff *) addr;
 }
 }
 
 
@@ -1984,7 +1984,6 @@ static void TLan_ResetLists( struct net_device *dev )
 	TLanList	*list;
 	TLanList	*list;
 	dma_addr_t	list_phys;
 	dma_addr_t	list_phys;
 	struct sk_buff	*skb;
 	struct sk_buff	*skb;
-	void		*t = NULL;
 
 
 	priv->txHead = 0;
 	priv->txHead = 0;
 	priv->txTail = 0;
 	priv->txTail = 0;
@@ -2022,7 +2021,8 @@ static void TLan_ResetLists( struct net_device *dev )
 			}
 			}
 
 
 			skb_reserve( skb, NET_IP_ALIGN );
 			skb_reserve( skb, NET_IP_ALIGN );
-			list->buffer[0].address = pci_map_single(priv->pciDev, t,
+			list->buffer[0].address = pci_map_single(priv->pciDev,
+								 skb->data,
 								 TLAN_MAX_FRAME_SIZE,
 								 TLAN_MAX_FRAME_SIZE,
 								 PCI_DMA_FROMDEVICE);
 								 PCI_DMA_FROMDEVICE);
 			TLan_StoreSKB(list, skb);
 			TLan_StoreSKB(list, skb);

+ 101 - 4
drivers/net/tun.c

@@ -358,6 +358,66 @@ static unsigned int tun_chr_poll(struct file *file, poll_table * wait)
 	return mask;
 	return mask;
 }
 }
 
 
+/* prepad is the amount to reserve at front.  len is length after that.
+ * linear is a hint as to how much to copy (usually headers). */
+static struct sk_buff *tun_alloc_skb(size_t prepad, size_t len, size_t linear,
+				     gfp_t gfp)
+{
+	struct sk_buff *skb;
+	unsigned int i;
+
+	skb = alloc_skb(prepad + len, gfp|__GFP_NOWARN);
+	if (skb) {
+		skb_reserve(skb, prepad);
+		skb_put(skb, len);
+		return skb;
+	}
+
+	/* Under a page?  Don't bother with paged skb. */
+	if (prepad + len < PAGE_SIZE)
+		return NULL;
+
+	/* Start with a normal skb, and add pages. */
+	skb = alloc_skb(prepad + linear, gfp);
+	if (!skb)
+		return NULL;
+
+	skb_reserve(skb, prepad);
+	skb_put(skb, linear);
+
+	len -= linear;
+
+	for (i = 0; i < MAX_SKB_FRAGS; i++) {
+		skb_frag_t *f = &skb_shinfo(skb)->frags[i];
+
+		f->page = alloc_page(gfp|__GFP_ZERO);
+		if (!f->page)
+			break;
+
+		f->page_offset = 0;
+		f->size = PAGE_SIZE;
+
+		skb->data_len += PAGE_SIZE;
+		skb->len += PAGE_SIZE;
+		skb->truesize += PAGE_SIZE;
+		skb_shinfo(skb)->nr_frags++;
+
+		if (len < PAGE_SIZE) {
+			len = 0;
+			break;
+		}
+		len -= PAGE_SIZE;
+	}
+
+	/* Too large, or alloc fail? */
+	if (unlikely(len)) {
+		kfree_skb(skb);
+		skb = NULL;
+	}
+
+	return skb;
+}
+
 /* Get packet from user space buffer */
 /* Get packet from user space buffer */
 static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv, size_t count)
 static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv, size_t count)
 {
 {
@@ -391,14 +451,12 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv,
 			return -EINVAL;
 			return -EINVAL;
 	}
 	}
 
 
-	if (!(skb = alloc_skb(len + align, GFP_KERNEL))) {
+	if (!(skb = tun_alloc_skb(align, len, gso.hdr_len, GFP_KERNEL))) {
 		tun->dev->stats.rx_dropped++;
 		tun->dev->stats.rx_dropped++;
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
 
 
-	if (align)
-		skb_reserve(skb, align);
-	if (memcpy_fromiovec(skb_put(skb, len), iv, len)) {
+	if (skb_copy_datagram_from_iovec(skb, 0, iv, len)) {
 		tun->dev->stats.rx_dropped++;
 		tun->dev->stats.rx_dropped++;
 		kfree_skb(skb);
 		kfree_skb(skb);
 		return -EFAULT;
 		return -EFAULT;
@@ -748,6 +806,36 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
 	return err;
 	return err;
 }
 }
 
 
+static int tun_get_iff(struct net *net, struct file *file, struct ifreq *ifr)
+{
+	struct tun_struct *tun = file->private_data;
+
+	if (!tun)
+		return -EBADFD;
+
+	DBG(KERN_INFO "%s: tun_get_iff\n", tun->dev->name);
+
+	strcpy(ifr->ifr_name, tun->dev->name);
+
+	ifr->ifr_flags = 0;
+
+	if (ifr->ifr_flags & TUN_TUN_DEV)
+		ifr->ifr_flags |= IFF_TUN;
+	else
+		ifr->ifr_flags |= IFF_TAP;
+
+	if (tun->flags & TUN_NO_PI)
+		ifr->ifr_flags |= IFF_NO_PI;
+
+	if (tun->flags & TUN_ONE_QUEUE)
+		ifr->ifr_flags |= IFF_ONE_QUEUE;
+
+	if (tun->flags & TUN_VNET_HDR)
+		ifr->ifr_flags |= IFF_VNET_HDR;
+
+	return 0;
+}
+
 /* This is like a cut-down ethtool ops, except done via tun fd so no
 /* This is like a cut-down ethtool ops, except done via tun fd so no
  * privs required. */
  * privs required. */
 static int set_offload(struct net_device *dev, unsigned long arg)
 static int set_offload(struct net_device *dev, unsigned long arg)
@@ -833,6 +921,15 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
 	DBG(KERN_INFO "%s: tun_chr_ioctl cmd %d\n", tun->dev->name, cmd);
 	DBG(KERN_INFO "%s: tun_chr_ioctl cmd %d\n", tun->dev->name, cmd);
 
 
 	switch (cmd) {
 	switch (cmd) {
+	case TUNGETIFF:
+		ret = tun_get_iff(current->nsproxy->net_ns, file, &ifr);
+		if (ret)
+			return ret;
+
+		if (copy_to_user(argp, &ifr, sizeof(ifr)))
+			return -EFAULT;
+		break;
+
 	case TUNSETNOCSUM:
 	case TUNSETNOCSUM:
 		/* Disable/Enable checksum */
 		/* Disable/Enable checksum */
 		if (arg)
 		if (arg)

+ 0 - 1
drivers/net/typhoon.c

@@ -128,7 +128,6 @@ static const int multicast_filter_limit = 32;
 #include <asm/io.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/uaccess.h>
 #include <linux/in6.h>
 #include <linux/in6.h>
-#include <linux/version.h>
 #include <linux/dma-mapping.h>
 #include <linux/dma-mapping.h>
 
 
 #include "typhoon.h"
 #include "typhoon.h"

+ 10 - 11
drivers/net/usb/Kconfig

@@ -154,17 +154,6 @@ config USB_NET_AX8817X
 	  This driver creates an interface named "ethX", where X depends on
 	  This driver creates an interface named "ethX", where X depends on
 	  what other networking devices you have in use.
 	  what other networking devices you have in use.
 
 
-config USB_HSO
-	tristate "Option USB High Speed Mobile Devices"
-	depends on USB && RFKILL
-	default n
-	help
-	  Choose this option if you have an Option HSDPA/HSUPA card.
-	  These cards support downlink speeds of 7.2Mbps or greater.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called hso.
-
 config USB_NET_CDCETHER
 config USB_NET_CDCETHER
 	tristate "CDC Ethernet support (smart devices such as cable modems)"
 	tristate "CDC Ethernet support (smart devices such as cable modems)"
 	depends on USB_USBNET
 	depends on USB_USBNET
@@ -337,5 +326,15 @@ config USB_NET_ZAURUS
 	  really need this non-conformant variant of CDC Ethernet (or in
 	  really need this non-conformant variant of CDC Ethernet (or in
 	  some cases CDC MDLM) protocol, not "g_ether".
 	  some cases CDC MDLM) protocol, not "g_ether".
 
 
+config USB_HSO
+	tristate "Option USB High Speed Mobile Devices"
+	depends on USB && RFKILL
+	default n
+	help
+	  Choose this option if you have an Option HSDPA/HSUPA card.
+	  These cards support downlink speeds of 7.2Mbps or greater.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called hso.
 
 
 endmenu
 endmenu

+ 30 - 23
drivers/net/usb/hso.c

@@ -102,8 +102,12 @@
 
 
 #define MAX_RX_URBS			2
 #define MAX_RX_URBS			2
 
 
-#define get_serial_by_tty(x)	\
-	(x ? (struct hso_serial *)x->driver_data : NULL)
+static inline struct hso_serial *get_serial_by_tty(struct tty_struct *tty)
+{
+	if (tty)
+		return tty->driver_data;
+	return NULL;
+}
 
 
 /*****************************************************************************/
 /*****************************************************************************/
 /* Debugging functions                                                       */
 /* Debugging functions                                                       */
@@ -294,24 +298,25 @@ static int hso_get_activity(struct hso_device *hso_dev);
 
 
 /* #define DEBUG */
 /* #define DEBUG */
 
 
-#define dev2net(x) (x->port_data.dev_net)
-#define dev2ser(x) (x->port_data.dev_serial)
+static inline struct hso_net *dev2net(struct hso_device *hso_dev)
+{
+	return hso_dev->port_data.dev_net;
+}
+
+static inline struct hso_serial *dev2ser(struct hso_device *hso_dev)
+{
+	return hso_dev->port_data.dev_serial;
+}
 
 
 /* Debugging functions */
 /* Debugging functions */
 #ifdef DEBUG
 #ifdef DEBUG
 static void dbg_dump(int line_count, const char *func_name, unsigned char *buf,
 static void dbg_dump(int line_count, const char *func_name, unsigned char *buf,
 		     unsigned int len)
 		     unsigned int len)
 {
 {
-	u8 i = 0;
+	static char name[255];
 
 
-	printk(KERN_DEBUG "[%d:%s]: len %d", line_count, func_name, len);
-
-	for (i = 0; i < len; i++) {
-		if (!(i % 16))
-			printk("\n    0x%03x:  ", i);
-		printk("%02x ", (unsigned char)buf[i]);
-	}
-	printk("\n");
+	sprintf(name, "hso[%d:%s]", line_count, func_name);
+	print_hex_dump_bytes(name, DUMP_PREFIX_NONE, buf, len);
 }
 }
 
 
 #define DUMP(buf_, len_)	\
 #define DUMP(buf_, len_)	\
@@ -528,13 +533,12 @@ static struct hso_serial *get_serial_by_shared_int_and_type(
 
 
 static struct hso_serial *get_serial_by_index(unsigned index)
 static struct hso_serial *get_serial_by_index(unsigned index)
 {
 {
-	struct hso_serial *serial;
+	struct hso_serial *serial = NULL;
 	unsigned long flags;
 	unsigned long flags;
 
 
-	if (!serial_table[index])
-		return NULL;
 	spin_lock_irqsave(&serial_table_lock, flags);
 	spin_lock_irqsave(&serial_table_lock, flags);
-	serial = dev2ser(serial_table[index]);
+	if (serial_table[index])
+		serial = dev2ser(serial_table[index]);
 	spin_unlock_irqrestore(&serial_table_lock, flags);
 	spin_unlock_irqrestore(&serial_table_lock, flags);
 
 
 	return serial;
 	return serial;
@@ -561,6 +565,7 @@ static int get_free_serial_index(void)
 static void set_serial_by_index(unsigned index, struct hso_serial *serial)
 static void set_serial_by_index(unsigned index, struct hso_serial *serial)
 {
 {
 	unsigned long flags;
 	unsigned long flags;
+
 	spin_lock_irqsave(&serial_table_lock, flags);
 	spin_lock_irqsave(&serial_table_lock, flags);
 	if (serial)
 	if (serial)
 		serial_table[index] = serial->parent;
 		serial_table[index] = serial->parent;
@@ -569,7 +574,7 @@ static void set_serial_by_index(unsigned index, struct hso_serial *serial)
 	spin_unlock_irqrestore(&serial_table_lock, flags);
 	spin_unlock_irqrestore(&serial_table_lock, flags);
 }
 }
 
 
-/* log a meaningfull explanation of an USB status */
+/* log a meaningful explanation of an USB status */
 static void log_usb_status(int status, const char *function)
 static void log_usb_status(int status, const char *function)
 {
 {
 	char *explanation;
 	char *explanation;
@@ -1103,8 +1108,8 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp)
 	/* reset the rts and dtr */
 	/* reset the rts and dtr */
 	/* do the actual close */
 	/* do the actual close */
 	serial->open_count--;
 	serial->open_count--;
+	kref_put(&serial->parent->ref, hso_serial_ref_free);
 	if (serial->open_count <= 0) {
 	if (serial->open_count <= 0) {
-		kref_put(&serial->parent->ref, hso_serial_ref_free);
 		serial->open_count = 0;
 		serial->open_count = 0;
 		if (serial->tty) {
 		if (serial->tty) {
 			serial->tty->driver_data = NULL;
 			serial->tty->driver_data = NULL;
@@ -1467,7 +1472,8 @@ static void hso_std_serial_write_bulk_callback(struct urb *urb)
 		return;
 		return;
 	}
 	}
 	hso_put_activity(serial->parent);
 	hso_put_activity(serial->parent);
-	tty_wakeup(serial->tty);
+	if (serial->tty)
+		tty_wakeup(serial->tty);
 	hso_kick_transmit(serial);
 	hso_kick_transmit(serial);
 
 
 	D1(" ");
 	D1(" ");
@@ -1538,7 +1544,8 @@ static void ctrl_callback(struct urb *urb)
 			clear_bit(HSO_SERIAL_FLAG_RX_SENT, &serial->flags);
 			clear_bit(HSO_SERIAL_FLAG_RX_SENT, &serial->flags);
 	} else {
 	} else {
 		hso_put_activity(serial->parent);
 		hso_put_activity(serial->parent);
-		tty_wakeup(serial->tty);
+		if (serial->tty)
+			tty_wakeup(serial->tty);
 		/* response to a write command */
 		/* response to a write command */
 		hso_kick_transmit(serial);
 		hso_kick_transmit(serial);
 	}
 	}
@@ -2652,7 +2659,7 @@ static void hso_free_interface(struct usb_interface *interface)
 			hso_stop_net_device(network_table[i]);
 			hso_stop_net_device(network_table[i]);
 			cancel_work_sync(&network_table[i]->async_put_intf);
 			cancel_work_sync(&network_table[i]->async_put_intf);
 			cancel_work_sync(&network_table[i]->async_get_intf);
 			cancel_work_sync(&network_table[i]->async_get_intf);
-			if(rfk)
+			if (rfk)
 				rfkill_unregister(rfk);
 				rfkill_unregister(rfk);
 			hso_free_net_device(network_table[i]);
 			hso_free_net_device(network_table[i]);
 		}
 		}
@@ -2723,7 +2730,7 @@ static int hso_mux_submit_intr_urb(struct hso_shared_int *shared_int,
 }
 }
 
 
 /* operations setup of the serial interface */
 /* operations setup of the serial interface */
-static struct tty_operations hso_serial_ops = {
+static const struct tty_operations hso_serial_ops = {
 	.open = hso_serial_open,
 	.open = hso_serial_open,
 	.close = hso_serial_close,
 	.close = hso_serial_close,
 	.write = hso_serial_write,
 	.write = hso_serial_write,

+ 2 - 7
drivers/net/wireless/ath5k/base.c

@@ -40,7 +40,6 @@
  *
  *
  */
  */
 
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/hardirq.h>
 #include <linux/hardirq.h>
@@ -587,7 +586,6 @@ ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 	ath5k_stop_hw(sc);
 	ath5k_stop_hw(sc);
 
 
 	free_irq(pdev->irq, sc);
 	free_irq(pdev->irq, sc);
-	pci_disable_msi(pdev);
 	pci_save_state(pdev);
 	pci_save_state(pdev);
 	pci_disable_device(pdev);
 	pci_disable_device(pdev);
 	pci_set_power_state(pdev, PCI_D3hot);
 	pci_set_power_state(pdev, PCI_D3hot);
@@ -616,12 +614,10 @@ ath5k_pci_resume(struct pci_dev *pdev)
 	 */
 	 */
 	pci_write_config_byte(pdev, 0x41, 0);
 	pci_write_config_byte(pdev, 0x41, 0);
 
 
-	pci_enable_msi(pdev);
-
 	err = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
 	err = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
 	if (err) {
 	if (err) {
 		ATH5K_ERR(sc, "request_irq failed\n");
 		ATH5K_ERR(sc, "request_irq failed\n");
-		goto err_msi;
+		goto err_no_irq;
 	}
 	}
 
 
 	err = ath5k_init(sc);
 	err = ath5k_init(sc);
@@ -642,8 +638,7 @@ ath5k_pci_resume(struct pci_dev *pdev)
 	return 0;
 	return 0;
 err_irq:
 err_irq:
 	free_irq(pdev->irq, sc);
 	free_irq(pdev->irq, sc);
-err_msi:
-	pci_disable_msi(pdev);
+err_no_irq:
 	pci_disable_device(pdev);
 	pci_disable_device(pdev);
 	return err;
 	return err;
 }
 }

+ 5 - 1
drivers/net/wireless/ath9k/hw.c

@@ -5017,7 +5017,11 @@ static void ath9k_hw_spur_mitigate(struct ath_hal *ah,
 
 
 	for (i = 0; i < 123; i++) {
 	for (i = 0; i < 123; i++) {
 		if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
 		if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
-			if ((abs(cur_vit_mask - bin)) < 75)
+
+			/* workaround for gcc bug #37014 */
+			volatile int tmp = abs(cur_vit_mask - bin);
+
+			if (tmp < 75)
 				mask_amt = 1;
 				mask_amt = 1;
 			else
 			else
 				mask_amt = 0;
 				mask_amt = 0;

+ 2 - 1
drivers/net/wireless/b43/main.c

@@ -33,7 +33,6 @@
 #include <linux/moduleparam.h>
 #include <linux/moduleparam.h>
 #include <linux/if_arp.h>
 #include <linux/if_arp.h>
 #include <linux/etherdevice.h>
 #include <linux/etherdevice.h>
-#include <linux/version.h>
 #include <linux/firmware.h>
 #include <linux/firmware.h>
 #include <linux/wireless.h>
 #include <linux/wireless.h>
 #include <linux/workqueue.h>
 #include <linux/workqueue.h>
@@ -4615,7 +4614,9 @@ static void b43_sprom_fixup(struct ssb_bus *bus)
 	if (bus->bustype == SSB_BUSTYPE_PCI) {
 	if (bus->bustype == SSB_BUSTYPE_PCI) {
 		pdev = bus->host_pci;
 		pdev = bus->host_pci;
 		if (IS_PDEV(pdev, BROADCOM, 0x4318, ASUSTEK, 0x100F) ||
 		if (IS_PDEV(pdev, BROADCOM, 0x4318, ASUSTEK, 0x100F) ||
+		    IS_PDEV(pdev, BROADCOM, 0x4320,    DELL, 0x0003) ||
 		    IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0015) ||
 		    IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0015) ||
+		    IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0014) ||
 		    IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0013))
 		    IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0013))
 			bus->sprom.boardflags_lo &= ~B43_BFL_BTCOEXIST;
 			bus->sprom.boardflags_lo &= ~B43_BFL_BTCOEXIST;
 	}
 	}

+ 0 - 1
drivers/net/wireless/ipw2100.c

@@ -157,7 +157,6 @@ that only one external action is invoked at a time.
 #include <linux/stringify.h>
 #include <linux/stringify.h>
 #include <linux/tcp.h>
 #include <linux/tcp.h>
 #include <linux/types.h>
 #include <linux/types.h>
-#include <linux/version.h>
 #include <linux/time.h>
 #include <linux/time.h>
 #include <linux/firmware.h>
 #include <linux/firmware.h>
 #include <linux/acpi.h>
 #include <linux/acpi.h>

+ 0 - 1
drivers/net/wireless/ipw2200.c

@@ -31,7 +31,6 @@
 ******************************************************************************/
 ******************************************************************************/
 
 
 #include "ipw2200.h"
 #include "ipw2200.h"
-#include <linux/version.h>
 
 
 
 
 #ifndef KBUILD_EXTMOD
 #ifndef KBUILD_EXTMOD

+ 0 - 1
drivers/net/wireless/iwlwifi/iwl-3945.c

@@ -26,7 +26,6 @@
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
 #include <linux/dma-mapping.h>

+ 1 - 2
drivers/net/wireless/iwlwifi/iwl-4965.c

@@ -26,7 +26,6 @@
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
 #include <linux/dma-mapping.h>
@@ -967,7 +966,7 @@ static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel,
 
 
 	s = iwl4965_get_sub_band(priv, channel);
 	s = iwl4965_get_sub_band(priv, channel);
 	if (s >= EEPROM_TX_POWER_BANDS) {
 	if (s >= EEPROM_TX_POWER_BANDS) {
-		IWL_ERROR("Tx Power can not find channel %d ", channel);
+		IWL_ERROR("Tx Power can not find channel %d\n", channel);
 		return -1;
 		return -1;
 	}
 	}
 
 

+ 0 - 1
drivers/net/wireless/iwlwifi/iwl-5000.c

@@ -25,7 +25,6 @@
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
 #include <linux/dma-mapping.h>

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

@@ -29,7 +29,6 @@
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
 #include <linux/dma-mapping.h>

+ 0 - 1
drivers/net/wireless/iwlwifi/iwl-core.c

@@ -28,7 +28,6 @@
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <net/mac80211.h>
 #include <net/mac80211.h>
 
 
 struct iwl_priv; /* FIXME: remove */
 struct iwl_priv; /* FIXME: remove */

+ 3 - 4
drivers/net/wireless/iwlwifi/iwl-eeprom.c

@@ -63,7 +63,6 @@
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/init.h>
 
 
 #include <net/mac80211.h>
 #include <net/mac80211.h>
@@ -146,7 +145,7 @@ int iwlcore_eeprom_verify_signature(struct iwl_priv *priv)
 {
 {
 	u32 gp = iwl_read32(priv, CSR_EEPROM_GP);
 	u32 gp = iwl_read32(priv, CSR_EEPROM_GP);
 	if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) {
 	if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) {
-		IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x", gp);
+		IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp);
 		return -ENOENT;
 		return -ENOENT;
 	}
 	}
 	return 0;
 	return 0;
@@ -227,7 +226,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
 
 
 	ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv);
 	ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv);
 	if (ret < 0) {
 	if (ret < 0) {
-		IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x", gp);
+		IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp);
 		ret = -ENOENT;
 		ret = -ENOENT;
 		goto err;
 		goto err;
 	}
 	}
@@ -254,7 +253,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
 		}
 		}
 
 
 		if (!(r & CSR_EEPROM_REG_READ_VALID_MSK)) {
 		if (!(r & CSR_EEPROM_REG_READ_VALID_MSK)) {
-			IWL_ERROR("Time out reading EEPROM[%d]", addr);
+			IWL_ERROR("Time out reading EEPROM[%d]\n", addr);
 			ret = -ETIMEDOUT;
 			ret = -ETIMEDOUT;
 			goto done;
 			goto done;
 		}
 		}

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

@@ -28,7 +28,6 @@
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <net/mac80211.h>
 #include <net/mac80211.h>
 
 
 #include "iwl-dev.h" /* FIXME: remove */
 #include "iwl-dev.h" /* FIXME: remove */

+ 0 - 1
drivers/net/wireless/iwlwifi/iwl-power.c

@@ -29,7 +29,6 @@
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/init.h>
 
 
 #include <net/mac80211.h>
 #include <net/mac80211.h>

+ 2 - 2
drivers/net/wireless/iwlwifi/iwl-sta.c

@@ -207,7 +207,7 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
 	case WLAN_HT_CAP_MIMO_PS_DISABLED:
 	case WLAN_HT_CAP_MIMO_PS_DISABLED:
 		break;
 		break;
 	default:
 	default:
-		IWL_WARNING("Invalid MIMO PS mode %d", mimo_ps_mode);
+		IWL_WARNING("Invalid MIMO PS mode %d\n", mimo_ps_mode);
 		break;
 		break;
 	}
 	}
 
 
@@ -969,7 +969,7 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
 		return priv->hw_params.bcast_sta_id;
 		return priv->hw_params.bcast_sta_id;
 
 
 	default:
 	default:
-		IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode);
+		IWL_WARNING("Unknown mode of operation: %d\n", priv->iw_mode);
 		return priv->hw_params.bcast_sta_id;
 		return priv->hw_params.bcast_sta_id;
 	}
 	}
 }
 }

+ 2 - 2
drivers/net/wireless/iwlwifi/iwl-tx.c

@@ -493,7 +493,7 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
 	/* Alloc keep-warm buffer */
 	/* Alloc keep-warm buffer */
 	ret = iwl_kw_alloc(priv);
 	ret = iwl_kw_alloc(priv);
 	if (ret) {
 	if (ret) {
-		IWL_ERROR("Keep Warm allocation failed");
+		IWL_ERROR("Keep Warm allocation failed\n");
 		goto error_kw;
 		goto error_kw;
 	}
 	}
 	spin_lock_irqsave(&priv->lock, flags);
 	spin_lock_irqsave(&priv->lock, flags);
@@ -1463,7 +1463,7 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
 	u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn);
 	u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn);
 
 
 	if (scd_flow >= priv->hw_params.max_txq_num) {
 	if (scd_flow >= priv->hw_params.max_txq_num) {
-		IWL_ERROR("BUG_ON scd_flow is bigger than number of queues");
+		IWL_ERROR("BUG_ON scd_flow is bigger than number of queues\n");
 		return;
 		return;
 	}
 	}
 
 

+ 3 - 4
drivers/net/wireless/iwlwifi/iwl3945-base.c

@@ -29,7 +29,6 @@
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
 #include <linux/dma-mapping.h>
@@ -1558,7 +1557,7 @@ int iwl3945_eeprom_init(struct iwl3945_priv *priv)
 	BUILD_BUG_ON(sizeof(priv->eeprom) != IWL_EEPROM_IMAGE_SIZE);
 	BUILD_BUG_ON(sizeof(priv->eeprom) != IWL_EEPROM_IMAGE_SIZE);
 
 
 	if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) {
 	if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) {
-		IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x", gp);
+		IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp);
 		return -ENOENT;
 		return -ENOENT;
 	}
 	}
 
 
@@ -1583,7 +1582,7 @@ int iwl3945_eeprom_init(struct iwl3945_priv *priv)
 		}
 		}
 
 
 		if (!(r & CSR_EEPROM_REG_READ_VALID_MSK)) {
 		if (!(r & CSR_EEPROM_REG_READ_VALID_MSK)) {
-			IWL_ERROR("Time out reading EEPROM[%d]", addr);
+			IWL_ERROR("Time out reading EEPROM[%d]\n", addr);
 			return -ETIMEDOUT;
 			return -ETIMEDOUT;
 		}
 		}
 		e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
 		e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
@@ -2507,7 +2506,7 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h
 		return priv->hw_setting.bcast_sta_id;
 		return priv->hw_setting.bcast_sta_id;
 
 
 	default:
 	default:
-		IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode);
+		IWL_WARNING("Unknown mode of operation: %d\n", priv->iw_mode);
 		return priv->hw_setting.bcast_sta_id;
 		return priv->hw_setting.bcast_sta_id;
 	}
 	}
 }
 }

+ 27 - 24
drivers/net/wireless/p54/p54common.c

@@ -413,12 +413,12 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
 			last_addr = range->end_addr;
 			last_addr = range->end_addr;
 			__skb_unlink(entry, &priv->tx_queue);
 			__skb_unlink(entry, &priv->tx_queue);
 			memset(&info->status, 0, sizeof(info->status));
 			memset(&info->status, 0, sizeof(info->status));
-			priv->tx_stats[skb_get_queue_mapping(skb)].len--;
 			entry_hdr = (struct p54_control_hdr *) entry->data;
 			entry_hdr = (struct p54_control_hdr *) entry->data;
 			entry_data = (struct p54_tx_control_allocdata *) entry_hdr->data;
 			entry_data = (struct p54_tx_control_allocdata *) entry_hdr->data;
 			if ((entry_hdr->magic1 & cpu_to_le16(0x4000)) != 0)
 			if ((entry_hdr->magic1 & cpu_to_le16(0x4000)) != 0)
 				pad = entry_data->align[0];
 				pad = entry_data->align[0];
 
 
+			priv->tx_stats[entry_data->hw_queue - 4].len--;
 			if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
 			if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
 				if (!(payload->status & 0x01))
 				if (!(payload->status & 0x01))
 					info->flags |= IEEE80211_TX_STAT_ACK;
 					info->flags |= IEEE80211_TX_STAT_ACK;
@@ -557,6 +557,7 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
 	struct p54_tx_control_allocdata *txhdr;
 	struct p54_tx_control_allocdata *txhdr;
 	size_t padding, len;
 	size_t padding, len;
 	u8 rate;
 	u8 rate;
+	u8 cts_rate = 0x20;
 
 
 	current_queue = &priv->tx_stats[skb_get_queue_mapping(skb)];
 	current_queue = &priv->tx_stats[skb_get_queue_mapping(skb)];
 	if (unlikely(current_queue->len > current_queue->limit))
 	if (unlikely(current_queue->len > current_queue->limit))
@@ -581,28 +582,28 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
 	hdr->type = (info->flags & IEEE80211_TX_CTL_NO_ACK) ? 0 : cpu_to_le16(1);
 	hdr->type = (info->flags & IEEE80211_TX_CTL_NO_ACK) ? 0 : cpu_to_le16(1);
 	hdr->retry1 = hdr->retry2 = info->control.retry_limit;
 	hdr->retry1 = hdr->retry2 = info->control.retry_limit;
 
 
-	memset(txhdr->wep_key, 0x0, 16);
-	txhdr->padding = 0;
-	txhdr->padding2 = 0;
-
 	/* TODO: add support for alternate retry TX rates */
 	/* TODO: add support for alternate retry TX rates */
 	rate = ieee80211_get_tx_rate(dev, info)->hw_value;
 	rate = ieee80211_get_tx_rate(dev, info)->hw_value;
-	if (info->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE)
+	if (info->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE) {
 		rate |= 0x10;
 		rate |= 0x10;
-	if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)
+		cts_rate |= 0x10;
+	}
+	if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) {
 		rate |= 0x40;
 		rate |= 0x40;
-	else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)
+		cts_rate |= ieee80211_get_rts_cts_rate(dev, info)->hw_value;
+	} else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) {
 		rate |= 0x20;
 		rate |= 0x20;
+		cts_rate |= ieee80211_get_rts_cts_rate(dev, info)->hw_value;
+	}
 	memset(txhdr->rateset, rate, 8);
 	memset(txhdr->rateset, rate, 8);
-	txhdr->wep_key_present = 0;
-	txhdr->wep_key_len = 0;
-	txhdr->frame_type = cpu_to_le32(skb_get_queue_mapping(skb) + 4);
-	txhdr->magic4 = 0;
-	txhdr->antenna = (info->antenna_sel_tx == 0) ?
+	txhdr->key_type = 0;
+	txhdr->key_len = 0;
+	txhdr->hw_queue = skb_get_queue_mapping(skb) + 4;
+	txhdr->tx_antenna = (info->antenna_sel_tx == 0) ?
 		2 : info->antenna_sel_tx - 1;
 		2 : info->antenna_sel_tx - 1;
 	txhdr->output_power = 0x7f; // HW Maximum
 	txhdr->output_power = 0x7f; // HW Maximum
-	txhdr->magic5 = (info->flags & IEEE80211_TX_CTL_NO_ACK) ?
-		0 : ((rate > 0x3) ? cpu_to_le32(0x33) : cpu_to_le32(0x23));
+	txhdr->cts_rate = (info->flags & IEEE80211_TX_CTL_NO_ACK) ?
+			  0 : cts_rate;
 	if (padding)
 	if (padding)
 		txhdr->align[0] = padding;
 		txhdr->align[0] = padding;
 
 
@@ -836,10 +837,21 @@ static int p54_start(struct ieee80211_hw *dev)
 	struct p54_common *priv = dev->priv;
 	struct p54_common *priv = dev->priv;
 	int err;
 	int err;
 
 
+	if (!priv->cached_vdcf) {
+		priv->cached_vdcf = kzalloc(sizeof(struct p54_tx_control_vdcf)+
+			priv->tx_hdr_len + sizeof(struct p54_control_hdr),
+			GFP_KERNEL);
+
+		if (!priv->cached_vdcf)
+			return -ENOMEM;
+	}
+
 	err = priv->open(dev);
 	err = priv->open(dev);
 	if (!err)
 	if (!err)
 		priv->mode = IEEE80211_IF_TYPE_MNTR;
 		priv->mode = IEEE80211_IF_TYPE_MNTR;
 
 
+	p54_init_vdcf(dev);
+
 	return err;
 	return err;
 }
 }
 
 
@@ -1019,15 +1031,6 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
 	dev->extra_tx_headroom = sizeof(struct p54_control_hdr) + 4 +
 	dev->extra_tx_headroom = sizeof(struct p54_control_hdr) + 4 +
 				 sizeof(struct p54_tx_control_allocdata);
 				 sizeof(struct p54_tx_control_allocdata);
 
 
-        priv->cached_vdcf = kzalloc(sizeof(struct p54_tx_control_vdcf) +
-              priv->tx_hdr_len + sizeof(struct p54_control_hdr), GFP_KERNEL);
-
-	if (!priv->cached_vdcf) {
-		ieee80211_free_hw(dev);
-		return NULL;
-	}
-
-	p54_init_vdcf(dev);
 	mutex_init(&priv->conf_mutex);
 	mutex_init(&priv->conf_mutex);
 
 
 	return dev;
 	return dev;

+ 9 - 9
drivers/net/wireless/p54/p54common.h

@@ -183,16 +183,16 @@ struct p54_frame_sent_hdr {
 
 
 struct p54_tx_control_allocdata {
 struct p54_tx_control_allocdata {
 	u8 rateset[8];
 	u8 rateset[8];
-	u16 padding;
-	u8 wep_key_present;
-	u8 wep_key_len;
-	u8 wep_key[16];
-	__le32 frame_type;
-	u32 padding2;
-	__le16 magic4;
-	u8 antenna;
+	u8 unalloc0[2];
+	u8 key_type;
+	u8 key_len;
+	u8 key[16];
+	u8 hw_queue;
+	u8 unalloc1[9];
+	u8 tx_antenna;
 	u8 output_power;
 	u8 output_power;
-	__le32 magic5;
+	u8 cts_rate;
+	u8 unalloc2[3];
 	u8 align[0];
 	u8 align[0];
 } __attribute__ ((packed));
 } __attribute__ ((packed));
 
 

+ 10 - 0
drivers/net/wireless/p54/p54usb.c

@@ -109,7 +109,17 @@ static void p54u_rx_cb(struct urb *urb)
 		urb->context = skb;
 		urb->context = skb;
 		skb_queue_tail(&priv->rx_queue, skb);
 		skb_queue_tail(&priv->rx_queue, skb);
 	} else {
 	} else {
+		if (!priv->hw_type)
+			skb_push(skb, sizeof(struct net2280_tx_hdr));
+
+		skb_reset_tail_pointer(skb);
 		skb_trim(skb, 0);
 		skb_trim(skb, 0);
+		if (urb->transfer_buffer != skb_tail_pointer(skb)) {
+			/* this should not happen */
+			WARN_ON(1);
+			urb->transfer_buffer = skb_tail_pointer(skb);
+		}
+
 		skb_queue_tail(&priv->rx_queue, skb);
 		skb_queue_tail(&priv->rx_queue, skb);
 	}
 	}
 
 

+ 4 - 4
drivers/net/wireless/rt2x00/rt2x00queue.h

@@ -173,10 +173,10 @@ struct rxdone_entry_desc {
  *	frame transmission failed due to excessive retries.
  *	frame transmission failed due to excessive retries.
  */
  */
 enum txdone_entry_desc_flags {
 enum txdone_entry_desc_flags {
-	TXDONE_UNKNOWN = 1 << 0,
-	TXDONE_SUCCESS = 1 << 1,
-	TXDONE_FAILURE = 1 << 2,
-	TXDONE_EXCESSIVE_RETRY = 1 << 3,
+	TXDONE_UNKNOWN,
+	TXDONE_SUCCESS,
+	TXDONE_FAILURE,
+	TXDONE_EXCESSIVE_RETRY,
 };
 };
 
 
 /**
 /**

+ 1 - 0
drivers/net/wireless/rt2x00/rt2x00usb.c

@@ -181,6 +181,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
 	 * (Only indirectly by looking at the failed TX counters
 	 * (Only indirectly by looking at the failed TX counters
 	 * in the register).
 	 * in the register).
 	 */
 	 */
+	txdesc.flags = 0;
 	if (!urb->status)
 	if (!urb->status)
 		__set_bit(TXDONE_UNKNOWN, &txdesc.flags);
 		__set_bit(TXDONE_UNKNOWN, &txdesc.flags);
 	else
 	else

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

@@ -40,6 +40,7 @@ static struct usb_device_id rtl8187_table[] __devinitdata = {
 	/* Netgear */
 	/* Netgear */
 	{USB_DEVICE(0x0846, 0x6100), .driver_info = DEVICE_RTL8187},
 	{USB_DEVICE(0x0846, 0x6100), .driver_info = DEVICE_RTL8187},
 	{USB_DEVICE(0x0846, 0x6a00), .driver_info = DEVICE_RTL8187},
 	{USB_DEVICE(0x0846, 0x6a00), .driver_info = DEVICE_RTL8187},
+	{USB_DEVICE(0x0846, 0x4260), .driver_info = DEVICE_RTL8187B},
 	/* HP */
 	/* HP */
 	{USB_DEVICE(0x03f0, 0xca02), .driver_info = DEVICE_RTL8187},
 	{USB_DEVICE(0x03f0, 0xca02), .driver_info = DEVICE_RTL8187},
 	/* Sitecom */
 	/* Sitecom */

+ 8 - 0
drivers/ssb/main.c

@@ -1165,15 +1165,19 @@ EXPORT_SYMBOL(ssb_dma_translation);
 
 
 int ssb_dma_set_mask(struct ssb_device *dev, u64 mask)
 int ssb_dma_set_mask(struct ssb_device *dev, u64 mask)
 {
 {
+#ifdef CONFIG_SSB_PCIHOST
 	int err;
 	int err;
+#endif
 
 
 	switch (dev->bus->bustype) {
 	switch (dev->bus->bustype) {
 	case SSB_BUSTYPE_PCI:
 	case SSB_BUSTYPE_PCI:
+#ifdef CONFIG_SSB_PCIHOST
 		err = pci_set_dma_mask(dev->bus->host_pci, mask);
 		err = pci_set_dma_mask(dev->bus->host_pci, mask);
 		if (err)
 		if (err)
 			return err;
 			return err;
 		err = pci_set_consistent_dma_mask(dev->bus->host_pci, mask);
 		err = pci_set_consistent_dma_mask(dev->bus->host_pci, mask);
 		return err;
 		return err;
+#endif
 	case SSB_BUSTYPE_SSB:
 	case SSB_BUSTYPE_SSB:
 		return dma_set_mask(dev->dev, mask);
 		return dma_set_mask(dev->dev, mask);
 	default:
 	default:
@@ -1188,6 +1192,7 @@ void * ssb_dma_alloc_consistent(struct ssb_device *dev, size_t size,
 {
 {
 	switch (dev->bus->bustype) {
 	switch (dev->bus->bustype) {
 	case SSB_BUSTYPE_PCI:
 	case SSB_BUSTYPE_PCI:
+#ifdef CONFIG_SSB_PCIHOST
 		if (gfp_flags & GFP_DMA) {
 		if (gfp_flags & GFP_DMA) {
 			/* Workaround: The PCI API does not support passing
 			/* Workaround: The PCI API does not support passing
 			 * a GFP flag. */
 			 * a GFP flag. */
@@ -1195,6 +1200,7 @@ void * ssb_dma_alloc_consistent(struct ssb_device *dev, size_t size,
 						  size, dma_handle, gfp_flags);
 						  size, dma_handle, gfp_flags);
 		}
 		}
 		return pci_alloc_consistent(dev->bus->host_pci, size, dma_handle);
 		return pci_alloc_consistent(dev->bus->host_pci, size, dma_handle);
+#endif
 	case SSB_BUSTYPE_SSB:
 	case SSB_BUSTYPE_SSB:
 		return dma_alloc_coherent(dev->dev, size, dma_handle, gfp_flags);
 		return dma_alloc_coherent(dev->dev, size, dma_handle, gfp_flags);
 	default:
 	default:
@@ -1210,6 +1216,7 @@ void ssb_dma_free_consistent(struct ssb_device *dev, size_t size,
 {
 {
 	switch (dev->bus->bustype) {
 	switch (dev->bus->bustype) {
 	case SSB_BUSTYPE_PCI:
 	case SSB_BUSTYPE_PCI:
+#ifdef CONFIG_SSB_PCIHOST
 		if (gfp_flags & GFP_DMA) {
 		if (gfp_flags & GFP_DMA) {
 			/* Workaround: The PCI API does not support passing
 			/* Workaround: The PCI API does not support passing
 			 * a GFP flag. */
 			 * a GFP flag. */
@@ -1220,6 +1227,7 @@ void ssb_dma_free_consistent(struct ssb_device *dev, size_t size,
 		pci_free_consistent(dev->bus->host_pci, size,
 		pci_free_consistent(dev->bus->host_pci, size,
 				    vaddr, dma_handle);
 				    vaddr, dma_handle);
 		return;
 		return;
+#endif
 	case SSB_BUSTYPE_SSB:
 	case SSB_BUSTYPE_SSB:
 		dma_free_coherent(dev->dev, size, vaddr, dma_handle);
 		dma_free_coherent(dev->dev, size, vaddr, dma_handle);
 		return;
 		return;

+ 1 - 0
include/linux/if_tun.h

@@ -45,6 +45,7 @@
 #define TUNGETFEATURES _IOR('T', 207, unsigned int)
 #define TUNGETFEATURES _IOR('T', 207, unsigned int)
 #define TUNSETOFFLOAD  _IOW('T', 208, unsigned int)
 #define TUNSETOFFLOAD  _IOW('T', 208, unsigned int)
 #define TUNSETTXFILTER _IOW('T', 209, unsigned int)
 #define TUNSETTXFILTER _IOW('T', 209, unsigned int)
+#define TUNGETIFF      _IOR('T', 210, unsigned int)
 
 
 /* TUNSETIFF ifr flags */
 /* TUNSETIFF ifr flags */
 #define IFF_TUN		0x0001
 #define IFF_TUN		0x0001

+ 4 - 0
include/linux/skbuff.h

@@ -1452,6 +1452,10 @@ extern int	       skb_copy_datagram_iovec(const struct sk_buff *from,
 extern int	       skb_copy_and_csum_datagram_iovec(struct sk_buff *skb,
 extern int	       skb_copy_and_csum_datagram_iovec(struct sk_buff *skb,
 							int hlen,
 							int hlen,
 							struct iovec *iov);
 							struct iovec *iov);
+extern int	       skb_copy_datagram_from_iovec(struct sk_buff *skb,
+						    int offset,
+						    struct iovec *from,
+						    int len);
 extern void	       skb_free_datagram(struct sock *sk, struct sk_buff *skb);
 extern void	       skb_free_datagram(struct sock *sk, struct sk_buff *skb);
 extern int	       skb_kill_datagram(struct sock *sk, struct sk_buff *skb,
 extern int	       skb_kill_datagram(struct sock *sk, struct sk_buff *skb,
 					 unsigned int flags);
 					 unsigned int flags);

+ 2 - 1
include/net/addrconf.h

@@ -80,7 +80,8 @@ extern struct inet6_ifaddr      *ipv6_get_ifaddr(struct net *net,
 						 struct net_device *dev,
 						 struct net_device *dev,
 						 int strict);
 						 int strict);
 
 
-extern int			ipv6_dev_get_saddr(struct net_device *dev, 
+extern int			ipv6_dev_get_saddr(struct net *net,
+					       struct net_device *dev,
 					       const struct in6_addr *daddr,
 					       const struct in6_addr *daddr,
 					       unsigned int srcprefs,
 					       unsigned int srcprefs,
 					       struct in6_addr *saddr);
 					       struct in6_addr *saddr);

+ 1 - 0
include/net/ip6_route.h

@@ -107,6 +107,7 @@ struct rt6_rtnl_dump_arg
 {
 {
 	struct sk_buff *skb;
 	struct sk_buff *skb;
 	struct netlink_callback *cb;
 	struct netlink_callback *cb;
+	struct net *net;
 };
 };
 
 
 extern int rt6_dump_route(struct rt6_info *rt, void *p_arg);
 extern int rt6_dump_route(struct rt6_info *rt, void *p_arg);

+ 3 - 8
include/net/mac80211.h

@@ -708,10 +708,7 @@ enum ieee80211_tkip_key_type {
  *	rely on the host system for such buffering. This option is used
  *	rely on the host system for such buffering. This option is used
  *	to configure the IEEE 802.11 upper layer to buffer broadcast and
  *	to configure the IEEE 802.11 upper layer to buffer broadcast and
  *	multicast frames when there are power saving stations so that
  *	multicast frames when there are power saving stations so that
- *	the driver can fetch them with ieee80211_get_buffered_bc(). Note
- *	that not setting this flag works properly only when the
- *	%IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE is also not set because
- *	otherwise the stack will not know when the DTIM beacon was sent.
+ *	the driver can fetch them with ieee80211_get_buffered_bc().
  *
  *
  * @IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE:
  * @IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE:
  *	Hardware is not capable of short slot operation on the 2.4 GHz band.
  *	Hardware is not capable of short slot operation on the 2.4 GHz band.
@@ -1099,10 +1096,8 @@ enum ieee80211_ampdu_mlme_action {
  *	See the section "Frame filtering" for more information.
  *	See the section "Frame filtering" for more information.
  *	This callback must be implemented and atomic.
  *	This callback must be implemented and atomic.
  *
  *
- * @set_tim: Set TIM bit. If the hardware/firmware takes care of beacon
- *	generation (that is, %IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE is set)
- *	mac80211 calls this function when a TIM bit must be set or cleared
- *	for a given AID. Must be atomic.
+ * @set_tim: Set TIM bit. mac80211 calls this function when a TIM bit
+ * 	must be set or cleared for a given AID. Must be atomic.
  *
  *
  * @set_key: See the section "Hardware crypto acceleration"
  * @set_key: See the section "Hardware crypto acceleration"
  *	This callback can sleep, and is only called between add_interface
  *	This callback can sleep, and is only called between add_interface

+ 1 - 1
include/net/sch_generic.h

@@ -27,6 +27,7 @@ enum qdisc_state_t
 {
 {
 	__QDISC_STATE_RUNNING,
 	__QDISC_STATE_RUNNING,
 	__QDISC_STATE_SCHED,
 	__QDISC_STATE_SCHED,
+	__QDISC_STATE_DEACTIVATED,
 };
 };
 
 
 struct qdisc_size_table {
 struct qdisc_size_table {
@@ -60,7 +61,6 @@ struct Qdisc
 	struct gnet_stats_basic	bstats;
 	struct gnet_stats_basic	bstats;
 	struct gnet_stats_queue	qstats;
 	struct gnet_stats_queue	qstats;
 	struct gnet_stats_rate_est	rate_est;
 	struct gnet_stats_rate_est	rate_est;
-	struct rcu_head 	q_rcu;
 	int			(*reshape_fail)(struct sk_buff *skb,
 	int			(*reshape_fail)(struct sk_buff *skb,
 					struct Qdisc *q);
 					struct Qdisc *q);
 
 

+ 1 - 1
net/bluetooth/af_bluetooth.c

@@ -456,7 +456,7 @@ static void __exit bt_exit(void)
 subsys_initcall(bt_init);
 subsys_initcall(bt_init);
 module_exit(bt_exit);
 module_exit(bt_exit);
 
 
-MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth Core ver " VERSION);
 MODULE_DESCRIPTION("Bluetooth Core ver " VERSION);
 MODULE_VERSION(VERSION);
 MODULE_VERSION(VERSION);
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");

+ 1 - 1
net/bluetooth/bnep/core.c

@@ -736,7 +736,7 @@ MODULE_PARM_DESC(compress_src, "Compress sources headers");
 module_param(compress_dst, bool, 0644);
 module_param(compress_dst, bool, 0644);
 MODULE_PARM_DESC(compress_dst, "Compress destination headers");
 MODULE_PARM_DESC(compress_dst, "Compress destination headers");
 
 
-MODULE_AUTHOR("David Libault <david.libault@inventel.fr>, Maxim Krasnyansky <maxk@qualcomm.com>");
+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth BNEP ver " VERSION);
 MODULE_DESCRIPTION("Bluetooth BNEP ver " VERSION);
 MODULE_VERSION(VERSION);
 MODULE_VERSION(VERSION);
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");

+ 189 - 187
net/bluetooth/hci_sysfs.c

@@ -3,8 +3,6 @@
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/init.h>
 
 
-#include <linux/platform_device.h>
-
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 #include <net/bluetooth/hci_core.h>
 
 
@@ -12,10 +10,164 @@
 #undef  BT_DBG
 #undef  BT_DBG
 #define BT_DBG(D...)
 #define BT_DBG(D...)
 #endif
 #endif
+
+struct class *bt_class = NULL;
+EXPORT_SYMBOL_GPL(bt_class);
+
 static struct workqueue_struct *btaddconn;
 static struct workqueue_struct *btaddconn;
 static struct workqueue_struct *btdelconn;
 static struct workqueue_struct *btdelconn;
 
 
-static inline char *typetostr(int type)
+static inline char *link_typetostr(int type)
+{
+	switch (type) {
+	case ACL_LINK:
+		return "ACL";
+	case SCO_LINK:
+		return "SCO";
+	case ESCO_LINK:
+		return "eSCO";
+	default:
+		return "UNKNOWN";
+	}
+}
+
+static ssize_t show_link_type(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct hci_conn *conn = dev_get_drvdata(dev);
+	return sprintf(buf, "%s\n", link_typetostr(conn->type));
+}
+
+static ssize_t show_link_address(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct hci_conn *conn = dev_get_drvdata(dev);
+	bdaddr_t bdaddr;
+	baswap(&bdaddr, &conn->dst);
+	return sprintf(buf, "%s\n", batostr(&bdaddr));
+}
+
+static ssize_t show_link_features(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct hci_conn *conn = dev_get_drvdata(dev);
+
+	return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
+				conn->features[0], conn->features[1],
+				conn->features[2], conn->features[3],
+				conn->features[4], conn->features[5],
+				conn->features[6], conn->features[7]);
+}
+
+#define LINK_ATTR(_name,_mode,_show,_store) \
+struct device_attribute link_attr_##_name = __ATTR(_name,_mode,_show,_store)
+
+static LINK_ATTR(type, S_IRUGO, show_link_type, NULL);
+static LINK_ATTR(address, S_IRUGO, show_link_address, NULL);
+static LINK_ATTR(features, S_IRUGO, show_link_features, NULL);
+
+static struct attribute *bt_link_attrs[] = {
+	&link_attr_type.attr,
+	&link_attr_address.attr,
+	&link_attr_features.attr,
+	NULL
+};
+
+static struct attribute_group bt_link_group = {
+	.attrs = bt_link_attrs,
+};
+
+static struct attribute_group *bt_link_groups[] = {
+	&bt_link_group,
+	NULL
+};
+
+static void bt_link_release(struct device *dev)
+{
+	void *data = dev_get_drvdata(dev);
+	kfree(data);
+}
+
+static struct device_type bt_link = {
+	.name    = "link",
+	.groups  = bt_link_groups,
+	.release = bt_link_release,
+};
+
+static void add_conn(struct work_struct *work)
+{
+	struct hci_conn *conn = container_of(work, struct hci_conn, work);
+
+	flush_workqueue(btdelconn);
+
+	if (device_add(&conn->dev) < 0) {
+		BT_ERR("Failed to register connection device");
+		return;
+	}
+}
+
+void hci_conn_add_sysfs(struct hci_conn *conn)
+{
+	struct hci_dev *hdev = conn->hdev;
+
+	BT_DBG("conn %p", conn);
+
+	conn->dev.type = &bt_link;
+	conn->dev.class = bt_class;
+	conn->dev.parent = &hdev->dev;
+
+	snprintf(conn->dev.bus_id, BUS_ID_SIZE, "%s:%d",
+					hdev->name, conn->handle);
+
+	dev_set_drvdata(&conn->dev, conn);
+
+	device_initialize(&conn->dev);
+
+	INIT_WORK(&conn->work, add_conn);
+
+	queue_work(btaddconn, &conn->work);
+}
+
+/*
+ * The rfcomm tty device will possibly retain even when conn
+ * is down, and sysfs doesn't support move zombie device,
+ * so we should move the device before conn device is destroyed.
+ */
+static int __match_tty(struct device *dev, void *data)
+{
+	return !strncmp(dev->bus_id, "rfcomm", 6);
+}
+
+static void del_conn(struct work_struct *work)
+{
+	struct hci_conn *conn = container_of(work, struct hci_conn, work);
+	struct hci_dev *hdev = conn->hdev;
+
+	while (1) {
+		struct device *dev;
+
+		dev = device_find_child(&conn->dev, NULL, __match_tty);
+		if (!dev)
+			break;
+		device_move(dev, NULL);
+		put_device(dev);
+	}
+
+	device_del(&conn->dev);
+	put_device(&conn->dev);
+	hci_dev_put(hdev);
+}
+
+void hci_conn_del_sysfs(struct hci_conn *conn)
+{
+	BT_DBG("conn %p", conn);
+
+	if (!device_is_registered(&conn->dev))
+		return;
+
+	INIT_WORK(&conn->work, del_conn);
+
+	queue_work(btdelconn, &conn->work);
+}
+
+static inline char *host_typetostr(int type)
 {
 {
 	switch (type) {
 	switch (type) {
 	case HCI_VIRTUAL:
 	case HCI_VIRTUAL:
@@ -40,7 +192,7 @@ static inline char *typetostr(int type)
 static ssize_t show_type(struct device *dev, struct device_attribute *attr, char *buf)
 static ssize_t show_type(struct device *dev, struct device_attribute *attr, char *buf)
 {
 {
 	struct hci_dev *hdev = dev_get_drvdata(dev);
 	struct hci_dev *hdev = dev_get_drvdata(dev);
-	return sprintf(buf, "%s\n", typetostr(hdev->type));
+	return sprintf(buf, "%s\n", host_typetostr(hdev->type));
 }
 }
 
 
 static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf)
 static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf)
@@ -221,183 +373,62 @@ static DEVICE_ATTR(sniff_max_interval, S_IRUGO | S_IWUSR,
 static DEVICE_ATTR(sniff_min_interval, S_IRUGO | S_IWUSR,
 static DEVICE_ATTR(sniff_min_interval, S_IRUGO | S_IWUSR,
 				show_sniff_min_interval, store_sniff_min_interval);
 				show_sniff_min_interval, store_sniff_min_interval);
 
 
-static struct device_attribute *bt_attrs[] = {
-	&dev_attr_type,
-	&dev_attr_name,
-	&dev_attr_class,
-	&dev_attr_address,
-	&dev_attr_features,
-	&dev_attr_manufacturer,
-	&dev_attr_hci_version,
-	&dev_attr_hci_revision,
-	&dev_attr_inquiry_cache,
-	&dev_attr_idle_timeout,
-	&dev_attr_sniff_max_interval,
-	&dev_attr_sniff_min_interval,
+static struct attribute *bt_host_attrs[] = {
+	&dev_attr_type.attr,
+	&dev_attr_name.attr,
+	&dev_attr_class.attr,
+	&dev_attr_address.attr,
+	&dev_attr_features.attr,
+	&dev_attr_manufacturer.attr,
+	&dev_attr_hci_version.attr,
+	&dev_attr_hci_revision.attr,
+	&dev_attr_inquiry_cache.attr,
+	&dev_attr_idle_timeout.attr,
+	&dev_attr_sniff_max_interval.attr,
+	&dev_attr_sniff_min_interval.attr,
 	NULL
 	NULL
 };
 };
 
 
-static ssize_t show_conn_type(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct hci_conn *conn = dev_get_drvdata(dev);
-	return sprintf(buf, "%s\n", conn->type == ACL_LINK ? "ACL" : "SCO");
-}
-
-static ssize_t show_conn_address(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct hci_conn *conn = dev_get_drvdata(dev);
-	bdaddr_t bdaddr;
-	baswap(&bdaddr, &conn->dst);
-	return sprintf(buf, "%s\n", batostr(&bdaddr));
-}
-
-static ssize_t show_conn_features(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct hci_conn *conn = dev_get_drvdata(dev);
-
-	return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
-				conn->features[0], conn->features[1],
-				conn->features[2], conn->features[3],
-				conn->features[4], conn->features[5],
-				conn->features[6], conn->features[7]);
-}
-
-#define CONN_ATTR(_name,_mode,_show,_store) \
-struct device_attribute conn_attr_##_name = __ATTR(_name,_mode,_show,_store)
-
-static CONN_ATTR(type, S_IRUGO, show_conn_type, NULL);
-static CONN_ATTR(address, S_IRUGO, show_conn_address, NULL);
-static CONN_ATTR(features, S_IRUGO, show_conn_features, NULL);
-
-static struct device_attribute *conn_attrs[] = {
-	&conn_attr_type,
-	&conn_attr_address,
-	&conn_attr_features,
-	NULL
+static struct attribute_group bt_host_group = {
+	.attrs = bt_host_attrs,
 };
 };
 
 
-struct class *bt_class = NULL;
-EXPORT_SYMBOL_GPL(bt_class);
-
-static struct bus_type bt_bus = {
-	.name	= "bluetooth",
+static struct attribute_group *bt_host_groups[] = {
+	&bt_host_group,
+	NULL
 };
 };
 
 
-static struct platform_device *bt_platform;
-
-static void bt_release(struct device *dev)
+static void bt_host_release(struct device *dev)
 {
 {
 	void *data = dev_get_drvdata(dev);
 	void *data = dev_get_drvdata(dev);
 	kfree(data);
 	kfree(data);
 }
 }
 
 
-static void add_conn(struct work_struct *work)
-{
-	struct hci_conn *conn = container_of(work, struct hci_conn, work);
-	int i;
-
-	flush_workqueue(btdelconn);
-
-	if (device_add(&conn->dev) < 0) {
-		BT_ERR("Failed to register connection device");
-		return;
-	}
-
-	for (i = 0; conn_attrs[i]; i++)
-		if (device_create_file(&conn->dev, conn_attrs[i]) < 0)
-			BT_ERR("Failed to create connection attribute");
-}
-
-void hci_conn_add_sysfs(struct hci_conn *conn)
-{
-	struct hci_dev *hdev = conn->hdev;
-
-	BT_DBG("conn %p", conn);
-
-	conn->dev.bus = &bt_bus;
-	conn->dev.parent = &hdev->dev;
-
-	conn->dev.release = bt_release;
-
-	snprintf(conn->dev.bus_id, BUS_ID_SIZE, "%s:%d",
-					hdev->name, conn->handle);
-
-	dev_set_drvdata(&conn->dev, conn);
-
-	device_initialize(&conn->dev);
-
-	INIT_WORK(&conn->work, add_conn);
-
-	queue_work(btaddconn, &conn->work);
-}
-
-/*
- * The rfcomm tty device will possibly retain even when conn
- * is down, and sysfs doesn't support move zombie device,
- * so we should move the device before conn device is destroyed.
- */
-static int __match_tty(struct device *dev, void *data)
-{
-	return !strncmp(dev->bus_id, "rfcomm", 6);
-}
-
-static void del_conn(struct work_struct *work)
-{
-	struct hci_conn *conn = container_of(work, struct hci_conn, work);
-	struct hci_dev *hdev = conn->hdev;
-
-	while (1) {
-		struct device *dev;
-
-		dev = device_find_child(&conn->dev, NULL, __match_tty);
-		if (!dev)
-			break;
-		device_move(dev, NULL);
-		put_device(dev);
-	}
-
-	device_del(&conn->dev);
-	put_device(&conn->dev);
-	hci_dev_put(hdev);
-}
-
-void hci_conn_del_sysfs(struct hci_conn *conn)
-{
-	BT_DBG("conn %p", conn);
-
-	if (!device_is_registered(&conn->dev))
-		return;
-
-	INIT_WORK(&conn->work, del_conn);
-
-	queue_work(btdelconn, &conn->work);
-}
+static struct device_type bt_host = {
+	.name    = "host",
+	.groups  = bt_host_groups,
+	.release = bt_host_release,
+};
 
 
 int hci_register_sysfs(struct hci_dev *hdev)
 int hci_register_sysfs(struct hci_dev *hdev)
 {
 {
 	struct device *dev = &hdev->dev;
 	struct device *dev = &hdev->dev;
-	unsigned int i;
 	int err;
 	int err;
 
 
 	BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
 	BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
 
 
-	dev->bus = &bt_bus;
+	dev->type = &bt_host;
+	dev->class = bt_class;
 	dev->parent = hdev->parent;
 	dev->parent = hdev->parent;
 
 
 	strlcpy(dev->bus_id, hdev->name, BUS_ID_SIZE);
 	strlcpy(dev->bus_id, hdev->name, BUS_ID_SIZE);
 
 
-	dev->release = bt_release;
-
 	dev_set_drvdata(dev, hdev);
 	dev_set_drvdata(dev, hdev);
 
 
 	err = device_register(dev);
 	err = device_register(dev);
 	if (err < 0)
 	if (err < 0)
 		return err;
 		return err;
 
 
-	for (i = 0; bt_attrs[i]; i++)
-		if (device_create_file(dev, bt_attrs[i]) < 0)
-			BT_ERR("Failed to create device attribute");
-
 	return 0;
 	return 0;
 }
 }
 
 
@@ -410,59 +441,30 @@ void hci_unregister_sysfs(struct hci_dev *hdev)
 
 
 int __init bt_sysfs_init(void)
 int __init bt_sysfs_init(void)
 {
 {
-	int err;
-
 	btaddconn = create_singlethread_workqueue("btaddconn");
 	btaddconn = create_singlethread_workqueue("btaddconn");
-	if (!btaddconn) {
-		err = -ENOMEM;
-		goto out;
-	}
+	if (!btaddconn)
+		return -ENOMEM;
 
 
 	btdelconn = create_singlethread_workqueue("btdelconn");
 	btdelconn = create_singlethread_workqueue("btdelconn");
 	if (!btdelconn) {
 	if (!btdelconn) {
-		err = -ENOMEM;
-		goto out_del;
-	}
-
-	bt_platform = platform_device_register_simple("bluetooth", -1, NULL, 0);
-	if (IS_ERR(bt_platform)) {
-		err = PTR_ERR(bt_platform);
-		goto out_platform;
+		destroy_workqueue(btaddconn);
+		return -ENOMEM;
 	}
 	}
 
 
-	err = bus_register(&bt_bus);
-	if (err < 0)
-		goto out_bus;
-
 	bt_class = class_create(THIS_MODULE, "bluetooth");
 	bt_class = class_create(THIS_MODULE, "bluetooth");
 	if (IS_ERR(bt_class)) {
 	if (IS_ERR(bt_class)) {
-		err = PTR_ERR(bt_class);
-		goto out_class;
+		destroy_workqueue(btdelconn);
+		destroy_workqueue(btaddconn);
+		return PTR_ERR(bt_class);
 	}
 	}
 
 
 	return 0;
 	return 0;
-
-out_class:
-	bus_unregister(&bt_bus);
-out_bus:
-	platform_device_unregister(bt_platform);
-out_platform:
-	destroy_workqueue(btdelconn);
-out_del:
-	destroy_workqueue(btaddconn);
-out:
-	return err;
 }
 }
 
 
 void bt_sysfs_cleanup(void)
 void bt_sysfs_cleanup(void)
 {
 {
 	destroy_workqueue(btaddconn);
 	destroy_workqueue(btaddconn);
-
 	destroy_workqueue(btdelconn);
 	destroy_workqueue(btdelconn);
 
 
 	class_destroy(bt_class);
 	class_destroy(bt_class);
-
-	bus_unregister(&bt_bus);
-
-	platform_device_unregister(bt_platform);
 }
 }

+ 1 - 1
net/bluetooth/l2cap.c

@@ -2516,7 +2516,7 @@ EXPORT_SYMBOL(l2cap_load);
 module_init(l2cap_init);
 module_init(l2cap_init);
 module_exit(l2cap_exit);
 module_exit(l2cap_exit);
 
 
-MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
 MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
 MODULE_VERSION(VERSION);
 MODULE_VERSION(VERSION);
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");

+ 1 - 1
net/bluetooth/rfcomm/core.c

@@ -2115,7 +2115,7 @@ MODULE_PARM_DESC(channel_mtu, "Default MTU for the RFCOMM channel");
 module_param(l2cap_mtu, uint, 0644);
 module_param(l2cap_mtu, uint, 0644);
 MODULE_PARM_DESC(l2cap_mtu, "Default MTU for the L2CAP connection");
 MODULE_PARM_DESC(l2cap_mtu, "Default MTU for the L2CAP connection");
 
 
-MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth RFCOMM ver " VERSION);
 MODULE_DESCRIPTION("Bluetooth RFCOMM ver " VERSION);
 MODULE_VERSION(VERSION);
 MODULE_VERSION(VERSION);
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");

+ 1 - 1
net/bluetooth/sco.c

@@ -1002,7 +1002,7 @@ module_exit(sco_exit);
 module_param(disable_esco, bool, 0644);
 module_param(disable_esco, bool, 0644);
 MODULE_PARM_DESC(disable_esco, "Disable eSCO connection creation");
 MODULE_PARM_DESC(disable_esco, "Disable eSCO connection creation");
 
 
-MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth SCO ver " VERSION);
 MODULE_DESCRIPTION("Bluetooth SCO ver " VERSION);
 MODULE_VERSION(VERSION);
 MODULE_VERSION(VERSION);
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");

+ 10 - 5
net/bridge/br_device.c

@@ -148,11 +148,16 @@ static int br_set_tx_csum(struct net_device *dev, u32 data)
 }
 }
 
 
 static struct ethtool_ops br_ethtool_ops = {
 static struct ethtool_ops br_ethtool_ops = {
-	.get_drvinfo = br_getinfo,
-	.get_link = ethtool_op_get_link,
-	.set_sg = br_set_sg,
-	.set_tx_csum = br_set_tx_csum,
-	.set_tso = br_set_tso,
+	.get_drvinfo    = br_getinfo,
+	.get_link	= ethtool_op_get_link,
+	.get_tx_csum	= ethtool_op_get_tx_csum,
+	.set_tx_csum 	= br_set_tx_csum,
+	.get_sg		= ethtool_op_get_sg,
+	.set_sg		= br_set_sg,
+	.get_tso	= ethtool_op_get_tso,
+	.set_tso	= br_set_tso,
+	.get_ufo	= ethtool_op_get_ufo,
+	.get_flags	= ethtool_op_get_flags,
 };
 };
 
 
 void br_dev_setup(struct net_device *dev)
 void br_dev_setup(struct net_device *dev)

+ 87 - 0
net/core/datagram.c

@@ -339,6 +339,93 @@ fault:
 	return -EFAULT;
 	return -EFAULT;
 }
 }
 
 
+/**
+ *	skb_copy_datagram_from_iovec - Copy a datagram from an iovec.
+ *	@skb: buffer to copy
+ *	@offset: offset in the buffer to start copying to
+ *	@from: io vector to copy to
+ *	@len: amount of data to copy to buffer from iovec
+ *
+ *	Returns 0 or -EFAULT.
+ *	Note: the iovec is modified during the copy.
+ */
+int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
+				 struct iovec *from, int len)
+{
+	int start = skb_headlen(skb);
+	int i, copy = start - offset;
+
+	/* Copy header. */
+	if (copy > 0) {
+		if (copy > len)
+			copy = len;
+		if (memcpy_fromiovec(skb->data + offset, from, copy))
+			goto fault;
+		if ((len -= copy) == 0)
+			return 0;
+		offset += copy;
+	}
+
+	/* Copy paged appendix. Hmm... why does this look so complicated? */
+	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+		int end;
+
+		WARN_ON(start > offset + len);
+
+		end = start + skb_shinfo(skb)->frags[i].size;
+		if ((copy = end - offset) > 0) {
+			int err;
+			u8  *vaddr;
+			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+			struct page *page = frag->page;
+
+			if (copy > len)
+				copy = len;
+			vaddr = kmap(page);
+			err = memcpy_fromiovec(vaddr + frag->page_offset +
+					       offset - start, from, copy);
+			kunmap(page);
+			if (err)
+				goto fault;
+
+			if (!(len -= copy))
+				return 0;
+			offset += copy;
+		}
+		start = end;
+	}
+
+	if (skb_shinfo(skb)->frag_list) {
+		struct sk_buff *list = skb_shinfo(skb)->frag_list;
+
+		for (; list; list = list->next) {
+			int end;
+
+			WARN_ON(start > offset + len);
+
+			end = start + list->len;
+			if ((copy = end - offset) > 0) {
+				if (copy > len)
+					copy = len;
+				if (skb_copy_datagram_from_iovec(list,
+								 offset - start,
+								 from, copy))
+					goto fault;
+				if ((len -= copy) == 0)
+					return 0;
+				offset += copy;
+			}
+			start = end;
+		}
+	}
+	if (!len)
+		return 0;
+
+fault:
+	return -EFAULT;
+}
+EXPORT_SYMBOL(skb_copy_datagram_from_iovec);
+
 static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
 static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
 				      u8 __user *to, int len,
 				      u8 __user *to, int len,
 				      __wsum *csump)
 				      __wsum *csump)

+ 30 - 19
net/core/dev.c

@@ -1339,19 +1339,23 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
 }
 }
 
 
 
 
-void __netif_schedule(struct Qdisc *q)
+static inline void __netif_reschedule(struct Qdisc *q)
 {
 {
-	if (!test_and_set_bit(__QDISC_STATE_SCHED, &q->state)) {
-		struct softnet_data *sd;
-		unsigned long flags;
+	struct softnet_data *sd;
+	unsigned long flags;
 
 
-		local_irq_save(flags);
-		sd = &__get_cpu_var(softnet_data);
-		q->next_sched = sd->output_queue;
-		sd->output_queue = q;
-		raise_softirq_irqoff(NET_TX_SOFTIRQ);
-		local_irq_restore(flags);
-	}
+	local_irq_save(flags);
+	sd = &__get_cpu_var(softnet_data);
+	q->next_sched = sd->output_queue;
+	sd->output_queue = q;
+	raise_softirq_irqoff(NET_TX_SOFTIRQ);
+	local_irq_restore(flags);
+}
+
+void __netif_schedule(struct Qdisc *q)
+{
+	if (!test_and_set_bit(__QDISC_STATE_SCHED, &q->state))
+		__netif_reschedule(q);
 }
 }
 EXPORT_SYMBOL(__netif_schedule);
 EXPORT_SYMBOL(__netif_schedule);
 
 
@@ -1800,9 +1804,13 @@ gso:
 
 
 		spin_lock(root_lock);
 		spin_lock(root_lock);
 
 
-		rc = qdisc_enqueue_root(skb, q);
-		qdisc_run(q);
-
+		if (unlikely(test_bit(__QDISC_STATE_DEACTIVATED, &q->state))) {
+			kfree_skb(skb);
+			rc = NET_XMIT_DROP;
+		} else {
+			rc = qdisc_enqueue_root(skb, q);
+			qdisc_run(q);
+		}
 		spin_unlock(root_lock);
 		spin_unlock(root_lock);
 
 
 		goto out;
 		goto out;
@@ -1974,15 +1982,17 @@ static void net_tx_action(struct softirq_action *h)
 
 
 			head = head->next_sched;
 			head = head->next_sched;
 
 
-			smp_mb__before_clear_bit();
-			clear_bit(__QDISC_STATE_SCHED, &q->state);
-
 			root_lock = qdisc_lock(q);
 			root_lock = qdisc_lock(q);
 			if (spin_trylock(root_lock)) {
 			if (spin_trylock(root_lock)) {
+				smp_mb__before_clear_bit();
+				clear_bit(__QDISC_STATE_SCHED,
+					  &q->state);
 				qdisc_run(q);
 				qdisc_run(q);
 				spin_unlock(root_lock);
 				spin_unlock(root_lock);
 			} else {
 			} else {
-				__netif_schedule(q);
+				if (!test_bit(__QDISC_STATE_DEACTIVATED,
+					      &q->state))
+					__netif_reschedule(q);
 			}
 			}
 		}
 		}
 	}
 	}
@@ -2084,7 +2094,8 @@ static int ing_filter(struct sk_buff *skb)
 	q = rxq->qdisc;
 	q = rxq->qdisc;
 	if (q != &noop_qdisc) {
 	if (q != &noop_qdisc) {
 		spin_lock(qdisc_lock(q));
 		spin_lock(qdisc_lock(q));
-		result = qdisc_enqueue_root(skb, q);
+		if (likely(!test_bit(__QDISC_STATE_DEACTIVATED, &q->state)))
+			result = qdisc_enqueue_root(skb, q);
 		spin_unlock(qdisc_lock(q));
 		spin_unlock(qdisc_lock(q));
 	}
 	}
 
 

+ 4 - 5
net/core/gen_estimator.c

@@ -99,7 +99,7 @@ struct gen_estimator_head
 
 
 static struct gen_estimator_head elist[EST_MAX_INTERVAL+1];
 static struct gen_estimator_head elist[EST_MAX_INTERVAL+1];
 
 
-/* Protects against NULL dereference and RCU write-side */
+/* Protects against NULL dereference */
 static DEFINE_RWLOCK(est_lock);
 static DEFINE_RWLOCK(est_lock);
 
 
 static void est_timer(unsigned long arg)
 static void est_timer(unsigned long arg)
@@ -185,7 +185,6 @@ int gen_new_estimator(struct gnet_stats_basic *bstats,
 	est->last_packets = bstats->packets;
 	est->last_packets = bstats->packets;
 	est->avpps = rate_est->pps<<10;
 	est->avpps = rate_est->pps<<10;
 
 
-	write_lock_bh(&est_lock);
 	if (!elist[idx].timer.function) {
 	if (!elist[idx].timer.function) {
 		INIT_LIST_HEAD(&elist[idx].list);
 		INIT_LIST_HEAD(&elist[idx].list);
 		setup_timer(&elist[idx].timer, est_timer, idx);
 		setup_timer(&elist[idx].timer, est_timer, idx);
@@ -195,7 +194,6 @@ int gen_new_estimator(struct gnet_stats_basic *bstats,
 		mod_timer(&elist[idx].timer, jiffies + ((HZ/4) << idx));
 		mod_timer(&elist[idx].timer, jiffies + ((HZ/4) << idx));
 
 
 	list_add_rcu(&est->list, &elist[idx].list);
 	list_add_rcu(&est->list, &elist[idx].list);
-	write_unlock_bh(&est_lock);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -214,6 +212,7 @@ static void __gen_kill_estimator(struct rcu_head *head)
  * Removes the rate estimator specified by &bstats and &rate_est
  * Removes the rate estimator specified by &bstats and &rate_est
  * and deletes the timer.
  * and deletes the timer.
  *
  *
+ * NOTE: Called under rtnl_mutex
  */
  */
 void gen_kill_estimator(struct gnet_stats_basic *bstats,
 void gen_kill_estimator(struct gnet_stats_basic *bstats,
 	struct gnet_stats_rate_est *rate_est)
 	struct gnet_stats_rate_est *rate_est)
@@ -227,17 +226,17 @@ void gen_kill_estimator(struct gnet_stats_basic *bstats,
 		if (!elist[idx].timer.function)
 		if (!elist[idx].timer.function)
 			continue;
 			continue;
 
 
-		write_lock_bh(&est_lock);
 		list_for_each_entry_safe(e, n, &elist[idx].list, list) {
 		list_for_each_entry_safe(e, n, &elist[idx].list, list) {
 			if (e->rate_est != rate_est || e->bstats != bstats)
 			if (e->rate_est != rate_est || e->bstats != bstats)
 				continue;
 				continue;
 
 
+			write_lock_bh(&est_lock);
 			e->bstats = NULL;
 			e->bstats = NULL;
+			write_unlock_bh(&est_lock);
 
 
 			list_del_rcu(&e->list);
 			list_del_rcu(&e->list);
 			call_rcu(&e->e_rcu, __gen_kill_estimator);
 			call_rcu(&e->e_rcu, __gen_kill_estimator);
 		}
 		}
-		write_unlock_bh(&est_lock);
 	}
 	}
 }
 }
 
 

+ 2 - 10
net/core/skbuff.c

@@ -2256,14 +2256,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features)
 			segs = nskb;
 			segs = nskb;
 		tail = nskb;
 		tail = nskb;
 
 
-		nskb->dev = skb->dev;
-		skb_copy_queue_mapping(nskb, skb);
-		nskb->priority = skb->priority;
-		nskb->protocol = skb->protocol;
-		nskb->vlan_tci = skb->vlan_tci;
-		nskb->dst = dst_clone(skb->dst);
-		memcpy(nskb->cb, skb->cb, sizeof(skb->cb));
-		nskb->pkt_type = skb->pkt_type;
+		__copy_skb_header(nskb, skb);
 		nskb->mac_len = skb->mac_len;
 		nskb->mac_len = skb->mac_len;
 
 
 		skb_reserve(nskb, headroom);
 		skb_reserve(nskb, headroom);
@@ -2274,6 +2267,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features)
 		skb_copy_from_linear_data(skb, skb_put(nskb, doffset),
 		skb_copy_from_linear_data(skb, skb_put(nskb, doffset),
 					  doffset);
 					  doffset);
 		if (!sg) {
 		if (!sg) {
+			nskb->ip_summed = CHECKSUM_NONE;
 			nskb->csum = skb_copy_and_csum_bits(skb, offset,
 			nskb->csum = skb_copy_and_csum_bits(skb, offset,
 							    skb_put(nskb, len),
 							    skb_put(nskb, len),
 							    len, 0);
 							    len, 0);
@@ -2283,8 +2277,6 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features)
 		frag = skb_shinfo(nskb)->frags;
 		frag = skb_shinfo(nskb)->frags;
 		k = 0;
 		k = 0;
 
 
-		nskb->ip_summed = CHECKSUM_PARTIAL;
-		nskb->csum = skb->csum;
 		skb_copy_from_linear_data_offset(skb, offset,
 		skb_copy_from_linear_data_offset(skb, offset,
 						 skb_put(nskb, hsize), hsize);
 						 skb_put(nskb, hsize), hsize);
 
 

+ 6 - 6
net/dccp/input.c

@@ -411,12 +411,6 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
 		struct dccp_sock *dp = dccp_sk(sk);
 		struct dccp_sock *dp = dccp_sk(sk);
 		long tstamp = dccp_timestamp();
 		long tstamp = dccp_timestamp();
 
 
-		/* Stop the REQUEST timer */
-		inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS);
-		WARN_ON(sk->sk_send_head == NULL);
-		__kfree_skb(sk->sk_send_head);
-		sk->sk_send_head = NULL;
-
 		if (!between48(DCCP_SKB_CB(skb)->dccpd_ack_seq,
 		if (!between48(DCCP_SKB_CB(skb)->dccpd_ack_seq,
 			       dp->dccps_awl, dp->dccps_awh)) {
 			       dp->dccps_awl, dp->dccps_awh)) {
 			dccp_pr_debug("invalid ackno: S.AWL=%llu, "
 			dccp_pr_debug("invalid ackno: S.AWL=%llu, "
@@ -441,6 +435,12 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
 				    DCCP_ACKVEC_STATE_RECEIVED))
 				    DCCP_ACKVEC_STATE_RECEIVED))
 			goto out_invalid_packet; /* FIXME: change error code */
 			goto out_invalid_packet; /* FIXME: change error code */
 
 
+		/* Stop the REQUEST timer */
+		inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS);
+		WARN_ON(sk->sk_send_head == NULL);
+		kfree_skb(sk->sk_send_head);
+		sk->sk_send_head = NULL;
+
 		dp->dccps_isr = DCCP_SKB_CB(skb)->dccpd_seq;
 		dp->dccps_isr = DCCP_SKB_CB(skb)->dccpd_seq;
 		dccp_update_gsr(sk, dp->dccps_isr);
 		dccp_update_gsr(sk, dp->dccps_isr);
 		/*
 		/*

+ 1 - 1
net/ipv4/netfilter/ipt_addrtype.c

@@ -70,7 +70,7 @@ addrtype_mt_v1(const struct sk_buff *skb, const struct net_device *in,
 		       (info->flags & IPT_ADDRTYPE_INVERT_SOURCE);
 		       (info->flags & IPT_ADDRTYPE_INVERT_SOURCE);
 	if (ret && info->dest)
 	if (ret && info->dest)
 		ret &= match_type(dev, iph->daddr, info->dest) ^
 		ret &= match_type(dev, iph->daddr, info->dest) ^
-		       (info->flags & IPT_ADDRTYPE_INVERT_DEST);
+		       !!(info->flags & IPT_ADDRTYPE_INVERT_DEST);
 	return ret;
 	return ret;
 }
 }
 
 

+ 6 - 2
net/ipv4/netfilter/nf_nat_proto_common.c

@@ -73,9 +73,13 @@ bool nf_nat_proto_unique_tuple(struct nf_conntrack_tuple *tuple,
 		range_size = ntohs(range->max.all) - min + 1;
 		range_size = ntohs(range->max.all) - min + 1;
 	}
 	}
 
 
-	off = *rover;
 	if (range->flags & IP_NAT_RANGE_PROTO_RANDOM)
 	if (range->flags & IP_NAT_RANGE_PROTO_RANDOM)
-		off = net_random();
+		off = secure_ipv4_port_ephemeral(tuple->src.u3.ip, tuple->dst.u3.ip,
+						 maniptype == IP_NAT_MANIP_SRC
+						 ? tuple->dst.u.all
+						 : tuple->src.u.all);
+	else
+		off = *rover;
 
 
 	for (i = 0; i < range_size; i++, off++) {
 	for (i = 0; i < range_size; i++, off++) {
 		*portptr = htons(min + off % range_size);
 		*portptr = htons(min + off % range_size);

+ 70 - 6
net/ipv4/route.c

@@ -2914,6 +2914,68 @@ static int ipv4_sysctl_rtcache_flush_strategy(ctl_table *table,
 	return 0;
 	return 0;
 }
 }
 
 
+static void rt_secret_reschedule(int old)
+{
+	struct net *net;
+	int new = ip_rt_secret_interval;
+	int diff = new - old;
+
+	if (!diff)
+		return;
+
+	rtnl_lock();
+	for_each_net(net) {
+		int deleted = del_timer_sync(&net->ipv4.rt_secret_timer);
+
+		if (!new)
+			continue;
+
+		if (deleted) {
+			long time = net->ipv4.rt_secret_timer.expires - jiffies;
+
+			if (time <= 0 || (time += diff) <= 0)
+				time = 0;
+
+			net->ipv4.rt_secret_timer.expires = time;
+		} else
+			net->ipv4.rt_secret_timer.expires = new;
+
+		net->ipv4.rt_secret_timer.expires += jiffies;
+		add_timer(&net->ipv4.rt_secret_timer);
+	}
+	rtnl_unlock();
+}
+
+static int ipv4_sysctl_rt_secret_interval(ctl_table *ctl, int write,
+					  struct file *filp,
+					  void __user *buffer, size_t *lenp,
+					  loff_t *ppos)
+{
+	int old = ip_rt_secret_interval;
+	int ret = proc_dointvec_jiffies(ctl, write, filp, buffer, lenp, ppos);
+
+	rt_secret_reschedule(old);
+
+	return ret;
+}
+
+static int ipv4_sysctl_rt_secret_interval_strategy(ctl_table *table,
+						   int __user *name,
+						   int nlen,
+						   void __user *oldval,
+						   size_t __user *oldlenp,
+						   void __user *newval,
+						   size_t newlen)
+{
+	int old = ip_rt_secret_interval;
+	int ret = sysctl_jiffies(table, name, nlen, oldval, oldlenp, newval,
+				 newlen);
+
+	rt_secret_reschedule(old);
+
+	return ret;
+}
+
 static ctl_table ipv4_route_table[] = {
 static ctl_table ipv4_route_table[] = {
 	{
 	{
 		.ctl_name	= NET_IPV4_ROUTE_GC_THRESH,
 		.ctl_name	= NET_IPV4_ROUTE_GC_THRESH,
@@ -3048,8 +3110,8 @@ static ctl_table ipv4_route_table[] = {
 		.data		= &ip_rt_secret_interval,
 		.data		= &ip_rt_secret_interval,
 		.maxlen		= sizeof(int),
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
 		.mode		= 0644,
-		.proc_handler	= &proc_dointvec_jiffies,
-		.strategy	= &sysctl_jiffies,
+		.proc_handler	= &ipv4_sysctl_rt_secret_interval,
+		.strategy	= &ipv4_sysctl_rt_secret_interval_strategy,
 	},
 	},
 	{ .ctl_name = 0 }
 	{ .ctl_name = 0 }
 };
 };
@@ -3126,10 +3188,12 @@ static __net_init int rt_secret_timer_init(struct net *net)
 	net->ipv4.rt_secret_timer.data = (unsigned long)net;
 	net->ipv4.rt_secret_timer.data = (unsigned long)net;
 	init_timer_deferrable(&net->ipv4.rt_secret_timer);
 	init_timer_deferrable(&net->ipv4.rt_secret_timer);
 
 
-	net->ipv4.rt_secret_timer.expires =
-		jiffies + net_random() % ip_rt_secret_interval +
-		ip_rt_secret_interval;
-	add_timer(&net->ipv4.rt_secret_timer);
+	if (ip_rt_secret_interval) {
+		net->ipv4.rt_secret_timer.expires =
+			jiffies + net_random() % ip_rt_secret_interval +
+			ip_rt_secret_interval;
+		add_timer(&net->ipv4.rt_secret_timer);
+	}
 	return 0;
 	return 0;
 }
 }
 
 

+ 1 - 2
net/ipv6/addrconf.c

@@ -1106,13 +1106,12 @@ out:
 	return ret;
 	return ret;
 }
 }
 
 
-int ipv6_dev_get_saddr(struct net_device *dst_dev,
+int ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev,
 		       const struct in6_addr *daddr, unsigned int prefs,
 		       const struct in6_addr *daddr, unsigned int prefs,
 		       struct in6_addr *saddr)
 		       struct in6_addr *saddr)
 {
 {
 	struct ipv6_saddr_score scores[2],
 	struct ipv6_saddr_score scores[2],
 				*score = &scores[0], *hiscore = &scores[1];
 				*score = &scores[0], *hiscore = &scores[1];
-	struct net *net = dev_net(dst_dev);
 	struct ipv6_saddr_dst dst;
 	struct ipv6_saddr_dst dst;
 	struct net_device *dev;
 	struct net_device *dev;
 	int dst_type;
 	int dst_type;

+ 2 - 1
net/ipv6/fib6_rules.c

@@ -93,7 +93,8 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
 			if (flags & RT6_LOOKUP_F_SRCPREF_COA)
 			if (flags & RT6_LOOKUP_F_SRCPREF_COA)
 				srcprefs |= IPV6_PREFER_SRC_COA;
 				srcprefs |= IPV6_PREFER_SRC_COA;
 
 
-			if (ipv6_dev_get_saddr(ip6_dst_idev(&rt->u.dst)->dev,
+			if (ipv6_dev_get_saddr(net,
+					       ip6_dst_idev(&rt->u.dst)->dev,
 					       &flp->fl6_dst, srcprefs,
 					       &flp->fl6_dst, srcprefs,
 					       &saddr))
 					       &saddr))
 				goto again;
 				goto again;

+ 1 - 0
net/ipv6/ip6_fib.c

@@ -378,6 +378,7 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
 
 
 	arg.skb = skb;
 	arg.skb = skb;
 	arg.cb = cb;
 	arg.cb = cb;
+	arg.net = net;
 	w->args = &arg;
 	w->args = &arg;
 
 
 	for (h = s_h; h < FIB_TABLE_HASHSZ; h++, s_e = 0) {
 	for (h = s_h; h < FIB_TABLE_HASHSZ; h++, s_e = 0) {

+ 1 - 1
net/ipv6/ip6_output.c

@@ -934,7 +934,7 @@ static int ip6_dst_lookup_tail(struct sock *sk,
 		goto out_err_release;
 		goto out_err_release;
 
 
 	if (ipv6_addr_any(&fl->fl6_src)) {
 	if (ipv6_addr_any(&fl->fl6_src)) {
-		err = ipv6_dev_get_saddr(ip6_dst_idev(*dst)->dev,
+		err = ipv6_dev_get_saddr(net, ip6_dst_idev(*dst)->dev,
 					 &fl->fl6_dst,
 					 &fl->fl6_dst,
 					 sk ? inet6_sk(sk)->srcprefs : 0,
 					 sk ? inet6_sk(sk)->srcprefs : 0,
 					 &fl->fl6_src);
 					 &fl->fl6_src);

+ 2 - 2
net/ipv6/ipv6_sockglue.c

@@ -911,7 +911,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
 		} else {
 		} else {
 			if (np->rxopt.bits.rxinfo) {
 			if (np->rxopt.bits.rxinfo) {
 				struct in6_pktinfo src_info;
 				struct in6_pktinfo src_info;
-				src_info.ipi6_ifindex = np->mcast_oif;
+				src_info.ipi6_ifindex = np->mcast_oif ? np->mcast_oif : sk->sk_bound_dev_if;
 				ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr);
 				ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr);
 				put_cmsg(&msg, SOL_IPV6, IPV6_PKTINFO, sizeof(src_info), &src_info);
 				put_cmsg(&msg, SOL_IPV6, IPV6_PKTINFO, sizeof(src_info), &src_info);
 			}
 			}
@@ -921,7 +921,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
 			}
 			}
 			if (np->rxopt.bits.rxoinfo) {
 			if (np->rxopt.bits.rxoinfo) {
 				struct in6_pktinfo src_info;
 				struct in6_pktinfo src_info;
-				src_info.ipi6_ifindex = np->mcast_oif;
+				src_info.ipi6_ifindex = np->mcast_oif ? np->mcast_oif : sk->sk_bound_dev_if;
 				ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr);
 				ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr);
 				put_cmsg(&msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info);
 				put_cmsg(&msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info);
 			}
 			}

Неке датотеке нису приказане због велике количине промена