Merge branch '1GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue

Jeff Kirsher says:

====================
1GbE Intel Wired LAN Driver Updates 2015-12-14

This series contains updates to e1000e and igb.

Alex Duyck changes e1000_up() to void since it always returned 0, also
by making it void, we can drop some code since we no longer have to worry
about non-zero return values.

Aaron Sierra removes GS40G specific defines and functions since the i210
internal PHY can be accessed with the access functions shared by 82580,
i350 and i354 devices.  Also removes the code to add the PHY address into
the PCDL register address, since there is no real reason to do so.

Joe updates the cable length function reports all four pairs true min, max
and average cable length for i210.  Also updated ethtool to use enum-based
labels instead of hard coded values.

Benjamin Poirier cleans up code that is never reachable since MSI-X
interrupts are not shared in e1000e.  Also removes the ICR read in the
other interrupt handler, since the information is not needed and IMS is
configured such that the only link status change can trigger the other
interrupt handler.  Fixed in MSI-X mode, there is no handler for the LSC
interrupt so there is no point in writing that to ICS now that we always
assume other interrupts are caused by LSC.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/Documentation/devicetree/bindings/net/ieee802154/adf7242.txt b/Documentation/devicetree/bindings/net/ieee802154/adf7242.txt
new file mode 100644
index 0000000..dea5124
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/ieee802154/adf7242.txt
@@ -0,0 +1,18 @@
+* ADF7242 IEEE 802.15.4 *
+
+Required properties:
+  - compatible:		should be "adi,adf7242"
+  - spi-max-frequency:	maximal bus speed (12.5 MHz)
+  - reg:		the chipselect index
+  - interrupts:		the interrupt generated by the device via pin IRQ1.
+			IRQ_TYPE_LEVEL_HIGH (4) or IRQ_TYPE_EDGE_FALLING (1)
+
+Example:
+
+	adf7242@0 {
+		compatible = "adi,adf7242";
+		spi-max-frequency = <10000000>;
+		reg = <0>;
+		interrupts = <98 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-parent = <&gpio3>;
+	};
diff --git a/Documentation/devicetree/bindings/net/macb.txt b/Documentation/devicetree/bindings/net/macb.txt
index b5d7976..4a7fb6c 100644
--- a/Documentation/devicetree/bindings/net/macb.txt
+++ b/Documentation/devicetree/bindings/net/macb.txt
@@ -19,6 +19,9 @@
 	Optional elements: 'tx_clk'
 - clocks: Phandles to input clocks.
 
+Optional properties:
+- phy-reset-gpios : Should specify the gpio for phy reset
+
 Examples:
 
 	macb0: ethernet@fffc4000 {
diff --git a/MAINTAINERS b/MAINTAINERS
index 8eba565..04e8d18 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -371,6 +371,15 @@
 M:	Jiri Kosina <jikos@kernel.org>
 S:	Maintained
 
+ADF7242 IEEE 802.15.4 RADIO DRIVER
+M:	Michael Hennerich <michael.hennerich@analog.com>
+W:	https://wiki.analog.com/ADF7242
+W:	http://ez.analog.com/community/linux-device-drivers
+L:	linux-wpan@vger.kernel.org
+S:	Supported
+F:	drivers/net/ieee802154/adf7242.c
+F:	Documentation/devicetree/bindings/net/ieee802154/adf7242.txt
+
 ADM1025 HARDWARE MONITOR DRIVER
 M:	Jean Delvare <jdelvare@suse.com>
 L:	lm-sensors@lm-sensors.org
@@ -9125,7 +9134,7 @@
 F:	block/partitions/ibm.c
 
 S390 NETWORK DRIVERS
-M:	Ursula Braun <ursula.braun@de.ibm.com>
+M:	Ursula Braun <ubraun@linux.vnet.ibm.com>
 L:	linux-s390@vger.kernel.org
 W:	http://www.ibm.com/developerworks/linux/linux390/
 S:	Supported
@@ -9155,7 +9164,7 @@
 F:	drivers/s390/scsi/zfcp_*
 
 S390 IUCV NETWORK LAYER
-M:	Ursula Braun <ursula.braun@de.ibm.com>
+M:	Ursula Braun <ubraun@linux.vnet.ibm.com>
 L:	linux-s390@vger.kernel.org
 W:	http://www.ibm.com/developerworks/linux/linux390/
 S:	Supported
diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
index 1f13e61..fce1548 100644
--- a/drivers/bluetooth/btintel.c
+++ b/drivers/bluetooth/btintel.c
@@ -73,6 +73,48 @@
 }
 EXPORT_SYMBOL_GPL(btintel_check_bdaddr);
 
+int btintel_enter_mfg(struct hci_dev *hdev)
+{
+	const u8 param[] = { 0x01, 0x00 };
+	struct sk_buff *skb;
+
+	skb = __hci_cmd_sync(hdev, 0xfc11, 2, param, HCI_CMD_TIMEOUT);
+	if (IS_ERR(skb)) {
+		bt_dev_err(hdev, "Entering manufacturer mode failed (%ld)",
+			   PTR_ERR(skb));
+		return PTR_ERR(skb);
+	}
+	kfree_skb(skb);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(btintel_enter_mfg);
+
+int btintel_exit_mfg(struct hci_dev *hdev, bool reset, bool patched)
+{
+	u8 param[] = { 0x00, 0x00 };
+	struct sk_buff *skb;
+
+	/* The 2nd command parameter specifies the manufacturing exit method:
+	 * 0x00: Just disable the manufacturing mode (0x00).
+	 * 0x01: Disable manufacturing mode and reset with patches deactivated.
+	 * 0x02: Disable manufacturing mode and reset with patches activated.
+	 */
+	if (reset)
+		param[1] |= patched ? 0x02 : 0x01;
+
+	skb = __hci_cmd_sync(hdev, 0xfc11, 2, param, HCI_CMD_TIMEOUT);
+	if (IS_ERR(skb)) {
+		bt_dev_err(hdev, "Exiting manufacturer mode failed (%ld)",
+			   PTR_ERR(skb));
+		return PTR_ERR(skb);
+	}
+	kfree_skb(skb);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(btintel_exit_mfg);
+
 int btintel_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
 {
 	struct sk_buff *skb;
@@ -126,37 +168,19 @@
 
 int btintel_set_diag_mfg(struct hci_dev *hdev, bool enable)
 {
-	struct sk_buff *skb;
-	u8 param[2];
-	int err;
+	int err, ret;
 
-	param[0] = 0x01;
-	param[1] = 0x00;
+	err = btintel_enter_mfg(hdev);
+	if (err)
+		return err;
 
-	skb = __hci_cmd_sync(hdev, 0xfc11, 2, param, HCI_INIT_TIMEOUT);
-	if (IS_ERR(skb)) {
-		err = PTR_ERR(skb);
-		BT_ERR("%s: Entering Intel manufacturer mode failed (%d)",
-		       hdev->name, err);
-		return PTR_ERR(skb);
-	}
-	kfree_skb(skb);
+	ret = btintel_set_diag(hdev, enable);
 
-	err = btintel_set_diag(hdev, enable);
+	err = btintel_exit_mfg(hdev, false, false);
+	if (err)
+		return err;
 
-	param[0] = 0x00;
-	param[1] = 0x00;
-
-	skb = __hci_cmd_sync(hdev, 0xfc11, 2, param, HCI_INIT_TIMEOUT);
-	if (IS_ERR(skb)) {
-		err = PTR_ERR(skb);
-		BT_ERR("%s: Leaving Intel manufacturer mode failed (%d)",
-		       hdev->name, err);
-		return PTR_ERR(skb);
-	}
-	kfree_skb(skb);
-
-	return err;
+	return ret;
 }
 EXPORT_SYMBOL_GPL(btintel_set_diag_mfg);
 
@@ -309,40 +333,47 @@
 
 int btintel_set_event_mask_mfg(struct hci_dev *hdev, bool debug)
 {
-	struct sk_buff *skb;
-	u8 param[2];
-	int err;
+	int err, ret;
 
-	param[0] = 0x01;
-	param[1] = 0x00;
+	err = btintel_enter_mfg(hdev);
+	if (err)
+		return err;
 
-	skb = __hci_cmd_sync(hdev, 0xfc11, 2, param, HCI_INIT_TIMEOUT);
-	if (IS_ERR(skb)) {
-		err = PTR_ERR(skb);
-		BT_ERR("%s: Entering Intel manufacturer mode failed (%d)",
-		       hdev->name, err);
-		return PTR_ERR(skb);
-	}
-	kfree_skb(skb);
+	ret = btintel_set_event_mask(hdev, debug);
 
-	err = btintel_set_event_mask(hdev, debug);
+	err = btintel_exit_mfg(hdev, false, false);
+	if (err)
+		return err;
 
-	param[0] = 0x00;
-	param[1] = 0x00;
-
-	skb = __hci_cmd_sync(hdev, 0xfc11, 2, param, HCI_INIT_TIMEOUT);
-	if (IS_ERR(skb)) {
-		err = PTR_ERR(skb);
-		BT_ERR("%s: Leaving Intel manufacturer mode failed (%d)",
-		       hdev->name, err);
-		return PTR_ERR(skb);
-	}
-	kfree_skb(skb);
-
-	return err;
+	return ret;
 }
 EXPORT_SYMBOL_GPL(btintel_set_event_mask_mfg);
 
+int btintel_read_version(struct hci_dev *hdev, struct intel_version *ver)
+{
+	struct sk_buff *skb;
+
+	skb = __hci_cmd_sync(hdev, 0xfc05, 0, NULL, HCI_CMD_TIMEOUT);
+	if (IS_ERR(skb)) {
+		bt_dev_err(hdev, "Reading Intel version information failed (%ld)",
+			   PTR_ERR(skb));
+		return PTR_ERR(skb);
+	}
+
+	if (skb->len != sizeof(*ver)) {
+		bt_dev_err(hdev, "Intel version event size mismatch");
+		kfree_skb(skb);
+		return -EILSEQ;
+	}
+
+	memcpy(ver, skb->data, sizeof(*ver));
+
+	kfree_skb(skb);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(btintel_read_version);
+
 /* ------- REGMAP IBT SUPPORT ------- */
 
 #define IBT_REG_MODE_8BIT  0x00
diff --git a/drivers/bluetooth/btintel.h b/drivers/bluetooth/btintel.h
index 07e58e0..1e8955a 100644
--- a/drivers/bluetooth/btintel.h
+++ b/drivers/bluetooth/btintel.h
@@ -72,6 +72,8 @@
 #if IS_ENABLED(CONFIG_BT_INTEL)
 
 int btintel_check_bdaddr(struct hci_dev *hdev);
+int btintel_enter_mfg(struct hci_dev *hdev);
+int btintel_exit_mfg(struct hci_dev *hdev, bool reset, bool patched);
 int btintel_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
 int btintel_set_diag(struct hci_dev *hdev, bool enable);
 int btintel_set_diag_mfg(struct hci_dev *hdev, bool enable);
@@ -83,6 +85,7 @@
 int btintel_load_ddc_config(struct hci_dev *hdev, const char *ddc_name);
 int btintel_set_event_mask(struct hci_dev *hdev, bool debug);
 int btintel_set_event_mask_mfg(struct hci_dev *hdev, bool debug);
+int btintel_read_version(struct hci_dev *hdev, struct intel_version *ver);
 
 struct regmap *btintel_regmap_init(struct hci_dev *hdev, u16 opcode_read,
 				   u16 opcode_write);
@@ -94,6 +97,16 @@
 	return -EOPNOTSUPP;
 }
 
+static inline int btintel_enter_mfg(struct hci_dev *hdev)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int btintel_exit_mfg(struct hci_dev *hdev, bool reset, bool patched)
+{
+	return -EOPNOTSUPP;
+}
+
 static inline int btintel_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
 {
 	return -EOPNOTSUPP;
@@ -140,6 +153,12 @@
 	return -EOPNOTSUPP;
 }
 
+static inline int btintel_read_version(struct hci_dev *hdev,
+				       struct intel_version *ver)
+{
+	return -EOPNOTSUPP;
+}
+
 static inline struct regmap *btintel_regmap_init(struct hci_dev *hdev,
 						 u16 opcode_read,
 						 u16 opcode_write)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 8063534..a191e31 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -153,6 +153,10 @@
 	{ USB_VENDOR_AND_INTERFACE_INFO(0x13d3, 0xff, 0x01, 0x01),
 	  .driver_info = BTUSB_BCM_PATCHRAM },
 
+	/* Toshiba Corp - Broadcom based */
+	{ USB_VENDOR_AND_INTERFACE_INFO(0x0930, 0xff, 0x01, 0x01),
+	  .driver_info = BTUSB_BCM_PATCHRAM },
+
 	/* Intel Bluetooth USB Bootloader (RAM module) */
 	{ USB_DEVICE(0x8087, 0x0a5a),
 	  .driver_info = BTUSB_INTEL_BOOT | BTUSB_BROKEN_ISOC },
@@ -1642,13 +1646,8 @@
 	struct sk_buff *skb;
 	const struct firmware *fw;
 	const u8 *fw_ptr;
-	int disable_patch;
-	struct intel_version *ver;
-
-	const u8 mfg_enable[] = { 0x01, 0x00 };
-	const u8 mfg_disable[] = { 0x00, 0x00 };
-	const u8 mfg_reset_deactivate[] = { 0x00, 0x01 };
-	const u8 mfg_reset_activate[] = { 0x00, 0x02 };
+	int disable_patch, err;
+	struct intel_version ver;
 
 	BT_DBG("%s", hdev->name);
 
@@ -1674,35 +1673,22 @@
 	 * The returned information are hardware variant and revision plus
 	 * firmware variant, revision and build number.
 	 */
-	skb = __hci_cmd_sync(hdev, 0xfc05, 0, NULL, HCI_INIT_TIMEOUT);
-	if (IS_ERR(skb)) {
-		BT_ERR("%s reading Intel fw version command failed (%ld)",
-		       hdev->name, PTR_ERR(skb));
-		return PTR_ERR(skb);
-	}
-
-	if (skb->len != sizeof(*ver)) {
-		BT_ERR("%s Intel version event length mismatch", hdev->name);
-		kfree_skb(skb);
-		return -EIO;
-	}
-
-	ver = (struct intel_version *)skb->data;
+	err = btintel_read_version(hdev, &ver);
+	if (err)
+		return err;
 
 	BT_INFO("%s: read Intel version: %02x%02x%02x%02x%02x%02x%02x%02x%02x",
-		hdev->name, ver->hw_platform, ver->hw_variant,
-		ver->hw_revision, ver->fw_variant,  ver->fw_revision,
-		ver->fw_build_num, ver->fw_build_ww, ver->fw_build_yy,
-		ver->fw_patch_num);
+		hdev->name, ver.hw_platform, ver.hw_variant, ver.hw_revision,
+		ver.fw_variant,  ver.fw_revision, ver.fw_build_num,
+		ver.fw_build_ww, ver.fw_build_yy, ver.fw_patch_num);
 
 	/* fw_patch_num indicates the version of patch the device currently
 	 * have. If there is no patch data in the device, it is always 0x00.
 	 * So, if it is other than 0x00, no need to patch the device again.
 	 */
-	if (ver->fw_patch_num) {
+	if (ver.fw_patch_num) {
 		BT_INFO("%s: Intel device is already patched. patch num: %02x",
-			hdev->name, ver->fw_patch_num);
-		kfree_skb(skb);
+			hdev->name, ver.fw_patch_num);
 		goto complete;
 	}
 
@@ -1712,31 +1698,21 @@
 	 * If no patch file is found, allow the device to operate without
 	 * a patch.
 	 */
-	fw = btusb_setup_intel_get_fw(hdev, ver);
-	if (!fw) {
-		kfree_skb(skb);
+	fw = btusb_setup_intel_get_fw(hdev, &ver);
+	if (!fw)
 		goto complete;
-	}
 	fw_ptr = fw->data;
 
-	kfree_skb(skb);
-
-	/* This Intel specific command enables the manufacturer mode of the
-	 * controller.
-	 *
+	/* Enable the manufacturer mode of the controller.
 	 * Only while this mode is enabled, the driver can download the
 	 * firmware patch data and configuration parameters.
 	 */
-	skb = __hci_cmd_sync(hdev, 0xfc11, 2, mfg_enable, HCI_INIT_TIMEOUT);
-	if (IS_ERR(skb)) {
-		BT_ERR("%s entering Intel manufacturer mode failed (%ld)",
-		       hdev->name, PTR_ERR(skb));
+	err = btintel_enter_mfg(hdev);
+	if (err) {
 		release_firmware(fw);
-		return PTR_ERR(skb);
+		return err;
 	}
 
-	kfree_skb(skb);
-
 	disable_patch = 1;
 
 	/* The firmware data file consists of list of Intel specific HCI
@@ -1776,14 +1752,9 @@
 	/* Patching completed successfully and disable the manufacturer mode
 	 * with reset and activate the downloaded firmware patches.
 	 */
-	skb = __hci_cmd_sync(hdev, 0xfc11, sizeof(mfg_reset_activate),
-			     mfg_reset_activate, HCI_INIT_TIMEOUT);
-	if (IS_ERR(skb)) {
-		BT_ERR("%s exiting Intel manufacturer mode failed (%ld)",
-		       hdev->name, PTR_ERR(skb));
-		return PTR_ERR(skb);
-	}
-	kfree_skb(skb);
+	err = btintel_exit_mfg(hdev, true, true);
+	if (err)
+		return err;
 
 	BT_INFO("%s: Intel Bluetooth firmware patch completed and activated",
 		hdev->name);
@@ -1792,14 +1763,9 @@
 
 exit_mfg_disable:
 	/* Disable the manufacturer mode without reset */
-	skb = __hci_cmd_sync(hdev, 0xfc11, sizeof(mfg_disable), mfg_disable,
-			     HCI_INIT_TIMEOUT);
-	if (IS_ERR(skb)) {
-		BT_ERR("%s exiting Intel manufacturer mode failed (%ld)",
-		       hdev->name, PTR_ERR(skb));
-		return PTR_ERR(skb);
-	}
-	kfree_skb(skb);
+	err = btintel_exit_mfg(hdev, false, false);
+	if (err)
+		return err;
 
 	BT_INFO("%s: Intel Bluetooth firmware patch completed", hdev->name);
 
@@ -1811,14 +1777,9 @@
 	/* Patching failed. Disable the manufacturer mode with reset and
 	 * deactivate the downloaded firmware patches.
 	 */
-	skb = __hci_cmd_sync(hdev, 0xfc11, sizeof(mfg_reset_deactivate),
-			     mfg_reset_deactivate, HCI_INIT_TIMEOUT);
-	if (IS_ERR(skb)) {
-		BT_ERR("%s exiting Intel manufacturer mode failed (%ld)",
-		       hdev->name, PTR_ERR(skb));
-		return PTR_ERR(skb);
-	}
-	kfree_skb(skb);
+	err = btintel_exit_mfg(hdev, true, false);
+	if (err)
+		return err;
 
 	BT_INFO("%s: Intel Bluetooth firmware patch completed and deactivated",
 		hdev->name);
@@ -2005,7 +1966,7 @@
 					  0x00, 0x08, 0x04, 0x00 };
 	struct btusb_data *data = hci_get_drvdata(hdev);
 	struct sk_buff *skb;
-	struct intel_version *ver;
+	struct intel_version ver;
 	struct intel_boot_params *params;
 	const struct firmware *fw;
 	const u8 *fw_ptr;
@@ -2023,28 +1984,16 @@
 	 * is in bootloader mode or if it already has operational firmware
 	 * loaded.
 	 */
-	skb = __hci_cmd_sync(hdev, 0xfc05, 0, NULL, HCI_INIT_TIMEOUT);
-	if (IS_ERR(skb)) {
-		BT_ERR("%s: Reading Intel version information failed (%ld)",
-		       hdev->name, PTR_ERR(skb));
-		return PTR_ERR(skb);
-	}
-
-	if (skb->len != sizeof(*ver)) {
-		BT_ERR("%s: Intel version event size mismatch", hdev->name);
-		kfree_skb(skb);
-		return -EILSEQ;
-	}
-
-	ver = (struct intel_version *)skb->data;
+	err = btintel_read_version(hdev, &ver);
+	if (err)
+		return err;
 
 	/* The hardware platform number has a fixed value of 0x37 and
 	 * for now only accept this single value.
 	 */
-	if (ver->hw_platform != 0x37) {
+	if (ver.hw_platform != 0x37) {
 		BT_ERR("%s: Unsupported Intel hardware platform (%u)",
-		       hdev->name, ver->hw_platform);
-		kfree_skb(skb);
+		       hdev->name, ver.hw_platform);
 		return -EINVAL;
 	}
 
@@ -2053,14 +2002,13 @@
 	 * put in place to ensure correct forward compatibility options
 	 * when newer hardware variants come along.
 	 */
-	if (ver->hw_variant != 0x0b) {
+	if (ver.hw_variant != 0x0b) {
 		BT_ERR("%s: Unsupported Intel hardware variant (%u)",
-		       hdev->name, ver->hw_variant);
-		kfree_skb(skb);
+		       hdev->name, ver.hw_variant);
 		return -EINVAL;
 	}
 
-	btintel_version_info(hdev, ver);
+	btintel_version_info(hdev, &ver);
 
 	/* The firmware variant determines if the device is in bootloader
 	 * mode or is running operational firmware. The value 0x06 identifies
@@ -2075,8 +2023,7 @@
 	 * It is not possible to use the Secure Boot Parameters in this
 	 * case since that command is only available in bootloader mode.
 	 */
-	if (ver->fw_variant == 0x23) {
-		kfree_skb(skb);
+	if (ver.fw_variant == 0x23) {
 		clear_bit(BTUSB_BOOTLOADER, &data->flags);
 		btintel_check_bdaddr(hdev);
 		return 0;
@@ -2085,15 +2032,12 @@
 	/* If the device is not in bootloader mode, then the only possible
 	 * choice is to return an error and abort the device initialization.
 	 */
-	if (ver->fw_variant != 0x06) {
+	if (ver.fw_variant != 0x06) {
 		BT_ERR("%s: Unsupported Intel firmware variant (%u)",
-		       hdev->name, ver->fw_variant);
-		kfree_skb(skb);
+		       hdev->name, ver.fw_variant);
 		return -ENODEV;
 	}
 
-	kfree_skb(skb);
-
 	/* Read the secure boot parameters to identify the operating
 	 * details of the bootloader.
 	 */
diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c
index db039f2..0879d64 100644
--- a/drivers/bluetooth/hci_h5.c
+++ b/drivers/bluetooth/hci_h5.c
@@ -116,18 +116,14 @@
 
 static u8 h5_cfg_field(struct h5 *h5)
 {
-	u8 field = 0;
-
 	/* Sliding window size (first 3 bits) */
-	field |= (h5->tx_win & 0x07);
-
-	return field;
+	return h5->tx_win & 0x07;
 }
 
 static void h5_timed_event(unsigned long arg)
 {
 	const unsigned char sync_req[] = { 0x01, 0x7e };
-	unsigned char conf_req[] = { 0x03, 0xfc, 0x01 };
+	unsigned char conf_req[3] = { 0x03, 0xfc };
 	struct hci_uart *hu = (struct hci_uart *)arg;
 	struct h5 *h5 = hu->priv;
 	struct sk_buff *skb;
@@ -285,7 +281,7 @@
 	struct h5 *h5 = hu->priv;
 	const unsigned char sync_req[] = { 0x01, 0x7e };
 	const unsigned char sync_rsp[] = { 0x02, 0x7d };
-	unsigned char conf_req[] = { 0x03, 0xfc, 0x01 };
+	unsigned char conf_req[3] = { 0x03, 0xfc };
 	const unsigned char conf_rsp[] = { 0x04, 0x7b };
 	const unsigned char wakeup_req[] = { 0x05, 0xfa };
 	const unsigned char woken_req[] = { 0x06, 0xf9 };
@@ -317,7 +313,7 @@
 		h5_link_control(hu, conf_req, 3);
 	} else if (memcmp(data, conf_rsp, 2) == 0) {
 		if (H5_HDR_LEN(hdr) > 2)
-			h5->tx_win = (data[2] & 7);
+			h5->tx_win = (data[2] & 0x07);
 		BT_DBG("Three-wire init complete. tx_win %u", h5->tx_win);
 		h5->state = H5_ACTIVE;
 		hci_uart_init_ready(hu);
diff --git a/drivers/bluetooth/hci_intel.c b/drivers/bluetooth/hci_intel.c
index 69760e2..3d63ea3 100644
--- a/drivers/bluetooth/hci_intel.c
+++ b/drivers/bluetooth/hci_intel.c
@@ -502,7 +502,7 @@
 	/* Device will not accept speed change if Intel version has not been
 	 * previously requested.
 	 */
-	skb = __hci_cmd_sync(hdev, 0xfc05, 0, NULL, HCI_INIT_TIMEOUT);
+	skb = __hci_cmd_sync(hdev, 0xfc05, 0, NULL, HCI_CMD_TIMEOUT);
 	if (IS_ERR(skb)) {
 		bt_dev_err(hdev, "Reading Intel version information failed (%ld)",
 			   PTR_ERR(skb));
@@ -542,7 +542,7 @@
 	struct intel_device *idev = NULL;
 	struct hci_dev *hdev = hu->hdev;
 	struct sk_buff *skb;
-	struct intel_version *ver;
+	struct intel_version ver;
 	struct intel_boot_params *params;
 	struct list_head *p;
 	const struct firmware *fw;
@@ -590,35 +590,16 @@
 	 * is in bootloader mode or if it already has operational firmware
 	 * loaded.
 	 */
-	skb = __hci_cmd_sync(hdev, 0xfc05, 0, NULL, HCI_INIT_TIMEOUT);
-	if (IS_ERR(skb)) {
-		bt_dev_err(hdev, "Reading Intel version information failed (%ld)",
-			   PTR_ERR(skb));
-		return PTR_ERR(skb);
-	}
-
-	if (skb->len != sizeof(*ver)) {
-		bt_dev_err(hdev, "Intel version event size mismatch");
-		kfree_skb(skb);
-		return -EILSEQ;
-	}
-
-	ver = (struct intel_version *)skb->data;
-	if (ver->status) {
-		bt_dev_err(hdev, "Intel version command failure (%02x)",
-			   ver->status);
-		err = -bt_to_errno(ver->status);
-		kfree_skb(skb);
+	 err = btintel_read_version(hdev, &ver);
+	 if (err)
 		return err;
-	}
 
 	/* The hardware platform number has a fixed value of 0x37 and
 	 * for now only accept this single value.
 	 */
-	if (ver->hw_platform != 0x37) {
+	if (ver.hw_platform != 0x37) {
 		bt_dev_err(hdev, "Unsupported Intel hardware platform (%u)",
-			   ver->hw_platform);
-		kfree_skb(skb);
+			   ver.hw_platform);
 		return -EINVAL;
 	}
 
@@ -627,14 +608,13 @@
 	 * put in place to ensure correct forward compatibility options
 	 * when newer hardware variants come along.
 	 */
-	if (ver->hw_variant != 0x0b) {
+	if (ver.hw_variant != 0x0b) {
 		bt_dev_err(hdev, "Unsupported Intel hardware variant (%u)",
-			   ver->hw_variant);
-		kfree_skb(skb);
+			   ver.hw_variant);
 		return -EINVAL;
 	}
 
-	btintel_version_info(hdev, ver);
+	btintel_version_info(hdev, &ver);
 
 	/* The firmware variant determines if the device is in bootloader
 	 * mode or is running operational firmware. The value 0x06 identifies
@@ -649,8 +629,7 @@
 	 * It is not possible to use the Secure Boot Parameters in this
 	 * case since that command is only available in bootloader mode.
 	 */
-	if (ver->fw_variant == 0x23) {
-		kfree_skb(skb);
+	if (ver.fw_variant == 0x23) {
 		clear_bit(STATE_BOOTLOADER, &intel->flags);
 		btintel_check_bdaddr(hdev);
 		return 0;
@@ -659,19 +638,16 @@
 	/* If the device is not in bootloader mode, then the only possible
 	 * choice is to return an error and abort the device initialization.
 	 */
-	if (ver->fw_variant != 0x06) {
+	if (ver.fw_variant != 0x06) {
 		bt_dev_err(hdev, "Unsupported Intel firmware variant (%u)",
-			   ver->fw_variant);
-		kfree_skb(skb);
+			   ver.fw_variant);
 		return -ENODEV;
 	}
 
-	kfree_skb(skb);
-
 	/* Read the secure boot parameters to identify the operating
 	 * details of the bootloader.
 	 */
-	skb = __hci_cmd_sync(hdev, 0xfc0d, 0, NULL, HCI_INIT_TIMEOUT);
+	skb = __hci_cmd_sync(hdev, 0xfc0d, 0, NULL, HCI_CMD_TIMEOUT);
 	if (IS_ERR(skb)) {
 		bt_dev_err(hdev, "Reading Intel boot parameters failed (%ld)",
 			   PTR_ERR(skb));
@@ -881,7 +857,7 @@
 	set_bit(STATE_BOOTING, &intel->flags);
 
 	skb = __hci_cmd_sync(hdev, 0xfc01, sizeof(reset_param), reset_param,
-			     HCI_INIT_TIMEOUT);
+			     HCI_CMD_TIMEOUT);
 	if (IS_ERR(skb))
 		return PTR_ERR(skb);
 
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 03146d7..73202624 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -462,13 +462,7 @@
 	INIT_WORK(&hu->init_ready, hci_uart_init_work);
 	INIT_WORK(&hu->write_work, hci_uart_write_work);
 
-	/* Flush any pending characters in the driver and line discipline. */
-
-	/* FIXME: why is this needed. Note don't use ldisc_ref here as the
-	   open path is before the ldisc is referencable */
-
-	if (tty->ldisc->ops->flush_buffer)
-		tty->ldisc->ops->flush_buffer(tty);
+	/* Flush any pending characters in the driver */
 	tty_driver_flush_buffer(tty);
 
 	return 0;
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index 169059c..0123646 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -2904,6 +2904,10 @@
 	else
 		macb_get_hwaddr(bp);
 
+	/* Power up the PHY if there is a GPIO reset */
+	bp->reset_gpio = devm_gpiod_get_optional(&bp->pdev->dev, "phy-reset",
+						 GPIOD_OUT_HIGH);
+
 	err = of_get_phy_mode(np);
 	if (err < 0) {
 		pdata = dev_get_platdata(&pdev->dev);
@@ -2970,6 +2974,10 @@
 		mdiobus_unregister(bp->mii_bus);
 		kfree(bp->mii_bus->irq);
 		mdiobus_free(bp->mii_bus);
+
+		/* Shutdown the PHY if there is a GPIO reset */
+		gpiod_set_value(bp->reset_gpio, 0);
+
 		unregister_netdev(dev);
 		clk_disable_unprepare(bp->tx_clk);
 		clk_disable_unprepare(bp->hclk);
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index d83b0db..5c03e81 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -829,6 +829,7 @@
 	unsigned int		dma_burst_length;
 
 	phy_interface_t		phy_interface;
+	struct gpio_desc	*reset_gpio;
 
 	/* AT91RM9200 transmit */
 	struct sk_buff *skb;			/* holds skb until xmit interrupt completes */
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index 1cf1226..120cc25 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -410,9 +410,11 @@
 	/* Timestamp enable */
 	ravb_write(ndev, TCCR_TFEN, TCCR);
 
-	/* Interrupt enable: */
+	/* Interrupt init: */
 	/* Frame receive */
 	ravb_write(ndev, RIC0_FRE0 | RIC0_FRE1, RIC0);
+	/* Disable FIFO full warning */
+	ravb_write(ndev, 0, RIC1);
 	/* Receive FIFO full error, descriptor empty */
 	ravb_write(ndev, RIC2_QFE0 | RIC2_QFE1 | RIC2_RFFE, RIC2);
 	/* Frame transmitted, timestamp FIFO updated */
@@ -1478,7 +1480,6 @@
 
 	/* Disable interrupts by clearing the interrupt masks. */
 	ravb_write(ndev, 0, RIC0);
-	ravb_write(ndev, 0, RIC1);
 	ravb_write(ndev, 0, RIC2);
 	ravb_write(ndev, 0, TIC);
 
diff --git a/drivers/net/ieee802154/Kconfig b/drivers/net/ieee802154/Kconfig
index ce5f1a2..3057a8d 100644
--- a/drivers/net/ieee802154/Kconfig
+++ b/drivers/net/ieee802154/Kconfig
@@ -71,3 +71,14 @@
 
 	  This driver can also be built as a module. To do so say M here.
 	  The module will be called 'atusb'.
+
+config IEEE802154_ADF7242
+       tristate "ADF7242 transceiver driver"
+       depends on IEEE802154_DRIVERS && MAC802154
+       depends on SPI
+	---help---
+	  Say Y here to enable the ADF7242 SPI 802.15.4 wireless
+	  controller.
+
+	  This driver can also be built as a module. To do so, say M here.
+	  the module will be called 'adf7242'.
diff --git a/drivers/net/ieee802154/Makefile b/drivers/net/ieee802154/Makefile
index cf1d2a6..3a923d3 100644
--- a/drivers/net/ieee802154/Makefile
+++ b/drivers/net/ieee802154/Makefile
@@ -3,3 +3,4 @@
 obj-$(CONFIG_IEEE802154_MRF24J40) += mrf24j40.o
 obj-$(CONFIG_IEEE802154_CC2520) += cc2520.o
 obj-$(CONFIG_IEEE802154_ATUSB) += atusb.o
+obj-$(CONFIG_IEEE802154_ADF7242) += adf7242.o
diff --git a/drivers/net/ieee802154/adf7242.c b/drivers/net/ieee802154/adf7242.c
new file mode 100644
index 0000000..89154c0
--- /dev/null
+++ b/drivers/net/ieee802154/adf7242.c
@@ -0,0 +1,1285 @@
+/*
+ * Analog Devices ADF7242 Low-Power IEEE 802.15.4 Transceiver
+ *
+ * Copyright 2009-2015 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ *
+ * http://www.analog.com/ADF7242
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/workqueue.h>
+#include <linux/spinlock.h>
+#include <linux/firmware.h>
+#include <linux/spi/spi.h>
+#include <linux/skbuff.h>
+#include <linux/of.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/debugfs.h>
+#include <linux/bitops.h>
+#include <linux/ieee802154.h>
+#include <net/mac802154.h>
+#include <net/cfg802154.h>
+
+#define FIRMWARE "adf7242_firmware.bin"
+#define MAX_POLL_LOOPS 200
+
+/* All Registers */
+
+#define REG_EXT_CTRL	0x100	/* RW External LNA/PA and internal PA control */
+#define REG_TX_FSK_TEST 0x101	/* RW TX FSK test mode configuration */
+#define REG_CCA1	0x105	/* RW RSSI threshold for CCA */
+#define REG_CCA2	0x106	/* RW CCA mode configuration */
+#define REG_BUFFERCFG	0x107	/* RW RX_BUFFER overwrite control */
+#define REG_PKT_CFG	0x108	/* RW FCS evaluation configuration */
+#define REG_DELAYCFG0	0x109	/* RW RC_RX command to SFD or sync word delay */
+#define REG_DELAYCFG1	0x10A	/* RW RC_TX command to TX state */
+#define REG_DELAYCFG2	0x10B	/* RW Mac delay extension */
+#define REG_SYNC_WORD0	0x10C	/* RW sync word bits [7:0] of [23:0]  */
+#define REG_SYNC_WORD1	0x10D	/* RW sync word bits [15:8] of [23:0]  */
+#define REG_SYNC_WORD2	0x10E	/* RW sync word bits [23:16] of [23:0]	*/
+#define REG_SYNC_CONFIG	0x10F	/* RW sync word configuration */
+#define REG_RC_CFG	0x13E	/* RW RX / TX packet configuration */
+#define REG_RC_VAR44	0x13F	/* RW RESERVED */
+#define REG_CH_FREQ0	0x300	/* RW Channel Frequency Settings - Low */
+#define REG_CH_FREQ1	0x301	/* RW Channel Frequency Settings - Middle */
+#define REG_CH_FREQ2	0x302	/* RW Channel Frequency Settings - High */
+#define REG_TX_FD	0x304	/* RW TX Frequency Deviation Register */
+#define REG_DM_CFG0	0x305	/* RW RX Discriminator BW Register */
+#define REG_TX_M	0x306	/* RW TX Mode Register */
+#define REG_RX_M	0x307	/* RW RX Mode Register */
+#define REG_RRB		0x30C	/* R RSSI Readback Register */
+#define REG_LRB		0x30D	/* R Link Quality Readback Register */
+#define REG_DR0		0x30E	/* RW bits [15:8] of [15:0] data rate setting */
+#define REG_DR1		0x30F	/* RW bits [7:0] of [15:0] data rate setting */
+#define REG_PRAMPG	0x313	/* RW RESERVED */
+#define REG_TXPB	0x314	/* RW TX Packet Storage Base Address */
+#define REG_RXPB	0x315	/* RW RX Packet Storage Base Address */
+#define REG_TMR_CFG0	0x316	/* RW Wake up Timer Conf Register - High */
+#define REG_TMR_CFG1	0x317	/* RW Wake up Timer Conf Register - Low */
+#define REG_TMR_RLD0	0x318	/* RW Wake up Timer Value Register - High */
+#define REG_TMR_RLD1	0x319	/* RW Wake up Timer Value Register - Low  */
+#define REG_TMR_CTRL	0x31A	/* RW Wake up Timer Timeout flag */
+#define REG_PD_AUX	0x31E	/* RW Battmon enable */
+#define REG_GP_CFG	0x32C	/* RW GPIO Configuration */
+#define REG_GP_OUT	0x32D	/* RW GPIO Configuration */
+#define REG_GP_IN	0x32E	/* R GPIO Configuration */
+#define REG_SYNT	0x335	/* RW bandwidth calibration timers */
+#define REG_CAL_CFG	0x33D	/* RW Calibration Settings */
+#define REG_PA_BIAS	0x36E	/* RW PA BIAS */
+#define REG_SYNT_CAL	0x371	/* RW Oscillator and Doubler Configuration */
+#define REG_IIRF_CFG	0x389	/* RW BB Filter Decimation Rate */
+#define REG_CDR_CFG	0x38A	/* RW CDR kVCO */
+#define REG_DM_CFG1	0x38B	/* RW Postdemodulator Filter */
+#define REG_AGCSTAT	0x38E	/* R RXBB Ref Osc Calibration Engine Readback */
+#define REG_RXCAL0	0x395	/* RW RX BB filter tuning, LSB */
+#define REG_RXCAL1	0x396	/* RW RX BB filter tuning, MSB */
+#define REG_RXFE_CFG	0x39B	/* RW RXBB Ref Osc & RXFE Calibration */
+#define REG_PA_RR	0x3A7	/* RW Set PA ramp rate */
+#define REG_PA_CFG	0x3A8	/* RW PA enable */
+#define REG_EXTPA_CFG	0x3A9	/* RW External PA BIAS DAC */
+#define REG_EXTPA_MSC	0x3AA	/* RW PA Bias Mode */
+#define REG_ADC_RBK	0x3AE	/* R Readback temp */
+#define REG_AGC_CFG1	0x3B2	/* RW GC Parameters */
+#define REG_AGC_MAX	0x3B4	/* RW Slew rate	 */
+#define REG_AGC_CFG2	0x3B6	/* RW RSSI Parameters */
+#define REG_AGC_CFG3	0x3B7	/* RW RSSI Parameters */
+#define REG_AGC_CFG4	0x3B8	/* RW RSSI Parameters */
+#define REG_AGC_CFG5	0x3B9	/* RW RSSI & NDEC Parameters */
+#define REG_AGC_CFG6	0x3BA	/* RW NDEC Parameters */
+#define REG_OCL_CFG1	0x3C4	/* RW OCL System Parameters */
+#define REG_IRQ1_EN0	0x3C7	/* RW Interrupt Mask set bits for IRQ1 */
+#define REG_IRQ1_EN1	0x3C8	/* RW Interrupt Mask set bits for IRQ1 */
+#define REG_IRQ2_EN0	0x3C9	/* RW Interrupt Mask set bits for IRQ2 */
+#define REG_IRQ2_EN1	0x3CA	/* RW Interrupt Mask set bits for IRQ2 */
+#define REG_IRQ1_SRC0	0x3CB	/* RW Interrupt Source bits for IRQ */
+#define REG_IRQ1_SRC1	0x3CC	/* RW Interrupt Source bits for IRQ */
+#define REG_OCL_BW0	0x3D2	/* RW OCL System Parameters */
+#define REG_OCL_BW1	0x3D3	/* RW OCL System Parameters */
+#define REG_OCL_BW2	0x3D4	/* RW OCL System Parameters */
+#define REG_OCL_BW3	0x3D5	/* RW OCL System Parameters */
+#define REG_OCL_BW4	0x3D6	/* RW OCL System Parameters */
+#define REG_OCL_BWS	0x3D7	/* RW OCL System Parameters */
+#define REG_OCL_CFG13	0x3E0	/* RW OCL System Parameters */
+#define REG_GP_DRV	0x3E3	/* RW I/O pads Configuration and bg trim */
+#define REG_BM_CFG	0x3E6	/* RW Batt. Monitor Threshold Voltage setting */
+#define REG_SFD_15_4	0x3F4	/* RW Option to set non standard SFD */
+#define REG_AFC_CFG	0x3F7	/* RW AFC mode and polarity */
+#define REG_AFC_KI_KP	0x3F8	/* RW AFC ki and kp */
+#define REG_AFC_RANGE	0x3F9	/* RW AFC range */
+#define REG_AFC_READ	0x3FA	/* RW Readback frequency error */
+
+/* REG_EXTPA_MSC */
+#define PA_PWR(x)		(((x) & 0xF) << 4)
+#define EXTPA_BIAS_SRC		BIT(3)
+#define EXTPA_BIAS_MODE(x)	(((x) & 0x7) << 0)
+
+/* REG_PA_CFG */
+#define PA_BRIDGE_DBIAS(x)	(((x) & 0x1F) << 0)
+#define PA_DBIAS_HIGH_POWER	21
+#define PA_DBIAS_LOW_POWER	13
+
+/* REG_PA_BIAS */
+#define PA_BIAS_CTRL(x)		(((x) & 0x1F) << 1)
+#define REG_PA_BIAS_DFL		BIT(0)
+#define PA_BIAS_HIGH_POWER	63
+#define PA_BIAS_LOW_POWER	55
+
+#define REG_PAN_ID0		0x112
+#define REG_PAN_ID1		0x113
+#define REG_SHORT_ADDR_0	0x114
+#define REG_SHORT_ADDR_1	0x115
+#define REG_IEEE_ADDR_0		0x116
+#define REG_IEEE_ADDR_1		0x117
+#define REG_IEEE_ADDR_2		0x118
+#define REG_IEEE_ADDR_3		0x119
+#define REG_IEEE_ADDR_4		0x11A
+#define REG_IEEE_ADDR_5		0x11B
+#define REG_IEEE_ADDR_6		0x11C
+#define REG_IEEE_ADDR_7		0x11D
+#define REG_FFILT_CFG		0x11E
+#define REG_AUTO_CFG		0x11F
+#define REG_AUTO_TX1		0x120
+#define REG_AUTO_TX2		0x121
+#define REG_AUTO_STATUS		0x122
+
+/* REG_FFILT_CFG */
+#define ACCEPT_BEACON_FRAMES   BIT(0)
+#define ACCEPT_DATA_FRAMES     BIT(1)
+#define ACCEPT_ACK_FRAMES      BIT(2)
+#define ACCEPT_MACCMD_FRAMES   BIT(3)
+#define ACCEPT_RESERVED_FRAMES BIT(4)
+#define ACCEPT_ALL_ADDRESS     BIT(5)
+
+/* REG_AUTO_CFG */
+#define AUTO_ACK_FRAMEPEND     BIT(0)
+#define IS_PANCOORD	       BIT(1)
+#define RX_AUTO_ACK_EN	       BIT(3)
+#define CSMA_CA_RX_TURNAROUND  BIT(4)
+
+/* REG_AUTO_TX1 */
+#define MAX_FRAME_RETRIES(x)   ((x) & 0xF)
+#define MAX_CCA_RETRIES(x)     (((x) & 0x7) << 4)
+
+/* REG_AUTO_TX2 */
+#define CSMA_MAX_BE(x)	       ((x) & 0xF)
+#define CSMA_MIN_BE(x)	       (((x) & 0xF) << 4)
+
+#define CMD_SPI_NOP		0xFF /* No operation. Use for dummy writes */
+#define CMD_SPI_PKT_WR		0x10 /* Write telegram to the Packet RAM
+				      * starting from the TX packet base address
+				      * pointer tx_packet_base
+				      */
+#define CMD_SPI_PKT_RD		0x30 /* Read telegram from the Packet RAM
+				      * starting from RX packet base address
+				      * pointer rxpb.rx_packet_base
+				      */
+#define CMD_SPI_MEM_WR(x)	(0x18 + (x >> 8)) /* Write data to MCR or
+						   * Packet RAM sequentially
+						   */
+#define CMD_SPI_MEM_RD(x)	(0x38 + (x >> 8)) /* Read data from MCR or
+						   * Packet RAM sequentially
+						   */
+#define CMD_SPI_MEMR_WR(x)	(0x08 + (x >> 8)) /* Write data to MCR or Packet
+						   * RAM as random block
+						   */
+#define CMD_SPI_MEMR_RD(x)	(0x28 + (x >> 8)) /* Read data from MCR or
+						   * Packet RAM random block
+						   */
+#define CMD_SPI_PRAM_WR		0x1E /* Write data sequentially to current
+				      * PRAM page selected
+				      */
+#define CMD_SPI_PRAM_RD		0x3E /* Read data sequentially from current
+				      * PRAM page selected
+				      */
+#define CMD_RC_SLEEP		0xB1 /* Invoke transition of radio controller
+				      * into SLEEP state
+				      */
+#define CMD_RC_IDLE		0xB2 /* Invoke transition of radio controller
+				      * into IDLE state
+				      */
+#define CMD_RC_PHY_RDY		0xB3 /* Invoke transition of radio controller
+				      * into PHY_RDY state
+				      */
+#define CMD_RC_RX		0xB4 /* Invoke transition of radio controller
+				      * into RX state
+				      */
+#define CMD_RC_TX		0xB5 /* Invoke transition of radio controller
+				      * into TX state
+				      */
+#define CMD_RC_MEAS		0xB6 /* Invoke transition of radio controller
+				      * into MEAS state
+				      */
+#define CMD_RC_CCA		0xB7 /* Invoke Clear channel assessment */
+#define CMD_RC_CSMACA		0xC1 /* initiates CSMA-CA channel access
+				      * sequence and frame transmission
+				      */
+#define CMD_RC_PC_RESET		0xC7 /* Program counter reset */
+#define CMD_RC_RESET		0xC8 /* Resets the ADF7242 and puts it in
+				      * the sleep state
+				      */
+#define CMD_RC_PC_RESET_NO_WAIT (CMD_RC_PC_RESET | BIT(31))
+
+/* STATUS */
+
+#define STAT_SPI_READY		BIT(7)
+#define STAT_IRQ_STATUS		BIT(6)
+#define STAT_RC_READY		BIT(5)
+#define STAT_CCA_RESULT		BIT(4)
+#define RC_STATUS_IDLE		1
+#define RC_STATUS_MEAS		2
+#define RC_STATUS_PHY_RDY	3
+#define RC_STATUS_RX		4
+#define RC_STATUS_TX		5
+#define RC_STATUS_MASK		0xF
+
+/* AUTO_STATUS */
+
+#define SUCCESS			0
+#define SUCCESS_DATPEND		1
+#define FAILURE_CSMACA		2
+#define FAILURE_NOACK		3
+#define AUTO_STATUS_MASK	0x3
+
+#define PRAM_PAGESIZE		256
+
+/* IRQ1 */
+
+#define IRQ_CCA_COMPLETE	BIT(0)
+#define IRQ_SFD_RX		BIT(1)
+#define IRQ_SFD_TX		BIT(2)
+#define IRQ_RX_PKT_RCVD		BIT(3)
+#define IRQ_TX_PKT_SENT		BIT(4)
+#define IRQ_FRAME_VALID		BIT(5)
+#define IRQ_ADDRESS_VALID	BIT(6)
+#define IRQ_CSMA_CA		BIT(7)
+
+#define AUTO_TX_TURNAROUND	BIT(3)
+#define ADDON_EN		BIT(4)
+
+#define FLAG_XMIT		0
+#define FLAG_START		1
+
+#define ADF7242_REPORT_CSMA_CA_STAT 0 /* framework doesn't handle yet */
+
+struct adf7242_local {
+	struct spi_device *spi;
+	struct completion tx_complete;
+	struct ieee802154_hw *hw;
+	struct mutex bmux; /* protect SPI messages */
+	struct spi_message stat_msg;
+	struct spi_transfer stat_xfer;
+	struct dentry *debugfs_root;
+	unsigned long flags;
+	int tx_stat;
+	bool promiscuous;
+	s8 rssi;
+	u8 max_frame_retries;
+	u8 max_cca_retries;
+	u8 max_be;
+	u8 min_be;
+
+	/* DMA (thus cache coherency maintenance) requires the
+	 * transfer buffers to live in their own cache lines.
+	 */
+
+	u8 buf[3] ____cacheline_aligned;
+	u8 buf_reg_tx[3];
+	u8 buf_read_tx[4];
+	u8 buf_read_rx[4];
+	u8 buf_stat_rx;
+	u8 buf_stat_tx;
+	u8 buf_cmd;
+};
+
+static int adf7242_soft_reset(struct adf7242_local *lp, int line);
+
+static int adf7242_status(struct adf7242_local *lp, u8 *stat)
+{
+	int status;
+
+	mutex_lock(&lp->bmux);
+	status = spi_sync(lp->spi, &lp->stat_msg);
+	*stat = lp->buf_stat_rx;
+	mutex_unlock(&lp->bmux);
+
+	return status;
+}
+
+static int adf7242_wait_status(struct adf7242_local *lp, unsigned status,
+			       unsigned mask, int line)
+{
+	int cnt = 0, ret = 0;
+	u8 stat;
+
+	do {
+		adf7242_status(lp, &stat);
+		cnt++;
+	} while (((stat & mask) != status) && (cnt < MAX_POLL_LOOPS));
+
+	if (cnt >= MAX_POLL_LOOPS) {
+		ret = -ETIMEDOUT;
+
+		if (!(stat & STAT_RC_READY)) {
+			adf7242_soft_reset(lp, line);
+			adf7242_status(lp, &stat);
+
+			if ((stat & mask) == status)
+				ret = 0;
+		}
+
+		if (ret < 0)
+			dev_warn(&lp->spi->dev,
+				 "%s:line %d Timeout status 0x%x (%d)\n",
+				 __func__, line, stat, cnt);
+	}
+
+	dev_vdbg(&lp->spi->dev, "%s : loops=%d line %d\n", __func__, cnt, line);
+
+	return ret;
+}
+
+static int adf7242_wait_ready(struct adf7242_local *lp, int line)
+{
+	return adf7242_wait_status(lp, STAT_RC_READY | STAT_SPI_READY,
+				   STAT_RC_READY | STAT_SPI_READY, line);
+}
+
+static int adf7242_write_fbuf(struct adf7242_local *lp, u8 *data, u8 len)
+{
+	u8 *buf = lp->buf;
+	int status;
+	struct spi_message msg;
+	struct spi_transfer xfer_head = {
+		.len = 2,
+		.tx_buf = buf,
+
+	};
+	struct spi_transfer xfer_buf = {
+		.len = len,
+		.tx_buf = data,
+	};
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer_head, &msg);
+	spi_message_add_tail(&xfer_buf, &msg);
+
+	adf7242_wait_ready(lp, __LINE__);
+
+	mutex_lock(&lp->bmux);
+	buf[0] = CMD_SPI_PKT_WR;
+	buf[1] = len + 2;
+
+	status = spi_sync(lp->spi, &msg);
+	mutex_unlock(&lp->bmux);
+
+	return status;
+}
+
+static int adf7242_read_fbuf(struct adf7242_local *lp,
+			     u8 *data, size_t len, bool packet_read)
+{
+	u8 *buf = lp->buf;
+	int status;
+	struct spi_message msg;
+	struct spi_transfer xfer_head = {
+		.len = 3,
+		.tx_buf = buf,
+		.rx_buf = buf,
+	};
+	struct spi_transfer xfer_buf = {
+		.len = len,
+		.rx_buf = data,
+	};
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer_head, &msg);
+	spi_message_add_tail(&xfer_buf, &msg);
+
+	adf7242_wait_ready(lp, __LINE__);
+
+	mutex_lock(&lp->bmux);
+	if (packet_read) {
+		buf[0] = CMD_SPI_PKT_RD;
+		buf[1] = CMD_SPI_NOP;
+		buf[2] = 0;	/* PHR */
+	} else {
+		buf[0] = CMD_SPI_PRAM_RD;
+		buf[1] = 0;
+		buf[2] = CMD_SPI_NOP;
+	}
+
+	status = spi_sync(lp->spi, &msg);
+
+	mutex_unlock(&lp->bmux);
+
+	return status;
+}
+
+static int adf7242_read_reg(struct adf7242_local *lp, u16 addr, u8 *data)
+{
+	int status;
+	struct spi_message msg;
+
+	struct spi_transfer xfer = {
+		.len = 4,
+		.tx_buf = lp->buf_read_tx,
+		.rx_buf = lp->buf_read_rx,
+	};
+
+	adf7242_wait_ready(lp, __LINE__);
+
+	mutex_lock(&lp->bmux);
+	lp->buf_read_tx[0] = CMD_SPI_MEM_RD(addr);
+	lp->buf_read_tx[1] = addr;
+	lp->buf_read_tx[2] = CMD_SPI_NOP;
+	lp->buf_read_tx[3] = CMD_SPI_NOP;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+
+	status = spi_sync(lp->spi, &msg);
+	if (msg.status)
+		status = msg.status;
+
+	if (!status)
+		*data = lp->buf_read_rx[3];
+
+	mutex_unlock(&lp->bmux);
+
+	dev_vdbg(&lp->spi->dev, "%s : REG 0x%X, VAL 0x%X\n", __func__,
+		 addr, *data);
+
+	return status;
+}
+
+static int adf7242_write_reg(struct adf7242_local *lp, u16 addr, u8 data)
+{
+	int status;
+
+	adf7242_wait_ready(lp, __LINE__);
+
+	mutex_lock(&lp->bmux);
+	lp->buf_reg_tx[0] = CMD_SPI_MEM_WR(addr);
+	lp->buf_reg_tx[1] = addr;
+	lp->buf_reg_tx[2] = data;
+	status = spi_write(lp->spi, lp->buf_reg_tx, 3);
+	mutex_unlock(&lp->bmux);
+
+	dev_vdbg(&lp->spi->dev, "%s : REG 0x%X, VAL 0x%X\n",
+		 __func__, addr, data);
+
+	return status;
+}
+
+static int adf7242_cmd(struct adf7242_local *lp, unsigned cmd)
+{
+	int status;
+
+	dev_vdbg(&lp->spi->dev, "%s : CMD=0x%X\n", __func__, cmd);
+
+	if (cmd != CMD_RC_PC_RESET_NO_WAIT)
+		adf7242_wait_ready(lp, __LINE__);
+
+	mutex_lock(&lp->bmux);
+	lp->buf_cmd = cmd;
+	status = spi_write(lp->spi, &lp->buf_cmd, 1);
+	mutex_unlock(&lp->bmux);
+
+	return status;
+}
+
+static int adf7242_upload_firmware(struct adf7242_local *lp, u8 *data, u16 len)
+{
+	struct spi_message msg;
+	struct spi_transfer xfer_buf = { };
+	int status, i, page = 0;
+	u8 *buf = lp->buf;
+
+	struct spi_transfer xfer_head = {
+		.len = 2,
+		.tx_buf = buf,
+	};
+
+	buf[0] = CMD_SPI_PRAM_WR;
+	buf[1] = 0;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer_head, &msg);
+	spi_message_add_tail(&xfer_buf, &msg);
+
+	for (i = len; i >= 0; i -= PRAM_PAGESIZE) {
+		adf7242_write_reg(lp, REG_PRAMPG, page);
+
+		xfer_buf.len = (i >= PRAM_PAGESIZE) ? PRAM_PAGESIZE : i;
+		xfer_buf.tx_buf = &data[page * PRAM_PAGESIZE];
+
+		mutex_lock(&lp->bmux);
+		status = spi_sync(lp->spi, &msg);
+		mutex_unlock(&lp->bmux);
+		page++;
+	}
+
+	return status;
+}
+
+static int adf7242_verify_firmware(struct adf7242_local *lp,
+				   const u8 *data, size_t len)
+{
+#ifdef DEBUG
+	int i, j;
+	unsigned int page;
+	u8 *buf = kmalloc(PRAM_PAGESIZE, GFP_KERNEL);
+
+	if (!buf)
+		return -ENOMEM;
+
+	for (page = 0, i = len; i >= 0; i -= PRAM_PAGESIZE, page++) {
+		size_t nb = (i >= PRAM_PAGESIZE) ? PRAM_PAGESIZE : i;
+
+		adf7242_write_reg(lp, REG_PRAMPG, page);
+		adf7242_read_fbuf(lp, buf, nb, false);
+
+		for (j = 0; j < nb; j++) {
+			if (buf[j] != data[page * PRAM_PAGESIZE + j]) {
+				kfree(buf);
+				return -EIO;
+			}
+		}
+	}
+	kfree(buf);
+#endif
+	return 0;
+}
+
+static int adf7242_set_txpower(struct ieee802154_hw *hw, int mbm)
+{
+	struct adf7242_local *lp = hw->priv;
+	u8 pwr, bias_ctrl, dbias, tmp;
+	int db = mbm / 100;
+
+	dev_vdbg(&lp->spi->dev, "%s : Power %d dB\n", __func__, db);
+
+	if (db > 5 || db < -26)
+		return -EINVAL;
+
+	db = DIV_ROUND_CLOSEST(db + 29, 2);
+
+	if (db > 15) {
+		dbias = PA_DBIAS_HIGH_POWER;
+		bias_ctrl = PA_BIAS_HIGH_POWER;
+	} else {
+		dbias = PA_DBIAS_LOW_POWER;
+		bias_ctrl = PA_BIAS_LOW_POWER;
+	}
+
+	pwr = clamp_t(u8, db, 3, 15);
+
+	adf7242_read_reg(lp, REG_PA_CFG, &tmp);
+	tmp &= ~PA_BRIDGE_DBIAS(~0);
+	tmp |= PA_BRIDGE_DBIAS(dbias);
+	adf7242_write_reg(lp, REG_PA_CFG, tmp);
+
+	adf7242_read_reg(lp, REG_PA_BIAS, &tmp);
+	tmp &= ~PA_BIAS_CTRL(~0);
+	tmp |= PA_BIAS_CTRL(bias_ctrl);
+	adf7242_write_reg(lp, REG_PA_BIAS, tmp);
+
+	adf7242_read_reg(lp, REG_EXTPA_MSC, &tmp);
+	tmp &= ~PA_PWR(~0);
+	tmp |= PA_PWR(pwr);
+
+	return adf7242_write_reg(lp, REG_EXTPA_MSC, tmp);
+}
+
+static int adf7242_set_csma_params(struct ieee802154_hw *hw, u8 min_be,
+				   u8 max_be, u8 retries)
+{
+	struct adf7242_local *lp = hw->priv;
+	int ret;
+
+	dev_vdbg(&lp->spi->dev, "%s : min_be=%d max_be=%d retries=%d\n",
+		 __func__, min_be, max_be, retries);
+
+	if (min_be > max_be || max_be > 8 || retries > 5)
+		return -EINVAL;
+
+	ret = adf7242_write_reg(lp, REG_AUTO_TX1,
+				MAX_FRAME_RETRIES(lp->max_frame_retries) |
+				MAX_CCA_RETRIES(retries));
+	if (ret)
+		return ret;
+
+	lp->max_cca_retries = retries;
+	lp->max_be = max_be;
+	lp->min_be = min_be;
+
+	return adf7242_write_reg(lp, REG_AUTO_TX2, CSMA_MAX_BE(max_be) |
+			CSMA_MIN_BE(min_be));
+}
+
+static int adf7242_set_frame_retries(struct ieee802154_hw *hw, s8 retries)
+{
+	struct adf7242_local *lp = hw->priv;
+	int ret = 0;
+
+	dev_vdbg(&lp->spi->dev, "%s : Retries = %d\n", __func__, retries);
+
+	if (retries < -1 || retries > 15)
+		return -EINVAL;
+
+	if (retries >= 0)
+		ret = adf7242_write_reg(lp, REG_AUTO_TX1,
+					MAX_FRAME_RETRIES(retries) |
+					MAX_CCA_RETRIES(lp->max_cca_retries));
+
+	lp->max_frame_retries = retries;
+
+	return ret;
+}
+
+static int adf7242_ed(struct ieee802154_hw *hw, u8 *level)
+{
+	struct adf7242_local *lp = hw->priv;
+
+	*level = lp->rssi;
+
+	dev_vdbg(&lp->spi->dev, "%s :Exit level=%d\n",
+		 __func__, *level);
+
+	return 0;
+}
+
+static int adf7242_start(struct ieee802154_hw *hw)
+{
+	struct adf7242_local *lp = hw->priv;
+
+	adf7242_cmd(lp, CMD_RC_PHY_RDY);
+	adf7242_write_reg(lp, REG_IRQ1_SRC1, 0xFF);
+	enable_irq(lp->spi->irq);
+	set_bit(FLAG_START, &lp->flags);
+
+	return adf7242_cmd(lp, CMD_RC_RX);
+}
+
+static void adf7242_stop(struct ieee802154_hw *hw)
+{
+	struct adf7242_local *lp = hw->priv;
+
+	adf7242_cmd(lp, CMD_RC_IDLE);
+	clear_bit(FLAG_START, &lp->flags);
+	disable_irq(lp->spi->irq);
+	adf7242_write_reg(lp, REG_IRQ1_SRC1, 0xFF);
+}
+
+static int adf7242_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
+{
+	struct adf7242_local *lp = hw->priv;
+	unsigned long freq;
+
+	dev_dbg(&lp->spi->dev, "%s :Channel=%d\n", __func__, channel);
+
+	might_sleep();
+
+	WARN_ON(page != 0);
+	WARN_ON(channel < 11);
+	WARN_ON(channel > 26);
+
+	freq = (2405 + 5 * (channel - 11)) * 100;
+	adf7242_cmd(lp, CMD_RC_PHY_RDY);
+
+	adf7242_write_reg(lp, REG_CH_FREQ0, freq);
+	adf7242_write_reg(lp, REG_CH_FREQ1, freq >> 8);
+	adf7242_write_reg(lp, REG_CH_FREQ2, freq >> 16);
+
+	return adf7242_cmd(lp, CMD_RC_RX);
+}
+
+static int adf7242_set_hw_addr_filt(struct ieee802154_hw *hw,
+				    struct ieee802154_hw_addr_filt *filt,
+				    unsigned long changed)
+{
+	struct adf7242_local *lp = hw->priv;
+	u8 reg;
+
+	dev_dbg(&lp->spi->dev, "%s :Changed=0x%lX\n", __func__, changed);
+
+	might_sleep();
+
+	if (changed & IEEE802154_AFILT_IEEEADDR_CHANGED) {
+		u8 addr[8], i;
+
+		memcpy(addr, &filt->ieee_addr, 8);
+
+		for (i = 0; i < 8; i++)
+			adf7242_write_reg(lp, REG_IEEE_ADDR_0 + i, addr[i]);
+	}
+
+	if (changed & IEEE802154_AFILT_SADDR_CHANGED) {
+		u16 saddr = le16_to_cpu(filt->short_addr);
+
+		adf7242_write_reg(lp, REG_SHORT_ADDR_0, saddr);
+		adf7242_write_reg(lp, REG_SHORT_ADDR_1, saddr >> 8);
+	}
+
+	if (changed & IEEE802154_AFILT_PANID_CHANGED) {
+		u16 pan_id = le16_to_cpu(filt->pan_id);
+
+		adf7242_write_reg(lp, REG_PAN_ID0, pan_id);
+		adf7242_write_reg(lp, REG_PAN_ID1, pan_id >> 8);
+	}
+
+	if (changed & IEEE802154_AFILT_PANC_CHANGED) {
+		adf7242_read_reg(lp, REG_AUTO_CFG, &reg);
+		if (filt->pan_coord)
+			reg |= IS_PANCOORD;
+		else
+			reg &= ~IS_PANCOORD;
+		adf7242_write_reg(lp, REG_AUTO_CFG, reg);
+	}
+
+	return 0;
+}
+
+static int adf7242_set_promiscuous_mode(struct ieee802154_hw *hw, bool on)
+{
+	struct adf7242_local *lp = hw->priv;
+
+	dev_dbg(&lp->spi->dev, "%s : mode %d\n", __func__, on);
+
+	lp->promiscuous = on;
+
+	if (on) {
+		adf7242_write_reg(lp, REG_AUTO_CFG, 0);
+		return adf7242_write_reg(lp, REG_FFILT_CFG,
+				  ACCEPT_BEACON_FRAMES |
+				  ACCEPT_DATA_FRAMES |
+				  ACCEPT_MACCMD_FRAMES |
+				  ACCEPT_ALL_ADDRESS |
+				  ACCEPT_ACK_FRAMES |
+				  ACCEPT_RESERVED_FRAMES);
+	} else {
+		adf7242_write_reg(lp, REG_FFILT_CFG,
+				  ACCEPT_BEACON_FRAMES |
+				  ACCEPT_DATA_FRAMES |
+				  ACCEPT_MACCMD_FRAMES |
+				  ACCEPT_RESERVED_FRAMES);
+
+		return adf7242_write_reg(lp, REG_AUTO_CFG, RX_AUTO_ACK_EN);
+	}
+}
+
+static int adf7242_set_cca_ed_level(struct ieee802154_hw *hw, s32 mbm)
+{
+	struct adf7242_local *lp = hw->priv;
+	s8 level = clamp_t(s8, mbm / 100, S8_MIN, S8_MAX);
+
+	dev_dbg(&lp->spi->dev, "%s : level %d\n", __func__, level);
+
+	return adf7242_write_reg(lp, REG_CCA1, level);
+}
+
+static int adf7242_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
+{
+	struct adf7242_local *lp = hw->priv;
+	int ret;
+
+	set_bit(FLAG_XMIT, &lp->flags);
+	reinit_completion(&lp->tx_complete);
+	adf7242_cmd(lp, CMD_RC_PHY_RDY);
+
+	ret = adf7242_write_fbuf(lp, skb->data, skb->len);
+	if (ret)
+		goto err;
+
+	ret = adf7242_cmd(lp, CMD_RC_CSMACA);
+	if (ret)
+		goto err;
+
+	ret = wait_for_completion_interruptible_timeout(&lp->tx_complete,
+							HZ / 10);
+	if (ret < 0)
+		goto err;
+	if (ret == 0) {
+		dev_dbg(&lp->spi->dev, "Timeout waiting for TX interrupt\n");
+		ret = -ETIMEDOUT;
+		goto err;
+	}
+
+	if (lp->tx_stat != SUCCESS) {
+		dev_dbg(&lp->spi->dev,
+			"Error xmit: Retry count exceeded Status=0x%x\n",
+			lp->tx_stat);
+		ret = -ECOMM;
+	} else {
+		ret = 0;
+	}
+
+err:
+	clear_bit(FLAG_XMIT, &lp->flags);
+	adf7242_cmd(lp, CMD_RC_RX);
+
+	return ret;
+}
+
+static int adf7242_rx(struct adf7242_local *lp)
+{
+	struct sk_buff *skb;
+	size_t len;
+	int ret;
+	u8 lqi, len_u8, *data;
+
+	adf7242_read_reg(lp, 0, &len_u8);
+
+	len = len_u8;
+
+	if (!ieee802154_is_valid_psdu_len(len)) {
+		dev_dbg(&lp->spi->dev,
+			"corrupted frame received len %d\n", (int)len);
+		len = IEEE802154_MTU;
+	}
+
+	skb = dev_alloc_skb(len);
+	if (!skb) {
+		adf7242_cmd(lp, CMD_RC_RX);
+		return -ENOMEM;
+	}
+
+	data = skb_put(skb, len);
+	ret = adf7242_read_fbuf(lp, data, len, true);
+	if (ret < 0) {
+		kfree_skb(skb);
+		adf7242_cmd(lp, CMD_RC_RX);
+		return ret;
+	}
+
+	lqi = data[len - 2];
+	lp->rssi = data[len - 1];
+
+	adf7242_cmd(lp, CMD_RC_RX);
+
+	skb_trim(skb, len - 2);	/* Don't put RSSI/LQI or CRC into the frame */
+
+	ieee802154_rx_irqsafe(lp->hw, skb, lqi);
+
+	dev_dbg(&lp->spi->dev, "%s: ret=%d len=%d lqi=%d rssi=%d\n",
+		__func__, ret, (int)len, (int)lqi, lp->rssi);
+
+	return 0;
+}
+
+static struct ieee802154_ops adf7242_ops = {
+	.owner = THIS_MODULE,
+	.xmit_sync = adf7242_xmit,
+	.ed = adf7242_ed,
+	.set_channel = adf7242_channel,
+	.set_hw_addr_filt = adf7242_set_hw_addr_filt,
+	.start = adf7242_start,
+	.stop = adf7242_stop,
+	.set_csma_params = adf7242_set_csma_params,
+	.set_frame_retries = adf7242_set_frame_retries,
+	.set_txpower = adf7242_set_txpower,
+	.set_promiscuous_mode = adf7242_set_promiscuous_mode,
+	.set_cca_ed_level = adf7242_set_cca_ed_level,
+};
+
+static void adf7242_debug(u8 irq1)
+{
+#ifdef DEBUG
+	u8 stat;
+
+	adf7242_status(lp, &stat);
+
+	dev_dbg(&lp->spi->dev, "%s IRQ1 = %X:\n%s%s%s%s%s%s%s%s\n",
+		__func__, irq1,
+		irq1 & IRQ_CCA_COMPLETE ? "IRQ_CCA_COMPLETE\n" : "",
+		irq1 & IRQ_SFD_RX ? "IRQ_SFD_RX\n" : "",
+		irq1 & IRQ_SFD_TX ? "IRQ_SFD_TX\n" : "",
+		irq1 & IRQ_RX_PKT_RCVD ? "IRQ_RX_PKT_RCVD\n" : "",
+		irq1 & IRQ_TX_PKT_SENT ? "IRQ_TX_PKT_SENT\n" : "",
+		irq1 & IRQ_CSMA_CA ? "IRQ_CSMA_CA\n" : "",
+		irq1 & IRQ_FRAME_VALID ? "IRQ_FRAME_VALID\n" : "",
+		irq1 & IRQ_ADDRESS_VALID ? "IRQ_ADDRESS_VALID\n" : "");
+
+	dev_dbg(&lp->spi->dev, "%s STATUS = %X:\n%s\n%s%s%s%s%s\n",
+		__func__, stat,
+		stat & STAT_RC_READY ? "RC_READY" : "RC_BUSY",
+		(stat & 0xf) == RC_STATUS_IDLE ? "RC_STATUS_IDLE" : "",
+		(stat & 0xf) == RC_STATUS_MEAS ? "RC_STATUS_MEAS" : "",
+		(stat & 0xf) == RC_STATUS_PHY_RDY ? "RC_STATUS_PHY_RDY" : "",
+		(stat & 0xf) == RC_STATUS_RX ? "RC_STATUS_RX" : "",
+		(stat & 0xf) == RC_STATUS_TX ? "RC_STATUS_TX" : "");
+	}
+#endif
+}
+
+static irqreturn_t adf7242_isr(int irq, void *data)
+{
+	struct adf7242_local *lp = data;
+	unsigned xmit;
+	u8 irq1;
+
+	adf7242_wait_status(lp, RC_STATUS_PHY_RDY, RC_STATUS_MASK, __LINE__);
+
+	adf7242_read_reg(lp, REG_IRQ1_SRC1, &irq1);
+	adf7242_write_reg(lp, REG_IRQ1_SRC1, irq1);
+
+	if (!(irq1 & (IRQ_RX_PKT_RCVD | IRQ_CSMA_CA)))
+		dev_err(&lp->spi->dev, "%s :ERROR IRQ1 = 0x%X\n",
+			__func__, irq1);
+
+	adf7242_debug(irq1);
+
+	xmit = test_bit(FLAG_XMIT, &lp->flags);
+
+	if (xmit && (irq1 & IRQ_CSMA_CA)) {
+		if (ADF7242_REPORT_CSMA_CA_STAT) {
+			u8 astat;
+
+			adf7242_read_reg(lp, REG_AUTO_STATUS, &astat);
+			astat &= AUTO_STATUS_MASK;
+
+			dev_dbg(&lp->spi->dev, "AUTO_STATUS = %X:\n%s%s%s%s\n",
+				astat,
+				astat == SUCCESS ? "SUCCESS" : "",
+				astat ==
+				SUCCESS_DATPEND ? "SUCCESS_DATPEND" : "",
+				astat == FAILURE_CSMACA ? "FAILURE_CSMACA" : "",
+				astat == FAILURE_NOACK ? "FAILURE_NOACK" : "");
+
+			/* save CSMA-CA completion status */
+			lp->tx_stat = astat;
+		} else {
+			lp->tx_stat = SUCCESS;
+		}
+		complete(&lp->tx_complete);
+	} else if (!xmit && (irq1 & IRQ_RX_PKT_RCVD) &&
+		   (irq1 & IRQ_FRAME_VALID)) {
+		adf7242_rx(lp);
+	} else if (!xmit && test_bit(FLAG_START, &lp->flags)) {
+		/* Invalid packet received - drop it and restart */
+		dev_dbg(&lp->spi->dev, "%s:%d : ERROR IRQ1 = 0x%X\n",
+			__func__, __LINE__, irq1);
+		adf7242_cmd(lp, CMD_RC_PHY_RDY);
+		adf7242_write_reg(lp, REG_IRQ1_SRC1, 0xFF);
+		adf7242_cmd(lp, CMD_RC_RX);
+	} else {
+		/* This can only be xmit without IRQ, likely a RX packet.
+		 * we get an TX IRQ shortly - do nothing or let the xmit
+		 * timeout handle this
+		 */
+		dev_dbg(&lp->spi->dev, "%s:%d : ERROR IRQ1 = 0x%X, xmit %d\n",
+			__func__, __LINE__, irq1, xmit);
+		complete(&lp->tx_complete);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int adf7242_soft_reset(struct adf7242_local *lp, int line)
+{
+	dev_warn(&lp->spi->dev, "%s (line %d)\n", __func__, line);
+
+	if (test_bit(FLAG_START, &lp->flags))
+		disable_irq_nosync(lp->spi->irq);
+
+	adf7242_cmd(lp, CMD_RC_PC_RESET_NO_WAIT);
+	usleep_range(200, 250);
+	adf7242_write_reg(lp, REG_PKT_CFG, ADDON_EN | BIT(2));
+	adf7242_cmd(lp, CMD_RC_PHY_RDY);
+	adf7242_set_promiscuous_mode(lp->hw, lp->promiscuous);
+	adf7242_set_csma_params(lp->hw, lp->min_be, lp->max_be,
+				lp->max_cca_retries);
+	adf7242_write_reg(lp, REG_IRQ1_SRC1, 0xFF);
+
+	if (test_bit(FLAG_START, &lp->flags)) {
+		enable_irq(lp->spi->irq);
+		return adf7242_cmd(lp, CMD_RC_RX);
+	}
+
+	return 0;
+}
+
+static int adf7242_hw_init(struct adf7242_local *lp)
+{
+	int ret;
+	const struct firmware *fw;
+
+	adf7242_cmd(lp, CMD_RC_RESET);
+	adf7242_cmd(lp, CMD_RC_IDLE);
+
+	/* get ADF7242 addon firmware
+	 * build this driver as module
+	 * and place under /lib/firmware/adf7242_firmware.bin
+	 * or compile firmware into the kernel.
+	 */
+	ret = request_firmware(&fw, FIRMWARE, &lp->spi->dev);
+	if (ret) {
+		dev_err(&lp->spi->dev,
+			"request_firmware() failed with %d\n", ret);
+		return ret;
+	}
+
+	ret = adf7242_upload_firmware(lp, (u8 *)fw->data, fw->size);
+	if (ret) {
+		dev_err(&lp->spi->dev,
+			"upload firmware failed with %d\n", ret);
+		return ret;
+	}
+
+	ret = adf7242_verify_firmware(lp, (u8 *)fw->data, fw->size);
+	if (ret) {
+		dev_err(&lp->spi->dev,
+			"verify firmware failed with %d\n", ret);
+		return ret;
+	}
+
+	adf7242_cmd(lp, CMD_RC_PC_RESET);
+
+	release_firmware(fw);
+
+	adf7242_write_reg(lp, REG_FFILT_CFG,
+			  ACCEPT_BEACON_FRAMES |
+			  ACCEPT_DATA_FRAMES |
+			  ACCEPT_MACCMD_FRAMES |
+			  ACCEPT_RESERVED_FRAMES);
+
+	adf7242_write_reg(lp, REG_AUTO_CFG, RX_AUTO_ACK_EN);
+
+	adf7242_write_reg(lp, REG_PKT_CFG, ADDON_EN | BIT(2));
+
+	adf7242_write_reg(lp, REG_EXTPA_MSC, 0xF1);
+	adf7242_write_reg(lp, REG_RXFE_CFG, 0x1D);
+
+	adf7242_write_reg(lp, REG_IRQ1_EN0, 0);
+	adf7242_write_reg(lp, REG_IRQ1_EN1, IRQ_RX_PKT_RCVD | IRQ_CSMA_CA);
+
+	adf7242_write_reg(lp, REG_IRQ1_SRC1, 0xFF);
+	adf7242_write_reg(lp, REG_IRQ1_SRC0, 0xFF);
+
+	adf7242_cmd(lp, CMD_RC_IDLE);
+
+	return 0;
+}
+
+static int adf7242_stats_show(struct seq_file *file, void *offset)
+{
+	struct adf7242_local *lp = spi_get_drvdata(file->private);
+	u8 stat, irq1;
+
+	adf7242_status(lp, &stat);
+	adf7242_read_reg(lp, REG_IRQ1_SRC1, &irq1);
+
+	seq_printf(file, "IRQ1 = %X:\n%s%s%s%s%s%s%s%s\n", irq1,
+		   irq1 & IRQ_CCA_COMPLETE ? "IRQ_CCA_COMPLETE\n" : "",
+		   irq1 & IRQ_SFD_RX ? "IRQ_SFD_RX\n" : "",
+		   irq1 & IRQ_SFD_TX ? "IRQ_SFD_TX\n" : "",
+		   irq1 & IRQ_RX_PKT_RCVD ? "IRQ_RX_PKT_RCVD\n" : "",
+		   irq1 & IRQ_TX_PKT_SENT ? "IRQ_TX_PKT_SENT\n" : "",
+		   irq1 & IRQ_CSMA_CA ? "IRQ_CSMA_CA\n" : "",
+		   irq1 & IRQ_FRAME_VALID ? "IRQ_FRAME_VALID\n" : "",
+		   irq1 & IRQ_ADDRESS_VALID ? "IRQ_ADDRESS_VALID\n" : "");
+
+	seq_printf(file, "STATUS = %X:\n%s\n%s%s%s%s%s\n", stat,
+		   stat & STAT_RC_READY ? "RC_READY" : "RC_BUSY",
+		   (stat & 0xf) == RC_STATUS_IDLE ? "RC_STATUS_IDLE" : "",
+		   (stat & 0xf) == RC_STATUS_MEAS ? "RC_STATUS_MEAS" : "",
+		   (stat & 0xf) == RC_STATUS_PHY_RDY ? "RC_STATUS_PHY_RDY" : "",
+		   (stat & 0xf) == RC_STATUS_RX ? "RC_STATUS_RX" : "",
+		   (stat & 0xf) == RC_STATUS_TX ? "RC_STATUS_TX" : "");
+
+	seq_printf(file, "RSSI = %d\n", lp->rssi);
+
+	return 0;
+}
+
+static int adf7242_debugfs_init(struct adf7242_local *lp)
+{
+	char debugfs_dir_name[DNAME_INLINE_LEN + 1] = "adf7242-";
+	struct dentry *stats;
+
+	strncat(debugfs_dir_name, dev_name(&lp->spi->dev), DNAME_INLINE_LEN);
+
+	lp->debugfs_root = debugfs_create_dir(debugfs_dir_name, NULL);
+	if (IS_ERR_OR_NULL(lp->debugfs_root))
+		return PTR_ERR_OR_ZERO(lp->debugfs_root);
+
+	stats = debugfs_create_devm_seqfile(&lp->spi->dev, "status",
+					    lp->debugfs_root,
+					    adf7242_stats_show);
+	return PTR_ERR_OR_ZERO(stats);
+
+	return 0;
+}
+
+static const s32 adf7242_powers[] = {
+	500, 400, 300, 200, 100, 0, -100, -200, -300, -400, -500, -600, -700,
+	-800, -900, -1000, -1100, -1200, -1300, -1400, -1500, -1600, -1700,
+	-1800, -1900, -2000, -2100, -2200, -2300, -2400, -2500, -2600,
+};
+
+static const s32 adf7242_ed_levels[] = {
+	-9000, -8900, -8800, -8700, -8600, -8500, -8400, -8300, -8200, -8100,
+	-8000, -7900, -7800, -7700, -7600, -7500, -7400, -7300, -7200, -7100,
+	-7000, -6900, -6800, -6700, -6600, -6500, -6400, -6300, -6200, -6100,
+	-6000, -5900, -5800, -5700, -5600, -5500, -5400, -5300, -5200, -5100,
+	-5000, -4900, -4800, -4700, -4600, -4500, -4400, -4300, -4200, -4100,
+	-4000, -3900, -3800, -3700, -3600, -3500, -3400, -3200, -3100, -3000
+};
+
+static int adf7242_probe(struct spi_device *spi)
+{
+	struct ieee802154_hw *hw;
+	struct adf7242_local *lp;
+	int ret, irq_type;
+
+	if (!spi->irq) {
+		dev_err(&spi->dev, "no IRQ specified\n");
+		return -EINVAL;
+	}
+
+	hw = ieee802154_alloc_hw(sizeof(*lp), &adf7242_ops);
+	if (!hw)
+		return -ENOMEM;
+
+	lp = hw->priv;
+	lp->hw = hw;
+	lp->spi = spi;
+
+	hw->priv = lp;
+	hw->parent = &spi->dev;
+	hw->extra_tx_headroom = 0;
+
+	/* We support only 2.4 Ghz */
+	hw->phy->supported.channels[0] = 0x7FFF800;
+
+	hw->flags = IEEE802154_HW_OMIT_CKSUM |
+		    IEEE802154_HW_CSMA_PARAMS |
+		    IEEE802154_HW_FRAME_RETRIES | IEEE802154_HW_AFILT |
+		    IEEE802154_HW_PROMISCUOUS;
+
+	hw->phy->flags = WPAN_PHY_FLAG_TXPOWER |
+			 WPAN_PHY_FLAG_CCA_ED_LEVEL |
+			 WPAN_PHY_FLAG_CCA_MODE;
+
+	hw->phy->supported.cca_modes = BIT(NL802154_CCA_ENERGY);
+
+	hw->phy->supported.cca_ed_levels = adf7242_ed_levels;
+	hw->phy->supported.cca_ed_levels_size = ARRAY_SIZE(adf7242_ed_levels);
+
+	hw->phy->cca.mode = NL802154_CCA_ENERGY;
+
+	hw->phy->supported.tx_powers = adf7242_powers;
+	hw->phy->supported.tx_powers_size = ARRAY_SIZE(adf7242_powers);
+
+	hw->phy->supported.min_minbe = 0;
+	hw->phy->supported.max_minbe = 8;
+
+	hw->phy->supported.min_maxbe = 3;
+	hw->phy->supported.max_maxbe = 8;
+
+	hw->phy->supported.min_frame_retries = 0;
+	hw->phy->supported.max_frame_retries = 15;
+
+	hw->phy->supported.min_csma_backoffs = 0;
+	hw->phy->supported.max_csma_backoffs = 5;
+
+	ieee802154_random_extended_addr(&hw->phy->perm_extended_addr);
+
+	mutex_init(&lp->bmux);
+	init_completion(&lp->tx_complete);
+
+	/* Setup Status Message */
+	lp->stat_xfer.len = 1;
+	lp->stat_xfer.tx_buf = &lp->buf_stat_tx;
+	lp->stat_xfer.rx_buf = &lp->buf_stat_rx;
+	lp->buf_stat_tx = CMD_SPI_NOP;
+
+	spi_message_init(&lp->stat_msg);
+	spi_message_add_tail(&lp->stat_xfer, &lp->stat_msg);
+
+	spi_set_drvdata(spi, lp);
+
+	ret = adf7242_hw_init(lp);
+	if (ret)
+		goto err_hw_init;
+
+	irq_type = irq_get_trigger_type(spi->irq);
+	if (!irq_type)
+		irq_type = IRQF_TRIGGER_HIGH;
+
+	ret = devm_request_threaded_irq(&spi->dev, spi->irq, NULL, adf7242_isr,
+					irq_type | IRQF_ONESHOT,
+					dev_name(&spi->dev), lp);
+	if (ret)
+		goto err_hw_init;
+
+	disable_irq(spi->irq);
+
+	ret = ieee802154_register_hw(lp->hw);
+	if (ret)
+		goto err_hw_init;
+
+	dev_set_drvdata(&spi->dev, lp);
+
+	adf7242_debugfs_init(lp);
+
+	dev_info(&spi->dev, "mac802154 IRQ-%d registered\n", spi->irq);
+
+	return ret;
+
+err_hw_init:
+	mutex_destroy(&lp->bmux);
+	ieee802154_free_hw(lp->hw);
+
+	return ret;
+}
+
+static int adf7242_remove(struct spi_device *spi)
+{
+	struct adf7242_local *lp = spi_get_drvdata(spi);
+
+	if (!IS_ERR_OR_NULL(lp->debugfs_root))
+		debugfs_remove_recursive(lp->debugfs_root);
+
+	ieee802154_unregister_hw(lp->hw);
+	mutex_destroy(&lp->bmux);
+	ieee802154_free_hw(lp->hw);
+
+	return 0;
+}
+
+static const struct of_device_id adf7242_of_match[] = {
+	{ .compatible = "adi,adf7242", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, adf7242_of_match);
+
+static const struct spi_device_id adf7242_device_id[] = {
+	{ .name = "adf7242", },
+	{ },
+};
+MODULE_DEVICE_TABLE(spi, adf7242_device_id);
+
+static struct spi_driver adf7242_driver = {
+	.id_table = adf7242_device_id,
+	.driver = {
+		   .of_match_table = of_match_ptr(adf7242_of_match),
+		   .name = "adf7242",
+		   .owner = THIS_MODULE,
+		   },
+	.probe = adf7242_probe,
+	.remove = adf7242_remove,
+};
+
+module_spi_driver(adf7242_driver);
+
+MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
+MODULE_DESCRIPTION("ADF7242 IEEE802.15.4 Transceiver Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ieee802154/atusb.c b/drivers/net/ieee802154/atusb.c
index 199a94a..b1cd865 100644
--- a/drivers/net/ieee802154/atusb.c
+++ b/drivers/net/ieee802154/atusb.c
@@ -310,8 +310,7 @@
 		urb = usb_get_from_anchor(&atusb->idle_urbs);
 		if (!urb)
 			break;
-		if (urb->context)
-			kfree_skb(urb->context);
+		kfree_skb(urb->context);
 		usb_free_urb(urb);
 	}
 }
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index 9a863c6..fc8ad00 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -1138,9 +1138,15 @@
 	.ndo_get_stats64 = ppp_get_stats64,
 };
 
+static struct device_type ppp_type = {
+	.name = "ppp",
+};
+
 static void ppp_setup(struct net_device *dev)
 {
 	dev->netdev_ops = &ppp_netdev_ops;
+	SET_NETDEV_DEVTYPE(dev, &ppp_type);
+
 	dev->hard_header_len = PPP_HDRLEN;
 	dev->mtu = PPP_MRU;
 	dev->addr_len = 0;
@@ -2720,8 +2726,7 @@
 	int ret = -ENOMEM;
 	int i;
 
-	dev = alloc_netdev(sizeof(struct ppp), "", NET_NAME_UNKNOWN,
-			   ppp_setup);
+	dev = alloc_netdev(sizeof(struct ppp), "", NET_NAME_ENUM, ppp_setup);
 	if (!dev)
 		goto out1;
 
diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c
index e73f138..a20d688 100644
--- a/drivers/net/wan/wanxl.c
+++ b/drivers/net/wan/wanxl.c
@@ -586,6 +586,7 @@
 	if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(28)) ||
 	    pci_set_dma_mask(pdev, DMA_BIT_MASK(28))) {
 		pr_err("No usable DMA configuration\n");
+		pci_disable_device(pdev);
 		return -EIO;
 	}
 
diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c
index 05c37d6..c3e2252 100644
--- a/drivers/s390/net/ctcm_main.c
+++ b/drivers/s390/net/ctcm_main.c
@@ -1677,11 +1677,8 @@
 
 	ccw_device_set_offline(cgdev->cdev[1]);
 	ccw_device_set_offline(cgdev->cdev[0]);
-
-	if (priv->channel[CTCM_READ])
-		channel_remove(priv->channel[CTCM_READ]);
-	if (priv->channel[CTCM_WRITE])
-		channel_remove(priv->channel[CTCM_WRITE]);
+	channel_remove(priv->channel[CTCM_READ]);
+	channel_remove(priv->channel[CTCM_WRITE]);
 	priv->channel[CTCM_READ] = priv->channel[CTCM_WRITE] = NULL;
 
 	return 0;
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index 1766a20..ec2e014 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -981,6 +981,10 @@
 			  int (*reply_cb)(struct qeth_card *,
 					  struct qeth_reply *, unsigned long),
 			  void *);
+struct qeth_cmd_buffer *qeth_get_setassparms_cmd(struct qeth_card *,
+						 enum qeth_ipa_funcs,
+						 __u16, __u16,
+						 enum qeth_prot_versions);
 int qeth_start_ipa_tx_checksum(struct qeth_card *);
 int qeth_set_rx_csum(struct qeth_card *, int);
 
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 31ac53f..7871537 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -2684,8 +2684,6 @@
 			sprintf(card->info.mcl_level, "%02x%02x",
 				card->info.mcl_level[2],
 				card->info.mcl_level[3]);
-
-			card->info.mcl_level[QETH_MCL_LENGTH] = 0;
 			break;
 		}
 		/* fallthrough */
@@ -5297,10 +5295,10 @@
 	return 0;
 }
 
-static struct qeth_cmd_buffer *qeth_get_setassparms_cmd(struct qeth_card *card,
-						  enum qeth_ipa_funcs ipa_func,
-						  __u16 cmd_code, __u16 len,
-						  enum qeth_prot_versions prot)
+struct qeth_cmd_buffer *qeth_get_setassparms_cmd(struct qeth_card *card,
+						 enum qeth_ipa_funcs ipa_func,
+						 __u16 cmd_code, __u16 len,
+						 enum qeth_prot_versions prot)
 {
 	struct qeth_cmd_buffer *iob;
 	struct qeth_ipa_cmd *cmd;
@@ -5319,6 +5317,7 @@
 
 	return iob;
 }
+EXPORT_SYMBOL_GPL(qeth_get_setassparms_cmd);
 
 int qeth_send_setassparms(struct qeth_card *card,
 			  struct qeth_cmd_buffer *iob, __u16 len, long data,
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 8f1b091..80b1979 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -1126,6 +1126,7 @@
 	qeth_l2_request_initial_mac(card);
 	SET_NETDEV_DEV(card->dev, &card->gdev->dev);
 	netif_napi_add(card->dev, &card->napi, qeth_l2_poll, QETH_NAPI_WEIGHT);
+	netif_carrier_off(card->dev);
 	return register_netdev(card->dev);
 }
 
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 543960e..7c8c68c 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -1043,28 +1043,6 @@
 	return 0;
 }
 
-static struct qeth_cmd_buffer *qeth_l3_get_setassparms_cmd(
-	struct qeth_card *card, enum qeth_ipa_funcs ipa_func, __u16 cmd_code,
-	__u16 len, enum qeth_prot_versions prot)
-{
-	struct qeth_cmd_buffer *iob;
-	struct qeth_ipa_cmd *cmd;
-
-	QETH_CARD_TEXT(card, 4, "getasscm");
-	iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETASSPARMS, prot);
-
-	if (iob) {
-		cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
-		cmd->data.setassparms.hdr.assist_no = ipa_func;
-		cmd->data.setassparms.hdr.length = 8 + len;
-		cmd->data.setassparms.hdr.command_code = cmd_code;
-		cmd->data.setassparms.hdr.return_code = 0;
-		cmd->data.setassparms.hdr.seq_no = 0;
-	}
-
-	return iob;
-}
-
 #ifdef CONFIG_QETH_IPV6
 static int qeth_l3_send_simple_setassparms_ipv6(struct qeth_card *card,
 		enum qeth_ipa_funcs ipa_func, __u16 cmd_code)
@@ -1073,7 +1051,7 @@
 	struct qeth_cmd_buffer *iob;
 
 	QETH_CARD_TEXT(card, 4, "simassp6");
-	iob = qeth_l3_get_setassparms_cmd(card, ipa_func, cmd_code,
+	iob = qeth_get_setassparms_cmd(card, ipa_func, cmd_code,
 				       0, QETH_PROT_IPV6);
 	if (!iob)
 		return -ENOMEM;
@@ -2344,10 +2322,11 @@
 
 	QETH_CARD_TEXT_(card, 3, "qarpipv%i", prot);
 
-	iob = qeth_l3_get_setassparms_cmd(card, IPA_ARP_PROCESSING,
-			IPA_CMD_ASS_ARP_QUERY_INFO,
-			sizeof(struct qeth_arp_query_data) - sizeof(char),
-			prot);
+	iob = qeth_get_setassparms_cmd(card, IPA_ARP_PROCESSING,
+				       IPA_CMD_ASS_ARP_QUERY_INFO,
+				       sizeof(struct qeth_arp_query_data)
+						- sizeof(char),
+				       prot);
 	if (!iob)
 		return -ENOMEM;
 	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
@@ -2439,7 +2418,7 @@
 		return -EOPNOTSUPP;
 	}
 
-	iob = qeth_l3_get_setassparms_cmd(card, IPA_ARP_PROCESSING,
+	iob = qeth_get_setassparms_cmd(card, IPA_ARP_PROCESSING,
 				       IPA_CMD_ASS_ARP_ADD_ENTRY,
 				       sizeof(struct qeth_arp_cache_entry),
 				       QETH_PROT_IPV4);
@@ -2480,7 +2459,7 @@
 		return -EOPNOTSUPP;
 	}
 	memcpy(buf, entry, 12);
-	iob = qeth_l3_get_setassparms_cmd(card, IPA_ARP_PROCESSING,
+	iob = qeth_get_setassparms_cmd(card, IPA_ARP_PROCESSING,
 				       IPA_CMD_ASS_ARP_REMOVE_ENTRY,
 				       12,
 				       QETH_PROT_IPV4);
@@ -2818,7 +2797,7 @@
 {
 	unsigned long tcpd = (unsigned long)tcp_hdr(skb) +
 		tcp_hdr(skb)->doff * 4;
-	int tcpd_len = skb->len - (tcpd - (unsigned long)skb->data);
+	int tcpd_len = skb_headlen(skb) - (tcpd - (unsigned long)skb->data);
 	int elements = PFN_UP(tcpd + tcpd_len - 1) - PFN_DOWN(tcpd);
 
 	elements += qeth_get_elements_for_frags(skb);
@@ -3220,6 +3199,7 @@
 
 	SET_NETDEV_DEV(card->dev, &card->gdev->dev);
 	netif_napi_add(card->dev, &card->napi, qeth_l3_poll, QETH_NAPI_WEIGHT);
+	netif_carrier_off(card->dev);
 	return register_netdev(card->dev);
 }
 
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 9b9b9ea..af4f6ac 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -833,7 +833,7 @@
  *	skb_fclone_busy - check if fclone is busy
  *	@skb: buffer
  *
- * Returns true is skb is a fast clone, and its clone is not freed.
+ * Returns true if skb is a fast clone, and its clone is not freed.
  * Some drivers call skb_orphan() in their ndo_start_xmit(),
  * so we also check that this didnt happen.
  */
diff --git a/include/net/6lowpan.h b/include/net/6lowpan.h
index cf3bc56..2f6a3f2 100644
--- a/include/net/6lowpan.h
+++ b/include/net/6lowpan.h
@@ -53,6 +53,8 @@
 #ifndef __6LOWPAN_H__
 #define __6LOWPAN_H__
 
+#include <linux/debugfs.h>
+
 #include <net/ipv6.h>
 #include <net/net_namespace.h>
 
@@ -98,6 +100,7 @@
 
 struct lowpan_priv {
 	enum lowpan_lltypes lltype;
+	struct dentry *iface_debugfs;
 
 	/* must be last */
 	u8 priv[0] __aligned(sizeof(void *));
@@ -185,7 +188,12 @@
 	*hc_ptr += len;
 }
 
-void lowpan_netdev_setup(struct net_device *dev, enum lowpan_lltypes lltype);
+int lowpan_register_netdevice(struct net_device *dev,
+			      enum lowpan_lltypes lltype);
+int lowpan_register_netdev(struct net_device *dev,
+			   enum lowpan_lltypes lltype);
+void lowpan_unregister_netdevice(struct net_device *dev);
+void lowpan_unregister_netdev(struct net_device *dev);
 
 /**
  * lowpan_header_decompress - replace 6LoWPAN header with IPv6 header
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index cc22167..339ea57 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -239,7 +239,6 @@
 	HCI_LE_ENABLED,
 	HCI_ADVERTISING,
 	HCI_ADVERTISING_CONNECTABLE,
-	HCI_ADVERTISING_INSTANCE,
 	HCI_CONNECTABLE,
 	HCI_DISCOVERABLE,
 	HCI_LIMITED_DISCOVERABLE,
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 55ce209..c95e032 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -329,6 +329,9 @@
 
 	struct work_struct	discov_update;
 	struct work_struct	bg_scan_update;
+	struct work_struct	scan_update;
+	struct work_struct	connectable_update;
+	struct work_struct	discoverable_update;
 	struct delayed_work	le_scan_disable;
 	struct delayed_work	le_scan_restart;
 
@@ -1432,10 +1435,8 @@
 void mgmt_index_added(struct hci_dev *hdev);
 void mgmt_index_removed(struct hci_dev *hdev);
 void mgmt_set_powered_failed(struct hci_dev *hdev, int err);
-int mgmt_powered(struct hci_dev *hdev, u8 powered);
-int mgmt_update_adv_data(struct hci_dev *hdev);
-void mgmt_discoverable_timeout(struct hci_dev *hdev);
-void mgmt_adv_timeout_expired(struct hci_dev *hdev);
+void mgmt_power_on(struct hci_dev *hdev, int err);
+void __mgmt_power_off(struct hci_dev *hdev);
 void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
 		       bool persistent);
 void mgmt_device_connected(struct hci_dev *hdev, struct hci_conn *conn,
@@ -1490,8 +1491,15 @@
 void mgmt_new_conn_param(struct hci_dev *hdev, bdaddr_t *bdaddr,
 			 u8 bdaddr_type, u8 store_hint, u16 min_interval,
 			 u16 max_interval, u16 latency, u16 timeout);
-void mgmt_reenable_advertising(struct hci_dev *hdev);
 void mgmt_smp_complete(struct hci_conn *conn, bool complete);
+bool mgmt_get_connectable(struct hci_dev *hdev);
+void mgmt_set_connectable_complete(struct hci_dev *hdev, u8 status);
+void mgmt_set_discoverable_complete(struct hci_dev *hdev, u8 status);
+u8 mgmt_get_adv_discov_flags(struct hci_dev *hdev);
+void mgmt_advertising_added(struct sock *sk, struct hci_dev *hdev,
+			    u8 instance);
+void mgmt_advertising_removed(struct sock *sk, struct hci_dev *hdev,
+			      u8 instance);
 
 u8 hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, u16 latency,
 		      u16 to_multiplier);
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 9a5c9f0..6570f379 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -401,6 +401,21 @@
 		pfx->s6_addr[o] = addr->s6_addr[o] & (0xff00 >> b);
 }
 
+static inline void ipv6_addr_prefix_copy(struct in6_addr *addr,
+					 const struct in6_addr *pfx,
+					 int plen)
+{
+	/* caller must guarantee 0 <= plen <= 128 */
+	int o = plen >> 3,
+	    b = plen & 0x7;
+
+	memcpy(addr->s6_addr, pfx, o);
+	if (b != 0) {
+		addr->s6_addr[o] &= ~(0xff00 >> b);
+		addr->s6_addr[o] |= (pfx->s6_addr[o] & (0xff00 >> b));
+	}
+}
+
 static inline void __ipv6_addr_set_half(__be32 *addr,
 					__be32 wh, __be32 wl)
 {
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 4f8f792..4466273f 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -5790,7 +5790,7 @@
 
 #if defined(CONFIG_CGROUP_NET_PRIO) || defined(CONFIG_CGROUP_NET_CLASSID)
 
-spinlock_t cgroup_sk_update_lock;
+DEFINE_SPINLOCK(cgroup_sk_update_lock);
 static bool cgroup_sk_alloc_disabled __read_mostly;
 
 void cgroup_sk_alloc_disable(void)
diff --git a/net/6lowpan/6lowpan_i.h b/net/6lowpan/6lowpan_i.h
new file mode 100644
index 0000000..d16bb4b
--- /dev/null
+++ b/net/6lowpan/6lowpan_i.h
@@ -0,0 +1,28 @@
+#ifndef __6LOWPAN_I_H
+#define __6LOWPAN_I_H
+
+#include <linux/netdevice.h>
+
+#ifdef CONFIG_6LOWPAN_DEBUGFS
+int lowpan_dev_debugfs_init(struct net_device *dev);
+void lowpan_dev_debugfs_exit(struct net_device *dev);
+
+int __init lowpan_debugfs_init(void);
+void lowpan_debugfs_exit(void);
+#else
+static inline int lowpan_dev_debugfs_init(struct net_device *dev)
+{
+	return 0;
+}
+
+static inline void lowpan_dev_debugfs_exit(struct net_device *dev) { }
+
+static inline int __init lowpan_debugfs_init(void)
+{
+	return 0;
+}
+
+static inline void lowpan_debugfs_exit(void) { }
+#endif /* CONFIG_6LOWPAN_DEBUGFS */
+
+#endif /* __6LOWPAN_I_H */
diff --git a/net/6lowpan/Kconfig b/net/6lowpan/Kconfig
index 7fa0f38..9c05151 100644
--- a/net/6lowpan/Kconfig
+++ b/net/6lowpan/Kconfig
@@ -5,12 +5,21 @@
 	  This enables IPv6 over Low power Wireless Personal Area Network -
 	  "6LoWPAN" which is supported by IEEE 802.15.4 or Bluetooth stacks.
 
+config 6LOWPAN_DEBUGFS
+	bool "6LoWPAN debugfs support"
+	depends on 6LOWPAN
+	depends on DEBUG_FS
+	---help---
+	  This enables 6LoWPAN debugfs support. For example to manipulate
+	  IPHC context information at runtime.
+
 menuconfig 6LOWPAN_NHC
-	tristate "Next Header Compression Support"
+	tristate "Next Header and Generic Header Compression Support"
 	depends on 6LOWPAN
 	default y
 	---help---
-	  Support for next header compression.
+	  Support for next header and generic header compression defined in
+	  RFC6282 and RFC7400.
 
 if 6LOWPAN_NHC
 
@@ -58,4 +67,38 @@
 	---help---
 	  6LoWPAN IPv6 UDP Header compression according to RFC6282.
 
+config 6LOWPAN_GHC_EXT_HDR_HOP
+	tristate "GHC Hop-by-Hop Options Header Support"
+	---help---
+	  6LoWPAN IPv6 Hop-by-Hop option generic header compression according
+	  to RFC7400.
+
+config 6LOWPAN_GHC_UDP
+	tristate "GHC UDP Support"
+	---help---
+	  6LoWPAN IPv6 UDP generic header compression according to RFC7400.
+
+config 6LOWPAN_GHC_ICMPV6
+	tristate "GHC ICMPv6 Support"
+	---help---
+	  6LoWPAN IPv6 ICMPv6 generic header compression according to RFC7400.
+
+config 6LOWPAN_GHC_EXT_HDR_DEST
+	tristate "GHC Destination Options Header Support"
+	---help---
+	  6LoWPAN IPv6 destination option generic header compression according
+	  to RFC7400.
+
+config 6LOWPAN_GHC_EXT_HDR_FRAG
+	tristate "GHC Fragmentation Options Header Support"
+	---help---
+	  6LoWPAN IPv6 fragmentation option generic header compression
+	  according to RFC7400.
+
+config 6LOWPAN_GHC_EXT_HDR_ROUTE
+	tristate "GHC Routing Options Header Support"
+	---help---
+	  6LoWPAN IPv6 routing option generic header compression according
+	  to RFC7400.
+
 endif
diff --git a/net/6lowpan/Makefile b/net/6lowpan/Makefile
index c6ffc55..e44f3bf 100644
--- a/net/6lowpan/Makefile
+++ b/net/6lowpan/Makefile
@@ -1,6 +1,7 @@
 obj-$(CONFIG_6LOWPAN) += 6lowpan.o
 
 6lowpan-y := core.o iphc.o nhc.o
+6lowpan-$(CONFIG_6LOWPAN_DEBUGFS) += debugfs.o
 
 #rfc6282 nhcs
 obj-$(CONFIG_6LOWPAN_NHC_DEST) += nhc_dest.o
@@ -10,3 +11,11 @@
 obj-$(CONFIG_6LOWPAN_NHC_MOBILITY) += nhc_mobility.o
 obj-$(CONFIG_6LOWPAN_NHC_ROUTING) += nhc_routing.o
 obj-$(CONFIG_6LOWPAN_NHC_UDP) += nhc_udp.o
+
+#rfc7400 ghcs
+obj-$(CONFIG_6LOWPAN_GHC_EXT_HDR_HOP) += nhc_ghc_ext_hop.o
+obj-$(CONFIG_6LOWPAN_GHC_UDP) += nhc_ghc_udp.o
+obj-$(CONFIG_6LOWPAN_GHC_ICMPV6) += nhc_ghc_icmpv6.o
+obj-$(CONFIG_6LOWPAN_GHC_EXT_HDR_DEST) += nhc_ghc_ext_dest.o
+obj-$(CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG) += nhc_ghc_ext_frag.o
+obj-$(CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE) += nhc_ghc_ext_route.o
diff --git a/net/6lowpan/core.c b/net/6lowpan/core.c
index 83b19e0..c7f06f5 100644
--- a/net/6lowpan/core.c
+++ b/net/6lowpan/core.c
@@ -15,19 +15,67 @@
 
 #include <net/6lowpan.h>
 
-void lowpan_netdev_setup(struct net_device *dev, enum lowpan_lltypes lltype)
+#include "6lowpan_i.h"
+
+int lowpan_register_netdevice(struct net_device *dev,
+			      enum lowpan_lltypes lltype)
 {
+	int ret;
+
 	dev->addr_len = EUI64_ADDR_LEN;
 	dev->type = ARPHRD_6LOWPAN;
 	dev->mtu = IPV6_MIN_MTU;
 	dev->priv_flags |= IFF_NO_QUEUE;
 
 	lowpan_priv(dev)->lltype = lltype;
+
+	ret = lowpan_dev_debugfs_init(dev);
+	if (ret < 0)
+		return ret;
+
+	ret = register_netdevice(dev);
+	if (ret < 0)
+		lowpan_dev_debugfs_exit(dev);
+
+	return ret;
 }
-EXPORT_SYMBOL(lowpan_netdev_setup);
+EXPORT_SYMBOL(lowpan_register_netdevice);
+
+int lowpan_register_netdev(struct net_device *dev,
+			   enum lowpan_lltypes lltype)
+{
+	int ret;
+
+	rtnl_lock();
+	ret = lowpan_register_netdevice(dev, lltype);
+	rtnl_unlock();
+	return ret;
+}
+EXPORT_SYMBOL(lowpan_register_netdev);
+
+void lowpan_unregister_netdevice(struct net_device *dev)
+{
+	unregister_netdevice(dev);
+	lowpan_dev_debugfs_exit(dev);
+}
+EXPORT_SYMBOL(lowpan_unregister_netdevice);
+
+void lowpan_unregister_netdev(struct net_device *dev)
+{
+	rtnl_lock();
+	lowpan_unregister_netdevice(dev);
+	rtnl_unlock();
+}
+EXPORT_SYMBOL(lowpan_unregister_netdev);
 
 static int __init lowpan_module_init(void)
 {
+	int ret;
+
+	ret = lowpan_debugfs_init();
+	if (ret < 0)
+		return ret;
+
 	request_module_nowait("ipv6");
 
 	request_module_nowait("nhc_dest");
@@ -40,6 +88,13 @@
 
 	return 0;
 }
+
+static void __exit lowpan_module_exit(void)
+{
+	lowpan_debugfs_exit();
+}
+
 module_init(lowpan_module_init);
+module_exit(lowpan_module_exit);
 
 MODULE_LICENSE("GPL");
diff --git a/net/6lowpan/debugfs.c b/net/6lowpan/debugfs.c
new file mode 100644
index 0000000..88eef84
--- /dev/null
+++ b/net/6lowpan/debugfs.c
@@ -0,0 +1,53 @@
+/* This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Authors:
+ * (C) 2015 Pengutronix, Alexander Aring <aar@pengutronix.de>
+ * Copyright (c)  2015 Nordic Semiconductor. All Rights Reserved.
+ */
+
+#include <net/6lowpan.h>
+
+#include "6lowpan_i.h"
+
+static struct dentry *lowpan_debugfs;
+
+int lowpan_dev_debugfs_init(struct net_device *dev)
+{
+	struct lowpan_priv *lpriv = lowpan_priv(dev);
+
+	/* creating the root */
+	lpriv->iface_debugfs = debugfs_create_dir(dev->name, lowpan_debugfs);
+	if (!lpriv->iface_debugfs)
+		goto fail;
+
+	return 0;
+
+fail:
+	return -EINVAL;
+}
+
+void lowpan_dev_debugfs_exit(struct net_device *dev)
+{
+	debugfs_remove_recursive(lowpan_priv(dev)->iface_debugfs);
+}
+
+int __init lowpan_debugfs_init(void)
+{
+	lowpan_debugfs = debugfs_create_dir("6lowpan", NULL);
+	if (!lowpan_debugfs)
+		return -EINVAL;
+
+	return 0;
+}
+
+void lowpan_debugfs_exit(void)
+{
+	debugfs_remove_recursive(lowpan_debugfs);
+}
diff --git a/net/6lowpan/nhc_ghc_ext_dest.c b/net/6lowpan/nhc_ghc_ext_dest.c
new file mode 100644
index 0000000..9887b3a
--- /dev/null
+++ b/net/6lowpan/nhc_ghc_ext_dest.c
@@ -0,0 +1,27 @@
+/*
+ *	6LoWPAN Extension Header compression according to RFC7400
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ */
+
+#include "nhc.h"
+
+#define LOWPAN_GHC_EXT_DEST_IDLEN	1
+#define LOWPAN_GHC_EXT_DEST_ID_0	0xb6
+#define LOWPAN_GHC_EXT_DEST_MASK_0	0xfe
+
+static void dest_ghid_setup(struct lowpan_nhc *nhc)
+{
+	nhc->id[0] = LOWPAN_GHC_EXT_DEST_ID_0;
+	nhc->idmask[0] = LOWPAN_GHC_EXT_DEST_MASK_0;
+}
+
+LOWPAN_NHC(ghc_ext_dest, "RFC7400 Destination Extension Header", NEXTHDR_DEST,
+	   0, dest_ghid_setup, LOWPAN_GHC_EXT_DEST_IDLEN, NULL, NULL);
+
+module_lowpan_nhc(ghc_ext_dest);
+MODULE_DESCRIPTION("6LoWPAN generic header destination extension compression");
+MODULE_LICENSE("GPL");
diff --git a/net/6lowpan/nhc_ghc_ext_frag.c b/net/6lowpan/nhc_ghc_ext_frag.c
new file mode 100644
index 0000000..1308b79
--- /dev/null
+++ b/net/6lowpan/nhc_ghc_ext_frag.c
@@ -0,0 +1,28 @@
+/*
+ *	6LoWPAN Extension Header compression according to RFC7400
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ */
+
+#include "nhc.h"
+
+#define LOWPAN_GHC_EXT_FRAG_IDLEN	1
+#define LOWPAN_GHC_EXT_FRAG_ID_0	0xb4
+#define LOWPAN_GHC_EXT_FRAG_MASK_0	0xfe
+
+static void frag_ghid_setup(struct lowpan_nhc *nhc)
+{
+	nhc->id[0] = LOWPAN_GHC_EXT_FRAG_ID_0;
+	nhc->idmask[0] = LOWPAN_GHC_EXT_FRAG_MASK_0;
+}
+
+LOWPAN_NHC(ghc_ext_frag, "RFC7400 Fragmentation Extension Header",
+	   NEXTHDR_FRAGMENT, 0, frag_ghid_setup,
+	   LOWPAN_GHC_EXT_FRAG_IDLEN, NULL, NULL);
+
+module_lowpan_nhc(ghc_ext_frag);
+MODULE_DESCRIPTION("6LoWPAN generic header fragmentation extension compression");
+MODULE_LICENSE("GPL");
diff --git a/net/6lowpan/nhc_ghc_ext_hop.c b/net/6lowpan/nhc_ghc_ext_hop.c
new file mode 100644
index 0000000..baec86f
--- /dev/null
+++ b/net/6lowpan/nhc_ghc_ext_hop.c
@@ -0,0 +1,27 @@
+/*
+ *	6LoWPAN Extension Header compression according to RFC7400
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ */
+
+#include "nhc.h"
+
+#define LOWPAN_GHC_EXT_HOP_IDLEN	1
+#define LOWPAN_GHC_EXT_HOP_ID_0		0xb0
+#define LOWPAN_GHC_EXT_HOP_MASK_0	0xfe
+
+static void hop_ghid_setup(struct lowpan_nhc *nhc)
+{
+	nhc->id[0] = LOWPAN_GHC_EXT_HOP_ID_0;
+	nhc->idmask[0] = LOWPAN_GHC_EXT_HOP_MASK_0;
+}
+
+LOWPAN_NHC(ghc_ext_hop, "RFC7400 Hop-by-Hop Extension Header", NEXTHDR_HOP, 0,
+	   hop_ghid_setup, LOWPAN_GHC_EXT_HOP_IDLEN, NULL, NULL);
+
+module_lowpan_nhc(ghc_ext_hop);
+MODULE_DESCRIPTION("6LoWPAN generic header hop-by-hop extension compression");
+MODULE_LICENSE("GPL");
diff --git a/net/6lowpan/nhc_ghc_ext_route.c b/net/6lowpan/nhc_ghc_ext_route.c
new file mode 100644
index 0000000..d7e5bd7
--- /dev/null
+++ b/net/6lowpan/nhc_ghc_ext_route.c
@@ -0,0 +1,27 @@
+/*
+ *	6LoWPAN Extension Header compression according to RFC7400
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ */
+
+#include "nhc.h"
+
+#define LOWPAN_GHC_EXT_ROUTE_IDLEN	1
+#define LOWPAN_GHC_EXT_ROUTE_ID_0	0xb2
+#define LOWPAN_GHC_EXT_ROUTE_MASK_0	0xfe
+
+static void route_ghid_setup(struct lowpan_nhc *nhc)
+{
+	nhc->id[0] = LOWPAN_GHC_EXT_ROUTE_ID_0;
+	nhc->idmask[0] = LOWPAN_GHC_EXT_ROUTE_MASK_0;
+}
+
+LOWPAN_NHC(ghc_ext_route, "RFC7400 Routing Extension Header", NEXTHDR_ROUTING,
+	   0, route_ghid_setup, LOWPAN_GHC_EXT_ROUTE_IDLEN, NULL, NULL);
+
+module_lowpan_nhc(ghc_ext_route);
+MODULE_DESCRIPTION("6LoWPAN generic header routing extension compression");
+MODULE_LICENSE("GPL");
diff --git a/net/6lowpan/nhc_ghc_icmpv6.c b/net/6lowpan/nhc_ghc_icmpv6.c
new file mode 100644
index 0000000..32e7c2c
--- /dev/null
+++ b/net/6lowpan/nhc_ghc_icmpv6.c
@@ -0,0 +1,27 @@
+/*
+ *	6LoWPAN ICMPv6 compression according to RFC7400
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ */
+
+#include "nhc.h"
+
+#define LOWPAN_GHC_ICMPV6_IDLEN		1
+#define LOWPAN_GHC_ICMPV6_ID_0		0xdf
+#define LOWPAN_GHC_ICMPV6_MASK_0	0xff
+
+static void icmpv6_ghid_setup(struct lowpan_nhc *nhc)
+{
+	nhc->id[0] = LOWPAN_GHC_ICMPV6_ID_0;
+	nhc->idmask[0] = LOWPAN_GHC_ICMPV6_MASK_0;
+}
+
+LOWPAN_NHC(ghc_icmpv6, "RFC7400 ICMPv6", NEXTHDR_ICMP, 0,
+	   icmpv6_ghid_setup, LOWPAN_GHC_ICMPV6_IDLEN, NULL, NULL);
+
+module_lowpan_nhc(ghc_icmpv6);
+MODULE_DESCRIPTION("6LoWPAN generic header ICMPv6 compression");
+MODULE_LICENSE("GPL");
diff --git a/net/6lowpan/nhc_ghc_udp.c b/net/6lowpan/nhc_ghc_udp.c
new file mode 100644
index 0000000..17beefa
--- /dev/null
+++ b/net/6lowpan/nhc_ghc_udp.c
@@ -0,0 +1,27 @@
+/*
+ *	6LoWPAN UDP compression according to RFC7400
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ */
+
+#include "nhc.h"
+
+#define LOWPAN_GHC_UDP_IDLEN	1
+#define LOWPAN_GHC_UDP_ID_0	0xd0
+#define LOWPAN_GHC_UDP_MASK_0	0xf8
+
+static void udp_ghid_setup(struct lowpan_nhc *nhc)
+{
+	nhc->id[0] = LOWPAN_GHC_UDP_ID_0;
+	nhc->idmask[0] = LOWPAN_GHC_UDP_MASK_0;
+}
+
+LOWPAN_NHC(ghc_udp, "RFC7400 UDP", NEXTHDR_UDP, 0,
+	   udp_ghid_setup, LOWPAN_GHC_UDP_IDLEN, NULL, NULL);
+
+module_lowpan_nhc(ghc_udp);
+MODULE_DESCRIPTION("6LoWPAN generic header UDP compression");
+MODULE_LICENSE("GPL");
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 9e9cca3..d040365 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -825,9 +825,7 @@
 	list_add_rcu(&(*dev)->list, &bt_6lowpan_devices);
 	spin_unlock(&devices_lock);
 
-	lowpan_netdev_setup(netdev, LOWPAN_LLTYPE_BTLE);
-
-	err = register_netdev(netdev);
+	err = lowpan_register_netdev(netdev, LOWPAN_LLTYPE_BTLE);
 	if (err < 0) {
 		BT_INFO("register_netdev failed %d", err);
 		spin_lock(&devices_lock);
@@ -890,7 +888,7 @@
 	struct lowpan_dev *entry = container_of(work, struct lowpan_dev,
 						delete_netdev);
 
-	unregister_netdev(entry->netdev);
+	lowpan_unregister_netdev(entry->netdev);
 
 	/* The entry pointer is deleted by the netdev destructor. */
 }
@@ -1348,7 +1346,7 @@
 		ifdown(entry->netdev);
 		BT_DBG("Unregistering netdev %s %p",
 		       entry->netdev->name, entry->netdev);
-		unregister_netdev(entry->netdev);
+		lowpan_unregister_netdev(entry->netdev);
 		kfree(entry);
 	}
 }
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 5785e8e..cb4e8d4 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -186,8 +186,8 @@
 
 		/* FIXME: Is this check still needed */
 		if (sk->sk_state == BT_CLOSED) {
-			release_sock(sk);
 			bt_accept_unlink(sk);
+			release_sock(sk);
 			continue;
 		}
 
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
index 1641367..fbf251f 100644
--- a/net/bluetooth/bnep/core.c
+++ b/net/bluetooth/bnep/core.c
@@ -608,8 +608,11 @@
 	s->msg.msg_flags = MSG_NOSIGNAL;
 
 #ifdef CONFIG_BT_BNEP_MC_FILTER
-	/* Set default mc filter */
-	set_bit(bnep_mc_hash(dev->broadcast), (ulong *) &s->mc_filter);
+	/* Set default mc filter to not filter out any mc addresses
+	 * as defined in the BNEP specification (revision 0.95a)
+	 * http://grouper.ieee.org/groups/802/15/Bluetooth/BNEP.pdf
+	 */
+	s->mc_filter = ~0LL;
 #endif
 
 #ifdef CONFIG_BT_BNEP_PROTO_FILTER
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 2d334e0..32575b4 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -668,8 +668,16 @@
 
 	conn->state = BT_CLOSED;
 
-	mgmt_connect_failed(hdev, &conn->dst, conn->type, conn->dst_type,
-			    status);
+	/* If the status indicates successful cancellation of
+	 * the attempt (i.e. Unkown Connection Id) there's no point of
+	 * notifying failure since we'll go back to keep trying to
+	 * connect. The only exception is explicit connect requests
+	 * where a timeout + cancel does indicate an actual failure.
+	 */
+	if (status != HCI_ERROR_UNKNOWN_CONN_ID ||
+	    (params && params->explicit_connect))
+		mgmt_connect_failed(hdev, &conn->dst, conn->type,
+				    conn->dst_type, status);
 
 	hci_connect_cfm(conn, status);
 
@@ -683,7 +691,7 @@
 	/* Re-enable advertising in case this was a failed connection
 	 * attempt as a peripheral.
 	 */
-	mgmt_reenable_advertising(hdev);
+	hci_req_reenable_advertising(hdev);
 }
 
 static void create_le_conn_complete(struct hci_dev *hdev, u8 status, u16 opcode)
@@ -726,8 +734,12 @@
 	if (hci_update_random_address(req, false, &own_addr_type))
 		return;
 
+	/* Set window to be the same value as the interval to enable
+	 * continuous scanning.
+	 */
 	cp.scan_interval = cpu_to_le16(hdev->le_scan_interval);
-	cp.scan_window = cpu_to_le16(hdev->le_scan_window);
+	cp.scan_window = cp.scan_interval;
+
 	bacpy(&cp.peer_addr, &conn->dst);
 	cp.peer_addr_type = conn->dst_type;
 	cp.own_address_type = own_addr_type;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 89af7e4..9fb443a 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1399,10 +1399,10 @@
 		    !hci_dev_test_flag(hdev, HCI_CONFIG) &&
 		    !hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
 		    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
+		    hci_dev_test_flag(hdev, HCI_MGMT) &&
 		    hdev->dev_type == HCI_BREDR) {
-			hci_dev_lock(hdev);
-			mgmt_powered(hdev, 1);
-			hci_dev_unlock(hdev);
+			ret = __hci_req_hci_power_on(hdev);
+			mgmt_power_on(hdev, ret);
 		}
 	} else {
 		/* Init failed, cleanup */
@@ -1537,7 +1537,6 @@
 	flush_work(&hdev->rx_work);
 
 	if (hdev->discov_timeout > 0) {
-		cancel_delayed_work(&hdev->discov_off);
 		hdev->discov_timeout = 0;
 		hci_dev_clear_flag(hdev, HCI_DISCOVERABLE);
 		hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
@@ -1549,11 +1548,6 @@
 	if (hci_dev_test_flag(hdev, HCI_MGMT))
 		cancel_delayed_work_sync(&hdev->rpa_expired);
 
-	if (hdev->adv_instance_timeout) {
-		cancel_delayed_work_sync(&hdev->adv_instance_expire);
-		hdev->adv_instance_timeout = 0;
-	}
-
 	/* Avoid potential lockdep warnings from the *_flush() calls by
 	 * ensuring the workqueue is empty up front.
 	 */
@@ -1565,8 +1559,9 @@
 
 	auto_off = hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF);
 
-	if (!auto_off && hdev->dev_type == HCI_BREDR)
-		mgmt_powered(hdev, 0);
+	if (!auto_off && hdev->dev_type == HCI_BREDR &&
+	    hci_dev_test_flag(hdev, HCI_MGMT))
+		__mgmt_power_off(hdev);
 
 	hci_inquiry_cache_flush(hdev);
 	hci_pend_le_actions_clear(hdev);
@@ -1774,7 +1769,7 @@
 		hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
 
 		if (hci_dev_test_flag(hdev, HCI_LE_ENABLED))
-			mgmt_update_adv_data(hdev);
+			hci_req_update_adv_data(hdev, hdev->cur_adv_instance);
 
 		mgmt_new_settings(hdev);
 	}
@@ -2019,6 +2014,16 @@
 
 	BT_DBG("%s", hdev->name);
 
+	if (test_bit(HCI_UP, &hdev->flags) &&
+	    hci_dev_test_flag(hdev, HCI_MGMT) &&
+	    hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) {
+		hci_req_sync_lock(hdev);
+		err = __hci_req_hci_power_on(hdev);
+		hci_req_sync_unlock(hdev);
+		mgmt_power_on(hdev, err);
+		return;
+	}
+
 	err = hci_dev_do_open(hdev);
 	if (err < 0) {
 		hci_dev_lock(hdev);
@@ -2101,28 +2106,6 @@
 	hci_dev_do_open(hdev);
 }
 
-static void hci_discov_off(struct work_struct *work)
-{
-	struct hci_dev *hdev;
-
-	hdev = container_of(work, struct hci_dev, discov_off.work);
-
-	BT_DBG("%s", hdev->name);
-
-	mgmt_discoverable_timeout(hdev);
-}
-
-static void hci_adv_timeout_expire(struct work_struct *work)
-{
-	struct hci_dev *hdev;
-
-	hdev = container_of(work, struct hci_dev, adv_instance_expire.work);
-
-	BT_DBG("%s", hdev->name);
-
-	mgmt_adv_timeout_expired(hdev);
-}
-
 void hci_uuids_clear(struct hci_dev *hdev)
 {
 	struct bt_uuid *uuid, *tmp;
@@ -2627,9 +2610,12 @@
 
 	BT_DBG("%s removing %dMR", hdev->name, instance);
 
-	if (hdev->cur_adv_instance == instance && hdev->adv_instance_timeout) {
-		cancel_delayed_work(&hdev->adv_instance_expire);
-		hdev->adv_instance_timeout = 0;
+	if (hdev->cur_adv_instance == instance) {
+		if (hdev->adv_instance_timeout) {
+			cancel_delayed_work(&hdev->adv_instance_expire);
+			hdev->adv_instance_timeout = 0;
+		}
+		hdev->cur_adv_instance = 0x00;
 	}
 
 	list_del(&adv_instance->list);
@@ -2656,6 +2642,7 @@
 	}
 
 	hdev->adv_instance_cnt = 0;
+	hdev->cur_adv_instance = 0x00;
 }
 
 /* This function requires the caller holds hdev->lock */
@@ -3002,8 +2989,6 @@
 	INIT_WORK(&hdev->error_reset, hci_error_reset);
 
 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
-	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
-	INIT_DELAYED_WORK(&hdev->adv_instance_expire, hci_adv_timeout_expire);
 
 	skb_queue_head_init(&hdev->rx_q);
 	skb_queue_head_init(&hdev->cmd_q);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index d57c11c..7554da5 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1183,7 +1183,7 @@
 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
 		else if (!hci_dev_test_flag(hdev, HCI_LE_ADV) &&
 			 hdev->discovery.state == DISCOVERY_FINDING)
-			mgmt_reenable_advertising(hdev);
+			hci_req_reenable_advertising(hdev);
 
 		break;
 
@@ -2176,7 +2176,7 @@
 			hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
 				     sizeof(cp), &cp);
 
-			hci_update_page_scan(hdev);
+			hci_req_update_scan(hdev);
 		}
 
 		/* Set packet type for incoming connection */
@@ -2362,7 +2362,7 @@
 		if (test_bit(HCI_CONN_FLUSH_KEY, &conn->flags))
 			hci_remove_link_key(hdev, &conn->dst);
 
-		hci_update_page_scan(hdev);
+		hci_req_update_scan(hdev);
 	}
 
 	params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
@@ -2401,7 +2401,7 @@
 	 * is timed out due to Directed Advertising."
 	 */
 	if (type == LE_LINK)
-		mgmt_reenable_advertising(hdev);
+		hci_req_reenable_advertising(hdev);
 
 unlock:
 	hci_dev_unlock(hdev);
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index e639671..9997c31 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -21,8 +21,11 @@
    SOFTWARE IS DISCLAIMED.
 */
 
+#include <asm/unaligned.h>
+
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
+#include <net/bluetooth/mgmt.h>
 
 #include "smp.h"
 #include "hci_request.h"
@@ -346,6 +349,311 @@
 	hci_req_add_ev(req, opcode, plen, param, 0);
 }
 
+void __hci_req_write_fast_connectable(struct hci_request *req, bool enable)
+{
+	struct hci_dev *hdev = req->hdev;
+	struct hci_cp_write_page_scan_activity acp;
+	u8 type;
+
+	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
+		return;
+
+	if (hdev->hci_ver < BLUETOOTH_VER_1_2)
+		return;
+
+	if (enable) {
+		type = PAGE_SCAN_TYPE_INTERLACED;
+
+		/* 160 msec page scan interval */
+		acp.interval = cpu_to_le16(0x0100);
+	} else {
+		type = PAGE_SCAN_TYPE_STANDARD;	/* default */
+
+		/* default 1.28 sec page scan */
+		acp.interval = cpu_to_le16(0x0800);
+	}
+
+	acp.window = cpu_to_le16(0x0012);
+
+	if (__cpu_to_le16(hdev->page_scan_interval) != acp.interval ||
+	    __cpu_to_le16(hdev->page_scan_window) != acp.window)
+		hci_req_add(req, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY,
+			    sizeof(acp), &acp);
+
+	if (hdev->page_scan_type != type)
+		hci_req_add(req, HCI_OP_WRITE_PAGE_SCAN_TYPE, 1, &type);
+}
+
+/* This function controls the background scanning based on hdev->pend_le_conns
+ * list. If there are pending LE connection we start the background scanning,
+ * otherwise we stop it.
+ *
+ * This function requires the caller holds hdev->lock.
+ */
+static void __hci_update_background_scan(struct hci_request *req)
+{
+	struct hci_dev *hdev = req->hdev;
+
+	if (!test_bit(HCI_UP, &hdev->flags) ||
+	    test_bit(HCI_INIT, &hdev->flags) ||
+	    hci_dev_test_flag(hdev, HCI_SETUP) ||
+	    hci_dev_test_flag(hdev, HCI_CONFIG) ||
+	    hci_dev_test_flag(hdev, HCI_AUTO_OFF) ||
+	    hci_dev_test_flag(hdev, HCI_UNREGISTER))
+		return;
+
+	/* No point in doing scanning if LE support hasn't been enabled */
+	if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED))
+		return;
+
+	/* If discovery is active don't interfere with it */
+	if (hdev->discovery.state != DISCOVERY_STOPPED)
+		return;
+
+	/* Reset RSSI and UUID filters when starting background scanning
+	 * since these filters are meant for service discovery only.
+	 *
+	 * The Start Discovery and Start Service Discovery operations
+	 * ensure to set proper values for RSSI threshold and UUID
+	 * filter list. So it is safe to just reset them here.
+	 */
+	hci_discovery_filter_clear(hdev);
+
+	if (list_empty(&hdev->pend_le_conns) &&
+	    list_empty(&hdev->pend_le_reports)) {
+		/* If there is no pending LE connections or devices
+		 * to be scanned for, we should stop the background
+		 * scanning.
+		 */
+
+		/* If controller is not scanning we are done. */
+		if (!hci_dev_test_flag(hdev, HCI_LE_SCAN))
+			return;
+
+		hci_req_add_le_scan_disable(req);
+
+		BT_DBG("%s stopping background scanning", hdev->name);
+	} else {
+		/* If there is at least one pending LE connection, we should
+		 * keep the background scan running.
+		 */
+
+		/* If controller is connecting, we should not start scanning
+		 * since some controllers are not able to scan and connect at
+		 * the same time.
+		 */
+		if (hci_lookup_le_connect(hdev))
+			return;
+
+		/* If controller is currently scanning, we stop it to ensure we
+		 * don't miss any advertising (due to duplicates filter).
+		 */
+		if (hci_dev_test_flag(hdev, HCI_LE_SCAN))
+			hci_req_add_le_scan_disable(req);
+
+		hci_req_add_le_passive_scan(req);
+
+		BT_DBG("%s starting background scanning", hdev->name);
+	}
+}
+
+void __hci_req_update_name(struct hci_request *req)
+{
+	struct hci_dev *hdev = req->hdev;
+	struct hci_cp_write_local_name cp;
+
+	memcpy(cp.name, hdev->dev_name, sizeof(cp.name));
+
+	hci_req_add(req, HCI_OP_WRITE_LOCAL_NAME, sizeof(cp), &cp);
+}
+
+#define PNP_INFO_SVCLASS_ID		0x1200
+
+static u8 *create_uuid16_list(struct hci_dev *hdev, u8 *data, ptrdiff_t len)
+{
+	u8 *ptr = data, *uuids_start = NULL;
+	struct bt_uuid *uuid;
+
+	if (len < 4)
+		return ptr;
+
+	list_for_each_entry(uuid, &hdev->uuids, list) {
+		u16 uuid16;
+
+		if (uuid->size != 16)
+			continue;
+
+		uuid16 = get_unaligned_le16(&uuid->uuid[12]);
+		if (uuid16 < 0x1100)
+			continue;
+
+		if (uuid16 == PNP_INFO_SVCLASS_ID)
+			continue;
+
+		if (!uuids_start) {
+			uuids_start = ptr;
+			uuids_start[0] = 1;
+			uuids_start[1] = EIR_UUID16_ALL;
+			ptr += 2;
+		}
+
+		/* Stop if not enough space to put next UUID */
+		if ((ptr - data) + sizeof(u16) > len) {
+			uuids_start[1] = EIR_UUID16_SOME;
+			break;
+		}
+
+		*ptr++ = (uuid16 & 0x00ff);
+		*ptr++ = (uuid16 & 0xff00) >> 8;
+		uuids_start[0] += sizeof(uuid16);
+	}
+
+	return ptr;
+}
+
+static u8 *create_uuid32_list(struct hci_dev *hdev, u8 *data, ptrdiff_t len)
+{
+	u8 *ptr = data, *uuids_start = NULL;
+	struct bt_uuid *uuid;
+
+	if (len < 6)
+		return ptr;
+
+	list_for_each_entry(uuid, &hdev->uuids, list) {
+		if (uuid->size != 32)
+			continue;
+
+		if (!uuids_start) {
+			uuids_start = ptr;
+			uuids_start[0] = 1;
+			uuids_start[1] = EIR_UUID32_ALL;
+			ptr += 2;
+		}
+
+		/* Stop if not enough space to put next UUID */
+		if ((ptr - data) + sizeof(u32) > len) {
+			uuids_start[1] = EIR_UUID32_SOME;
+			break;
+		}
+
+		memcpy(ptr, &uuid->uuid[12], sizeof(u32));
+		ptr += sizeof(u32);
+		uuids_start[0] += sizeof(u32);
+	}
+
+	return ptr;
+}
+
+static u8 *create_uuid128_list(struct hci_dev *hdev, u8 *data, ptrdiff_t len)
+{
+	u8 *ptr = data, *uuids_start = NULL;
+	struct bt_uuid *uuid;
+
+	if (len < 18)
+		return ptr;
+
+	list_for_each_entry(uuid, &hdev->uuids, list) {
+		if (uuid->size != 128)
+			continue;
+
+		if (!uuids_start) {
+			uuids_start = ptr;
+			uuids_start[0] = 1;
+			uuids_start[1] = EIR_UUID128_ALL;
+			ptr += 2;
+		}
+
+		/* Stop if not enough space to put next UUID */
+		if ((ptr - data) + 16 > len) {
+			uuids_start[1] = EIR_UUID128_SOME;
+			break;
+		}
+
+		memcpy(ptr, uuid->uuid, 16);
+		ptr += 16;
+		uuids_start[0] += 16;
+	}
+
+	return ptr;
+}
+
+static void create_eir(struct hci_dev *hdev, u8 *data)
+{
+	u8 *ptr = data;
+	size_t name_len;
+
+	name_len = strlen(hdev->dev_name);
+
+	if (name_len > 0) {
+		/* EIR Data type */
+		if (name_len > 48) {
+			name_len = 48;
+			ptr[1] = EIR_NAME_SHORT;
+		} else
+			ptr[1] = EIR_NAME_COMPLETE;
+
+		/* EIR Data length */
+		ptr[0] = name_len + 1;
+
+		memcpy(ptr + 2, hdev->dev_name, name_len);
+
+		ptr += (name_len + 2);
+	}
+
+	if (hdev->inq_tx_power != HCI_TX_POWER_INVALID) {
+		ptr[0] = 2;
+		ptr[1] = EIR_TX_POWER;
+		ptr[2] = (u8) hdev->inq_tx_power;
+
+		ptr += 3;
+	}
+
+	if (hdev->devid_source > 0) {
+		ptr[0] = 9;
+		ptr[1] = EIR_DEVICE_ID;
+
+		put_unaligned_le16(hdev->devid_source, ptr + 2);
+		put_unaligned_le16(hdev->devid_vendor, ptr + 4);
+		put_unaligned_le16(hdev->devid_product, ptr + 6);
+		put_unaligned_le16(hdev->devid_version, ptr + 8);
+
+		ptr += 10;
+	}
+
+	ptr = create_uuid16_list(hdev, ptr, HCI_MAX_EIR_LENGTH - (ptr - data));
+	ptr = create_uuid32_list(hdev, ptr, HCI_MAX_EIR_LENGTH - (ptr - data));
+	ptr = create_uuid128_list(hdev, ptr, HCI_MAX_EIR_LENGTH - (ptr - data));
+}
+
+void __hci_req_update_eir(struct hci_request *req)
+{
+	struct hci_dev *hdev = req->hdev;
+	struct hci_cp_write_eir cp;
+
+	if (!hdev_is_powered(hdev))
+		return;
+
+	if (!lmp_ext_inq_capable(hdev))
+		return;
+
+	if (!hci_dev_test_flag(hdev, HCI_SSP_ENABLED))
+		return;
+
+	if (hci_dev_test_flag(hdev, HCI_SERVICE_CACHE))
+		return;
+
+	memset(&cp, 0, sizeof(cp));
+
+	create_eir(hdev, cp.data);
+
+	if (memcmp(cp.data, hdev->eir, sizeof(cp.data)) == 0)
+		return;
+
+	memcpy(hdev->eir, cp.data, sizeof(cp.data));
+
+	hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
+}
+
 void hci_req_add_le_scan_disable(struct hci_request *req)
 {
 	struct hci_cp_le_set_scan_enable cp;
@@ -507,6 +815,483 @@
 		    &enable_cp);
 }
 
+static u8 get_cur_adv_instance_scan_rsp_len(struct hci_dev *hdev)
+{
+	u8 instance = hdev->cur_adv_instance;
+	struct adv_info *adv_instance;
+
+	/* Ignore instance 0 */
+	if (instance == 0x00)
+		return 0;
+
+	adv_instance = hci_find_adv_instance(hdev, instance);
+	if (!adv_instance)
+		return 0;
+
+	/* TODO: Take into account the "appearance" and "local-name" flags here.
+	 * These are currently being ignored as they are not supported.
+	 */
+	return adv_instance->scan_rsp_len;
+}
+
+void __hci_req_disable_advertising(struct hci_request *req)
+{
+	u8 enable = 0x00;
+
+	hci_req_add(req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable);
+}
+
+static u32 get_adv_instance_flags(struct hci_dev *hdev, u8 instance)
+{
+	u32 flags;
+	struct adv_info *adv_instance;
+
+	if (instance == 0x00) {
+		/* Instance 0 always manages the "Tx Power" and "Flags"
+		 * fields
+		 */
+		flags = MGMT_ADV_FLAG_TX_POWER | MGMT_ADV_FLAG_MANAGED_FLAGS;
+
+		/* For instance 0, the HCI_ADVERTISING_CONNECTABLE setting
+		 * corresponds to the "connectable" instance flag.
+		 */
+		if (hci_dev_test_flag(hdev, HCI_ADVERTISING_CONNECTABLE))
+			flags |= MGMT_ADV_FLAG_CONNECTABLE;
+
+		return flags;
+	}
+
+	adv_instance = hci_find_adv_instance(hdev, instance);
+
+	/* Return 0 when we got an invalid instance identifier. */
+	if (!adv_instance)
+		return 0;
+
+	return adv_instance->flags;
+}
+
+void __hci_req_enable_advertising(struct hci_request *req)
+{
+	struct hci_dev *hdev = req->hdev;
+	struct hci_cp_le_set_adv_param cp;
+	u8 own_addr_type, enable = 0x01;
+	bool connectable;
+	u32 flags;
+
+	if (hci_conn_num(hdev, LE_LINK) > 0)
+		return;
+
+	if (hci_dev_test_flag(hdev, HCI_LE_ADV))
+		__hci_req_disable_advertising(req);
+
+	/* Clear the HCI_LE_ADV bit temporarily so that the
+	 * hci_update_random_address knows that it's safe to go ahead
+	 * and write a new random address. The flag will be set back on
+	 * as soon as the SET_ADV_ENABLE HCI command completes.
+	 */
+	hci_dev_clear_flag(hdev, HCI_LE_ADV);
+
+	flags = get_adv_instance_flags(hdev, hdev->cur_adv_instance);
+
+	/* If the "connectable" instance flag was not set, then choose between
+	 * ADV_IND and ADV_NONCONN_IND based on the global connectable setting.
+	 */
+	connectable = (flags & MGMT_ADV_FLAG_CONNECTABLE) ||
+		      mgmt_get_connectable(hdev);
+
+	/* Set require_privacy to true only when non-connectable
+	 * advertising is used. In that case it is fine to use a
+	 * non-resolvable private address.
+	 */
+	if (hci_update_random_address(req, !connectable, &own_addr_type) < 0)
+		return;
+
+	memset(&cp, 0, sizeof(cp));
+	cp.min_interval = cpu_to_le16(hdev->le_adv_min_interval);
+	cp.max_interval = cpu_to_le16(hdev->le_adv_max_interval);
+
+	if (connectable)
+		cp.type = LE_ADV_IND;
+	else if (get_cur_adv_instance_scan_rsp_len(hdev))
+		cp.type = LE_ADV_SCAN_IND;
+	else
+		cp.type = LE_ADV_NONCONN_IND;
+
+	cp.own_address_type = own_addr_type;
+	cp.channel_map = hdev->le_adv_channel_map;
+
+	hci_req_add(req, HCI_OP_LE_SET_ADV_PARAM, sizeof(cp), &cp);
+
+	hci_req_add(req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable);
+}
+
+static u8 create_default_scan_rsp_data(struct hci_dev *hdev, u8 *ptr)
+{
+	u8 ad_len = 0;
+	size_t name_len;
+
+	name_len = strlen(hdev->dev_name);
+	if (name_len > 0) {
+		size_t max_len = HCI_MAX_AD_LENGTH - ad_len - 2;
+
+		if (name_len > max_len) {
+			name_len = max_len;
+			ptr[1] = EIR_NAME_SHORT;
+		} else
+			ptr[1] = EIR_NAME_COMPLETE;
+
+		ptr[0] = name_len + 1;
+
+		memcpy(ptr + 2, hdev->dev_name, name_len);
+
+		ad_len += (name_len + 2);
+		ptr += (name_len + 2);
+	}
+
+	return ad_len;
+}
+
+static u8 create_instance_scan_rsp_data(struct hci_dev *hdev, u8 instance,
+					u8 *ptr)
+{
+	struct adv_info *adv_instance;
+
+	adv_instance = hci_find_adv_instance(hdev, instance);
+	if (!adv_instance)
+		return 0;
+
+	/* TODO: Set the appropriate entries based on advertising instance flags
+	 * here once flags other than 0 are supported.
+	 */
+	memcpy(ptr, adv_instance->scan_rsp_data,
+	       adv_instance->scan_rsp_len);
+
+	return adv_instance->scan_rsp_len;
+}
+
+void __hci_req_update_scan_rsp_data(struct hci_request *req, u8 instance)
+{
+	struct hci_dev *hdev = req->hdev;
+	struct hci_cp_le_set_scan_rsp_data cp;
+	u8 len;
+
+	if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED))
+		return;
+
+	memset(&cp, 0, sizeof(cp));
+
+	if (instance)
+		len = create_instance_scan_rsp_data(hdev, instance, cp.data);
+	else
+		len = create_default_scan_rsp_data(hdev, cp.data);
+
+	if (hdev->scan_rsp_data_len == len &&
+	    !memcmp(cp.data, hdev->scan_rsp_data, len))
+		return;
+
+	memcpy(hdev->scan_rsp_data, cp.data, sizeof(cp.data));
+	hdev->scan_rsp_data_len = len;
+
+	cp.length = len;
+
+	hci_req_add(req, HCI_OP_LE_SET_SCAN_RSP_DATA, sizeof(cp), &cp);
+}
+
+static u8 create_instance_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr)
+{
+	struct adv_info *adv_instance = NULL;
+	u8 ad_len = 0, flags = 0;
+	u32 instance_flags;
+
+	/* Return 0 when the current instance identifier is invalid. */
+	if (instance) {
+		adv_instance = hci_find_adv_instance(hdev, instance);
+		if (!adv_instance)
+			return 0;
+	}
+
+	instance_flags = get_adv_instance_flags(hdev, instance);
+
+	/* The Add Advertising command allows userspace to set both the general
+	 * and limited discoverable flags.
+	 */
+	if (instance_flags & MGMT_ADV_FLAG_DISCOV)
+		flags |= LE_AD_GENERAL;
+
+	if (instance_flags & MGMT_ADV_FLAG_LIMITED_DISCOV)
+		flags |= LE_AD_LIMITED;
+
+	if (flags || (instance_flags & MGMT_ADV_FLAG_MANAGED_FLAGS)) {
+		/* If a discovery flag wasn't provided, simply use the global
+		 * settings.
+		 */
+		if (!flags)
+			flags |= mgmt_get_adv_discov_flags(hdev);
+
+		if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
+			flags |= LE_AD_NO_BREDR;
+
+		/* If flags would still be empty, then there is no need to
+		 * include the "Flags" AD field".
+		 */
+		if (flags) {
+			ptr[0] = 0x02;
+			ptr[1] = EIR_FLAGS;
+			ptr[2] = flags;
+
+			ad_len += 3;
+			ptr += 3;
+		}
+	}
+
+	if (adv_instance) {
+		memcpy(ptr, adv_instance->adv_data,
+		       adv_instance->adv_data_len);
+		ad_len += adv_instance->adv_data_len;
+		ptr += adv_instance->adv_data_len;
+	}
+
+	/* Provide Tx Power only if we can provide a valid value for it */
+	if (hdev->adv_tx_power != HCI_TX_POWER_INVALID &&
+	    (instance_flags & MGMT_ADV_FLAG_TX_POWER)) {
+		ptr[0] = 0x02;
+		ptr[1] = EIR_TX_POWER;
+		ptr[2] = (u8)hdev->adv_tx_power;
+
+		ad_len += 3;
+		ptr += 3;
+	}
+
+	return ad_len;
+}
+
+void __hci_req_update_adv_data(struct hci_request *req, u8 instance)
+{
+	struct hci_dev *hdev = req->hdev;
+	struct hci_cp_le_set_adv_data cp;
+	u8 len;
+
+	if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED))
+		return;
+
+	memset(&cp, 0, sizeof(cp));
+
+	len = create_instance_adv_data(hdev, instance, cp.data);
+
+	/* There's nothing to do if the data hasn't changed */
+	if (hdev->adv_data_len == len &&
+	    memcmp(cp.data, hdev->adv_data, len) == 0)
+		return;
+
+	memcpy(hdev->adv_data, cp.data, sizeof(cp.data));
+	hdev->adv_data_len = len;
+
+	cp.length = len;
+
+	hci_req_add(req, HCI_OP_LE_SET_ADV_DATA, sizeof(cp), &cp);
+}
+
+int hci_req_update_adv_data(struct hci_dev *hdev, u8 instance)
+{
+	struct hci_request req;
+
+	hci_req_init(&req, hdev);
+	__hci_req_update_adv_data(&req, instance);
+
+	return hci_req_run(&req, NULL);
+}
+
+static void adv_enable_complete(struct hci_dev *hdev, u8 status, u16 opcode)
+{
+	BT_DBG("%s status %u", hdev->name, status);
+}
+
+void hci_req_reenable_advertising(struct hci_dev *hdev)
+{
+	struct hci_request req;
+
+	if (!hci_dev_test_flag(hdev, HCI_ADVERTISING) &&
+	    list_empty(&hdev->adv_instances))
+		return;
+
+	hci_req_init(&req, hdev);
+
+	if (hdev->cur_adv_instance) {
+		__hci_req_schedule_adv_instance(&req, hdev->cur_adv_instance,
+						true);
+	} else {
+		__hci_req_update_adv_data(&req, 0x00);
+		__hci_req_update_scan_rsp_data(&req, 0x00);
+		__hci_req_enable_advertising(&req);
+	}
+
+	hci_req_run(&req, adv_enable_complete);
+}
+
+static void adv_timeout_expire(struct work_struct *work)
+{
+	struct hci_dev *hdev = container_of(work, struct hci_dev,
+					    adv_instance_expire.work);
+
+	struct hci_request req;
+	u8 instance;
+
+	BT_DBG("%s", hdev->name);
+
+	hci_dev_lock(hdev);
+
+	hdev->adv_instance_timeout = 0;
+
+	instance = hdev->cur_adv_instance;
+	if (instance == 0x00)
+		goto unlock;
+
+	hci_req_init(&req, hdev);
+
+	hci_req_clear_adv_instance(hdev, &req, instance, false);
+
+	if (list_empty(&hdev->adv_instances))
+		__hci_req_disable_advertising(&req);
+
+	hci_req_run(&req, NULL);
+
+unlock:
+	hci_dev_unlock(hdev);
+}
+
+int __hci_req_schedule_adv_instance(struct hci_request *req, u8 instance,
+				    bool force)
+{
+	struct hci_dev *hdev = req->hdev;
+	struct adv_info *adv_instance = NULL;
+	u16 timeout;
+
+	if (hci_dev_test_flag(hdev, HCI_ADVERTISING) ||
+	    list_empty(&hdev->adv_instances))
+		return -EPERM;
+
+	if (hdev->adv_instance_timeout)
+		return -EBUSY;
+
+	adv_instance = hci_find_adv_instance(hdev, instance);
+	if (!adv_instance)
+		return -ENOENT;
+
+	/* A zero timeout means unlimited advertising. As long as there is
+	 * only one instance, duration should be ignored. We still set a timeout
+	 * in case further instances are being added later on.
+	 *
+	 * If the remaining lifetime of the instance is more than the duration
+	 * then the timeout corresponds to the duration, otherwise it will be
+	 * reduced to the remaining instance lifetime.
+	 */
+	if (adv_instance->timeout == 0 ||
+	    adv_instance->duration <= adv_instance->remaining_time)
+		timeout = adv_instance->duration;
+	else
+		timeout = adv_instance->remaining_time;
+
+	/* The remaining time is being reduced unless the instance is being
+	 * advertised without time limit.
+	 */
+	if (adv_instance->timeout)
+		adv_instance->remaining_time =
+				adv_instance->remaining_time - timeout;
+
+	hdev->adv_instance_timeout = timeout;
+	queue_delayed_work(hdev->req_workqueue,
+			   &hdev->adv_instance_expire,
+			   msecs_to_jiffies(timeout * 1000));
+
+	/* If we're just re-scheduling the same instance again then do not
+	 * execute any HCI commands. This happens when a single instance is
+	 * being advertised.
+	 */
+	if (!force && hdev->cur_adv_instance == instance &&
+	    hci_dev_test_flag(hdev, HCI_LE_ADV))
+		return 0;
+
+	hdev->cur_adv_instance = instance;
+	__hci_req_update_adv_data(req, instance);
+	__hci_req_update_scan_rsp_data(req, instance);
+	__hci_req_enable_advertising(req);
+
+	return 0;
+}
+
+static void cancel_adv_timeout(struct hci_dev *hdev)
+{
+	if (hdev->adv_instance_timeout) {
+		hdev->adv_instance_timeout = 0;
+		cancel_delayed_work(&hdev->adv_instance_expire);
+	}
+}
+
+/* For a single instance:
+ * - force == true: The instance will be removed even when its remaining
+ *   lifetime is not zero.
+ * - force == false: the instance will be deactivated but kept stored unless
+ *   the remaining lifetime is zero.
+ *
+ * For instance == 0x00:
+ * - force == true: All instances will be removed regardless of their timeout
+ *   setting.
+ * - force == false: Only instances that have a timeout will be removed.
+ */
+void hci_req_clear_adv_instance(struct hci_dev *hdev, struct hci_request *req,
+				u8 instance, bool force)
+{
+	struct adv_info *adv_instance, *n, *next_instance = NULL;
+	int err;
+	u8 rem_inst;
+
+	/* Cancel any timeout concerning the removed instance(s). */
+	if (!instance || hdev->cur_adv_instance == instance)
+		cancel_adv_timeout(hdev);
+
+	/* Get the next instance to advertise BEFORE we remove
+	 * the current one. This can be the same instance again
+	 * if there is only one instance.
+	 */
+	if (instance && hdev->cur_adv_instance == instance)
+		next_instance = hci_get_next_instance(hdev, instance);
+
+	if (instance == 0x00) {
+		list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances,
+					 list) {
+			if (!(force || adv_instance->timeout))
+				continue;
+
+			rem_inst = adv_instance->instance;
+			err = hci_remove_adv_instance(hdev, rem_inst);
+			if (!err)
+				mgmt_advertising_removed(NULL, hdev, rem_inst);
+		}
+	} else {
+		adv_instance = hci_find_adv_instance(hdev, instance);
+
+		if (force || (adv_instance && adv_instance->timeout &&
+			      !adv_instance->remaining_time)) {
+			/* Don't advertise a removed instance. */
+			if (next_instance &&
+			    next_instance->instance == instance)
+				next_instance = NULL;
+
+			err = hci_remove_adv_instance(hdev, instance);
+			if (!err)
+				mgmt_advertising_removed(NULL, hdev, instance);
+		}
+	}
+
+	if (!req || !hdev_is_powered(hdev) ||
+	    hci_dev_test_flag(hdev, HCI_ADVERTISING))
+		return;
+
+	if (next_instance)
+		__hci_req_schedule_adv_instance(req, next_instance->instance,
+						false);
+}
+
 static void set_random_addr(struct hci_request *req, bdaddr_t *rpa)
 {
 	struct hci_dev *hdev = req->hdev;
@@ -637,7 +1422,7 @@
 	return false;
 }
 
-void __hci_update_page_scan(struct hci_request *req)
+void __hci_req_update_scan(struct hci_request *req)
 {
 	struct hci_dev *hdev = req->hdev;
 	u8 scan;
@@ -657,95 +1442,168 @@
 	else
 		scan = SCAN_DISABLED;
 
-	if (test_bit(HCI_PSCAN, &hdev->flags) == !!(scan & SCAN_PAGE))
-		return;
-
 	if (hci_dev_test_flag(hdev, HCI_DISCOVERABLE))
 		scan |= SCAN_INQUIRY;
 
+	if (test_bit(HCI_PSCAN, &hdev->flags) == !!(scan & SCAN_PAGE) &&
+	    test_bit(HCI_ISCAN, &hdev->flags) == !!(scan & SCAN_INQUIRY))
+		return;
+
 	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
 }
 
-void hci_update_page_scan(struct hci_dev *hdev)
+static int update_scan(struct hci_request *req, unsigned long opt)
 {
-	struct hci_request req;
-
-	hci_req_init(&req, hdev);
-	__hci_update_page_scan(&req);
-	hci_req_run(&req, NULL);
+	hci_dev_lock(req->hdev);
+	__hci_req_update_scan(req);
+	hci_dev_unlock(req->hdev);
+	return 0;
 }
 
-/* This function controls the background scanning based on hdev->pend_le_conns
- * list. If there are pending LE connection we start the background scanning,
- * otherwise we stop it.
- *
- * This function requires the caller holds hdev->lock.
- */
-static void __hci_update_background_scan(struct hci_request *req)
+static void scan_update_work(struct work_struct *work)
+{
+	struct hci_dev *hdev = container_of(work, struct hci_dev, scan_update);
+
+	hci_req_sync(hdev, update_scan, 0, HCI_CMD_TIMEOUT, NULL);
+}
+
+static int connectable_update(struct hci_request *req, unsigned long opt)
 {
 	struct hci_dev *hdev = req->hdev;
 
-	if (!test_bit(HCI_UP, &hdev->flags) ||
-	    test_bit(HCI_INIT, &hdev->flags) ||
-	    hci_dev_test_flag(hdev, HCI_SETUP) ||
-	    hci_dev_test_flag(hdev, HCI_CONFIG) ||
-	    hci_dev_test_flag(hdev, HCI_AUTO_OFF) ||
-	    hci_dev_test_flag(hdev, HCI_UNREGISTER))
-		return;
+	hci_dev_lock(hdev);
 
-	/* No point in doing scanning if LE support hasn't been enabled */
-	if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED))
-		return;
+	__hci_req_update_scan(req);
 
-	/* If discovery is active don't interfere with it */
-	if (hdev->discovery.state != DISCOVERY_STOPPED)
-		return;
-
-	/* Reset RSSI and UUID filters when starting background scanning
-	 * since these filters are meant for service discovery only.
-	 *
-	 * The Start Discovery and Start Service Discovery operations
-	 * ensure to set proper values for RSSI threshold and UUID
-	 * filter list. So it is safe to just reset them here.
+	/* If BR/EDR is not enabled and we disable advertising as a
+	 * by-product of disabling connectable, we need to update the
+	 * advertising flags.
 	 */
-	hci_discovery_filter_clear(hdev);
+	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
+		__hci_req_update_adv_data(req, hdev->cur_adv_instance);
 
-	if (list_empty(&hdev->pend_le_conns) &&
-	    list_empty(&hdev->pend_le_reports)) {
-		/* If there is no pending LE connections or devices
-		 * to be scanned for, we should stop the background
-		 * scanning.
-		 */
+	/* Update the advertising parameters if necessary */
+	if (hci_dev_test_flag(hdev, HCI_ADVERTISING) ||
+	    !list_empty(&hdev->adv_instances))
+		__hci_req_enable_advertising(req);
 
-		/* If controller is not scanning we are done. */
-		if (!hci_dev_test_flag(hdev, HCI_LE_SCAN))
-			return;
+	__hci_update_background_scan(req);
 
-		hci_req_add_le_scan_disable(req);
+	hci_dev_unlock(hdev);
 
-		BT_DBG("%s stopping background scanning", hdev->name);
+	return 0;
+}
+
+static void connectable_update_work(struct work_struct *work)
+{
+	struct hci_dev *hdev = container_of(work, struct hci_dev,
+					    connectable_update);
+	u8 status;
+
+	hci_req_sync(hdev, connectable_update, 0, HCI_CMD_TIMEOUT, &status);
+	mgmt_set_connectable_complete(hdev, status);
+}
+
+static u8 get_service_classes(struct hci_dev *hdev)
+{
+	struct bt_uuid *uuid;
+	u8 val = 0;
+
+	list_for_each_entry(uuid, &hdev->uuids, list)
+		val |= uuid->svc_hint;
+
+	return val;
+}
+
+void __hci_req_update_class(struct hci_request *req)
+{
+	struct hci_dev *hdev = req->hdev;
+	u8 cod[3];
+
+	BT_DBG("%s", hdev->name);
+
+	if (!hdev_is_powered(hdev))
+		return;
+
+	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
+		return;
+
+	if (hci_dev_test_flag(hdev, HCI_SERVICE_CACHE))
+		return;
+
+	cod[0] = hdev->minor_class;
+	cod[1] = hdev->major_class;
+	cod[2] = get_service_classes(hdev);
+
+	if (hci_dev_test_flag(hdev, HCI_LIMITED_DISCOVERABLE))
+		cod[1] |= 0x20;
+
+	if (memcmp(cod, hdev->dev_class, 3) == 0)
+		return;
+
+	hci_req_add(req, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod);
+}
+
+static void write_iac(struct hci_request *req)
+{
+	struct hci_dev *hdev = req->hdev;
+	struct hci_cp_write_current_iac_lap cp;
+
+	if (!hci_dev_test_flag(hdev, HCI_DISCOVERABLE))
+		return;
+
+	if (hci_dev_test_flag(hdev, HCI_LIMITED_DISCOVERABLE)) {
+		/* Limited discoverable mode */
+		cp.num_iac = min_t(u8, hdev->num_iac, 2);
+		cp.iac_lap[0] = 0x00;	/* LIAC */
+		cp.iac_lap[1] = 0x8b;
+		cp.iac_lap[2] = 0x9e;
+		cp.iac_lap[3] = 0x33;	/* GIAC */
+		cp.iac_lap[4] = 0x8b;
+		cp.iac_lap[5] = 0x9e;
 	} else {
-		/* If there is at least one pending LE connection, we should
-		 * keep the background scan running.
-		 */
-
-		/* If controller is connecting, we should not start scanning
-		 * since some controllers are not able to scan and connect at
-		 * the same time.
-		 */
-		if (hci_lookup_le_connect(hdev))
-			return;
-
-		/* If controller is currently scanning, we stop it to ensure we
-		 * don't miss any advertising (due to duplicates filter).
-		 */
-		if (hci_dev_test_flag(hdev, HCI_LE_SCAN))
-			hci_req_add_le_scan_disable(req);
-
-		hci_req_add_le_passive_scan(req);
-
-		BT_DBG("%s starting background scanning", hdev->name);
+		/* General discoverable mode */
+		cp.num_iac = 1;
+		cp.iac_lap[0] = 0x33;	/* GIAC */
+		cp.iac_lap[1] = 0x8b;
+		cp.iac_lap[2] = 0x9e;
 	}
+
+	hci_req_add(req, HCI_OP_WRITE_CURRENT_IAC_LAP,
+		    (cp.num_iac * 3) + 1, &cp);
+}
+
+static int discoverable_update(struct hci_request *req, unsigned long opt)
+{
+	struct hci_dev *hdev = req->hdev;
+
+	hci_dev_lock(hdev);
+
+	if (hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
+		write_iac(req);
+		__hci_req_update_scan(req);
+		__hci_req_update_class(req);
+	}
+
+	/* Advertising instances don't use the global discoverable setting, so
+	 * only update AD if advertising was enabled using Set Advertising.
+	 */
+	if (hci_dev_test_flag(hdev, HCI_ADVERTISING))
+		__hci_req_update_adv_data(req, 0x00);
+
+	hci_dev_unlock(hdev);
+
+	return 0;
+}
+
+static void discoverable_update_work(struct work_struct *work)
+{
+	struct hci_dev *hdev = container_of(work, struct hci_dev,
+					    discoverable_update);
+	u8 status;
+
+	hci_req_sync(hdev, discoverable_update, 0, HCI_CMD_TIMEOUT, &status);
+	mgmt_set_discoverable_complete(hdev, status);
 }
 
 void __hci_abort_conn(struct hci_request *req, struct hci_conn *conn,
@@ -1024,14 +1882,6 @@
 	hci_dev_unlock(hdev);
 }
 
-static void cancel_adv_timeout(struct hci_dev *hdev)
-{
-	if (hdev->adv_instance_timeout) {
-		hdev->adv_instance_timeout = 0;
-		cancel_delayed_work(&hdev->adv_instance_expire);
-	}
-}
-
 static void disable_advertising(struct hci_request *req)
 {
 	u8 enable = 0x00;
@@ -1266,12 +2116,134 @@
 	}
 }
 
+static void discov_off(struct work_struct *work)
+{
+	struct hci_dev *hdev = container_of(work, struct hci_dev,
+					    discov_off.work);
+
+	BT_DBG("%s", hdev->name);
+
+	hci_dev_lock(hdev);
+
+	/* When discoverable timeout triggers, then just make sure
+	 * the limited discoverable flag is cleared. Even in the case
+	 * of a timeout triggered from general discoverable, it is
+	 * safe to unconditionally clear the flag.
+	 */
+	hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
+	hci_dev_clear_flag(hdev, HCI_DISCOVERABLE);
+	hdev->discov_timeout = 0;
+
+	hci_dev_unlock(hdev);
+
+	hci_req_sync(hdev, discoverable_update, 0, HCI_CMD_TIMEOUT, NULL);
+	mgmt_new_settings(hdev);
+}
+
+static int powered_update_hci(struct hci_request *req, unsigned long opt)
+{
+	struct hci_dev *hdev = req->hdev;
+	u8 link_sec;
+
+	hci_dev_lock(hdev);
+
+	if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED) &&
+	    !lmp_host_ssp_capable(hdev)) {
+		u8 mode = 0x01;
+
+		hci_req_add(req, HCI_OP_WRITE_SSP_MODE, sizeof(mode), &mode);
+
+		if (bredr_sc_enabled(hdev) && !lmp_host_sc_capable(hdev)) {
+			u8 support = 0x01;
+
+			hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT,
+				    sizeof(support), &support);
+		}
+	}
+
+	if (hci_dev_test_flag(hdev, HCI_LE_ENABLED) &&
+	    lmp_bredr_capable(hdev)) {
+		struct hci_cp_write_le_host_supported cp;
+
+		cp.le = 0x01;
+		cp.simul = 0x00;
+
+		/* Check first if we already have the right
+		 * host state (host features set)
+		 */
+		if (cp.le != lmp_host_le_capable(hdev) ||
+		    cp.simul != lmp_host_le_br_capable(hdev))
+			hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED,
+				    sizeof(cp), &cp);
+	}
+
+	if (hci_dev_test_flag(hdev, HCI_LE_ENABLED)) {
+		/* Make sure the controller has a good default for
+		 * advertising data. This also applies to the case
+		 * where BR/EDR was toggled during the AUTO_OFF phase.
+		 */
+		if (hci_dev_test_flag(hdev, HCI_ADVERTISING) ||
+		    list_empty(&hdev->adv_instances)) {
+			__hci_req_update_adv_data(req, 0x00);
+			__hci_req_update_scan_rsp_data(req, 0x00);
+
+			if (hci_dev_test_flag(hdev, HCI_ADVERTISING))
+				__hci_req_enable_advertising(req);
+		} else if (!list_empty(&hdev->adv_instances)) {
+			struct adv_info *adv_instance;
+
+			adv_instance = list_first_entry(&hdev->adv_instances,
+							struct adv_info, list);
+			__hci_req_schedule_adv_instance(req,
+							adv_instance->instance,
+							true);
+		}
+	}
+
+	link_sec = hci_dev_test_flag(hdev, HCI_LINK_SECURITY);
+	if (link_sec != test_bit(HCI_AUTH, &hdev->flags))
+		hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE,
+			    sizeof(link_sec), &link_sec);
+
+	if (lmp_bredr_capable(hdev)) {
+		if (hci_dev_test_flag(hdev, HCI_FAST_CONNECTABLE))
+			__hci_req_write_fast_connectable(req, true);
+		else
+			__hci_req_write_fast_connectable(req, false);
+		__hci_req_update_scan(req);
+		__hci_req_update_class(req);
+		__hci_req_update_name(req);
+		__hci_req_update_eir(req);
+	}
+
+	hci_dev_unlock(hdev);
+	return 0;
+}
+
+int __hci_req_hci_power_on(struct hci_dev *hdev)
+{
+	/* Register the available SMP channels (BR/EDR and LE) only when
+	 * successfully powering on the controller. This late
+	 * registration is required so that LE SMP can clearly decide if
+	 * the public address or static address is used.
+	 */
+	smp_register(hdev);
+
+	return __hci_req_sync(hdev, powered_update_hci, 0, HCI_CMD_TIMEOUT,
+			      NULL);
+}
+
 void hci_request_setup(struct hci_dev *hdev)
 {
 	INIT_WORK(&hdev->discov_update, discov_update);
 	INIT_WORK(&hdev->bg_scan_update, bg_scan_update);
+	INIT_WORK(&hdev->scan_update, scan_update_work);
+	INIT_WORK(&hdev->connectable_update, connectable_update_work);
+	INIT_WORK(&hdev->discoverable_update, discoverable_update_work);
+	INIT_DELAYED_WORK(&hdev->discov_off, discov_off);
 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
 	INIT_DELAYED_WORK(&hdev->le_scan_restart, le_scan_restart_work);
+	INIT_DELAYED_WORK(&hdev->adv_instance_expire, adv_timeout_expire);
 }
 
 void hci_request_cancel_all(struct hci_dev *hdev)
@@ -1280,6 +2252,15 @@
 
 	cancel_work_sync(&hdev->discov_update);
 	cancel_work_sync(&hdev->bg_scan_update);
+	cancel_work_sync(&hdev->scan_update);
+	cancel_work_sync(&hdev->connectable_update);
+	cancel_work_sync(&hdev->discoverable_update);
+	cancel_delayed_work_sync(&hdev->discov_off);
 	cancel_delayed_work_sync(&hdev->le_scan_disable);
 	cancel_delayed_work_sync(&hdev->le_scan_restart);
+
+	if (hdev->adv_instance_timeout) {
+		cancel_delayed_work_sync(&hdev->adv_instance_expire);
+		hdev->adv_instance_timeout = 0;
+	}
 }
diff --git a/net/bluetooth/hci_request.h b/net/bluetooth/hci_request.h
index 6b9e59f..64ff8c0 100644
--- a/net/bluetooth/hci_request.h
+++ b/net/bluetooth/hci_request.h
@@ -55,14 +55,38 @@
 struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, u32 plen,
 				const void *param);
 
+int __hci_req_hci_power_on(struct hci_dev *hdev);
+
+void __hci_req_write_fast_connectable(struct hci_request *req, bool enable);
+void __hci_req_update_name(struct hci_request *req);
+void __hci_req_update_eir(struct hci_request *req);
+
 void hci_req_add_le_scan_disable(struct hci_request *req);
 void hci_req_add_le_passive_scan(struct hci_request *req);
 
+void hci_req_reenable_advertising(struct hci_dev *hdev);
+void __hci_req_enable_advertising(struct hci_request *req);
+void __hci_req_disable_advertising(struct hci_request *req);
+void __hci_req_update_adv_data(struct hci_request *req, u8 instance);
+int hci_req_update_adv_data(struct hci_dev *hdev, u8 instance);
+void __hci_req_update_scan_rsp_data(struct hci_request *req, u8 instance);
+
+int __hci_req_schedule_adv_instance(struct hci_request *req, u8 instance,
+				    bool force);
+void hci_req_clear_adv_instance(struct hci_dev *hdev, struct hci_request *req,
+				u8 instance, bool force);
+
+void __hci_req_update_class(struct hci_request *req);
+
 /* Returns true if HCI commands were queued */
 bool hci_req_stop_discovery(struct hci_request *req);
 
-void hci_update_page_scan(struct hci_dev *hdev);
-void __hci_update_page_scan(struct hci_request *req);
+static inline void hci_req_update_scan(struct hci_dev *hdev)
+{
+	queue_work(hdev->req_workqueue, &hdev->scan_update);
+}
+
+void __hci_req_update_scan(struct hci_request *req);
 
 int hci_update_random_address(struct hci_request *req, bool require_privacy,
 			      u8 *own_addr_type);
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 3d9d2e4..621f6fd 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -719,116 +719,6 @@
 	return settings;
 }
 
-#define PNP_INFO_SVCLASS_ID		0x1200
-
-static u8 *create_uuid16_list(struct hci_dev *hdev, u8 *data, ptrdiff_t len)
-{
-	u8 *ptr = data, *uuids_start = NULL;
-	struct bt_uuid *uuid;
-
-	if (len < 4)
-		return ptr;
-
-	list_for_each_entry(uuid, &hdev->uuids, list) {
-		u16 uuid16;
-
-		if (uuid->size != 16)
-			continue;
-
-		uuid16 = get_unaligned_le16(&uuid->uuid[12]);
-		if (uuid16 < 0x1100)
-			continue;
-
-		if (uuid16 == PNP_INFO_SVCLASS_ID)
-			continue;
-
-		if (!uuids_start) {
-			uuids_start = ptr;
-			uuids_start[0] = 1;
-			uuids_start[1] = EIR_UUID16_ALL;
-			ptr += 2;
-		}
-
-		/* Stop if not enough space to put next UUID */
-		if ((ptr - data) + sizeof(u16) > len) {
-			uuids_start[1] = EIR_UUID16_SOME;
-			break;
-		}
-
-		*ptr++ = (uuid16 & 0x00ff);
-		*ptr++ = (uuid16 & 0xff00) >> 8;
-		uuids_start[0] += sizeof(uuid16);
-	}
-
-	return ptr;
-}
-
-static u8 *create_uuid32_list(struct hci_dev *hdev, u8 *data, ptrdiff_t len)
-{
-	u8 *ptr = data, *uuids_start = NULL;
-	struct bt_uuid *uuid;
-
-	if (len < 6)
-		return ptr;
-
-	list_for_each_entry(uuid, &hdev->uuids, list) {
-		if (uuid->size != 32)
-			continue;
-
-		if (!uuids_start) {
-			uuids_start = ptr;
-			uuids_start[0] = 1;
-			uuids_start[1] = EIR_UUID32_ALL;
-			ptr += 2;
-		}
-
-		/* Stop if not enough space to put next UUID */
-		if ((ptr - data) + sizeof(u32) > len) {
-			uuids_start[1] = EIR_UUID32_SOME;
-			break;
-		}
-
-		memcpy(ptr, &uuid->uuid[12], sizeof(u32));
-		ptr += sizeof(u32);
-		uuids_start[0] += sizeof(u32);
-	}
-
-	return ptr;
-}
-
-static u8 *create_uuid128_list(struct hci_dev *hdev, u8 *data, ptrdiff_t len)
-{
-	u8 *ptr = data, *uuids_start = NULL;
-	struct bt_uuid *uuid;
-
-	if (len < 18)
-		return ptr;
-
-	list_for_each_entry(uuid, &hdev->uuids, list) {
-		if (uuid->size != 128)
-			continue;
-
-		if (!uuids_start) {
-			uuids_start = ptr;
-			uuids_start[0] = 1;
-			uuids_start[1] = EIR_UUID128_ALL;
-			ptr += 2;
-		}
-
-		/* Stop if not enough space to put next UUID */
-		if ((ptr - data) + 16 > len) {
-			uuids_start[1] = EIR_UUID128_SOME;
-			break;
-		}
-
-		memcpy(ptr, uuid->uuid, 16);
-		ptr += 16;
-		uuids_start[0] += 16;
-	}
-
-	return ptr;
-}
-
 static struct mgmt_pending_cmd *pending_find(u16 opcode, struct hci_dev *hdev)
 {
 	return mgmt_pending_find(HCI_CHANNEL_CONTROL, opcode, hdev);
@@ -841,98 +731,7 @@
 	return mgmt_pending_find_data(HCI_CHANNEL_CONTROL, opcode, hdev, data);
 }
 
-static u8 get_current_adv_instance(struct hci_dev *hdev)
-{
-	/* The "Set Advertising" setting supersedes the "Add Advertising"
-	 * setting. Here we set the advertising data based on which
-	 * setting was set. When neither apply, default to the global settings,
-	 * represented by instance "0".
-	 */
-	if (hci_dev_test_flag(hdev, HCI_ADVERTISING_INSTANCE) &&
-	    !hci_dev_test_flag(hdev, HCI_ADVERTISING))
-		return hdev->cur_adv_instance;
-
-	return 0x00;
-}
-
-static u8 create_default_scan_rsp_data(struct hci_dev *hdev, u8 *ptr)
-{
-	u8 ad_len = 0;
-	size_t name_len;
-
-	name_len = strlen(hdev->dev_name);
-	if (name_len > 0) {
-		size_t max_len = HCI_MAX_AD_LENGTH - ad_len - 2;
-
-		if (name_len > max_len) {
-			name_len = max_len;
-			ptr[1] = EIR_NAME_SHORT;
-		} else
-			ptr[1] = EIR_NAME_COMPLETE;
-
-		ptr[0] = name_len + 1;
-
-		memcpy(ptr + 2, hdev->dev_name, name_len);
-
-		ad_len += (name_len + 2);
-		ptr += (name_len + 2);
-	}
-
-	return ad_len;
-}
-
-static u8 create_instance_scan_rsp_data(struct hci_dev *hdev, u8 instance,
-					u8 *ptr)
-{
-	struct adv_info *adv_instance;
-
-	adv_instance = hci_find_adv_instance(hdev, instance);
-	if (!adv_instance)
-		return 0;
-
-	/* TODO: Set the appropriate entries based on advertising instance flags
-	 * here once flags other than 0 are supported.
-	 */
-	memcpy(ptr, adv_instance->scan_rsp_data,
-	       adv_instance->scan_rsp_len);
-
-	return adv_instance->scan_rsp_len;
-}
-
-static void update_inst_scan_rsp_data(struct hci_request *req, u8 instance)
-{
-	struct hci_dev *hdev = req->hdev;
-	struct hci_cp_le_set_scan_rsp_data cp;
-	u8 len;
-
-	if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED))
-		return;
-
-	memset(&cp, 0, sizeof(cp));
-
-	if (instance)
-		len = create_instance_scan_rsp_data(hdev, instance, cp.data);
-	else
-		len = create_default_scan_rsp_data(hdev, cp.data);
-
-	if (hdev->scan_rsp_data_len == len &&
-	    !memcmp(cp.data, hdev->scan_rsp_data, len))
-		return;
-
-	memcpy(hdev->scan_rsp_data, cp.data, sizeof(cp.data));
-	hdev->scan_rsp_data_len = len;
-
-	cp.length = len;
-
-	hci_req_add(req, HCI_OP_LE_SET_SCAN_RSP_DATA, sizeof(cp), &cp);
-}
-
-static void update_scan_rsp_data(struct hci_request *req)
-{
-	update_inst_scan_rsp_data(req, get_current_adv_instance(req->hdev));
-}
-
-static u8 get_adv_discov_flags(struct hci_dev *hdev)
+u8 mgmt_get_adv_discov_flags(struct hci_dev *hdev)
 {
 	struct mgmt_pending_cmd *cmd;
 
@@ -956,7 +755,7 @@
 	return 0;
 }
 
-static bool get_connectable(struct hci_dev *hdev)
+bool mgmt_get_connectable(struct hci_dev *hdev)
 {
 	struct mgmt_pending_cmd *cmd;
 
@@ -973,344 +772,6 @@
 	return hci_dev_test_flag(hdev, HCI_CONNECTABLE);
 }
 
-static u32 get_adv_instance_flags(struct hci_dev *hdev, u8 instance)
-{
-	u32 flags;
-	struct adv_info *adv_instance;
-
-	if (instance == 0x00) {
-		/* Instance 0 always manages the "Tx Power" and "Flags"
-		 * fields
-		 */
-		flags = MGMT_ADV_FLAG_TX_POWER | MGMT_ADV_FLAG_MANAGED_FLAGS;
-
-		/* For instance 0, the HCI_ADVERTISING_CONNECTABLE setting
-		 * corresponds to the "connectable" instance flag.
-		 */
-		if (hci_dev_test_flag(hdev, HCI_ADVERTISING_CONNECTABLE))
-			flags |= MGMT_ADV_FLAG_CONNECTABLE;
-
-		return flags;
-	}
-
-	adv_instance = hci_find_adv_instance(hdev, instance);
-
-	/* Return 0 when we got an invalid instance identifier. */
-	if (!adv_instance)
-		return 0;
-
-	return adv_instance->flags;
-}
-
-static u8 get_cur_adv_instance_scan_rsp_len(struct hci_dev *hdev)
-{
-	u8 instance = get_current_adv_instance(hdev);
-	struct adv_info *adv_instance;
-
-	/* Ignore instance 0 */
-	if (instance == 0x00)
-		return 0;
-
-	adv_instance = hci_find_adv_instance(hdev, instance);
-	if (!adv_instance)
-		return 0;
-
-	/* TODO: Take into account the "appearance" and "local-name" flags here.
-	 * These are currently being ignored as they are not supported.
-	 */
-	return adv_instance->scan_rsp_len;
-}
-
-static u8 create_instance_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr)
-{
-	struct adv_info *adv_instance = NULL;
-	u8 ad_len = 0, flags = 0;
-	u32 instance_flags;
-
-	/* Return 0 when the current instance identifier is invalid. */
-	if (instance) {
-		adv_instance = hci_find_adv_instance(hdev, instance);
-		if (!adv_instance)
-			return 0;
-	}
-
-	instance_flags = get_adv_instance_flags(hdev, instance);
-
-	/* The Add Advertising command allows userspace to set both the general
-	 * and limited discoverable flags.
-	 */
-	if (instance_flags & MGMT_ADV_FLAG_DISCOV)
-		flags |= LE_AD_GENERAL;
-
-	if (instance_flags & MGMT_ADV_FLAG_LIMITED_DISCOV)
-		flags |= LE_AD_LIMITED;
-
-	if (flags || (instance_flags & MGMT_ADV_FLAG_MANAGED_FLAGS)) {
-		/* If a discovery flag wasn't provided, simply use the global
-		 * settings.
-		 */
-		if (!flags)
-			flags |= get_adv_discov_flags(hdev);
-
-		if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
-			flags |= LE_AD_NO_BREDR;
-
-		/* If flags would still be empty, then there is no need to
-		 * include the "Flags" AD field".
-		 */
-		if (flags) {
-			ptr[0] = 0x02;
-			ptr[1] = EIR_FLAGS;
-			ptr[2] = flags;
-
-			ad_len += 3;
-			ptr += 3;
-		}
-	}
-
-	if (adv_instance) {
-		memcpy(ptr, adv_instance->adv_data,
-		       adv_instance->adv_data_len);
-		ad_len += adv_instance->adv_data_len;
-		ptr += adv_instance->adv_data_len;
-	}
-
-	/* Provide Tx Power only if we can provide a valid value for it */
-	if (hdev->adv_tx_power != HCI_TX_POWER_INVALID &&
-	    (instance_flags & MGMT_ADV_FLAG_TX_POWER)) {
-		ptr[0] = 0x02;
-		ptr[1] = EIR_TX_POWER;
-		ptr[2] = (u8)hdev->adv_tx_power;
-
-		ad_len += 3;
-		ptr += 3;
-	}
-
-	return ad_len;
-}
-
-static void update_inst_adv_data(struct hci_request *req, u8 instance)
-{
-	struct hci_dev *hdev = req->hdev;
-	struct hci_cp_le_set_adv_data cp;
-	u8 len;
-
-	if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED))
-		return;
-
-	memset(&cp, 0, sizeof(cp));
-
-	len = create_instance_adv_data(hdev, instance, cp.data);
-
-	/* There's nothing to do if the data hasn't changed */
-	if (hdev->adv_data_len == len &&
-	    memcmp(cp.data, hdev->adv_data, len) == 0)
-		return;
-
-	memcpy(hdev->adv_data, cp.data, sizeof(cp.data));
-	hdev->adv_data_len = len;
-
-	cp.length = len;
-
-	hci_req_add(req, HCI_OP_LE_SET_ADV_DATA, sizeof(cp), &cp);
-}
-
-static void update_adv_data(struct hci_request *req)
-{
-	update_inst_adv_data(req, get_current_adv_instance(req->hdev));
-}
-
-int mgmt_update_adv_data(struct hci_dev *hdev)
-{
-	struct hci_request req;
-
-	hci_req_init(&req, hdev);
-	update_adv_data(&req);
-
-	return hci_req_run(&req, NULL);
-}
-
-static void create_eir(struct hci_dev *hdev, u8 *data)
-{
-	u8 *ptr = data;
-	size_t name_len;
-
-	name_len = strlen(hdev->dev_name);
-
-	if (name_len > 0) {
-		/* EIR Data type */
-		if (name_len > 48) {
-			name_len = 48;
-			ptr[1] = EIR_NAME_SHORT;
-		} else
-			ptr[1] = EIR_NAME_COMPLETE;
-
-		/* EIR Data length */
-		ptr[0] = name_len + 1;
-
-		memcpy(ptr + 2, hdev->dev_name, name_len);
-
-		ptr += (name_len + 2);
-	}
-
-	if (hdev->inq_tx_power != HCI_TX_POWER_INVALID) {
-		ptr[0] = 2;
-		ptr[1] = EIR_TX_POWER;
-		ptr[2] = (u8) hdev->inq_tx_power;
-
-		ptr += 3;
-	}
-
-	if (hdev->devid_source > 0) {
-		ptr[0] = 9;
-		ptr[1] = EIR_DEVICE_ID;
-
-		put_unaligned_le16(hdev->devid_source, ptr + 2);
-		put_unaligned_le16(hdev->devid_vendor, ptr + 4);
-		put_unaligned_le16(hdev->devid_product, ptr + 6);
-		put_unaligned_le16(hdev->devid_version, ptr + 8);
-
-		ptr += 10;
-	}
-
-	ptr = create_uuid16_list(hdev, ptr, HCI_MAX_EIR_LENGTH - (ptr - data));
-	ptr = create_uuid32_list(hdev, ptr, HCI_MAX_EIR_LENGTH - (ptr - data));
-	ptr = create_uuid128_list(hdev, ptr, HCI_MAX_EIR_LENGTH - (ptr - data));
-}
-
-static void update_eir(struct hci_request *req)
-{
-	struct hci_dev *hdev = req->hdev;
-	struct hci_cp_write_eir cp;
-
-	if (!hdev_is_powered(hdev))
-		return;
-
-	if (!lmp_ext_inq_capable(hdev))
-		return;
-
-	if (!hci_dev_test_flag(hdev, HCI_SSP_ENABLED))
-		return;
-
-	if (hci_dev_test_flag(hdev, HCI_SERVICE_CACHE))
-		return;
-
-	memset(&cp, 0, sizeof(cp));
-
-	create_eir(hdev, cp.data);
-
-	if (memcmp(cp.data, hdev->eir, sizeof(cp.data)) == 0)
-		return;
-
-	memcpy(hdev->eir, cp.data, sizeof(cp.data));
-
-	hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
-}
-
-static u8 get_service_classes(struct hci_dev *hdev)
-{
-	struct bt_uuid *uuid;
-	u8 val = 0;
-
-	list_for_each_entry(uuid, &hdev->uuids, list)
-		val |= uuid->svc_hint;
-
-	return val;
-}
-
-static void update_class(struct hci_request *req)
-{
-	struct hci_dev *hdev = req->hdev;
-	u8 cod[3];
-
-	BT_DBG("%s", hdev->name);
-
-	if (!hdev_is_powered(hdev))
-		return;
-
-	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
-		return;
-
-	if (hci_dev_test_flag(hdev, HCI_SERVICE_CACHE))
-		return;
-
-	cod[0] = hdev->minor_class;
-	cod[1] = hdev->major_class;
-	cod[2] = get_service_classes(hdev);
-
-	if (hci_dev_test_flag(hdev, HCI_LIMITED_DISCOVERABLE))
-		cod[1] |= 0x20;
-
-	if (memcmp(cod, hdev->dev_class, 3) == 0)
-		return;
-
-	hci_req_add(req, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod);
-}
-
-static void disable_advertising(struct hci_request *req)
-{
-	u8 enable = 0x00;
-
-	hci_req_add(req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable);
-}
-
-static void enable_advertising(struct hci_request *req)
-{
-	struct hci_dev *hdev = req->hdev;
-	struct hci_cp_le_set_adv_param cp;
-	u8 own_addr_type, enable = 0x01;
-	bool connectable;
-	u8 instance;
-	u32 flags;
-
-	if (hci_conn_num(hdev, LE_LINK) > 0)
-		return;
-
-	if (hci_dev_test_flag(hdev, HCI_LE_ADV))
-		disable_advertising(req);
-
-	/* Clear the HCI_LE_ADV bit temporarily so that the
-	 * hci_update_random_address knows that it's safe to go ahead
-	 * and write a new random address. The flag will be set back on
-	 * as soon as the SET_ADV_ENABLE HCI command completes.
-	 */
-	hci_dev_clear_flag(hdev, HCI_LE_ADV);
-
-	instance = get_current_adv_instance(hdev);
-	flags = get_adv_instance_flags(hdev, instance);
-
-	/* If the "connectable" instance flag was not set, then choose between
-	 * ADV_IND and ADV_NONCONN_IND based on the global connectable setting.
-	 */
-	connectable = (flags & MGMT_ADV_FLAG_CONNECTABLE) ||
-		      get_connectable(hdev);
-
-	/* Set require_privacy to true only when non-connectable
-	 * advertising is used. In that case it is fine to use a
-	 * non-resolvable private address.
-	 */
-	if (hci_update_random_address(req, !connectable, &own_addr_type) < 0)
-		return;
-
-	memset(&cp, 0, sizeof(cp));
-	cp.min_interval = cpu_to_le16(hdev->le_adv_min_interval);
-	cp.max_interval = cpu_to_le16(hdev->le_adv_max_interval);
-
-	if (connectable)
-		cp.type = LE_ADV_IND;
-	else if (get_cur_adv_instance_scan_rsp_len(hdev))
-		cp.type = LE_ADV_SCAN_IND;
-	else
-		cp.type = LE_ADV_NONCONN_IND;
-
-	cp.own_address_type = own_addr_type;
-	cp.channel_map = hdev->le_adv_channel_map;
-
-	hci_req_add(req, HCI_OP_LE_SET_ADV_PARAM, sizeof(cp), &cp);
-
-	hci_req_add(req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable);
-}
-
 static void service_cache_off(struct work_struct *work)
 {
 	struct hci_dev *hdev = container_of(work, struct hci_dev,
@@ -1324,8 +785,8 @@
 
 	hci_dev_lock(hdev);
 
-	update_eir(&req);
-	update_class(&req);
+	__hci_req_update_eir(&req);
+	__hci_req_update_class(&req);
 
 	hci_dev_unlock(hdev);
 
@@ -1346,10 +807,11 @@
 		return;
 
 	/* The generation of a new RPA and programming it into the
-	 * controller happens in the enable_advertising() function.
+	 * controller happens in the hci_req_enable_advertising()
+	 * function.
 	 */
 	hci_req_init(&req, hdev);
-	enable_advertising(&req);
+	__hci_req_enable_advertising(&req);
 	hci_req_run(&req, NULL);
 }
 
@@ -1417,8 +879,7 @@
 	}
 }
 
-static void advertising_added(struct sock *sk, struct hci_dev *hdev,
-			      u8 instance)
+void mgmt_advertising_added(struct sock *sk, struct hci_dev *hdev, u8 instance)
 {
 	struct mgmt_ev_advertising_added ev;
 
@@ -1427,8 +888,8 @@
 	mgmt_event(MGMT_EV_ADVERTISING_ADDED, hdev, &ev, sizeof(ev), sk);
 }
 
-static void advertising_removed(struct sock *sk, struct hci_dev *hdev,
-				u8 instance)
+void mgmt_advertising_removed(struct sock *sk, struct hci_dev *hdev,
+			      u8 instance)
 {
 	struct mgmt_ev_advertising_removed ev;
 
@@ -1437,65 +898,6 @@
 	mgmt_event(MGMT_EV_ADVERTISING_REMOVED, hdev, &ev, sizeof(ev), sk);
 }
 
-static int schedule_adv_instance(struct hci_request *req, u8 instance,
-				 bool force) {
-	struct hci_dev *hdev = req->hdev;
-	struct adv_info *adv_instance = NULL;
-	u16 timeout;
-
-	if (hci_dev_test_flag(hdev, HCI_ADVERTISING) ||
-	    !hci_dev_test_flag(hdev, HCI_ADVERTISING_INSTANCE))
-		return -EPERM;
-
-	if (hdev->adv_instance_timeout)
-		return -EBUSY;
-
-	adv_instance = hci_find_adv_instance(hdev, instance);
-	if (!adv_instance)
-		return -ENOENT;
-
-	/* A zero timeout means unlimited advertising. As long as there is
-	 * only one instance, duration should be ignored. We still set a timeout
-	 * in case further instances are being added later on.
-	 *
-	 * If the remaining lifetime of the instance is more than the duration
-	 * then the timeout corresponds to the duration, otherwise it will be
-	 * reduced to the remaining instance lifetime.
-	 */
-	if (adv_instance->timeout == 0 ||
-	    adv_instance->duration <= adv_instance->remaining_time)
-		timeout = adv_instance->duration;
-	else
-		timeout = adv_instance->remaining_time;
-
-	/* The remaining time is being reduced unless the instance is being
-	 * advertised without time limit.
-	 */
-	if (adv_instance->timeout)
-		adv_instance->remaining_time =
-				adv_instance->remaining_time - timeout;
-
-	hdev->adv_instance_timeout = timeout;
-	queue_delayed_work(hdev->workqueue,
-			   &hdev->adv_instance_expire,
-			   msecs_to_jiffies(timeout * 1000));
-
-	/* If we're just re-scheduling the same instance again then do not
-	 * execute any HCI commands. This happens when a single instance is
-	 * being advertised.
-	 */
-	if (!force && hdev->cur_adv_instance == instance &&
-	    hci_dev_test_flag(hdev, HCI_LE_ADV))
-		return 0;
-
-	hdev->cur_adv_instance = instance;
-	update_adv_data(req);
-	update_scan_rsp_data(req);
-	enable_advertising(req);
-
-	return 0;
-}
-
 static void cancel_adv_timeout(struct hci_dev *hdev)
 {
 	if (hdev->adv_instance_timeout) {
@@ -1504,76 +906,6 @@
 	}
 }
 
-/* For a single instance:
- * - force == true: The instance will be removed even when its remaining
- *   lifetime is not zero.
- * - force == false: the instance will be deactivated but kept stored unless
- *   the remaining lifetime is zero.
- *
- * For instance == 0x00:
- * - force == true: All instances will be removed regardless of their timeout
- *   setting.
- * - force == false: Only instances that have a timeout will be removed.
- */
-static void clear_adv_instance(struct hci_dev *hdev, struct hci_request *req,
-			       u8 instance, bool force)
-{
-	struct adv_info *adv_instance, *n, *next_instance = NULL;
-	int err;
-	u8 rem_inst;
-
-	/* Cancel any timeout concerning the removed instance(s). */
-	if (!instance || hdev->cur_adv_instance == instance)
-		cancel_adv_timeout(hdev);
-
-	/* Get the next instance to advertise BEFORE we remove
-	 * the current one. This can be the same instance again
-	 * if there is only one instance.
-	 */
-	if (instance && hdev->cur_adv_instance == instance)
-		next_instance = hci_get_next_instance(hdev, instance);
-
-	if (instance == 0x00) {
-		list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances,
-					 list) {
-			if (!(force || adv_instance->timeout))
-				continue;
-
-			rem_inst = adv_instance->instance;
-			err = hci_remove_adv_instance(hdev, rem_inst);
-			if (!err)
-				advertising_removed(NULL, hdev, rem_inst);
-		}
-		hdev->cur_adv_instance = 0x00;
-	} else {
-		adv_instance = hci_find_adv_instance(hdev, instance);
-
-		if (force || (adv_instance && adv_instance->timeout &&
-			      !adv_instance->remaining_time)) {
-			/* Don't advertise a removed instance. */
-			if (next_instance &&
-			    next_instance->instance == instance)
-				next_instance = NULL;
-
-			err = hci_remove_adv_instance(hdev, instance);
-			if (!err)
-				advertising_removed(NULL, hdev, instance);
-		}
-	}
-
-	if (list_empty(&hdev->adv_instances)) {
-		hdev->cur_adv_instance = 0x00;
-		hci_dev_clear_flag(hdev, HCI_ADVERTISING_INSTANCE);
-	}
-
-	if (!req || !hdev_is_powered(hdev) ||
-	    hci_dev_test_flag(hdev, HCI_ADVERTISING))
-		return;
-
-	if (next_instance)
-		schedule_adv_instance(req, next_instance->instance, false);
-}
-
 static int clean_up_hci_state(struct hci_dev *hdev)
 {
 	struct hci_request req;
@@ -1589,10 +921,10 @@
 		hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
 	}
 
-	clear_adv_instance(hdev, NULL, 0x00, false);
+	hci_req_clear_adv_instance(hdev, NULL, 0x00, false);
 
 	if (hci_dev_test_flag(hdev, HCI_LE_ADV))
-		disable_advertising(&req);
+		__hci_req_disable_advertising(&req);
 
 	discov_stopped = hci_req_stop_discovery(&req);
 
@@ -1629,17 +961,6 @@
 		goto failed;
 	}
 
-	if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) {
-		cancel_delayed_work(&hdev->power_off);
-
-		if (cp->val) {
-			mgmt_pending_add(sk, MGMT_OP_SET_POWERED, hdev,
-					 data, len);
-			err = mgmt_powered(hdev, 1);
-			goto failed;
-		}
-	}
-
 	if (!!cp->val == hdev_is_powered(hdev)) {
 		err = send_settings_rsp(sk, MGMT_OP_SET_POWERED, hdev);
 		goto failed;
@@ -1763,13 +1084,9 @@
 		return MGMT_STATUS_SUCCESS;
 }
 
-static void set_discoverable_complete(struct hci_dev *hdev, u8 status,
-				      u16 opcode)
+void mgmt_set_discoverable_complete(struct hci_dev *hdev, u8 status)
 {
 	struct mgmt_pending_cmd *cmd;
-	struct mgmt_mode *cp;
-	struct hci_request req;
-	bool changed;
 
 	BT_DBG("status 0x%02x", status);
 
@@ -1786,33 +1103,14 @@
 		goto remove_cmd;
 	}
 
-	cp = cmd->param;
-	if (cp->val) {
-		changed = !hci_dev_test_and_set_flag(hdev, HCI_DISCOVERABLE);
-
-		if (hdev->discov_timeout > 0) {
-			int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
-			queue_delayed_work(hdev->workqueue, &hdev->discov_off,
-					   to);
-		}
-	} else {
-		changed = hci_dev_test_and_clear_flag(hdev, HCI_DISCOVERABLE);
+	if (hci_dev_test_flag(hdev, HCI_DISCOVERABLE) &&
+	    hdev->discov_timeout > 0) {
+		int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
+		queue_delayed_work(hdev->req_workqueue, &hdev->discov_off, to);
 	}
 
 	send_settings_rsp(cmd->sk, MGMT_OP_SET_DISCOVERABLE, hdev);
-
-	if (changed)
-		new_settings(hdev, cmd->sk);
-
-	/* When the discoverable mode gets changed, make sure
-	 * that class of device has the limited discoverable
-	 * bit correctly set. Also update page scan based on whitelist
-	 * entries.
-	 */
-	hci_req_init(&req, hdev);
-	__hci_update_page_scan(&req);
-	update_class(&req);
-	hci_req_run(&req, NULL);
+	new_settings(hdev, cmd->sk);
 
 remove_cmd:
 	mgmt_pending_remove(cmd);
@@ -1826,9 +1124,7 @@
 {
 	struct mgmt_cp_set_discoverable *cp = data;
 	struct mgmt_pending_cmd *cmd;
-	struct hci_request req;
 	u16 timeout;
-	u8 scan;
 	int err;
 
 	BT_DBG("request for %s", hdev->name);
@@ -1907,8 +1203,8 @@
 
 		if (cp->val && hdev->discov_timeout > 0) {
 			int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
-			queue_delayed_work(hdev->workqueue, &hdev->discov_off,
-					   to);
+			queue_delayed_work(hdev->req_workqueue,
+					   &hdev->discov_off, to);
 		}
 
 		err = send_settings_rsp(sk, MGMT_OP_SET_DISCOVERABLE, hdev);
@@ -1928,105 +1224,28 @@
 	cancel_delayed_work(&hdev->discov_off);
 	hdev->discov_timeout = timeout;
 
+	if (cp->val)
+		hci_dev_set_flag(hdev, HCI_DISCOVERABLE);
+	else
+		hci_dev_clear_flag(hdev, HCI_DISCOVERABLE);
+
 	/* Limited discoverable mode */
 	if (cp->val == 0x02)
 		hci_dev_set_flag(hdev, HCI_LIMITED_DISCOVERABLE);
 	else
 		hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
 
-	hci_req_init(&req, hdev);
-
-	/* The procedure for LE-only controllers is much simpler - just
-	 * update the advertising data.
-	 */
-	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
-		goto update_ad;
-
-	scan = SCAN_PAGE;
-
-	if (cp->val) {
-		struct hci_cp_write_current_iac_lap hci_cp;
-
-		if (cp->val == 0x02) {
-			/* Limited discoverable mode */
-			hci_cp.num_iac = min_t(u8, hdev->num_iac, 2);
-			hci_cp.iac_lap[0] = 0x00;	/* LIAC */
-			hci_cp.iac_lap[1] = 0x8b;
-			hci_cp.iac_lap[2] = 0x9e;
-			hci_cp.iac_lap[3] = 0x33;	/* GIAC */
-			hci_cp.iac_lap[4] = 0x8b;
-			hci_cp.iac_lap[5] = 0x9e;
-		} else {
-			/* General discoverable mode */
-			hci_cp.num_iac = 1;
-			hci_cp.iac_lap[0] = 0x33;	/* GIAC */
-			hci_cp.iac_lap[1] = 0x8b;
-			hci_cp.iac_lap[2] = 0x9e;
-		}
-
-		hci_req_add(&req, HCI_OP_WRITE_CURRENT_IAC_LAP,
-			    (hci_cp.num_iac * 3) + 1, &hci_cp);
-
-		scan |= SCAN_INQUIRY;
-	} else {
-		hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
-	}
-
-	hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan);
-
-update_ad:
-	update_adv_data(&req);
-
-	err = hci_req_run(&req, set_discoverable_complete);
-	if (err < 0)
-		mgmt_pending_remove(cmd);
+	queue_work(hdev->req_workqueue, &hdev->discoverable_update);
+	err = 0;
 
 failed:
 	hci_dev_unlock(hdev);
 	return err;
 }
 
-static void write_fast_connectable(struct hci_request *req, bool enable)
-{
-	struct hci_dev *hdev = req->hdev;
-	struct hci_cp_write_page_scan_activity acp;
-	u8 type;
-
-	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
-		return;
-
-	if (hdev->hci_ver < BLUETOOTH_VER_1_2)
-		return;
-
-	if (enable) {
-		type = PAGE_SCAN_TYPE_INTERLACED;
-
-		/* 160 msec page scan interval */
-		acp.interval = cpu_to_le16(0x0100);
-	} else {
-		type = PAGE_SCAN_TYPE_STANDARD;	/* default */
-
-		/* default 1.28 sec page scan */
-		acp.interval = cpu_to_le16(0x0800);
-	}
-
-	acp.window = cpu_to_le16(0x0012);
-
-	if (__cpu_to_le16(hdev->page_scan_interval) != acp.interval ||
-	    __cpu_to_le16(hdev->page_scan_window) != acp.window)
-		hci_req_add(req, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY,
-			    sizeof(acp), &acp);
-
-	if (hdev->page_scan_type != type)
-		hci_req_add(req, HCI_OP_WRITE_PAGE_SCAN_TYPE, 1, &type);
-}
-
-static void set_connectable_complete(struct hci_dev *hdev, u8 status,
-				     u16 opcode)
+void mgmt_set_connectable_complete(struct hci_dev *hdev, u8 status)
 {
 	struct mgmt_pending_cmd *cmd;
-	struct mgmt_mode *cp;
-	bool conn_changed, discov_changed;
 
 	BT_DBG("status 0x%02x", status);
 
@@ -2042,27 +1261,8 @@
 		goto remove_cmd;
 	}
 
-	cp = cmd->param;
-	if (cp->val) {
-		conn_changed = !hci_dev_test_and_set_flag(hdev,
-							  HCI_CONNECTABLE);
-		discov_changed = false;
-	} else {
-		conn_changed = hci_dev_test_and_clear_flag(hdev,
-							   HCI_CONNECTABLE);
-		discov_changed = hci_dev_test_and_clear_flag(hdev,
-							     HCI_DISCOVERABLE);
-	}
-
 	send_settings_rsp(cmd->sk, MGMT_OP_SET_CONNECTABLE, hdev);
-
-	if (conn_changed || discov_changed) {
-		new_settings(hdev, cmd->sk);
-		hci_update_page_scan(hdev);
-		if (discov_changed)
-			mgmt_update_adv_data(hdev);
-		hci_update_background_scan(hdev);
-	}
+	new_settings(hdev, cmd->sk);
 
 remove_cmd:
 	mgmt_pending_remove(cmd);
@@ -2092,7 +1292,7 @@
 		return err;
 
 	if (changed) {
-		hci_update_page_scan(hdev);
+		hci_req_update_scan(hdev);
 		hci_update_background_scan(hdev);
 		return new_settings(hdev, sk);
 	}
@@ -2105,8 +1305,6 @@
 {
 	struct mgmt_mode *cp = data;
 	struct mgmt_pending_cmd *cmd;
-	struct hci_request req;
-	u8 scan;
 	int err;
 
 	BT_DBG("request for %s", hdev->name);
@@ -2140,57 +1338,19 @@
 		goto failed;
 	}
 
-	hci_req_init(&req, hdev);
+	if (cp->val) {
+		hci_dev_set_flag(hdev, HCI_CONNECTABLE);
+	} else {
+		if (hdev->discov_timeout > 0)
+			cancel_delayed_work(&hdev->discov_off);
 
-	/* If BR/EDR is not enabled and we disable advertising as a
-	 * by-product of disabling connectable, we need to update the
-	 * advertising flags.
-	 */
-	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
-		if (!cp->val) {
-			hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
-			hci_dev_clear_flag(hdev, HCI_DISCOVERABLE);
-		}
-		update_adv_data(&req);
-	} else if (cp->val != test_bit(HCI_PSCAN, &hdev->flags)) {
-		if (cp->val) {
-			scan = SCAN_PAGE;
-		} else {
-			/* If we don't have any whitelist entries just
-			 * disable all scanning. If there are entries
-			 * and we had both page and inquiry scanning
-			 * enabled then fall back to only page scanning.
-			 * Otherwise no changes are needed.
-			 */
-			if (list_empty(&hdev->whitelist))
-				scan = SCAN_DISABLED;
-			else if (test_bit(HCI_ISCAN, &hdev->flags))
-				scan = SCAN_PAGE;
-			else
-				goto no_scan_update;
-
-			if (test_bit(HCI_ISCAN, &hdev->flags) &&
-			    hdev->discov_timeout > 0)
-				cancel_delayed_work(&hdev->discov_off);
-		}
-
-		hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
+		hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
+		hci_dev_clear_flag(hdev, HCI_DISCOVERABLE);
+		hci_dev_clear_flag(hdev, HCI_CONNECTABLE);
 	}
 
-no_scan_update:
-	/* Update the advertising parameters if necessary */
-	if (hci_dev_test_flag(hdev, HCI_ADVERTISING) ||
-	    hci_dev_test_flag(hdev, HCI_ADVERTISING_INSTANCE))
-		enable_advertising(&req);
-
-	err = hci_req_run(&req, set_connectable_complete);
-	if (err < 0) {
-		mgmt_pending_remove(cmd);
-		if (err == -ENODATA)
-			err = set_connectable_update_settings(hdev, sk,
-							      cp->val);
-		goto failed;
-	}
+	queue_work(hdev->req_workqueue, &hdev->connectable_update);
+	err = 0;
 
 failed:
 	hci_dev_unlock(hdev);
@@ -2466,8 +1626,8 @@
 		struct hci_request req;
 
 		hci_req_init(&req, hdev);
-		update_adv_data(&req);
-		update_scan_rsp_data(&req);
+		__hci_req_update_adv_data(&req, 0x00);
+		__hci_req_update_scan_rsp_data(&req, 0x00);
 		hci_req_run(&req, NULL);
 		hci_update_background_scan(hdev);
 	}
@@ -2518,7 +1678,7 @@
 	enabled = lmp_host_le_capable(hdev);
 
 	if (!val)
-		clear_adv_instance(hdev, NULL, 0x00, true);
+		hci_req_clear_adv_instance(hdev, NULL, 0x00, true);
 
 	if (!hdev_is_powered(hdev) || val == enabled) {
 		bool changed = false;
@@ -2565,7 +1725,7 @@
 		hci_cp.simul = 0x00;
 	} else {
 		if (hci_dev_test_flag(hdev, HCI_LE_ADV))
-			disable_advertising(&req);
+			__hci_req_disable_advertising(&req);
 	}
 
 	hci_req_add(&req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(hci_cp),
@@ -2680,8 +1840,8 @@
 
 	hci_req_init(&req, hdev);
 
-	update_class(&req);
-	update_eir(&req);
+	__hci_req_update_class(&req);
+	__hci_req_update_eir(&req);
 
 	err = hci_req_run(&req, add_uuid_complete);
 	if (err < 0) {
@@ -2780,8 +1940,8 @@
 update_class:
 	hci_req_init(&req, hdev);
 
-	update_class(&req);
-	update_eir(&req);
+	__hci_req_update_class(&req);
+	__hci_req_update_eir(&req);
 
 	err = hci_req_run(&req, remove_uuid_complete);
 	if (err < 0) {
@@ -2856,10 +2016,10 @@
 		hci_dev_unlock(hdev);
 		cancel_delayed_work_sync(&hdev->service_cache);
 		hci_dev_lock(hdev);
-		update_eir(&req);
+		__hci_req_update_eir(&req);
 	}
 
-	update_class(&req);
+	__hci_req_update_class(&req);
 
 	err = hci_req_run(&req, set_class_complete);
 	if (err < 0) {
@@ -3760,16 +2920,6 @@
 				 HCI_OP_USER_PASSKEY_NEG_REPLY, 0);
 }
 
-static void update_name(struct hci_request *req)
-{
-	struct hci_dev *hdev = req->hdev;
-	struct hci_cp_write_local_name cp;
-
-	memcpy(cp.name, hdev->dev_name, sizeof(cp.name));
-
-	hci_req_add(req, HCI_OP_WRITE_LOCAL_NAME, sizeof(cp), &cp);
-}
-
 static void set_name_complete(struct hci_dev *hdev, u8 status, u16 opcode)
 {
 	struct mgmt_cp_set_local_name *cp;
@@ -3848,15 +2998,15 @@
 	hci_req_init(&req, hdev);
 
 	if (lmp_bredr_capable(hdev)) {
-		update_name(&req);
-		update_eir(&req);
+		__hci_req_update_name(&req);
+		__hci_req_update_eir(&req);
 	}
 
 	/* The name is stored in the scan response data and so
 	 * no need to udpate the advertising data here.
 	 */
 	if (lmp_le_capable(hdev))
-		update_scan_rsp_data(&req);
+		__hci_req_update_scan_rsp_data(&req, hdev->cur_adv_instance);
 
 	err = hci_req_run(&req, set_name_complete);
 	if (err < 0)
@@ -4534,7 +3684,7 @@
 				NULL, 0);
 
 	hci_req_init(&req, hdev);
-	update_eir(&req);
+	__hci_req_update_eir(&req);
 	hci_req_run(&req, NULL);
 
 	hci_dev_unlock(hdev);
@@ -4584,7 +3734,6 @@
 	 * set up earlier, then re-enable multi-instance advertising.
 	 */
 	if (hci_dev_test_flag(hdev, HCI_ADVERTISING) ||
-	    !hci_dev_test_flag(hdev, HCI_ADVERTISING_INSTANCE) ||
 	    list_empty(&hdev->adv_instances))
 		goto unlock;
 
@@ -4600,7 +3749,7 @@
 
 	hci_req_init(&req, hdev);
 
-	err = schedule_adv_instance(&req, instance, true);
+	err = __hci_req_schedule_adv_instance(&req, instance, true);
 
 	if (!err)
 		err = hci_req_run(&req, enable_advertising_instance);
@@ -4650,6 +3799,7 @@
 		bool changed;
 
 		if (cp->val) {
+			hdev->cur_adv_instance = 0x00;
 			changed = !hci_dev_test_and_set_flag(hdev, HCI_ADVERTISING);
 			if (cp->val == 0x02)
 				hci_dev_set_flag(hdev, HCI_ADVERTISING_CONNECTABLE);
@@ -4697,11 +3847,12 @@
 		 * We cannot use update_[adv|scan_rsp]_data() here as the
 		 * HCI_ADVERTISING flag is not yet set.
 		 */
-		update_inst_adv_data(&req, 0x00);
-		update_inst_scan_rsp_data(&req, 0x00);
-		enable_advertising(&req);
+		hdev->cur_adv_instance = 0x00;
+		__hci_req_update_adv_data(&req, 0x00);
+		__hci_req_update_scan_rsp_data(&req, 0x00);
+		__hci_req_enable_advertising(&req);
 	} else {
-		disable_advertising(&req);
+		__hci_req_disable_advertising(&req);
 	}
 
 	err = hci_req_run(&req, set_advertising_complete);
@@ -4898,7 +4049,7 @@
 
 	hci_req_init(&req, hdev);
 
-	write_fast_connectable(&req, cp->val);
+	__hci_req_write_fast_connectable(&req, cp->val);
 
 	err = hci_req_run(&req, fast_connectable_complete);
 	if (err < 0) {
@@ -5033,20 +4184,20 @@
 		goto unlock;
 	}
 
-	/* We need to flip the bit already here so that update_adv_data
-	 * generates the correct flags.
+	/* We need to flip the bit already here so that
+	 * hci_req_update_adv_data generates the correct flags.
 	 */
 	hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
 
 	hci_req_init(&req, hdev);
 
-	write_fast_connectable(&req, false);
-	__hci_update_page_scan(&req);
+	__hci_req_write_fast_connectable(&req, false);
+	__hci_req_update_scan(&req);
 
 	/* Since only the advertising data flags will change, there
 	 * is no need to update the scan response data.
 	 */
-	update_adv_data(&req);
+	__hci_req_update_adv_data(&req, hdev->cur_adv_instance);
 
 	err = hci_req_run(&req, set_bredr_complete);
 	if (err < 0)
@@ -5927,7 +5078,7 @@
 		if (err)
 			goto unlock;
 
-		hci_update_page_scan(hdev);
+		hci_req_update_scan(hdev);
 
 		goto added;
 	}
@@ -6024,7 +5175,7 @@
 				goto unlock;
 			}
 
-			hci_update_page_scan(hdev);
+			hci_req_update_scan(hdev);
 
 			device_removed(sk, hdev, &cp->addr.bdaddr,
 				       cp->addr.type);
@@ -6089,7 +5240,7 @@
 			kfree(b);
 		}
 
-		hci_update_page_scan(hdev);
+		hci_req_update_scan(hdev);
 
 		list_for_each_entry_safe(p, tmp, &hdev->le_conn_params, list) {
 			if (p->auto_connect == HCI_AUTO_CONN_DISABLED)
@@ -6583,7 +5734,7 @@
 						  rand, sizeof(rand));
 		}
 
-		flags = get_adv_discov_flags(hdev);
+		flags = mgmt_get_adv_discov_flags(hdev);
 
 		if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
 			flags |= LE_AD_NO_BREDR;
@@ -6638,10 +5789,10 @@
 {
 	struct mgmt_rp_read_adv_features *rp;
 	size_t rp_len;
-	int err, i;
-	bool instance;
+	int err;
 	struct adv_info *adv_instance;
 	u32 supported_flags;
+	u8 *instance;
 
 	BT_DBG("%s", hdev->name);
 
@@ -6651,12 +5802,7 @@
 
 	hci_dev_lock(hdev);
 
-	rp_len = sizeof(*rp);
-
-	instance = hci_dev_test_flag(hdev, HCI_ADVERTISING_INSTANCE);
-	if (instance)
-		rp_len += hdev->adv_instance_cnt;
-
+	rp_len = sizeof(*rp) + hdev->adv_instance_cnt;
 	rp = kmalloc(rp_len, GFP_ATOMIC);
 	if (!rp) {
 		hci_dev_unlock(hdev);
@@ -6669,19 +5815,12 @@
 	rp->max_adv_data_len = HCI_MAX_AD_LENGTH;
 	rp->max_scan_rsp_len = HCI_MAX_AD_LENGTH;
 	rp->max_instances = HCI_MAX_ADV_INSTANCES;
+	rp->num_instances = hdev->adv_instance_cnt;
 
-	if (instance) {
-		i = 0;
-		list_for_each_entry(adv_instance, &hdev->adv_instances, list) {
-			if (i >= hdev->adv_instance_cnt)
-				break;
-
-			rp->instance[i] = adv_instance->instance;
-			i++;
-		}
-		rp->num_instances = hdev->adv_instance_cnt;
-	} else {
-		rp->num_instances = 0;
+	instance = rp->instance;
+	list_for_each_entry(adv_instance, &hdev->adv_instances, list) {
+		*instance = adv_instance->instance;
+		instance++;
 	}
 
 	hci_dev_unlock(hdev);
@@ -6754,9 +5893,6 @@
 
 	cmd = pending_find(MGMT_OP_ADD_ADVERTISING, hdev);
 
-	if (status)
-		hci_dev_clear_flag(hdev, HCI_ADVERTISING_INSTANCE);
-
 	list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list) {
 		if (!adv_instance->pending)
 			continue;
@@ -6772,7 +5908,7 @@
 			cancel_adv_timeout(hdev);
 
 		hci_remove_adv_instance(hdev, instance);
-		advertising_removed(cmd ? cmd->sk : NULL, hdev, instance);
+		mgmt_advertising_removed(cmd ? cmd->sk : NULL, hdev, instance);
 	}
 
 	if (!cmd)
@@ -6794,31 +5930,6 @@
 	hci_dev_unlock(hdev);
 }
 
-void mgmt_adv_timeout_expired(struct hci_dev *hdev)
-{
-	u8 instance;
-	struct hci_request req;
-
-	hdev->adv_instance_timeout = 0;
-
-	instance = get_current_adv_instance(hdev);
-	if (instance == 0x00)
-		return;
-
-	hci_dev_lock(hdev);
-	hci_req_init(&req, hdev);
-
-	clear_adv_instance(hdev, &req, instance, false);
-
-	if (list_empty(&hdev->adv_instances))
-		disable_advertising(&req);
-
-	if (!skb_queue_empty(&req.cmd_q))
-		hci_req_run(&req, NULL);
-
-	hci_dev_unlock(hdev);
-}
-
 static int add_advertising(struct sock *sk, struct hci_dev *hdev,
 			   void *data, u16 data_len)
 {
@@ -6897,9 +6008,7 @@
 	 * actually added.
 	 */
 	if (hdev->adv_instance_cnt > prev_instance_cnt)
-		advertising_added(sk, hdev, cp->instance);
-
-	hci_dev_set_flag(hdev, HCI_ADVERTISING_INSTANCE);
+		mgmt_advertising_added(sk, hdev, cp->instance);
 
 	if (hdev->cur_adv_instance == cp->instance) {
 		/* If the currently advertised instance is being changed then
@@ -6944,7 +6053,7 @@
 
 	hci_req_init(&req, hdev);
 
-	err = schedule_adv_instance(&req, schedule_instance, true);
+	err = __hci_req_schedule_adv_instance(&req, schedule_instance, true);
 
 	if (!err)
 		err = hci_req_run(&req, add_advertising_complete);
@@ -7016,7 +6125,7 @@
 		goto unlock;
 	}
 
-	if (!hci_dev_test_flag(hdev, HCI_ADVERTISING_INSTANCE)) {
+	if (list_empty(&hdev->adv_instances)) {
 		err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_REMOVE_ADVERTISING,
 				      MGMT_STATUS_INVALID_PARAMS);
 		goto unlock;
@@ -7024,10 +6133,10 @@
 
 	hci_req_init(&req, hdev);
 
-	clear_adv_instance(hdev, &req, cp->instance, true);
+	hci_req_clear_adv_instance(hdev, &req, cp->instance, true);
 
 	if (list_empty(&hdev->adv_instances))
-		disable_advertising(&req);
+		__hci_req_disable_advertising(&req);
 
 	/* If no HCI commands have been collected so far or the HCI_ADVERTISING
 	 * flag is set or the device isn't powered then we have no HCI
@@ -7298,138 +6407,33 @@
 	}
 }
 
-static void powered_complete(struct hci_dev *hdev, u8 status, u16 opcode)
+void mgmt_power_on(struct hci_dev *hdev, int err)
 {
 	struct cmd_lookup match = { NULL, hdev };
 
-	BT_DBG("status 0x%02x", status);
+	BT_DBG("err %d", err);
 
-	if (!status) {
+	hci_dev_lock(hdev);
+
+	if (!err) {
 		restart_le_actions(hdev);
 		hci_update_background_scan(hdev);
 	}
 
-	hci_dev_lock(hdev);
-
 	mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
 
 	new_settings(hdev, match.sk);
 
-	hci_dev_unlock(hdev);
-
 	if (match.sk)
 		sock_put(match.sk);
+
+	hci_dev_unlock(hdev);
 }
 
-static int powered_update_hci(struct hci_dev *hdev)
-{
-	struct hci_request req;
-	struct adv_info *adv_instance;
-	u8 link_sec;
-
-	hci_req_init(&req, hdev);
-
-	if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED) &&
-	    !lmp_host_ssp_capable(hdev)) {
-		u8 mode = 0x01;
-
-		hci_req_add(&req, HCI_OP_WRITE_SSP_MODE, sizeof(mode), &mode);
-
-		if (bredr_sc_enabled(hdev) && !lmp_host_sc_capable(hdev)) {
-			u8 support = 0x01;
-
-			hci_req_add(&req, HCI_OP_WRITE_SC_SUPPORT,
-				    sizeof(support), &support);
-		}
-	}
-
-	if (hci_dev_test_flag(hdev, HCI_LE_ENABLED) &&
-	    lmp_bredr_capable(hdev)) {
-		struct hci_cp_write_le_host_supported cp;
-
-		cp.le = 0x01;
-		cp.simul = 0x00;
-
-		/* Check first if we already have the right
-		 * host state (host features set)
-		 */
-		if (cp.le != lmp_host_le_capable(hdev) ||
-		    cp.simul != lmp_host_le_br_capable(hdev))
-			hci_req_add(&req, HCI_OP_WRITE_LE_HOST_SUPPORTED,
-				    sizeof(cp), &cp);
-	}
-
-	if (lmp_le_capable(hdev)) {
-		/* Make sure the controller has a good default for
-		 * advertising data. This also applies to the case
-		 * where BR/EDR was toggled during the AUTO_OFF phase.
-		 */
-		if (hci_dev_test_flag(hdev, HCI_LE_ENABLED) &&
-		    (hci_dev_test_flag(hdev, HCI_ADVERTISING) ||
-		     !hci_dev_test_flag(hdev, HCI_ADVERTISING_INSTANCE))) {
-			update_adv_data(&req);
-			update_scan_rsp_data(&req);
-		}
-
-		if (hci_dev_test_flag(hdev, HCI_ADVERTISING_INSTANCE) &&
-		    hdev->cur_adv_instance == 0x00 &&
-		    !list_empty(&hdev->adv_instances)) {
-			adv_instance = list_first_entry(&hdev->adv_instances,
-							struct adv_info, list);
-			hdev->cur_adv_instance = adv_instance->instance;
-		}
-
-		if (hci_dev_test_flag(hdev, HCI_ADVERTISING))
-			enable_advertising(&req);
-		else if (hci_dev_test_flag(hdev, HCI_ADVERTISING_INSTANCE) &&
-			 hdev->cur_adv_instance)
-			schedule_adv_instance(&req, hdev->cur_adv_instance,
-					      true);
-	}
-
-	link_sec = hci_dev_test_flag(hdev, HCI_LINK_SECURITY);
-	if (link_sec != test_bit(HCI_AUTH, &hdev->flags))
-		hci_req_add(&req, HCI_OP_WRITE_AUTH_ENABLE,
-			    sizeof(link_sec), &link_sec);
-
-	if (lmp_bredr_capable(hdev)) {
-		if (hci_dev_test_flag(hdev, HCI_FAST_CONNECTABLE))
-			write_fast_connectable(&req, true);
-		else
-			write_fast_connectable(&req, false);
-		__hci_update_page_scan(&req);
-		update_class(&req);
-		update_name(&req);
-		update_eir(&req);
-	}
-
-	return hci_req_run(&req, powered_complete);
-}
-
-int mgmt_powered(struct hci_dev *hdev, u8 powered)
+void __mgmt_power_off(struct hci_dev *hdev)
 {
 	struct cmd_lookup match = { NULL, hdev };
 	u8 status, zero_cod[] = { 0, 0, 0 };
-	int err;
-
-	if (!hci_dev_test_flag(hdev, HCI_MGMT))
-		return 0;
-
-	if (powered) {
-		/* Register the available SMP channels (BR/EDR and LE) only
-		 * when successfully powering on the controller. This late
-		 * registration is required so that LE SMP can clearly
-		 * decide if the public address or static address is used.
-		 */
-		smp_register(hdev);
-
-		if (powered_update_hci(hdev) == 0)
-			return 0;
-
-		mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp,
-				     &match);
-		goto new_settings;
-	}
 
 	mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
 
@@ -7451,13 +6455,10 @@
 		mgmt_generic_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev,
 				   zero_cod, sizeof(zero_cod), NULL);
 
-new_settings:
-	err = new_settings(hdev, match.sk);
+	new_settings(hdev, match.sk);
 
 	if (match.sk)
 		sock_put(match.sk);
-
-	return err;
 }
 
 void mgmt_set_powered_failed(struct hci_dev *hdev, int err)
@@ -7479,43 +6480,6 @@
 	mgmt_pending_remove(cmd);
 }
 
-void mgmt_discoverable_timeout(struct hci_dev *hdev)
-{
-	struct hci_request req;
-
-	hci_dev_lock(hdev);
-
-	/* When discoverable timeout triggers, then just make sure
-	 * the limited discoverable flag is cleared. Even in the case
-	 * of a timeout triggered from general discoverable, it is
-	 * safe to unconditionally clear the flag.
-	 */
-	hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
-	hci_dev_clear_flag(hdev, HCI_DISCOVERABLE);
-
-	hci_req_init(&req, hdev);
-	if (hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
-		u8 scan = SCAN_PAGE;
-		hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE,
-			    sizeof(scan), &scan);
-	}
-	update_class(&req);
-
-	/* Advertising instances don't use the global discoverable setting, so
-	 * only update AD if advertising was enabled using Set Advertising.
-	 */
-	if (hci_dev_test_flag(hdev, HCI_ADVERTISING))
-		update_adv_data(&req);
-
-	hci_req_run(&req, NULL);
-
-	hdev->discov_timeout = 0;
-
-	new_settings(hdev, NULL);
-
-	hci_dev_unlock(hdev);
-}
-
 void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
 		       bool persistent)
 {
@@ -8058,7 +7022,7 @@
 		if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS))
 			hci_req_add(&req, HCI_OP_WRITE_SSP_DEBUG_MODE,
 				    sizeof(enable), &enable);
-		update_eir(&req);
+		__hci_req_update_eir(&req);
 	} else {
 		clear_eir(&req);
 	}
@@ -8352,35 +7316,6 @@
 	mgmt_event(MGMT_EV_DISCOVERING, hdev, &ev, sizeof(ev), NULL);
 }
 
-static void adv_enable_complete(struct hci_dev *hdev, u8 status, u16 opcode)
-{
-	BT_DBG("%s status %u", hdev->name, status);
-}
-
-void mgmt_reenable_advertising(struct hci_dev *hdev)
-{
-	struct hci_request req;
-	u8 instance;
-
-	if (!hci_dev_test_flag(hdev, HCI_ADVERTISING) &&
-	    !hci_dev_test_flag(hdev, HCI_ADVERTISING_INSTANCE))
-		return;
-
-	instance = get_current_adv_instance(hdev);
-
-	hci_req_init(&req, hdev);
-
-	if (instance) {
-		schedule_adv_instance(&req, instance, true);
-	} else {
-		update_adv_data(&req);
-		update_scan_rsp_data(&req);
-		enable_advertising(&req);
-	}
-
-	hci_req_run(&req, adv_enable_complete);
-}
-
 static struct hci_mgmt_chan chan = {
 	.channel	= HCI_CHANNEL_CONTROL,
 	.handler_count	= ARRAY_SIZE(mgmt_handlers),
diff --git a/net/ieee802154/6lowpan/core.c b/net/ieee802154/6lowpan/core.c
index 20c49c7..737c87a 100644
--- a/net/ieee802154/6lowpan/core.c
+++ b/net/ieee802154/6lowpan/core.c
@@ -161,9 +161,7 @@
 				wdev->needed_headroom;
 	ldev->needed_tailroom = wdev->needed_tailroom;
 
-	lowpan_netdev_setup(ldev, LOWPAN_LLTYPE_IEEE802154);
-
-	ret = register_netdevice(ldev);
+	ret = lowpan_register_netdevice(ldev, LOWPAN_LLTYPE_IEEE802154);
 	if (ret < 0) {
 		dev_put(wdev);
 		return ret;
@@ -180,7 +178,7 @@
 	ASSERT_RTNL();
 
 	wdev->ieee802154_ptr->lowpan_dev = NULL;
-	unregister_netdevice(ldev);
+	lowpan_unregister_netdevice(ldev);
 	dev_put(wdev);
 }
 
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 5e9111d..7082fb7 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -70,7 +70,7 @@
 #include <net/sock.h>
 #include <net/snmp.h>
 
-#include <net/af_ieee802154.h>
+#include <net/6lowpan.h>
 #include <net/firewire.h>
 #include <net/ipv6.h>
 #include <net/protocol.h>
@@ -1947,9 +1947,9 @@
 
 static int addrconf_ifid_eui64(u8 *eui, struct net_device *dev)
 {
-	if (dev->addr_len != IEEE802154_ADDR_LEN)
+	if (dev->addr_len != EUI64_ADDR_LEN)
 		return -1;
-	memcpy(eui, dev->dev_addr, 8);
+	memcpy(eui, dev->dev_addr, EUI64_ADDR_LEN);
 	eui[0] ^= 2;
 	return 0;
 }
@@ -2041,7 +2041,6 @@
 	case ARPHRD_IPGRE:
 		return addrconf_ifid_gre(eui, dev);
 	case ARPHRD_6LOWPAN:
-	case ARPHRD_IEEE802154:
 		return addrconf_ifid_eui64(eui, dev);
 	case ARPHRD_IEEE1394:
 		return addrconf_ifid_ieee1394(eui, dev);
@@ -3066,7 +3065,6 @@
 	    (dev->type != ARPHRD_FDDI) &&
 	    (dev->type != ARPHRD_ARCNET) &&
 	    (dev->type != ARPHRD_INFINIBAND) &&
-	    (dev->type != ARPHRD_IEEE802154) &&
 	    (dev->type != ARPHRD_IEEE1394) &&
 	    (dev->type != ARPHRD_TUNNEL6) &&
 	    (dev->type != ARPHRD_6LOWPAN)) {
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index 3ea4c98..ef50a94 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -1031,7 +1031,7 @@
 	struct sock *sk = sock->sk;
 	struct iucv_sock *iucv = iucv_sk(sk);
 	struct sk_buff *skb;
-	struct iucv_message txmsg;
+	struct iucv_message txmsg = {0};
 	struct cmsghdr *cmsg;
 	int cmsg_done;
 	long timeo;
@@ -2084,11 +2084,7 @@
 		return NET_RX_SUCCESS;
 	}
 
-		/* write stuff from iucv_msg to skb cb */
-	if (skb->len < sizeof(struct af_iucv_trans_hdr)) {
-		kfree_skb(skb);
-		return NET_RX_SUCCESS;
-	}
+	/* write stuff from iucv_msg to skb cb */
 	skb_pull(skb, sizeof(struct af_iucv_trans_hdr));
 	skb_reset_transport_header(skb);
 	skb_reset_network_header(skb);
@@ -2119,6 +2115,20 @@
 	char nullstring[8];
 	int err = 0;
 
+	if (skb->len < (ETH_HLEN + sizeof(struct af_iucv_trans_hdr))) {
+		WARN_ONCE(1, "AF_IUCV too short skb, len=%d, min=%d",
+			  (int)skb->len,
+			  (int)(ETH_HLEN + sizeof(struct af_iucv_trans_hdr)));
+		kfree_skb(skb);
+		return NET_RX_SUCCESS;
+	}
+	if (skb_headlen(skb) < (ETH_HLEN + sizeof(struct af_iucv_trans_hdr)))
+		if (skb_linearize(skb)) {
+			WARN_ONCE(1, "AF_IUCV skb_linearize failed, len=%d",
+				  (int)skb->len);
+			kfree_skb(skb);
+			return NET_RX_SUCCESS;
+		}
 	skb_pull(skb, ETH_HLEN);
 	trans_hdr = (struct af_iucv_trans_hdr *)skb->data;
 	EBCASC(trans_hdr->destAppName, sizeof(trans_hdr->destAppName));
diff --git a/net/mac802154/driver-ops.h b/net/mac802154/driver-ops.h
index 0550f33..fd9daf2 100644
--- a/net/mac802154/driver-ops.h
+++ b/net/mac802154/driver-ops.h
@@ -18,9 +18,6 @@
 static inline int
 drv_xmit_sync(struct ieee802154_local *local, struct sk_buff *skb)
 {
-	/* don't allow other operations while sync xmit */
-	ASSERT_RTNL();
-
 	might_sleep();
 
 	return local->ops->xmit_sync(&local->hw, skb);
diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c
index 3827f35..7e25345 100644
--- a/net/mac802154/tx.c
+++ b/net/mac802154/tx.c
@@ -38,12 +38,6 @@
 	struct net_device *dev = skb->dev;
 	int res;
 
-	rtnl_lock();
-
-	/* check if ifdown occurred while schedule */
-	if (!netif_running(dev))
-		goto err_tx;
-
 	res = drv_xmit_sync(local, skb);
 	if (res)
 		goto err_tx;
@@ -53,14 +47,11 @@
 	dev->stats.tx_packets++;
 	dev->stats.tx_bytes += skb->len;
 
-	rtnl_unlock();
-
 	return;
 
 err_tx:
 	/* Restart the netif queue on each sub_if_data object. */
 	ieee802154_wake_queue(&local->hw);
-	rtnl_unlock();
 	kfree_skb(skb);
 	netdev_dbg(dev, "transmission failed\n");
 }