Browse Source

Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next

John W. Linville says:

====================
Please pull this batch of updates intended for the 3.17 stream...

This is primarily a Bluetooth pull.  Gustavo says:

"A lot of patches to 3.17. The bulk of changes here are for LE support.
The 6loWPAN over Bluetooth now has it own module, we also have support for
background auto-connection and passive scanning, Bluetooth device address
provisioning, support for reading Bluetooth clock values and LE connection
parameters plus many many fixes."

The balance is just a pull of the wireless.git tree, to avoid some
pending merge problems.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
David S. Miller 11 years ago
parent
commit
66568b3925
45 changed files with 3758 additions and 1478 deletions
  1. 6 6
      drivers/bluetooth/Kconfig
  2. 4 4
      drivers/bluetooth/ath3k.c
  3. 3 0
      drivers/bluetooth/btmrvl_drv.h
  4. 43 1
      drivers/bluetooth/btmrvl_main.c
  5. 5 0
      drivers/bluetooth/btmrvl_sdio.c
  6. 2 0
      drivers/bluetooth/btmrvl_sdio.h
  7. 158 30
      drivers/bluetooth/btusb.c
  8. 1 4
      drivers/bluetooth/hci_h5.c
  9. 25 9
      drivers/bluetooth/hci_vhci.c
  10. 5 1
      drivers/net/wireless/ath/ath10k/core.c
  11. 0 18
      drivers/net/wireless/ath/ath10k/htt_rx.c
  12. 3 2
      drivers/net/wireless/brcm80211/brcmfmac/usb.c
  13. 1 0
      drivers/net/wireless/mwifiex/11n_aggr.c
  14. 1 0
      drivers/net/wireless/mwifiex/cfg80211.c
  15. 1 0
      drivers/net/wireless/mwifiex/cmdevt.c
  16. 1 0
      drivers/net/wireless/mwifiex/main.c
  17. 1 0
      drivers/net/wireless/mwifiex/sta_tx.c
  18. 2 0
      drivers/net/wireless/mwifiex/tdls.c
  19. 1 0
      drivers/net/wireless/mwifiex/txrx.c
  20. 1 0
      drivers/net/wireless/mwifiex/uap_txrx.c
  21. 22 6
      drivers/net/wireless/rt2x00/rt2800usb.c
  22. 9 9
      include/net/bluetooth/bluetooth.h
  23. 119 16
      include/net/bluetooth/hci.h
  24. 94 40
      include/net/bluetooth/hci_core.h
  25. 32 4
      include/net/bluetooth/l2cap.h
  26. 99 0
      include/net/bluetooth/mgmt.h
  27. 649 208
      net/bluetooth/6lowpan.c
  28. 0 47
      net/bluetooth/6lowpan.h
  29. 3 3
      net/bluetooth/Kconfig
  30. 3 1
      net/bluetooth/Makefile
  31. 5 3
      net/bluetooth/a2mp.c
  32. 1 1
      net/bluetooth/af_bluetooth.c
  33. 127 49
      net/bluetooth/hci_conn.c
  34. 476 433
      net/bluetooth/hci_core.c
  35. 515 183
      net/bluetooth/hci_event.c
  36. 8 4
      net/bluetooth/hci_sock.c
  37. 76 68
      net/bluetooth/l2cap_core.c
  38. 29 17
      net/bluetooth/l2cap_sock.c
  39. 1060 194
      net/bluetooth/mgmt.c
  40. 144 93
      net/bluetooth/smp.c
  41. 7 0
      net/bluetooth/smp.h
  42. 3 2
      net/mac80211/util.c
  43. 1 1
      net/wireless/core.h
  44. 5 6
      net/wireless/nl80211.c
  45. 7 15
      net/wireless/reg.c

+ 6 - 6
drivers/bluetooth/Kconfig

@@ -30,8 +30,8 @@ config BT_HCIUART
 	help
 	help
 	  Bluetooth HCI UART driver.
 	  Bluetooth HCI UART driver.
 	  This driver is required if you want to use Bluetooth devices with
 	  This driver is required if you want to use Bluetooth devices with
-	  serial port interface. You will also need this driver if you have 
-	  UART based Bluetooth PCMCIA and CF devices like Xircom Credit Card 
+	  serial port interface. You will also need this driver if you have
+	  UART based Bluetooth PCMCIA and CF devices like Xircom Credit Card
 	  adapter and BrainBoxes Bluetooth PC Card.
 	  adapter and BrainBoxes Bluetooth PC Card.
 
 
 	  Say Y here to compile support for Bluetooth UART devices into the
 	  Say Y here to compile support for Bluetooth UART devices into the
@@ -41,9 +41,9 @@ config BT_HCIUART_H4
 	bool "UART (H4) protocol support"
 	bool "UART (H4) protocol support"
 	depends on BT_HCIUART
 	depends on BT_HCIUART
 	help
 	help
-	  UART (H4) is serial protocol for communication between Bluetooth 
-	  device and host. This protocol is required for most Bluetooth devices 
-	  with UART interface, including PCMCIA and CF cards. 
+	  UART (H4) is serial protocol for communication between Bluetooth
+	  device and host. This protocol is required for most Bluetooth devices
+	  with UART interface, including PCMCIA and CF cards.
 
 
 	  Say Y here to compile support for HCI UART (H4) protocol.
 	  Say Y here to compile support for HCI UART (H4) protocol.
 
 
@@ -52,7 +52,7 @@ config BT_HCIUART_BCSP
 	depends on BT_HCIUART
 	depends on BT_HCIUART
 	select BITREVERSE
 	select BITREVERSE
 	help
 	help
-	  BCSP (BlueCore Serial Protocol) is serial protocol for communication 
+	  BCSP (BlueCore Serial Protocol) is serial protocol for communication
 	  between Bluetooth device and host. This protocol is required for non
 	  between Bluetooth device and host. This protocol is required for non
 	  USB Bluetooth devices based on CSR BlueCore chip, including PCMCIA and
 	  USB Bluetooth devices based on CSR BlueCore chip, including PCMCIA and
 	  CF cards.
 	  CF cards.

+ 4 - 4
drivers/bluetooth/ath3k.c

@@ -90,7 +90,6 @@ static const struct usb_device_id ath3k_table[] = {
 	{ USB_DEVICE(0x0b05, 0x17d0) },
 	{ USB_DEVICE(0x0b05, 0x17d0) },
 	{ USB_DEVICE(0x0CF3, 0x0036) },
 	{ USB_DEVICE(0x0CF3, 0x0036) },
 	{ USB_DEVICE(0x0CF3, 0x3004) },
 	{ USB_DEVICE(0x0CF3, 0x3004) },
-	{ USB_DEVICE(0x0CF3, 0x3005) },
 	{ USB_DEVICE(0x0CF3, 0x3008) },
 	{ USB_DEVICE(0x0CF3, 0x3008) },
 	{ USB_DEVICE(0x0CF3, 0x311D) },
 	{ USB_DEVICE(0x0CF3, 0x311D) },
 	{ USB_DEVICE(0x0CF3, 0x311E) },
 	{ USB_DEVICE(0x0CF3, 0x311E) },
@@ -104,6 +103,7 @@ static const struct usb_device_id ath3k_table[] = {
 	{ USB_DEVICE(0x13d3, 0x3375) },
 	{ USB_DEVICE(0x13d3, 0x3375) },
 	{ USB_DEVICE(0x13d3, 0x3393) },
 	{ USB_DEVICE(0x13d3, 0x3393) },
 	{ USB_DEVICE(0x13d3, 0x3402) },
 	{ USB_DEVICE(0x13d3, 0x3402) },
+	{ USB_DEVICE(0x13d3, 0x3432) },
 
 
 	/* Atheros AR5BBU12 with sflash firmware */
 	/* Atheros AR5BBU12 with sflash firmware */
 	{ USB_DEVICE(0x0489, 0xE02C) },
 	{ USB_DEVICE(0x0489, 0xE02C) },
@@ -140,7 +140,6 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
 	{ USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x0cf3, 0x3005), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x311E), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x311E), .driver_info = BTUSB_ATH3012 },
@@ -154,6 +153,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
 	{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 },
 
 
 	/* Atheros AR5BBU22 with sflash firmware */
 	/* Atheros AR5BBU22 with sflash firmware */
 	{ USB_DEVICE(0x0489, 0xE036), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0489, 0xE036), .driver_info = BTUSB_ATH3012 },
@@ -290,10 +290,10 @@ static int ath3k_load_fwfile(struct usb_device *udev,
 	sent += size;
 	sent += size;
 	count -= size;
 	count -= size;
 
 
+	pipe = usb_sndbulkpipe(udev, 0x02);
+
 	while (count) {
 	while (count) {
 		size = min_t(uint, count, BULK_SIZE);
 		size = min_t(uint, count, BULK_SIZE);
-		pipe = usb_sndbulkpipe(udev, 0x02);
-
 		memcpy(send_buf, firmware->data + sent, size);
 		memcpy(send_buf, firmware->data + sent, size);
 
 
 		err = usb_bulk_msg(udev, pipe, send_buf, size,
 		err = usb_bulk_msg(udev, pipe, send_buf, size,

+ 3 - 0
drivers/bluetooth/btmrvl_drv.h

@@ -68,6 +68,7 @@ struct btmrvl_adapter {
 	u8 hs_state;
 	u8 hs_state;
 	u8 wakeup_tries;
 	u8 wakeup_tries;
 	wait_queue_head_t cmd_wait_q;
 	wait_queue_head_t cmd_wait_q;
+	wait_queue_head_t event_hs_wait_q;
 	u8 cmd_complete;
 	u8 cmd_complete;
 	bool is_suspended;
 	bool is_suspended;
 };
 };
@@ -89,6 +90,7 @@ struct btmrvl_private {
 #define MRVL_VENDOR_PKT			0xFE
 #define MRVL_VENDOR_PKT			0xFE
 
 
 /* Vendor specific Bluetooth commands */
 /* Vendor specific Bluetooth commands */
+#define BT_CMD_PSCAN_WIN_REPORT_ENABLE	0xFC03
 #define BT_CMD_AUTO_SLEEP_MODE		0xFC23
 #define BT_CMD_AUTO_SLEEP_MODE		0xFC23
 #define BT_CMD_HOST_SLEEP_CONFIG	0xFC59
 #define BT_CMD_HOST_SLEEP_CONFIG	0xFC59
 #define BT_CMD_HOST_SLEEP_ENABLE	0xFC5A
 #define BT_CMD_HOST_SLEEP_ENABLE	0xFC5A
@@ -143,6 +145,7 @@ bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb);
 int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb);
 int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb);
 
 
 int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, u8 subcmd);
 int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, u8 subcmd);
+int btmrvl_pscan_window_reporting(struct btmrvl_private *priv, u8 subcmd);
 int btmrvl_send_hscfg_cmd(struct btmrvl_private *priv);
 int btmrvl_send_hscfg_cmd(struct btmrvl_private *priv);
 int btmrvl_enable_ps(struct btmrvl_private *priv);
 int btmrvl_enable_ps(struct btmrvl_private *priv);
 int btmrvl_prepare_command(struct btmrvl_private *priv);
 int btmrvl_prepare_command(struct btmrvl_private *priv);

+ 43 - 1
drivers/bluetooth/btmrvl_main.c

@@ -114,6 +114,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
 			adapter->hs_state = HS_ACTIVATED;
 			adapter->hs_state = HS_ACTIVATED;
 			if (adapter->psmode)
 			if (adapter->psmode)
 				adapter->ps_state = PS_SLEEP;
 				adapter->ps_state = PS_SLEEP;
+			wake_up_interruptible(&adapter->event_hs_wait_q);
 			BT_DBG("HS ACTIVATED!");
 			BT_DBG("HS ACTIVATED!");
 		} else {
 		} else {
 			BT_DBG("HS Enable failed");
 			BT_DBG("HS Enable failed");
@@ -214,6 +215,23 @@ int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, u8 subcmd)
 }
 }
 EXPORT_SYMBOL_GPL(btmrvl_send_module_cfg_cmd);
 EXPORT_SYMBOL_GPL(btmrvl_send_module_cfg_cmd);
 
 
+int btmrvl_pscan_window_reporting(struct btmrvl_private *priv, u8 subcmd)
+{
+	struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
+	int ret;
+
+	if (!card->support_pscan_win_report)
+		return 0;
+
+	ret = btmrvl_send_sync_cmd(priv, BT_CMD_PSCAN_WIN_REPORT_ENABLE,
+				   &subcmd, 1);
+	if (ret)
+		BT_ERR("PSCAN_WIN_REPORT_ENABLE command failed: %#x", ret);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(btmrvl_pscan_window_reporting);
+
 int btmrvl_send_hscfg_cmd(struct btmrvl_private *priv)
 int btmrvl_send_hscfg_cmd(struct btmrvl_private *priv)
 {
 {
 	int ret;
 	int ret;
@@ -253,11 +271,31 @@ EXPORT_SYMBOL_GPL(btmrvl_enable_ps);
 
 
 int btmrvl_enable_hs(struct btmrvl_private *priv)
 int btmrvl_enable_hs(struct btmrvl_private *priv)
 {
 {
+	struct btmrvl_adapter *adapter = priv->adapter;
 	int ret;
 	int ret;
 
 
 	ret = btmrvl_send_sync_cmd(priv, BT_CMD_HOST_SLEEP_ENABLE, NULL, 0);
 	ret = btmrvl_send_sync_cmd(priv, BT_CMD_HOST_SLEEP_ENABLE, NULL, 0);
-	if (ret)
+	if (ret) {
 		BT_ERR("Host sleep enable command failed\n");
 		BT_ERR("Host sleep enable command failed\n");
+		return ret;
+	}
+
+	ret = wait_event_interruptible_timeout(adapter->event_hs_wait_q,
+					       adapter->hs_state,
+			msecs_to_jiffies(WAIT_UNTIL_HS_STATE_CHANGED));
+	if (ret < 0) {
+		BT_ERR("event_hs_wait_q terminated (%d): %d,%d,%d",
+		       ret, adapter->hs_state, adapter->ps_state,
+		       adapter->wakeup_tries);
+	} else if (!ret) {
+		BT_ERR("hs_enable timeout: %d,%d,%d", adapter->hs_state,
+		       adapter->ps_state, adapter->wakeup_tries);
+		ret = -ETIMEDOUT;
+	} else {
+		BT_DBG("host sleep enabled: %d,%d,%d", adapter->hs_state,
+		       adapter->ps_state, adapter->wakeup_tries);
+		ret = 0;
+	}
 
 
 	return ret;
 	return ret;
 }
 }
@@ -358,6 +396,7 @@ static void btmrvl_init_adapter(struct btmrvl_private *priv)
 	}
 	}
 
 
 	init_waitqueue_head(&priv->adapter->cmd_wait_q);
 	init_waitqueue_head(&priv->adapter->cmd_wait_q);
+	init_waitqueue_head(&priv->adapter->event_hs_wait_q);
 }
 }
 
 
 static void btmrvl_free_adapter(struct btmrvl_private *priv)
 static void btmrvl_free_adapter(struct btmrvl_private *priv)
@@ -489,6 +528,8 @@ static int btmrvl_setup(struct hci_dev *hdev)
 
 
 	btmrvl_cal_data_dt(priv);
 	btmrvl_cal_data_dt(priv);
 
 
+	btmrvl_pscan_window_reporting(priv, 0x01);
+
 	priv->btmrvl_dev.psmode = 1;
 	priv->btmrvl_dev.psmode = 1;
 	btmrvl_enable_ps(priv);
 	btmrvl_enable_ps(priv);
 
 
@@ -666,6 +707,7 @@ int btmrvl_remove_card(struct btmrvl_private *priv)
 	hdev = priv->btmrvl_dev.hcidev;
 	hdev = priv->btmrvl_dev.hcidev;
 
 
 	wake_up_interruptible(&priv->adapter->cmd_wait_q);
 	wake_up_interruptible(&priv->adapter->cmd_wait_q);
+	wake_up_interruptible(&priv->adapter->event_hs_wait_q);
 
 
 	kthread_stop(priv->main_thread.task);
 	kthread_stop(priv->main_thread.task);
 
 

+ 5 - 0
drivers/bluetooth/btmrvl_sdio.c

@@ -108,6 +108,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
 	.helper		= "mrvl/sd8688_helper.bin",
 	.helper		= "mrvl/sd8688_helper.bin",
 	.firmware	= "mrvl/sd8688.bin",
 	.firmware	= "mrvl/sd8688.bin",
 	.reg		= &btmrvl_reg_8688,
 	.reg		= &btmrvl_reg_8688,
+	.support_pscan_win_report = false,
 	.sd_blksz_fw_dl	= 64,
 	.sd_blksz_fw_dl	= 64,
 };
 };
 
 
@@ -115,6 +116,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = {
 	.helper		= NULL,
 	.helper		= NULL,
 	.firmware	= "mrvl/sd8787_uapsta.bin",
 	.firmware	= "mrvl/sd8787_uapsta.bin",
 	.reg		= &btmrvl_reg_87xx,
 	.reg		= &btmrvl_reg_87xx,
+	.support_pscan_win_report = false,
 	.sd_blksz_fw_dl	= 256,
 	.sd_blksz_fw_dl	= 256,
 };
 };
 
 
@@ -122,6 +124,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = {
 	.helper		= NULL,
 	.helper		= NULL,
 	.firmware	= "mrvl/sd8797_uapsta.bin",
 	.firmware	= "mrvl/sd8797_uapsta.bin",
 	.reg		= &btmrvl_reg_87xx,
 	.reg		= &btmrvl_reg_87xx,
+	.support_pscan_win_report = false,
 	.sd_blksz_fw_dl	= 256,
 	.sd_blksz_fw_dl	= 256,
 };
 };
 
 
@@ -129,6 +132,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = {
 	.helper		= NULL,
 	.helper		= NULL,
 	.firmware	= "mrvl/sd8897_uapsta.bin",
 	.firmware	= "mrvl/sd8897_uapsta.bin",
 	.reg		= &btmrvl_reg_88xx,
 	.reg		= &btmrvl_reg_88xx,
+	.support_pscan_win_report = true,
 	.sd_blksz_fw_dl	= 256,
 	.sd_blksz_fw_dl	= 256,
 };
 };
 
 
@@ -1067,6 +1071,7 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
 		card->firmware = data->firmware;
 		card->firmware = data->firmware;
 		card->reg = data->reg;
 		card->reg = data->reg;
 		card->sd_blksz_fw_dl = data->sd_blksz_fw_dl;
 		card->sd_blksz_fw_dl = data->sd_blksz_fw_dl;
+		card->support_pscan_win_report = data->support_pscan_win_report;
 	}
 	}
 
 
 	if (btmrvl_sdio_register_dev(card) < 0) {
 	if (btmrvl_sdio_register_dev(card) < 0) {

+ 2 - 0
drivers/bluetooth/btmrvl_sdio.h

@@ -89,6 +89,7 @@ struct btmrvl_sdio_card {
 	const char *helper;
 	const char *helper;
 	const char *firmware;
 	const char *firmware;
 	const struct btmrvl_sdio_card_reg *reg;
 	const struct btmrvl_sdio_card_reg *reg;
+	bool support_pscan_win_report;
 	u16 sd_blksz_fw_dl;
 	u16 sd_blksz_fw_dl;
 	u8 rx_unit;
 	u8 rx_unit;
 	struct btmrvl_private *priv;
 	struct btmrvl_private *priv;
@@ -98,6 +99,7 @@ struct btmrvl_sdio_device {
 	const char *helper;
 	const char *helper;
 	const char *firmware;
 	const char *firmware;
 	const struct btmrvl_sdio_card_reg *reg;
 	const struct btmrvl_sdio_card_reg *reg;
+	const bool support_pscan_win_report;
 	u16 sd_blksz_fw_dl;
 	u16 sd_blksz_fw_dl;
 };
 };
 
 

+ 158 - 30
drivers/bluetooth/btusb.c

@@ -30,9 +30,6 @@
 
 
 #define VERSION "0.6"
 #define VERSION "0.6"
 
 
-static bool ignore_dga;
-static bool ignore_csr;
-static bool ignore_sniffer;
 static bool disable_scofix;
 static bool disable_scofix;
 static bool force_scofix;
 static bool force_scofix;
 
 
@@ -49,7 +46,8 @@ static struct usb_driver btusb_driver;
 #define BTUSB_WRONG_SCO_MTU	0x40
 #define BTUSB_WRONG_SCO_MTU	0x40
 #define BTUSB_ATH3012		0x80
 #define BTUSB_ATH3012		0x80
 #define BTUSB_INTEL		0x100
 #define BTUSB_INTEL		0x100
-#define BTUSB_BCM_PATCHRAM	0x200
+#define BTUSB_INTEL_BOOT	0x200
+#define BTUSB_BCM_PATCHRAM	0x400
 
 
 static const struct usb_device_id btusb_table[] = {
 static const struct usb_device_id btusb_table[] = {
 	/* Generic Bluetooth USB device */
 	/* Generic Bluetooth USB device */
@@ -121,6 +119,10 @@ static const struct usb_device_id btusb_table[] = {
 	/* IMC Networks - Broadcom based */
 	/* IMC Networks - Broadcom based */
 	{ USB_VENDOR_AND_INTERFACE_INFO(0x13d3, 0xff, 0x01, 0x01) },
 	{ USB_VENDOR_AND_INTERFACE_INFO(0x13d3, 0xff, 0x01, 0x01) },
 
 
+	/* Intel Bluetooth USB Bootloader (RAM module) */
+	{ USB_DEVICE(0x8087, 0x0a5a),
+	  .driver_info = BTUSB_INTEL_BOOT | BTUSB_BROKEN_ISOC },
+
 	{ }	/* Terminating entry */
 	{ }	/* Terminating entry */
 };
 };
 
 
@@ -162,7 +164,6 @@ static const struct usb_device_id blacklist_table[] = {
 	{ USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x0cf3, 0x3005), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x311e), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x311e), .driver_info = BTUSB_ATH3012 },
@@ -176,6 +177,7 @@ static const struct usb_device_id blacklist_table[] = {
 	{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 },
 
 
 	/* Atheros AR5BBU12 with sflash firmware */
 	/* Atheros AR5BBU12 with sflash firmware */
 	{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
 	{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
@@ -229,10 +231,12 @@ static const struct usb_device_id blacklist_table[] = {
 	{ USB_DEVICE(0x08fd, 0x0002), .driver_info = BTUSB_IGNORE },
 	{ USB_DEVICE(0x08fd, 0x0002), .driver_info = BTUSB_IGNORE },
 
 
 	/* CSR BlueCore Bluetooth Sniffer */
 	/* CSR BlueCore Bluetooth Sniffer */
-	{ USB_DEVICE(0x0a12, 0x0002), .driver_info = BTUSB_SNIFFER },
+	{ USB_DEVICE(0x0a12, 0x0002),
+	  .driver_info = BTUSB_SNIFFER | BTUSB_BROKEN_ISOC },
 
 
 	/* Frontline ComProbe Bluetooth Sniffer */
 	/* Frontline ComProbe Bluetooth Sniffer */
-	{ USB_DEVICE(0x16d3, 0x0002), .driver_info = BTUSB_SNIFFER },
+	{ USB_DEVICE(0x16d3, 0x0002),
+	  .driver_info = BTUSB_SNIFFER | BTUSB_BROKEN_ISOC },
 
 
 	/* Intel Bluetooth device */
 	/* Intel Bluetooth device */
 	{ USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL },
 	{ USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL },
@@ -1183,6 +1187,51 @@ static int btusb_setup_intel_patching(struct hci_dev *hdev,
 	return 0;
 	return 0;
 }
 }
 
 
+#define BDADDR_INTEL (&(bdaddr_t) {{0x00, 0x8b, 0x9e, 0x19, 0x03, 0x00}})
+
+static int btusb_check_bdaddr_intel(struct hci_dev *hdev)
+{
+	struct sk_buff *skb;
+	struct hci_rp_read_bd_addr *rp;
+
+	skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
+			     HCI_INIT_TIMEOUT);
+	if (IS_ERR(skb)) {
+		BT_ERR("%s reading Intel device address failed (%ld)",
+		       hdev->name, PTR_ERR(skb));
+		return PTR_ERR(skb);
+	}
+
+	if (skb->len != sizeof(*rp)) {
+		BT_ERR("%s Intel device address length mismatch", hdev->name);
+		kfree_skb(skb);
+		return -EIO;
+	}
+
+	rp = (struct hci_rp_read_bd_addr *) skb->data;
+	if (rp->status) {
+		BT_ERR("%s Intel device address result failed (%02x)",
+		       hdev->name, rp->status);
+		kfree_skb(skb);
+		return -bt_to_errno(rp->status);
+	}
+
+	/* For some Intel based controllers, the default Bluetooth device
+	 * address 00:03:19:9E:8B:00 can be found. These controllers are
+	 * fully operational, but have the danger of duplicate addresses
+	 * and that in turn can cause problems with Bluetooth operation.
+	 */
+	if (!bacmp(&rp->bdaddr, BDADDR_INTEL)) {
+		BT_ERR("%s found Intel default device address (%pMR)",
+		       hdev->name, &rp->bdaddr);
+		set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
+	}
+
+	kfree_skb(skb);
+
+	return 0;
+}
+
 static int btusb_setup_intel(struct hci_dev *hdev)
 static int btusb_setup_intel(struct hci_dev *hdev)
 {
 {
 	struct sk_buff *skb;
 	struct sk_buff *skb;
@@ -1255,6 +1304,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
 		BT_INFO("%s: Intel device is already patched. patch num: %02x",
 		BT_INFO("%s: Intel device is already patched. patch num: %02x",
 			hdev->name, ver->fw_patch_num);
 			hdev->name, ver->fw_patch_num);
 		kfree_skb(skb);
 		kfree_skb(skb);
+		btusb_check_bdaddr_intel(hdev);
 		return 0;
 		return 0;
 	}
 	}
 
 
@@ -1267,6 +1317,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
 	fw = btusb_setup_intel_get_fw(hdev, ver);
 	fw = btusb_setup_intel_get_fw(hdev, ver);
 	if (!fw) {
 	if (!fw) {
 		kfree_skb(skb);
 		kfree_skb(skb);
+		btusb_check_bdaddr_intel(hdev);
 		return 0;
 		return 0;
 	}
 	}
 	fw_ptr = fw->data;
 	fw_ptr = fw->data;
@@ -1346,6 +1397,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
 	BT_INFO("%s: Intel Bluetooth firmware patch completed and activated",
 	BT_INFO("%s: Intel Bluetooth firmware patch completed and activated",
 		hdev->name);
 		hdev->name);
 
 
+	btusb_check_bdaddr_intel(hdev);
 	return 0;
 	return 0;
 
 
 exit_mfg_disable:
 exit_mfg_disable:
@@ -1360,6 +1412,8 @@ exit_mfg_disable:
 	kfree_skb(skb);
 	kfree_skb(skb);
 
 
 	BT_INFO("%s: Intel Bluetooth firmware patch completed", hdev->name);
 	BT_INFO("%s: Intel Bluetooth firmware patch completed", hdev->name);
+
+	btusb_check_bdaddr_intel(hdev);
 	return 0;
 	return 0;
 
 
 exit_mfg_deactivate:
 exit_mfg_deactivate:
@@ -1380,9 +1434,29 @@ exit_mfg_deactivate:
 	BT_INFO("%s: Intel Bluetooth firmware patch completed and deactivated",
 	BT_INFO("%s: Intel Bluetooth firmware patch completed and deactivated",
 		hdev->name);
 		hdev->name);
 
 
+	btusb_check_bdaddr_intel(hdev);
+	return 0;
+}
+
+static int btusb_set_bdaddr_intel(struct hci_dev *hdev, const bdaddr_t *bdaddr)
+{
+	struct sk_buff *skb;
+	long ret;
+
+	skb = __hci_cmd_sync(hdev, 0xfc31, 6, bdaddr, HCI_INIT_TIMEOUT);
+	if (IS_ERR(skb)) {
+		ret = PTR_ERR(skb);
+		BT_ERR("%s: changing Intel device address failed (%ld)",
+			hdev->name, ret);
+		return ret;
+	}
+	kfree_skb(skb);
+
 	return 0;
 	return 0;
 }
 }
 
 
+#define BDADDR_BCM20702A0 (&(bdaddr_t) {{0x00, 0xa0, 0x02, 0x70, 0x20, 0x00}})
+
 static int btusb_setup_bcm_patchram(struct hci_dev *hdev)
 static int btusb_setup_bcm_patchram(struct hci_dev *hdev)
 {
 {
 	struct btusb_data *data = hci_get_drvdata(hdev);
 	struct btusb_data *data = hci_get_drvdata(hdev);
@@ -1396,6 +1470,7 @@ static int btusb_setup_bcm_patchram(struct hci_dev *hdev)
 	u16 opcode;
 	u16 opcode;
 	struct sk_buff *skb;
 	struct sk_buff *skb;
 	struct hci_rp_read_local_version *ver;
 	struct hci_rp_read_local_version *ver;
+	struct hci_rp_read_bd_addr *bda;
 	long ret;
 	long ret;
 
 
 	snprintf(fw_name, sizeof(fw_name), "brcm/%s-%04x-%04x.hcd",
 	snprintf(fw_name, sizeof(fw_name), "brcm/%s-%04x-%04x.hcd",
@@ -1405,8 +1480,7 @@ static int btusb_setup_bcm_patchram(struct hci_dev *hdev)
 
 
 	ret = request_firmware(&fw, fw_name, &hdev->dev);
 	ret = request_firmware(&fw, fw_name, &hdev->dev);
 	if (ret < 0) {
 	if (ret < 0) {
-		BT_INFO("%s: BCM: patch %s not found", hdev->name,
-			fw_name);
+		BT_INFO("%s: BCM: patch %s not found", hdev->name, fw_name);
 		return 0;
 		return 0;
 	}
 	}
 
 
@@ -1525,12 +1599,67 @@ reset_fw:
 		ver->lmp_ver, ver->lmp_subver);
 		ver->lmp_ver, ver->lmp_subver);
 	kfree_skb(skb);
 	kfree_skb(skb);
 
 
+	/* Read BD Address */
+	skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
+			     HCI_INIT_TIMEOUT);
+	if (IS_ERR(skb)) {
+		ret = PTR_ERR(skb);
+		BT_ERR("%s: HCI_OP_READ_BD_ADDR failed (%ld)",
+			hdev->name, ret);
+		goto done;
+	}
+
+	if (skb->len != sizeof(*bda)) {
+		BT_ERR("%s: HCI_OP_READ_BD_ADDR event length mismatch",
+			hdev->name);
+		kfree_skb(skb);
+		ret = -EIO;
+		goto done;
+	}
+
+	bda = (struct hci_rp_read_bd_addr *) skb->data;
+	if (bda->status) {
+		BT_ERR("%s: HCI_OP_READ_BD_ADDR error status (%02x)",
+		       hdev->name, bda->status);
+		kfree_skb(skb);
+		ret = -bt_to_errno(bda->status);
+		goto done;
+	}
+
+	/* The address 00:20:70:02:A0:00 indicates a BCM20702A0 controller
+	 * with no configured address.
+	 */
+	if (!bacmp(&bda->bdaddr, BDADDR_BCM20702A0)) {
+		BT_INFO("%s: BCM: using default device address (%pMR)",
+			hdev->name, &bda->bdaddr);
+		set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
+	}
+
+	kfree_skb(skb);
+
 done:
 done:
 	release_firmware(fw);
 	release_firmware(fw);
 
 
 	return ret;
 	return ret;
 }
 }
 
 
+static int btusb_set_bdaddr_bcm(struct hci_dev *hdev, const bdaddr_t *bdaddr)
+{
+	struct sk_buff *skb;
+	long ret;
+
+	skb = __hci_cmd_sync(hdev, 0xfc01, 6, bdaddr, HCI_INIT_TIMEOUT);
+	if (IS_ERR(skb)) {
+		ret = PTR_ERR(skb);
+		BT_ERR("%s: BCM: Change address command failed (%ld)",
+			hdev->name, ret);
+		return ret;
+	}
+	kfree_skb(skb);
+
+	return 0;
+}
+
 static int btusb_probe(struct usb_interface *intf,
 static int btusb_probe(struct usb_interface *intf,
 				const struct usb_device_id *id)
 				const struct usb_device_id *id)
 {
 {
@@ -1555,15 +1684,6 @@ static int btusb_probe(struct usb_interface *intf,
 	if (id->driver_info == BTUSB_IGNORE)
 	if (id->driver_info == BTUSB_IGNORE)
 		return -ENODEV;
 		return -ENODEV;
 
 
-	if (ignore_dga && id->driver_info & BTUSB_DIGIANSWER)
-		return -ENODEV;
-
-	if (ignore_csr && id->driver_info & BTUSB_CSR)
-		return -ENODEV;
-
-	if (ignore_sniffer && id->driver_info & BTUSB_SNIFFER)
-		return -ENODEV;
-
 	if (id->driver_info & BTUSB_ATH3012) {
 	if (id->driver_info & BTUSB_ATH3012) {
 		struct usb_device *udev = interface_to_usbdev(intf);
 		struct usb_device *udev = interface_to_usbdev(intf);
 
 
@@ -1636,11 +1756,18 @@ static int btusb_probe(struct usb_interface *intf,
 	if (id->driver_info & BTUSB_BCM92035)
 	if (id->driver_info & BTUSB_BCM92035)
 		hdev->setup = btusb_setup_bcm92035;
 		hdev->setup = btusb_setup_bcm92035;
 
 
-	if (id->driver_info & BTUSB_BCM_PATCHRAM)
+	if (id->driver_info & BTUSB_BCM_PATCHRAM) {
 		hdev->setup = btusb_setup_bcm_patchram;
 		hdev->setup = btusb_setup_bcm_patchram;
+		hdev->set_bdaddr = btusb_set_bdaddr_bcm;
+	}
 
 
-	if (id->driver_info & BTUSB_INTEL)
+	if (id->driver_info & BTUSB_INTEL) {
 		hdev->setup = btusb_setup_intel;
 		hdev->setup = btusb_setup_intel;
+		hdev->set_bdaddr = btusb_set_bdaddr_intel;
+	}
+
+	if (id->driver_info & BTUSB_INTEL_BOOT)
+		set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
 
 
 	/* Interface numbers are hardcoded in the specification */
 	/* Interface numbers are hardcoded in the specification */
 	data->isoc = usb_ifnum_to_if(data->udev, 1);
 	data->isoc = usb_ifnum_to_if(data->udev, 1);
@@ -1680,8 +1807,18 @@ static int btusb_probe(struct usb_interface *intf,
 		/* New sniffer firmware has crippled HCI interface */
 		/* New sniffer firmware has crippled HCI interface */
 		if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997)
 		if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997)
 			set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
 			set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
+	}
 
 
-		data->isoc = NULL;
+	if (id->driver_info & BTUSB_INTEL_BOOT) {
+		/* A bug in the bootloader causes that interrupt interface is
+		 * only enabled after receiving SetInterface(0, AltSetting=0).
+		 */
+		err = usb_set_interface(data->udev, 0, 0);
+		if (err < 0) {
+			BT_ERR("failed to set interface 0, alt 0 %d", err);
+			hci_free_dev(hdev);
+			return err;
+		}
 	}
 	}
 
 
 	if (data->isoc) {
 	if (data->isoc) {
@@ -1846,15 +1983,6 @@ static struct usb_driver btusb_driver = {
 
 
 module_usb_driver(btusb_driver);
 module_usb_driver(btusb_driver);
 
 
-module_param(ignore_dga, bool, 0644);
-MODULE_PARM_DESC(ignore_dga, "Ignore devices with id 08fd:0001");
-
-module_param(ignore_csr, bool, 0644);
-MODULE_PARM_DESC(ignore_csr, "Ignore devices with id 0a12:0001");
-
-module_param(ignore_sniffer, bool, 0644);
-MODULE_PARM_DESC(ignore_sniffer, "Ignore devices with id 0a12:0002");
-
 module_param(disable_scofix, bool, 0644);
 module_param(disable_scofix, bool, 0644);
 MODULE_PARM_DESC(disable_scofix, "Disable fixup of wrong SCO buffer size");
 MODULE_PARM_DESC(disable_scofix, "Disable fixup of wrong SCO buffer size");
 
 

+ 1 - 4
drivers/bluetooth/hci_h5.c

@@ -355,10 +355,7 @@ static void h5_complete_rx_pkt(struct hci_uart *hu)
 
 
 static int h5_rx_crc(struct hci_uart *hu, unsigned char c)
 static int h5_rx_crc(struct hci_uart *hu, unsigned char c)
 {
 {
-	struct h5 *h5 = hu->priv;
-
 	h5_complete_rx_pkt(hu);
 	h5_complete_rx_pkt(hu);
-	h5_reset_rx(h5);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -373,7 +370,6 @@ static int h5_rx_payload(struct hci_uart *hu, unsigned char c)
 		h5->rx_pending = 2;
 		h5->rx_pending = 2;
 	} else {
 	} else {
 		h5_complete_rx_pkt(hu);
 		h5_complete_rx_pkt(hu);
-		h5_reset_rx(h5);
 	}
 	}
 
 
 	return 0;
 	return 0;
@@ -406,6 +402,7 @@ static int h5_rx_3wire_hdr(struct hci_uart *hu, unsigned char c)
 	    H5_HDR_PKT_TYPE(hdr) != HCI_3WIRE_LINK_PKT) {
 	    H5_HDR_PKT_TYPE(hdr) != HCI_3WIRE_LINK_PKT) {
 		BT_ERR("Non-link packet received in non-active state");
 		BT_ERR("Non-link packet received in non-active state");
 		h5_reset_rx(h5);
 		h5_reset_rx(h5);
+		return 0;
 	}
 	}
 
 
 	h5->rx_func = h5_rx_payload;
 	h5->rx_func = h5_rx_payload;

+ 25 - 9
drivers/bluetooth/hci_vhci.c

@@ -40,7 +40,7 @@
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 #include <net/bluetooth/hci_core.h>
 
 
-#define VERSION "1.4"
+#define VERSION "1.5"
 
 
 static bool amp;
 static bool amp;
 
 
@@ -95,10 +95,21 @@ static int vhci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 	return 0;
 	return 0;
 }
 }
 
 
-static int vhci_create_device(struct vhci_data *data, __u8 dev_type)
+static int vhci_create_device(struct vhci_data *data, __u8 opcode)
 {
 {
 	struct hci_dev *hdev;
 	struct hci_dev *hdev;
 	struct sk_buff *skb;
 	struct sk_buff *skb;
+	__u8 dev_type;
+
+	/* bits 0-1 are dev_type (BR/EDR or AMP) */
+	dev_type = opcode & 0x03;
+
+	if (dev_type != HCI_BREDR && dev_type != HCI_AMP)
+		return -EINVAL;
+
+	/* bits 2-5 are reserved (must be zero) */
+	if (opcode & 0x3c)
+		return -EINVAL;
 
 
 	skb = bt_skb_alloc(4, GFP_KERNEL);
 	skb = bt_skb_alloc(4, GFP_KERNEL);
 	if (!skb)
 	if (!skb)
@@ -121,6 +132,14 @@ static int vhci_create_device(struct vhci_data *data, __u8 dev_type)
 	hdev->flush = vhci_flush;
 	hdev->flush = vhci_flush;
 	hdev->send  = vhci_send_frame;
 	hdev->send  = vhci_send_frame;
 
 
+	/* bit 6 is for external configuration */
+	if (opcode & 0x40)
+		set_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks);
+
+	/* bit 7 is for raw device */
+	if (opcode & 0x80)
+		set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
+
 	if (hci_register_dev(hdev) < 0) {
 	if (hci_register_dev(hdev) < 0) {
 		BT_ERR("Can't register HCI device");
 		BT_ERR("Can't register HCI device");
 		hci_free_dev(hdev);
 		hci_free_dev(hdev);
@@ -132,7 +151,7 @@ static int vhci_create_device(struct vhci_data *data, __u8 dev_type)
 	bt_cb(skb)->pkt_type = HCI_VENDOR_PKT;
 	bt_cb(skb)->pkt_type = HCI_VENDOR_PKT;
 
 
 	*skb_put(skb, 1) = 0xff;
 	*skb_put(skb, 1) = 0xff;
-	*skb_put(skb, 1) = dev_type;
+	*skb_put(skb, 1) = opcode;
 	put_unaligned_le16(hdev->id, skb_put(skb, 2));
 	put_unaligned_le16(hdev->id, skb_put(skb, 2));
 	skb_queue_tail(&data->readq, skb);
 	skb_queue_tail(&data->readq, skb);
 
 
@@ -146,7 +165,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *data,
 {
 {
 	size_t len = iov_length(iov, count);
 	size_t len = iov_length(iov, count);
 	struct sk_buff *skb;
 	struct sk_buff *skb;
-	__u8 pkt_type, dev_type;
+	__u8 pkt_type, opcode;
 	unsigned long i;
 	unsigned long i;
 	int ret;
 	int ret;
 
 
@@ -190,7 +209,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *data,
 
 
 		cancel_delayed_work_sync(&data->open_timeout);
 		cancel_delayed_work_sync(&data->open_timeout);
 
 
-		dev_type = *((__u8 *) skb->data);
+		opcode = *((__u8 *) skb->data);
 		skb_pull(skb, 1);
 		skb_pull(skb, 1);
 
 
 		if (skb->len > 0) {
 		if (skb->len > 0) {
@@ -200,10 +219,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *data,
 
 
 		kfree_skb(skb);
 		kfree_skb(skb);
 
 
-		if (dev_type != HCI_BREDR && dev_type != HCI_AMP)
-			return -EINVAL;
-
-		ret = vhci_create_device(data, dev_type);
+		ret = vhci_create_device(data, opcode);
 		break;
 		break;
 
 
 	default:
 	default:

+ 5 - 1
drivers/net/wireless/ath/ath10k/core.c

@@ -795,7 +795,11 @@ int ath10k_core_start(struct ath10k *ar)
 	if (status)
 	if (status)
 		goto err_htc_stop;
 		goto err_htc_stop;
 
 
-	ar->free_vdev_map = (1 << TARGET_NUM_VDEVS) - 1;
+	if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features))
+		ar->free_vdev_map = (1 << TARGET_10X_NUM_VDEVS) - 1;
+	else
+		ar->free_vdev_map = (1 << TARGET_NUM_VDEVS) - 1;
+
 	INIT_LIST_HEAD(&ar->arvifs);
 	INIT_LIST_HEAD(&ar->arvifs);
 
 
 	if (!test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags))
 	if (!test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags))

+ 0 - 18
drivers/net/wireless/ath/ath10k/htt_rx.c

@@ -312,7 +312,6 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
 	int msdu_len, msdu_chaining = 0;
 	int msdu_len, msdu_chaining = 0;
 	struct sk_buff *msdu;
 	struct sk_buff *msdu;
 	struct htt_rx_desc *rx_desc;
 	struct htt_rx_desc *rx_desc;
-	bool corrupted = false;
 
 
 	lockdep_assert_held(&htt->rx_ring.lock);
 	lockdep_assert_held(&htt->rx_ring.lock);
 
 
@@ -439,9 +438,6 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
 		last_msdu = __le32_to_cpu(rx_desc->msdu_end.info0) &
 		last_msdu = __le32_to_cpu(rx_desc->msdu_end.info0) &
 				RX_MSDU_END_INFO0_LAST_MSDU;
 				RX_MSDU_END_INFO0_LAST_MSDU;
 
 
-		if (msdu_chaining && !last_msdu)
-			corrupted = true;
-
 		if (last_msdu) {
 		if (last_msdu) {
 			msdu->next = NULL;
 			msdu->next = NULL;
 			break;
 			break;
@@ -456,20 +452,6 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
 	if (*head_msdu == NULL)
 	if (*head_msdu == NULL)
 		msdu_chaining = -1;
 		msdu_chaining = -1;
 
 
-	/*
-	 * Apparently FW sometimes reports weird chained MSDU sequences with
-	 * more than one rx descriptor. This seems like a bug but needs more
-	 * analyzing. For the time being fix it by dropping such sequences to
-	 * avoid blowing up the host system.
-	 */
-	if (corrupted) {
-		ath10k_warn("failed to pop chained msdus, dropping\n");
-		ath10k_htt_rx_free_msdu_chain(*head_msdu);
-		*head_msdu = NULL;
-		*tail_msdu = NULL;
-		msdu_chaining = -EINVAL;
-	}
-
 	/*
 	/*
 	 * Don't refill the ring yet.
 	 * Don't refill the ring yet.
 	 *
 	 *

+ 3 - 2
drivers/net/wireless/brcm80211/brcmfmac/usb.c

@@ -1183,8 +1183,6 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
 	bus->bus_priv.usb = bus_pub;
 	bus->bus_priv.usb = bus_pub;
 	dev_set_drvdata(dev, bus);
 	dev_set_drvdata(dev, bus);
 	bus->ops = &brcmf_usb_bus_ops;
 	bus->ops = &brcmf_usb_bus_ops;
-	bus->chip = bus_pub->devid;
-	bus->chiprev = bus_pub->chiprev;
 	bus->proto_type = BRCMF_PROTO_BCDC;
 	bus->proto_type = BRCMF_PROTO_BCDC;
 	bus->always_use_fws_queue = true;
 	bus->always_use_fws_queue = true;
 
 
@@ -1193,6 +1191,9 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
 		if (ret)
 		if (ret)
 			goto fail;
 			goto fail;
 	}
 	}
+	bus->chip = bus_pub->devid;
+	bus->chiprev = bus_pub->chiprev;
+
 	/* request firmware here */
 	/* request firmware here */
 	brcmf_fw_get_firmwares(dev, 0, brcmf_usb_get_fwname(devinfo), NULL,
 	brcmf_fw_get_firmwares(dev, 0, brcmf_usb_get_fwname(devinfo), NULL,
 			       brcmf_usb_probe_phase2);
 			       brcmf_usb_probe_phase2);

+ 1 - 0
drivers/net/wireless/mwifiex/11n_aggr.c

@@ -185,6 +185,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
 	skb_reserve(skb_aggr, headroom + sizeof(struct txpd));
 	skb_reserve(skb_aggr, headroom + sizeof(struct txpd));
 	tx_info_aggr =  MWIFIEX_SKB_TXCB(skb_aggr);
 	tx_info_aggr =  MWIFIEX_SKB_TXCB(skb_aggr);
 
 
+	memset(tx_info_aggr, 0, sizeof(*tx_info_aggr));
 	tx_info_aggr->bss_type = tx_info_src->bss_type;
 	tx_info_aggr->bss_type = tx_info_src->bss_type;
 	tx_info_aggr->bss_num = tx_info_src->bss_num;
 	tx_info_aggr->bss_num = tx_info_src->bss_num;
 
 

+ 1 - 0
drivers/net/wireless/mwifiex/cfg80211.c

@@ -188,6 +188,7 @@ mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
 	}
 	}
 
 
 	tx_info = MWIFIEX_SKB_TXCB(skb);
 	tx_info = MWIFIEX_SKB_TXCB(skb);
+	memset(tx_info, 0, sizeof(*tx_info));
 	tx_info->bss_num = priv->bss_num;
 	tx_info->bss_num = priv->bss_num;
 	tx_info->bss_type = priv->bss_type;
 	tx_info->bss_type = priv->bss_type;
 	tx_info->pkt_len = pkt_len;
 	tx_info->pkt_len = pkt_len;

+ 1 - 0
drivers/net/wireless/mwifiex/cmdevt.c

@@ -462,6 +462,7 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
 
 
 	if (skb) {
 	if (skb) {
 		rx_info = MWIFIEX_SKB_RXCB(skb);
 		rx_info = MWIFIEX_SKB_RXCB(skb);
+		memset(rx_info, 0, sizeof(*rx_info));
 		rx_info->bss_num = priv->bss_num;
 		rx_info->bss_num = priv->bss_num;
 		rx_info->bss_type = priv->bss_type;
 		rx_info->bss_type = priv->bss_type;
 	}
 	}

+ 1 - 0
drivers/net/wireless/mwifiex/main.c

@@ -644,6 +644,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	}
 	}
 
 
 	tx_info = MWIFIEX_SKB_TXCB(skb);
 	tx_info = MWIFIEX_SKB_TXCB(skb);
+	memset(tx_info, 0, sizeof(*tx_info));
 	tx_info->bss_num = priv->bss_num;
 	tx_info->bss_num = priv->bss_num;
 	tx_info->bss_type = priv->bss_type;
 	tx_info->bss_type = priv->bss_type;
 	tx_info->pkt_len = skb->len;
 	tx_info->pkt_len = skb->len;

+ 1 - 0
drivers/net/wireless/mwifiex/sta_tx.c

@@ -150,6 +150,7 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags)
 		return -1;
 		return -1;
 
 
 	tx_info = MWIFIEX_SKB_TXCB(skb);
 	tx_info = MWIFIEX_SKB_TXCB(skb);
+	memset(tx_info, 0, sizeof(*tx_info));
 	tx_info->bss_num = priv->bss_num;
 	tx_info->bss_num = priv->bss_num;
 	tx_info->bss_type = priv->bss_type;
 	tx_info->bss_type = priv->bss_type;
 	tx_info->pkt_len = data_len - (sizeof(struct txpd) + INTF_HEADER_LEN);
 	tx_info->pkt_len = data_len - (sizeof(struct txpd) + INTF_HEADER_LEN);

+ 2 - 0
drivers/net/wireless/mwifiex/tdls.c

@@ -604,6 +604,7 @@ int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv, const u8 *peer,
 	}
 	}
 
 
 	tx_info = MWIFIEX_SKB_TXCB(skb);
 	tx_info = MWIFIEX_SKB_TXCB(skb);
+	memset(tx_info, 0, sizeof(*tx_info));
 	tx_info->bss_num = priv->bss_num;
 	tx_info->bss_num = priv->bss_num;
 	tx_info->bss_type = priv->bss_type;
 	tx_info->bss_type = priv->bss_type;
 
 
@@ -757,6 +758,7 @@ int mwifiex_send_tdls_action_frame(struct mwifiex_private *priv, const u8 *peer,
 	skb->priority = MWIFIEX_PRIO_VI;
 	skb->priority = MWIFIEX_PRIO_VI;
 
 
 	tx_info = MWIFIEX_SKB_TXCB(skb);
 	tx_info = MWIFIEX_SKB_TXCB(skb);
+	memset(tx_info, 0, sizeof(*tx_info));
 	tx_info->bss_num = priv->bss_num;
 	tx_info->bss_num = priv->bss_num;
 	tx_info->bss_type = priv->bss_type;
 	tx_info->bss_type = priv->bss_type;
 	tx_info->flags |= MWIFIEX_BUF_FLAG_TDLS_PKT;
 	tx_info->flags |= MWIFIEX_BUF_FLAG_TDLS_PKT;

+ 1 - 0
drivers/net/wireless/mwifiex/txrx.c

@@ -55,6 +55,7 @@ int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter,
 		return -1;
 		return -1;
 	}
 	}
 
 
+	memset(rx_info, 0, sizeof(*rx_info));
 	rx_info->bss_num = priv->bss_num;
 	rx_info->bss_num = priv->bss_num;
 	rx_info->bss_type = priv->bss_type;
 	rx_info->bss_type = priv->bss_type;
 
 

+ 1 - 0
drivers/net/wireless/mwifiex/uap_txrx.c

@@ -174,6 +174,7 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
 	}
 	}
 
 
 	tx_info = MWIFIEX_SKB_TXCB(skb);
 	tx_info = MWIFIEX_SKB_TXCB(skb);
+	memset(tx_info, 0, sizeof(*tx_info));
 	tx_info->bss_num = priv->bss_num;
 	tx_info->bss_num = priv->bss_num;
 	tx_info->bss_type = priv->bss_type;
 	tx_info->bss_type = priv->bss_type;
 	tx_info->flags |= MWIFIEX_BUF_FLAG_BRIDGED_PKT;
 	tx_info->flags |= MWIFIEX_BUF_FLAG_BRIDGED_PKT;

+ 22 - 6
drivers/net/wireless/rt2x00/rt2800usb.c

@@ -231,9 +231,12 @@ static enum hrtimer_restart rt2800usb_tx_sta_fifo_timeout(struct hrtimer *timer)
  */
  */
 static int rt2800usb_autorun_detect(struct rt2x00_dev *rt2x00dev)
 static int rt2800usb_autorun_detect(struct rt2x00_dev *rt2x00dev)
 {
 {
-	__le32 reg;
+	__le32 *reg;
 	u32 fw_mode;
 	u32 fw_mode;
 
 
+	reg = kmalloc(sizeof(*reg), GFP_KERNEL);
+	if (reg == NULL)
+		return -ENOMEM;
 	/* cannot use rt2x00usb_register_read here as it uses different
 	/* cannot use rt2x00usb_register_read here as it uses different
 	 * mode (MULTI_READ vs. DEVICE_MODE) and does not pass the
 	 * mode (MULTI_READ vs. DEVICE_MODE) and does not pass the
 	 * magic value USB_MODE_AUTORUN (0x11) to the device, thus the
 	 * magic value USB_MODE_AUTORUN (0x11) to the device, thus the
@@ -241,8 +244,9 @@ static int rt2800usb_autorun_detect(struct rt2x00_dev *rt2x00dev)
 	 */
 	 */
 	rt2x00usb_vendor_request(rt2x00dev, USB_DEVICE_MODE,
 	rt2x00usb_vendor_request(rt2x00dev, USB_DEVICE_MODE,
 				 USB_VENDOR_REQUEST_IN, 0, USB_MODE_AUTORUN,
 				 USB_VENDOR_REQUEST_IN, 0, USB_MODE_AUTORUN,
-				 &reg, sizeof(reg), REGISTER_TIMEOUT_FIRMWARE);
-	fw_mode = le32_to_cpu(reg);
+				 reg, sizeof(*reg), REGISTER_TIMEOUT_FIRMWARE);
+	fw_mode = le32_to_cpu(*reg);
+	kfree(reg);
 
 
 	if ((fw_mode & 0x00000003) == 2)
 	if ((fw_mode & 0x00000003) == 2)
 		return 1;
 		return 1;
@@ -261,6 +265,7 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev,
 	int status;
 	int status;
 	u32 offset;
 	u32 offset;
 	u32 length;
 	u32 length;
+	int retval;
 
 
 	/*
 	/*
 	 * Check which section of the firmware we need.
 	 * Check which section of the firmware we need.
@@ -278,7 +283,10 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev,
 	/*
 	/*
 	 * Write firmware to device.
 	 * Write firmware to device.
 	 */
 	 */
-	if (rt2800usb_autorun_detect(rt2x00dev)) {
+	retval = rt2800usb_autorun_detect(rt2x00dev);
+	if (retval < 0)
+		return retval;
+	if (retval) {
 		rt2x00_info(rt2x00dev,
 		rt2x00_info(rt2x00dev,
 			    "Firmware loading not required - NIC in AutoRun mode\n");
 			    "Firmware loading not required - NIC in AutoRun mode\n");
 	} else {
 	} else {
@@ -763,7 +771,12 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
  */
  */
 static int rt2800usb_efuse_detect(struct rt2x00_dev *rt2x00dev)
 static int rt2800usb_efuse_detect(struct rt2x00_dev *rt2x00dev)
 {
 {
-	if (rt2800usb_autorun_detect(rt2x00dev))
+	int retval;
+
+	retval = rt2800usb_autorun_detect(rt2x00dev);
+	if (retval < 0)
+		return retval;
+	if (retval)
 		return 1;
 		return 1;
 	return rt2800_efuse_detect(rt2x00dev);
 	return rt2800_efuse_detect(rt2x00dev);
 }
 }
@@ -772,7 +785,10 @@ static int rt2800usb_read_eeprom(struct rt2x00_dev *rt2x00dev)
 {
 {
 	int retval;
 	int retval;
 
 
-	if (rt2800usb_efuse_detect(rt2x00dev))
+	retval = rt2800usb_efuse_detect(rt2x00dev);
+	if (retval < 0)
+		return retval;
+	if (retval)
 		retval = rt2800_read_eeprom_efuse(rt2x00dev);
 		retval = rt2800_read_eeprom_efuse(rt2x00dev);
 	else
 	else
 		retval = rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom,
 		retval = rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom,

+ 9 - 9
include/net/bluetooth/bluetooth.h

@@ -260,15 +260,15 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock);
 
 
 /* Skb helpers */
 /* Skb helpers */
 struct l2cap_ctrl {
 struct l2cap_ctrl {
-	unsigned int	sframe:1,
-			poll:1,
-			final:1,
-			fcs:1,
-			sar:2,
-			super:2;
-	__u16		reqseq;
-	__u16		txseq;
-	__u8		retries;
+	__u8	sframe:1,
+		poll:1,
+		final:1,
+		fcs:1,
+		sar:2,
+		super:2;
+	__u16	reqseq;
+	__u16	txseq;
+	__u8	retries;
 };
 };
 
 
 struct hci_dev;
 struct hci_dev;

+ 119 - 16
include/net/bluetooth/hci.h

@@ -81,10 +81,54 @@
 
 
 /* HCI device quirks */
 /* HCI device quirks */
 enum {
 enum {
+	/* When this quirk is set, the HCI Reset command is send when
+	 * closing the transport instead of when opening it.
+	 *
+	 * This quirk must be set before hci_register_dev is called.
+	 */
 	HCI_QUIRK_RESET_ON_CLOSE,
 	HCI_QUIRK_RESET_ON_CLOSE,
+
+	/* When this quirk is set, the device is turned into a raw-only
+	 * device and it will stay in unconfigured state.
+	 *
+	 * This quirk must be set before hci_register_dev is called.
+	 */
 	HCI_QUIRK_RAW_DEVICE,
 	HCI_QUIRK_RAW_DEVICE,
+
+	/* When this quirk is set, the buffer sizes reported by
+	 * HCI Read Buffer Size command are corrected if invalid.
+	 *
+	 * This quirk must be set before hci_register_dev is called.
+	 */
 	HCI_QUIRK_FIXUP_BUFFER_SIZE,
 	HCI_QUIRK_FIXUP_BUFFER_SIZE,
+
+	/* When this quirk is set, then no stored link key handling
+	 * is performed. This is mainly due to the fact that the
+	 * HCI Delete Stored Link Key command is advertised, but
+	 * not supported.
+	 *
+	 * This quirk must be set before hci_register_dev is called.
+	 */
 	HCI_QUIRK_BROKEN_STORED_LINK_KEY,
 	HCI_QUIRK_BROKEN_STORED_LINK_KEY,
+
+	/* When this quirk is set, an external configuration step
+	 * is required and will be indicated with the controller
+	 * configuation.
+	 *
+	 * This quirk can be set before hci_register_dev is called or
+	 * during the hdev->setup vendor callback.
+	 */
+	HCI_QUIRK_EXTERNAL_CONFIG,
+
+	/* When this quirk is set, the public Bluetooth address
+	 * initially reported by HCI Read BD Address command
+	 * is considered invalid. Controller configuration is
+	 * required before this device can be used.
+	 *
+	 * This quirk can be set before hci_register_dev is called or
+	 * during the hdev->setup vendor callback.
+	 */
+	HCI_QUIRK_INVALID_BDADDR,
 };
 };
 
 
 /* HCI device flags */
 /* HCI device flags */
@@ -104,24 +148,34 @@ enum {
 	HCI_RESET,
 	HCI_RESET,
 };
 };
 
 
+/* BR/EDR and/or LE controller flags: the flags defined here should represent
+ * states configured via debugfs for debugging and testing purposes only.
+ */
+enum {
+	HCI_DUT_MODE,
+	HCI_FORCE_SC,
+	HCI_FORCE_STATIC_ADDR,
+};
+
 /*
 /*
  * BR/EDR and/or LE controller flags: the flags defined here should represent
  * BR/EDR and/or LE controller flags: the flags defined here should represent
  * states from the controller.
  * states from the controller.
  */
  */
 enum {
 enum {
 	HCI_SETUP,
 	HCI_SETUP,
+	HCI_CONFIG,
 	HCI_AUTO_OFF,
 	HCI_AUTO_OFF,
 	HCI_RFKILLED,
 	HCI_RFKILLED,
 	HCI_MGMT,
 	HCI_MGMT,
 	HCI_PAIRABLE,
 	HCI_PAIRABLE,
 	HCI_SERVICE_CACHE,
 	HCI_SERVICE_CACHE,
-	HCI_DEBUG_KEYS,
-	HCI_DUT_MODE,
-	HCI_FORCE_SC,
-	HCI_FORCE_STATIC_ADDR,
+	HCI_KEEP_DEBUG_KEYS,
+	HCI_USE_DEBUG_KEYS,
 	HCI_UNREGISTER,
 	HCI_UNREGISTER,
+	HCI_UNCONFIGURED,
 	HCI_USER_CHANNEL,
 	HCI_USER_CHANNEL,
-
+	HCI_EXT_CONFIGURED,
+	HCI_LE_ADV,
 	HCI_LE_SCAN,
 	HCI_LE_SCAN,
 	HCI_SSP_ENABLED,
 	HCI_SSP_ENABLED,
 	HCI_SC_ENABLED,
 	HCI_SC_ENABLED,
@@ -139,7 +193,6 @@ enum {
 	HCI_PERIODIC_INQ,
 	HCI_PERIODIC_INQ,
 	HCI_FAST_CONNECTABLE,
 	HCI_FAST_CONNECTABLE,
 	HCI_BREDR_ENABLED,
 	HCI_BREDR_ENABLED,
-	HCI_6LOWPAN_ENABLED,
 	HCI_LE_SCAN_INTERRUPTED,
 	HCI_LE_SCAN_INTERRUPTED,
 };
 };
 
 
@@ -147,7 +200,7 @@ enum {
  * or the HCI device is closed.
  * or the HCI device is closed.
  */
  */
 #define HCI_PERSISTENT_MASK (BIT(HCI_LE_SCAN) | BIT(HCI_PERIODIC_INQ) | \
 #define HCI_PERSISTENT_MASK (BIT(HCI_LE_SCAN) | BIT(HCI_PERIODIC_INQ) | \
-			      BIT(HCI_FAST_CONNECTABLE))
+			      BIT(HCI_FAST_CONNECTABLE) | BIT(HCI_LE_ADV))
 
 
 /* HCI ioctl defines */
 /* HCI ioctl defines */
 #define HCIDEVUP	_IOW('H', 201, int)
 #define HCIDEVUP	_IOW('H', 201, int)
@@ -185,6 +238,7 @@ enum {
 #define HCI_AUTO_OFF_TIMEOUT	msecs_to_jiffies(2000)	/* 2 seconds */
 #define HCI_AUTO_OFF_TIMEOUT	msecs_to_jiffies(2000)	/* 2 seconds */
 #define HCI_POWER_OFF_TIMEOUT	msecs_to_jiffies(5000)	/* 5 seconds */
 #define HCI_POWER_OFF_TIMEOUT	msecs_to_jiffies(5000)	/* 5 seconds */
 #define HCI_LE_CONN_TIMEOUT	msecs_to_jiffies(20000)	/* 20 seconds */
 #define HCI_LE_CONN_TIMEOUT	msecs_to_jiffies(20000)	/* 20 seconds */
+#define HCI_LE_AUTOCONN_TIMEOUT	msecs_to_jiffies(2000)	/* 2 seconds */
 
 
 /* HCI data types */
 /* HCI data types */
 #define HCI_COMMAND_PKT		0x01
 #define HCI_COMMAND_PKT		0x01
@@ -301,6 +355,10 @@ enum {
 #define LMP_HOST_LE_BREDR	0x04
 #define LMP_HOST_LE_BREDR	0x04
 #define LMP_HOST_SC		0x08
 #define LMP_HOST_SC		0x08
 
 
+/* LE features */
+#define HCI_LE_CONN_PARAM_REQ_PROC	0x02
+#define HCI_LE_PING			0x10
+
 /* Connection modes */
 /* Connection modes */
 #define HCI_CM_ACTIVE	0x0000
 #define HCI_CM_ACTIVE	0x0000
 #define HCI_CM_HOLD	0x0001
 #define HCI_CM_HOLD	0x0001
@@ -347,17 +405,9 @@ enum {
 #define HCI_LK_CHANGED_COMBINATION	0x06
 #define HCI_LK_CHANGED_COMBINATION	0x06
 #define HCI_LK_UNAUTH_COMBINATION_P256	0x07
 #define HCI_LK_UNAUTH_COMBINATION_P256	0x07
 #define HCI_LK_AUTH_COMBINATION_P256	0x08
 #define HCI_LK_AUTH_COMBINATION_P256	0x08
-/* The spec doesn't define types for SMP keys, the _MASTER suffix is implied */
-#define HCI_SMP_STK			0x80
-#define HCI_SMP_STK_SLAVE		0x81
-#define HCI_SMP_LTK			0x82
-#define HCI_SMP_LTK_SLAVE		0x83
-
-/* Long Term Key types */
-#define HCI_LTK_UNAUTH			0x00
-#define HCI_LTK_AUTH			0x01
 
 
 /* ---- HCI Error Codes ---- */
 /* ---- HCI Error Codes ---- */
+#define HCI_ERROR_UNKNOWN_CONN_ID	0x02
 #define HCI_ERROR_AUTH_FAILURE		0x05
 #define HCI_ERROR_AUTH_FAILURE		0x05
 #define HCI_ERROR_MEMORY_EXCEEDED	0x07
 #define HCI_ERROR_MEMORY_EXCEEDED	0x07
 #define HCI_ERROR_CONNECTION_TIMEOUT	0x08
 #define HCI_ERROR_CONNECTION_TIMEOUT	0x08
@@ -367,6 +417,7 @@ enum {
 #define HCI_ERROR_REMOTE_POWER_OFF	0x15
 #define HCI_ERROR_REMOTE_POWER_OFF	0x15
 #define HCI_ERROR_LOCAL_HOST_TERM	0x16
 #define HCI_ERROR_LOCAL_HOST_TERM	0x16
 #define HCI_ERROR_PAIRING_NOT_ALLOWED	0x18
 #define HCI_ERROR_PAIRING_NOT_ALLOWED	0x18
+#define HCI_ERROR_INVALID_LL_PARAMS	0x1E
 #define HCI_ERROR_ADVERTISING_TIMEOUT	0x3c
 #define HCI_ERROR_ADVERTISING_TIMEOUT	0x3c
 
 
 /* Flow control modes */
 /* Flow control modes */
@@ -536,6 +587,11 @@ struct hci_cp_read_remote_version {
 	__le16   handle;
 	__le16   handle;
 } __packed;
 } __packed;
 
 
+#define HCI_OP_READ_CLOCK_OFFSET	0x041f
+struct hci_cp_read_clock_offset {
+	__le16   handle;
+} __packed;
+
 #define HCI_OP_SETUP_SYNC_CONN		0x0428
 #define HCI_OP_SETUP_SYNC_CONN		0x0428
 struct hci_cp_setup_sync_conn {
 struct hci_cp_setup_sync_conn {
 	__le16   handle;
 	__le16   handle;
@@ -1085,6 +1141,18 @@ struct hci_rp_read_rssi {
 	__s8     rssi;
 	__s8     rssi;
 } __packed;
 } __packed;
 
 
+#define HCI_OP_READ_CLOCK		0x1407
+struct hci_cp_read_clock {
+	__le16   handle;
+	__u8     which;
+} __packed;
+struct hci_rp_read_clock {
+	__u8     status;
+	__le16   handle;
+	__le32   clock;
+	__le16   accuracy;
+} __packed;
+
 #define HCI_OP_READ_LOCAL_AMP_INFO	0x1409
 #define HCI_OP_READ_LOCAL_AMP_INFO	0x1409
 struct hci_rp_read_local_amp_info {
 struct hci_rp_read_local_amp_info {
 	__u8     status;
 	__u8     status;
@@ -1291,6 +1359,23 @@ struct hci_rp_le_read_supported_states {
 	__u8	le_states[8];
 	__u8	le_states[8];
 } __packed;
 } __packed;
 
 
+#define HCI_OP_LE_CONN_PARAM_REQ_REPLY	0x2020
+struct hci_cp_le_conn_param_req_reply {
+	__le16	handle;
+	__le16	interval_min;
+	__le16	interval_max;
+	__le16	latency;
+	__le16	timeout;
+	__le16	min_ce_len;
+	__le16	max_ce_len;
+} __packed;
+
+#define HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY	0x2021
+struct hci_cp_le_conn_param_req_neg_reply {
+	__le16	handle;
+	__u8	reason;
+} __packed;
+
 /* ---- HCI Events ---- */
 /* ---- HCI Events ---- */
 #define HCI_EV_INQUIRY_COMPLETE		0x01
 #define HCI_EV_INQUIRY_COMPLETE		0x01
 
 
@@ -1670,6 +1755,15 @@ struct hci_ev_le_conn_complete {
 	__u8     clk_accurancy;
 	__u8     clk_accurancy;
 } __packed;
 } __packed;
 
 
+#define HCI_EV_LE_CONN_UPDATE_COMPLETE	0x03
+struct hci_ev_le_conn_update_complete {
+	__u8     status;
+	__le16   handle;
+	__le16   interval;
+	__le16   latency;
+	__le16   supervision_timeout;
+} __packed;
+
 #define HCI_EV_LE_LTK_REQ		0x05
 #define HCI_EV_LE_LTK_REQ		0x05
 struct hci_ev_le_ltk_req {
 struct hci_ev_le_ltk_req {
 	__le16	handle;
 	__le16	handle;
@@ -1677,6 +1771,15 @@ struct hci_ev_le_ltk_req {
 	__le16	ediv;
 	__le16	ediv;
 } __packed;
 } __packed;
 
 
+#define HCI_EV_LE_REMOTE_CONN_PARAM_REQ	0x06
+struct hci_ev_le_remote_conn_param_req {
+	__le16 handle;
+	__le16 interval_min;
+	__le16 interval_max;
+	__le16 latency;
+	__le16 timeout;
+} __packed;
+
 /* Advertising report event types */
 /* Advertising report event types */
 #define LE_ADV_IND		0x00
 #define LE_ADV_IND		0x00
 #define LE_ADV_DIRECT_IND	0x01
 #define LE_ADV_DIRECT_IND	0x01

+ 94 - 40
include/net/bluetooth/hci_core.h

@@ -71,6 +71,7 @@ struct discovery_state {
 	bdaddr_t		last_adv_addr;
 	bdaddr_t		last_adv_addr;
 	u8			last_adv_addr_type;
 	u8			last_adv_addr_type;
 	s8			last_adv_rssi;
 	s8			last_adv_rssi;
+	u32			last_adv_flags;
 	u8			last_adv_data[HCI_MAX_AD_LENGTH];
 	u8			last_adv_data[HCI_MAX_AD_LENGTH];
 	u8			last_adv_data_len;
 	u8			last_adv_data_len;
 };
 };
@@ -170,6 +171,8 @@ struct hci_dev {
 	__u8		bus;
 	__u8		bus;
 	__u8		dev_type;
 	__u8		dev_type;
 	bdaddr_t	bdaddr;
 	bdaddr_t	bdaddr;
+	bdaddr_t	setup_addr;
+	bdaddr_t	public_addr;
 	bdaddr_t	random_addr;
 	bdaddr_t	random_addr;
 	bdaddr_t	static_addr;
 	bdaddr_t	static_addr;
 	__u8		adv_addr_type;
 	__u8		adv_addr_type;
@@ -203,10 +206,13 @@ struct hci_dev {
 	__u16		le_scan_window;
 	__u16		le_scan_window;
 	__u16		le_conn_min_interval;
 	__u16		le_conn_min_interval;
 	__u16		le_conn_max_interval;
 	__u16		le_conn_max_interval;
+	__u16		le_conn_latency;
+	__u16		le_supv_timeout;
 	__u16		discov_interleaved_timeout;
 	__u16		discov_interleaved_timeout;
 	__u16		conn_info_min_age;
 	__u16		conn_info_min_age;
 	__u16		conn_info_max_age;
 	__u16		conn_info_max_age;
 	__u8		ssp_debug_mode;
 	__u8		ssp_debug_mode;
+	__u32		clock;
 
 
 	__u16		devid_source;
 	__u16		devid_source;
 	__u16		devid_vendor;
 	__u16		devid_vendor;
@@ -273,7 +279,7 @@ struct hci_dev {
 
 
 	struct delayed_work	service_cache;
 	struct delayed_work	service_cache;
 
 
-	struct timer_list	cmd_timer;
+	struct delayed_work	cmd_timer;
 
 
 	struct work_struct	rx_work;
 	struct work_struct	rx_work;
 	struct work_struct	cmd_work;
 	struct work_struct	cmd_work;
@@ -299,6 +305,7 @@ struct hci_dev {
 
 
 	struct list_head	mgmt_pending;
 	struct list_head	mgmt_pending;
 	struct list_head	blacklist;
 	struct list_head	blacklist;
+	struct list_head	whitelist;
 	struct list_head	uuids;
 	struct list_head	uuids;
 	struct list_head	link_keys;
 	struct list_head	link_keys;
 	struct list_head	long_term_keys;
 	struct list_head	long_term_keys;
@@ -307,6 +314,7 @@ struct hci_dev {
 	struct list_head	le_white_list;
 	struct list_head	le_white_list;
 	struct list_head	le_conn_params;
 	struct list_head	le_conn_params;
 	struct list_head	pend_le_conns;
 	struct list_head	pend_le_conns;
+	struct list_head	pend_le_reports;
 
 
 	struct hci_dev_stats	stat;
 	struct hci_dev_stats	stat;
 
 
@@ -318,6 +326,7 @@ struct hci_dev {
 
 
 	struct rfkill		*rfkill;
 	struct rfkill		*rfkill;
 
 
+	unsigned long		dbg_flags;
 	unsigned long		dev_flags;
 	unsigned long		dev_flags;
 
 
 	struct delayed_work	le_scan_disable;
 	struct delayed_work	le_scan_disable;
@@ -339,6 +348,7 @@ struct hci_dev {
 	int (*setup)(struct hci_dev *hdev);
 	int (*setup)(struct hci_dev *hdev);
 	int (*send)(struct hci_dev *hdev, struct sk_buff *skb);
 	int (*send)(struct hci_dev *hdev, struct sk_buff *skb);
 	void (*notify)(struct hci_dev *hdev, unsigned int evt);
 	void (*notify)(struct hci_dev *hdev, unsigned int evt);
+	int (*set_bdaddr)(struct hci_dev *hdev, const bdaddr_t *bdaddr);
 };
 };
 
 
 #define HCI_PHY_HANDLE(handle)	(handle & 0xff)
 #define HCI_PHY_HANDLE(handle)	(handle & 0xff)
@@ -366,7 +376,6 @@ struct hci_conn {
 	__u8		features[HCI_MAX_PAGES][8];
 	__u8		features[HCI_MAX_PAGES][8];
 	__u16		pkt_type;
 	__u16		pkt_type;
 	__u16		link_policy;
 	__u16		link_policy;
-	__u32		link_mode;
 	__u8		key_type;
 	__u8		key_type;
 	__u8		auth_type;
 	__u8		auth_type;
 	__u8		sec_level;
 	__u8		sec_level;
@@ -377,20 +386,26 @@ struct hci_conn {
 	__u32		passkey_notify;
 	__u32		passkey_notify;
 	__u8		passkey_entered;
 	__u8		passkey_entered;
 	__u16		disc_timeout;
 	__u16		disc_timeout;
+	__u16		conn_timeout;
 	__u16		setting;
 	__u16		setting;
 	__u16		le_conn_min_interval;
 	__u16		le_conn_min_interval;
 	__u16		le_conn_max_interval;
 	__u16		le_conn_max_interval;
+	__u16		le_conn_interval;
+	__u16		le_conn_latency;
+	__u16		le_supv_timeout;
 	__s8		rssi;
 	__s8		rssi;
 	__s8		tx_power;
 	__s8		tx_power;
 	__s8		max_tx_power;
 	__s8		max_tx_power;
 	unsigned long	flags;
 	unsigned long	flags;
 
 
+	__u32		clock;
+	__u16		clock_accuracy;
+
 	unsigned long	conn_info_timestamp;
 	unsigned long	conn_info_timestamp;
 
 
 	__u8		remote_cap;
 	__u8		remote_cap;
 	__u8		remote_auth;
 	__u8		remote_auth;
 	__u8		remote_id;
 	__u8		remote_id;
-	bool		flush_key;
 
 
 	unsigned int	sent;
 	unsigned int	sent;
 
 
@@ -407,7 +422,6 @@ struct hci_conn {
 	struct hci_dev	*hdev;
 	struct hci_dev	*hdev;
 	void		*l2cap_data;
 	void		*l2cap_data;
 	void		*sco_data;
 	void		*sco_data;
-	void		*smp_conn;
 	struct amp_mgr	*amp_mgr;
 	struct amp_mgr	*amp_mgr;
 
 
 	struct hci_conn	*link;
 	struct hci_conn	*link;
@@ -428,15 +442,19 @@ struct hci_chan {
 
 
 struct hci_conn_params {
 struct hci_conn_params {
 	struct list_head list;
 	struct list_head list;
+	struct list_head action;
 
 
 	bdaddr_t addr;
 	bdaddr_t addr;
 	u8 addr_type;
 	u8 addr_type;
 
 
 	u16 conn_min_interval;
 	u16 conn_min_interval;
 	u16 conn_max_interval;
 	u16 conn_max_interval;
+	u16 conn_latency;
+	u16 supervision_timeout;
 
 
 	enum {
 	enum {
 		HCI_AUTO_CONN_DISABLED,
 		HCI_AUTO_CONN_DISABLED,
+		HCI_AUTO_CONN_REPORT,
 		HCI_AUTO_CONN_ALWAYS,
 		HCI_AUTO_CONN_ALWAYS,
 		HCI_AUTO_CONN_LINK_LOSS,
 		HCI_AUTO_CONN_LINK_LOSS,
 	} auto_connect;
 	} auto_connect;
@@ -501,8 +519,8 @@ struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
 						       int state);
 						       int state);
 void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
 void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
 				      struct inquiry_entry *ie);
 				      struct inquiry_entry *ie);
-bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
-			      bool name_known, bool *ssp);
+u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
+			     bool name_known);
 void hci_inquiry_cache_flush(struct hci_dev *hdev);
 void hci_inquiry_cache_flush(struct hci_dev *hdev);
 
 
 /* ----- HCI Connections ----- */
 /* ----- HCI Connections ----- */
@@ -520,7 +538,13 @@ enum {
 	HCI_CONN_AES_CCM,
 	HCI_CONN_AES_CCM,
 	HCI_CONN_POWER_SAVE,
 	HCI_CONN_POWER_SAVE,
 	HCI_CONN_REMOTE_OOB,
 	HCI_CONN_REMOTE_OOB,
-	HCI_CONN_6LOWPAN,
+	HCI_CONN_FLUSH_KEY,
+	HCI_CONN_MASTER,
+	HCI_CONN_ENCRYPT,
+	HCI_CONN_AUTH,
+	HCI_CONN_SECURE,
+	HCI_CONN_FIPS,
+	HCI_CONN_STK_ENCRYPT,
 };
 };
 
 
 static inline bool hci_conn_ssp_enabled(struct hci_conn *conn)
 static inline bool hci_conn_ssp_enabled(struct hci_conn *conn)
@@ -681,7 +705,8 @@ void hci_chan_list_flush(struct hci_conn *conn);
 struct hci_chan *hci_chan_lookup_handle(struct hci_dev *hdev, __u16 handle);
 struct hci_chan *hci_chan_lookup_handle(struct hci_dev *hdev, __u16 handle);
 
 
 struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
 struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
-				u8 dst_type, u8 sec_level, u8 auth_type);
+				u8 dst_type, u8 sec_level, u16 conn_timeout,
+				bool master);
 struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
 struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
 				 u8 sec_level, u8 auth_type);
 				 u8 sec_level, u8 auth_type);
 struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,
 struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,
@@ -825,30 +850,25 @@ int hci_get_conn_info(struct hci_dev *hdev, void __user *arg);
 int hci_get_auth_info(struct hci_dev *hdev, void __user *arg);
 int hci_get_auth_info(struct hci_dev *hdev, void __user *arg);
 int hci_inquiry(void __user *arg);
 int hci_inquiry(void __user *arg);
 
 
-struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev,
-					 bdaddr_t *bdaddr, u8 type);
-int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
-int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
-
-struct bdaddr_list *hci_white_list_lookup(struct hci_dev *hdev,
-					  bdaddr_t *bdaddr, u8 type);
-void hci_white_list_clear(struct hci_dev *hdev);
-int hci_white_list_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
-int hci_white_list_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
+struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *list,
+					   bdaddr_t *bdaddr, u8 type);
+int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type);
+int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type);
+void hci_bdaddr_list_clear(struct list_head *list);
 
 
 struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
 struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
 					       bdaddr_t *addr, u8 addr_type);
 					       bdaddr_t *addr, u8 addr_type);
-int hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
-			u8 auto_connect, u16 conn_min_interval,
-			u16 conn_max_interval);
+struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev,
+					    bdaddr_t *addr, u8 addr_type);
+int hci_conn_params_set(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
+			u8 auto_connect);
 void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type);
 void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type);
-void hci_conn_params_clear(struct hci_dev *hdev);
+void hci_conn_params_clear_all(struct hci_dev *hdev);
+void hci_conn_params_clear_disabled(struct hci_dev *hdev);
 
 
-struct bdaddr_list *hci_pend_le_conn_lookup(struct hci_dev *hdev,
-					    bdaddr_t *addr, u8 addr_type);
-void hci_pend_le_conn_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type);
-void hci_pend_le_conn_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type);
-void hci_pend_le_conns_clear(struct hci_dev *hdev);
+struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list,
+						  bdaddr_t *addr,
+						  u8 addr_type);
 
 
 void hci_update_background_scan(struct hci_dev *hdev);
 void hci_update_background_scan(struct hci_dev *hdev);
 
 
@@ -856,8 +876,9 @@ void hci_uuids_clear(struct hci_dev *hdev);
 
 
 void hci_link_keys_clear(struct hci_dev *hdev);
 void hci_link_keys_clear(struct hci_dev *hdev);
 struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
 struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
-int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
-		     bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len);
+struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn,
+				  bdaddr_t *bdaddr, u8 *val, u8 type,
+				  u8 pin_len, bool *persistent);
 struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, __le64 rand,
 struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, __le64 rand,
 			     bool master);
 			     bool master);
 struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
 struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
@@ -1021,7 +1042,7 @@ static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status)
 	if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags))
 	if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags))
 		return;
 		return;
 
 
-	encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00;
+	encrypt = test_bit(HCI_CONN_ENCRYPT, &conn->flags) ? 0x01 : 0x00;
 	l2cap_security_cfm(conn, status, encrypt);
 	l2cap_security_cfm(conn, status, encrypt);
 
 
 	if (conn->security_cfm_cb)
 	if (conn->security_cfm_cb)
@@ -1062,7 +1083,7 @@ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
 	if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags))
 	if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags))
 		return;
 		return;
 
 
-	encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00;
+	encrypt = test_bit(HCI_CONN_ENCRYPT, &conn->flags) ? 0x01 : 0x00;
 
 
 	read_lock(&hci_cb_list_lock);
 	read_lock(&hci_cb_list_lock);
 	list_for_each_entry(cb, &hci_cb_list, list) {
 	list_for_each_entry(cb, &hci_cb_list, list) {
@@ -1147,7 +1168,7 @@ static inline bool eir_has_data_type(u8 *data, size_t data_len, u8 type)
 
 
 static inline bool hci_bdaddr_is_rpa(bdaddr_t *bdaddr, u8 addr_type)
 static inline bool hci_bdaddr_is_rpa(bdaddr_t *bdaddr, u8 addr_type)
 {
 {
-	if (addr_type != 0x01)
+	if (addr_type != ADDR_LE_DEV_RANDOM)
 		return false;
 		return false;
 
 
 	if ((bdaddr->b[5] & 0xc0) == 0x40)
 	if ((bdaddr->b[5] & 0xc0) == 0x40)
@@ -1156,6 +1177,18 @@ static inline bool hci_bdaddr_is_rpa(bdaddr_t *bdaddr, u8 addr_type)
 	return false;
 	return false;
 }
 }
 
 
+static inline bool hci_is_identity_address(bdaddr_t *addr, u8 addr_type)
+{
+	if (addr_type == ADDR_LE_DEV_PUBLIC)
+		return true;
+
+	/* Check for Random Static address type */
+	if ((addr->b[5] & 0xc0) == 0xc0)
+		return true;
+
+	return false;
+}
+
 static inline struct smp_irk *hci_get_irk(struct hci_dev *hdev,
 static inline struct smp_irk *hci_get_irk(struct hci_dev *hdev,
 					  bdaddr_t *bdaddr, u8 addr_type)
 					  bdaddr_t *bdaddr, u8 addr_type)
 {
 {
@@ -1165,6 +1198,27 @@ static inline struct smp_irk *hci_get_irk(struct hci_dev *hdev,
 	return hci_find_irk_by_rpa(hdev, bdaddr);
 	return hci_find_irk_by_rpa(hdev, bdaddr);
 }
 }
 
 
+static inline int hci_check_conn_params(u16 min, u16 max, u16 latency,
+					u16 to_multiplier)
+{
+	u16 max_latency;
+
+	if (min > max || min < 6 || max > 3200)
+		return -EINVAL;
+
+	if (to_multiplier < 10 || to_multiplier > 3200)
+		return -EINVAL;
+
+	if (max >= to_multiplier * 8)
+		return -EINVAL;
+
+	max_latency = (to_multiplier * 8 / max) - 1;
+	if (latency > 499 || latency > max_latency)
+		return -EINVAL;
+
+	return 0;
+}
+
 int hci_register_cb(struct hci_cb *hcb);
 int hci_register_cb(struct hci_cb *hcb);
 int hci_unregister_cb(struct hci_cb *hcb);
 int hci_unregister_cb(struct hci_cb *hcb);
 
 
@@ -1227,6 +1281,7 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event);
 #define DISCOV_BREDR_INQUIRY_LEN	0x08
 #define DISCOV_BREDR_INQUIRY_LEN	0x08
 
 
 int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len);
 int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len);
+int mgmt_new_settings(struct hci_dev *hdev);
 void mgmt_index_added(struct hci_dev *hdev);
 void mgmt_index_added(struct hci_dev *hdev);
 void mgmt_index_removed(struct hci_dev *hdev);
 void mgmt_index_removed(struct hci_dev *hdev);
 void mgmt_set_powered_failed(struct hci_dev *hdev, int err);
 void mgmt_set_powered_failed(struct hci_dev *hdev, int err);
@@ -1234,7 +1289,6 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered);
 void mgmt_discoverable_timeout(struct hci_dev *hdev);
 void mgmt_discoverable_timeout(struct hci_dev *hdev);
 void mgmt_discoverable(struct hci_dev *hdev, u8 discoverable);
 void mgmt_discoverable(struct hci_dev *hdev, u8 discoverable);
 void mgmt_connectable(struct hci_dev *hdev, u8 connectable);
 void mgmt_connectable(struct hci_dev *hdev, u8 connectable);
-void mgmt_advertising(struct hci_dev *hdev, u8 advertising);
 void mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status);
 void mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status);
 void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
 void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
 		       bool persistent);
 		       bool persistent);
@@ -1281,18 +1335,18 @@ void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192,
 				       u8 *randomizer192, u8 *hash256,
 				       u8 *randomizer192, u8 *hash256,
 				       u8 *randomizer256, u8 status);
 				       u8 *randomizer256, u8 status);
 void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
 void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
-		       u8 addr_type, u8 *dev_class, s8 rssi, u8 cfm_name,
-		       u8 ssp, u8 *eir, u16 eir_len, u8 *scan_rsp,
-		       u8 scan_rsp_len);
+		       u8 addr_type, u8 *dev_class, s8 rssi, u32 flags,
+		       u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len);
 void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
 void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
 		      u8 addr_type, s8 rssi, u8 *name, u8 name_len);
 		      u8 addr_type, s8 rssi, u8 *name, u8 name_len);
 void mgmt_discovering(struct hci_dev *hdev, u8 discovering);
 void mgmt_discovering(struct hci_dev *hdev, u8 discovering);
-int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
-int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
 void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent);
 void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent);
 void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk);
 void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk);
 void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk,
 void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk,
 		   bool persistent);
 		   bool persistent);
+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_reenable_advertising(struct hci_dev *hdev);
 void mgmt_smp_complete(struct hci_conn *conn, bool complete);
 void mgmt_smp_complete(struct hci_conn *conn, bool complete);
 
 
@@ -1324,8 +1378,8 @@ struct hci_sec_filter {
 #define hci_req_lock(d)		mutex_lock(&d->req_lock)
 #define hci_req_lock(d)		mutex_lock(&d->req_lock)
 #define hci_req_unlock(d)	mutex_unlock(&d->req_lock)
 #define hci_req_unlock(d)	mutex_unlock(&d->req_lock)
 
 
-void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
-					u16 latency, u16 to_multiplier);
+u8 hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, u16 latency,
+		      u16 to_multiplier);
 void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __le64 rand,
 void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __le64 rand,
 							__u8 ltk[16]);
 							__u8 ltk[16]);
 
 

+ 32 - 4
include/net/bluetooth/l2cap.h

@@ -137,7 +137,6 @@ struct l2cap_conninfo {
 #define L2CAP_FC_L2CAP		0x02
 #define L2CAP_FC_L2CAP		0x02
 #define L2CAP_FC_CONNLESS	0x04
 #define L2CAP_FC_CONNLESS	0x04
 #define L2CAP_FC_A2MP		0x08
 #define L2CAP_FC_A2MP		0x08
-#define L2CAP_FC_6LOWPAN        0x3e /* reserved and temporary value */
 
 
 /* L2CAP Control Field bit masks */
 /* L2CAP Control Field bit masks */
 #define L2CAP_CTRL_SAR			0xC000
 #define L2CAP_CTRL_SAR			0xC000
@@ -579,7 +578,7 @@ struct l2cap_chan {
 	struct list_head	global_l;
 	struct list_head	global_l;
 
 
 	void			*data;
 	void			*data;
-	struct l2cap_ops	*ops;
+	const struct l2cap_ops	*ops;
 	struct mutex		lock;
 	struct mutex		lock;
 };
 };
 
 
@@ -600,7 +599,12 @@ struct l2cap_ops {
 	void			(*set_shutdown) (struct l2cap_chan *chan);
 	void			(*set_shutdown) (struct l2cap_chan *chan);
 	long			(*get_sndtimeo) (struct l2cap_chan *chan);
 	long			(*get_sndtimeo) (struct l2cap_chan *chan);
 	struct sk_buff		*(*alloc_skb) (struct l2cap_chan *chan,
 	struct sk_buff		*(*alloc_skb) (struct l2cap_chan *chan,
+					       unsigned long hdr_len,
 					       unsigned long len, int nb);
 					       unsigned long len, int nb);
+	int			(*memcpy_fromiovec) (struct l2cap_chan *chan,
+						     unsigned char *kdata,
+						     struct iovec *iov,
+						     int len);
 };
 };
 
 
 struct l2cap_conn {
 struct l2cap_conn {
@@ -856,6 +860,31 @@ static inline long l2cap_chan_no_get_sndtimeo(struct l2cap_chan *chan)
 	return 0;
 	return 0;
 }
 }
 
 
+static inline int l2cap_chan_no_memcpy_fromiovec(struct l2cap_chan *chan,
+						 unsigned char *kdata,
+						 struct iovec *iov,
+						 int len)
+{
+	/* Following is safe since for compiler definitions of kvec and
+	 * iovec are identical, yielding the same in-core layout and alignment
+	 */
+	struct kvec *vec = (struct kvec *)iov;
+
+	while (len > 0) {
+		if (vec->iov_len) {
+			int copy = min_t(unsigned int, len, vec->iov_len);
+			memcpy(kdata, vec->iov_base, copy);
+			len -= copy;
+			kdata += copy;
+			vec->iov_base += copy;
+			vec->iov_len -= copy;
+		}
+		vec++;
+	}
+
+	return 0;
+}
+
 extern bool disable_ertm;
 extern bool disable_ertm;
 
 
 int l2cap_init_sockets(void);
 int l2cap_init_sockets(void);
@@ -872,8 +901,7 @@ struct l2cap_chan *l2cap_chan_create(void);
 void l2cap_chan_close(struct l2cap_chan *chan, int reason);
 void l2cap_chan_close(struct l2cap_chan *chan, int reason);
 int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
 int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
 		       bdaddr_t *dst, u8 dst_type);
 		       bdaddr_t *dst, u8 dst_type);
-int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
-								u32 priority);
+int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len);
 void l2cap_chan_busy(struct l2cap_chan *chan, int busy);
 void l2cap_chan_busy(struct l2cap_chan *chan, int busy);
 int l2cap_chan_check_security(struct l2cap_chan *chan);
 int l2cap_chan_check_security(struct l2cap_chan *chan);
 void l2cap_chan_set_defaults(struct l2cap_chan *chan);
 void l2cap_chan_set_defaults(struct l2cap_chan *chan);

+ 99 - 0
include/net/bluetooth/mgmt.h

@@ -97,6 +97,7 @@ struct mgmt_rp_read_index_list {
 #define MGMT_SETTING_SECURE_CONN	0x00000800
 #define MGMT_SETTING_SECURE_CONN	0x00000800
 #define MGMT_SETTING_DEBUG_KEYS		0x00001000
 #define MGMT_SETTING_DEBUG_KEYS		0x00001000
 #define MGMT_SETTING_PRIVACY		0x00002000
 #define MGMT_SETTING_PRIVACY		0x00002000
+#define MGMT_SETTING_CONFIGURATION	0x00004000
 
 
 #define MGMT_OP_READ_INFO		0x0004
 #define MGMT_OP_READ_INFO		0x0004
 #define MGMT_READ_INFO_SIZE		0
 #define MGMT_READ_INFO_SIZE		0
@@ -424,6 +425,76 @@ struct mgmt_rp_get_conn_info {
 	__s8	max_tx_power;
 	__s8	max_tx_power;
 } __packed;
 } __packed;
 
 
+#define MGMT_OP_GET_CLOCK_INFO		0x0032
+struct mgmt_cp_get_clock_info {
+	struct mgmt_addr_info addr;
+} __packed;
+#define MGMT_GET_CLOCK_INFO_SIZE	MGMT_ADDR_INFO_SIZE
+struct mgmt_rp_get_clock_info {
+	struct mgmt_addr_info addr;
+	__le32  local_clock;
+	__le32  piconet_clock;
+	__le16  accuracy;
+} __packed;
+
+#define MGMT_OP_ADD_DEVICE		0x0033
+struct mgmt_cp_add_device {
+	struct mgmt_addr_info addr;
+	__u8	action;
+} __packed;
+#define MGMT_ADD_DEVICE_SIZE		(MGMT_ADDR_INFO_SIZE + 1)
+
+#define MGMT_OP_REMOVE_DEVICE		0x0034
+struct mgmt_cp_remove_device {
+	struct mgmt_addr_info addr;
+} __packed;
+#define MGMT_REMOVE_DEVICE_SIZE		MGMT_ADDR_INFO_SIZE
+
+struct mgmt_conn_param {
+	struct mgmt_addr_info addr;
+	__le16 min_interval;
+	__le16 max_interval;
+	__le16 latency;
+	__le16 timeout;
+} __packed;
+
+#define MGMT_OP_LOAD_CONN_PARAM		0x0035
+struct mgmt_cp_load_conn_param {
+	__le16 param_count;
+	struct mgmt_conn_param params[0];
+} __packed;
+#define MGMT_LOAD_CONN_PARAM_SIZE	2
+
+#define MGMT_OP_READ_UNCONF_INDEX_LIST	0x0036
+#define MGMT_READ_UNCONF_INDEX_LIST_SIZE 0
+struct mgmt_rp_read_unconf_index_list {
+	__le16	num_controllers;
+	__le16	index[0];
+} __packed;
+
+#define MGMT_OPTION_EXTERNAL_CONFIG	0x00000001
+#define MGMT_OPTION_PUBLIC_ADDRESS	0x00000002
+
+#define MGMT_OP_READ_CONFIG_INFO	0x0037
+#define MGMT_READ_CONFIG_INFO_SIZE	0
+struct mgmt_rp_read_config_info {
+	__le16	manufacturer;
+	__le32	supported_options;
+	__le32	missing_options;
+} __packed;
+
+#define MGMT_OP_SET_EXTERNAL_CONFIG	0x0038
+struct mgmt_cp_set_external_config {
+	__u8 config;
+} __packed;
+#define MGMT_SET_EXTERNAL_CONFIG_SIZE	1
+
+#define MGMT_OP_SET_PUBLIC_ADDRESS	0x0039
+struct mgmt_cp_set_public_address {
+	bdaddr_t bdaddr;
+} __packed;
+#define MGMT_SET_PUBLIC_ADDRESS_SIZE	6
+
 #define MGMT_EV_CMD_COMPLETE		0x0001
 #define MGMT_EV_CMD_COMPLETE		0x0001
 struct mgmt_ev_cmd_complete {
 struct mgmt_ev_cmd_complete {
 	__le16	opcode;
 	__le16	opcode;
@@ -522,6 +593,7 @@ struct mgmt_ev_auth_failed {
 
 
 #define MGMT_DEV_FOUND_CONFIRM_NAME    0x01
 #define MGMT_DEV_FOUND_CONFIRM_NAME    0x01
 #define MGMT_DEV_FOUND_LEGACY_PAIRING  0x02
 #define MGMT_DEV_FOUND_LEGACY_PAIRING  0x02
+#define MGMT_DEV_FOUND_NOT_CONNECTABLE 0x04
 
 
 #define MGMT_EV_DEVICE_FOUND		0x0012
 #define MGMT_EV_DEVICE_FOUND		0x0012
 struct mgmt_ev_device_found {
 struct mgmt_ev_device_found {
@@ -578,3 +650,30 @@ struct mgmt_ev_new_csrk {
 	__u8 store_hint;
 	__u8 store_hint;
 	struct mgmt_csrk_info key;
 	struct mgmt_csrk_info key;
 } __packed;
 } __packed;
+
+#define MGMT_EV_DEVICE_ADDED		0x001a
+struct mgmt_ev_device_added {
+	struct mgmt_addr_info addr;
+	__u8 action;
+} __packed;
+
+#define MGMT_EV_DEVICE_REMOVED		0x001b
+struct mgmt_ev_device_removed {
+	struct mgmt_addr_info addr;
+} __packed;
+
+#define MGMT_EV_NEW_CONN_PARAM		0x001c
+struct mgmt_ev_new_conn_param {
+	struct mgmt_addr_info addr;
+	__u8 store_hint;
+	__le16 min_interval;
+	__le16 max_interval;
+	__le16 latency;
+	__le16 timeout;
+} __packed;
+
+#define MGMT_EV_UNCONF_INDEX_ADDED	0x001d
+
+#define MGMT_EV_UNCONF_INDEX_REMOVED	0x001e
+
+#define MGMT_EV_NEW_CONFIG_OPTIONS	0x001f

+ 649 - 208
net/bluetooth/6lowpan.c

@@ -1,5 +1,5 @@
 /*
 /*
-   Copyright (c) 2013 Intel Corp.
+   Copyright (c) 2013-2014 Intel Corp.
 
 
    This program is free software; you can redistribute it and/or modify
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License version 2 and
    it under the terms of the GNU General Public License version 2 and
@@ -14,6 +14,8 @@
 #include <linux/if_arp.h>
 #include <linux/if_arp.h>
 #include <linux/netdevice.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/module.h>
+#include <linux/debugfs.h>
 
 
 #include <net/ipv6.h>
 #include <net/ipv6.h>
 #include <net/ip6_route.h>
 #include <net/ip6_route.h>
@@ -25,16 +27,20 @@
 #include <net/bluetooth/hci_core.h>
 #include <net/bluetooth/hci_core.h>
 #include <net/bluetooth/l2cap.h>
 #include <net/bluetooth/l2cap.h>
 
 
-#include "6lowpan.h"
-
 #include <net/6lowpan.h> /* for the compression support */
 #include <net/6lowpan.h> /* for the compression support */
 
 
+#define VERSION "0.1"
+
+static struct dentry *lowpan_psm_debugfs;
+static struct dentry *lowpan_control_debugfs;
+
 #define IFACE_NAME_TEMPLATE "bt%d"
 #define IFACE_NAME_TEMPLATE "bt%d"
 #define EUI64_ADDR_LEN 8
 #define EUI64_ADDR_LEN 8
 
 
 struct skb_cb {
 struct skb_cb {
 	struct in6_addr addr;
 	struct in6_addr addr;
-	struct l2cap_conn *conn;
+	struct l2cap_chan *chan;
+	int status;
 };
 };
 #define lowpan_cb(skb) ((struct skb_cb *)((skb)->cb))
 #define lowpan_cb(skb) ((struct skb_cb *)((skb)->cb))
 
 
@@ -48,9 +54,19 @@ struct skb_cb {
 static LIST_HEAD(bt_6lowpan_devices);
 static LIST_HEAD(bt_6lowpan_devices);
 static DEFINE_RWLOCK(devices_lock);
 static DEFINE_RWLOCK(devices_lock);
 
 
+/* If psm is set to 0 (default value), then 6lowpan is disabled.
+ * Other values are used to indicate a Protocol Service Multiplexer
+ * value for 6lowpan.
+ */
+static u16 psm_6lowpan;
+
+/* We are listening incoming connections via this channel
+ */
+static struct l2cap_chan *listen_chan;
+
 struct lowpan_peer {
 struct lowpan_peer {
 	struct list_head list;
 	struct list_head list;
-	struct l2cap_conn *conn;
+	struct l2cap_chan *chan;
 
 
 	/* peer addresses in various formats */
 	/* peer addresses in various formats */
 	unsigned char eui64_addr[EUI64_ADDR_LEN];
 	unsigned char eui64_addr[EUI64_ADDR_LEN];
@@ -84,6 +100,8 @@ static inline bool peer_del(struct lowpan_dev *dev, struct lowpan_peer *peer)
 {
 {
 	list_del(&peer->list);
 	list_del(&peer->list);
 
 
+	module_put(THIS_MODULE);
+
 	if (atomic_dec_and_test(&dev->peer_count)) {
 	if (atomic_dec_and_test(&dev->peer_count)) {
 		BT_DBG("last peer");
 		BT_DBG("last peer");
 		return true;
 		return true;
@@ -101,13 +119,26 @@ static inline struct lowpan_peer *peer_lookup_ba(struct lowpan_dev *dev,
 	       ba, type);
 	       ba, type);
 
 
 	list_for_each_entry_safe(peer, tmp, &dev->peers, list) {
 	list_for_each_entry_safe(peer, tmp, &dev->peers, list) {
-		BT_DBG("addr %pMR type %d",
-		       &peer->conn->hcon->dst, peer->conn->hcon->dst_type);
+		BT_DBG("dst addr %pMR dst type %d",
+		       &peer->chan->dst, peer->chan->dst_type);
 
 
-		if (bacmp(&peer->conn->hcon->dst, ba))
+		if (bacmp(&peer->chan->dst, ba))
 			continue;
 			continue;
 
 
-		if (type == peer->conn->hcon->dst_type)
+		if (type == peer->chan->dst_type)
+			return peer;
+	}
+
+	return NULL;
+}
+
+static inline struct lowpan_peer *peer_lookup_chan(struct lowpan_dev *dev,
+						   struct l2cap_chan *chan)
+{
+	struct lowpan_peer *peer, *tmp;
+
+	list_for_each_entry_safe(peer, tmp, &dev->peers, list) {
+		if (peer->chan == chan)
 			return peer;
 			return peer;
 	}
 	}
 
 
@@ -120,7 +151,7 @@ static inline struct lowpan_peer *peer_lookup_conn(struct lowpan_dev *dev,
 	struct lowpan_peer *peer, *tmp;
 	struct lowpan_peer *peer, *tmp;
 
 
 	list_for_each_entry_safe(peer, tmp, &dev->peers, list) {
 	list_for_each_entry_safe(peer, tmp, &dev->peers, list) {
-		if (peer->conn == conn)
+		if (peer->chan->conn == conn)
 			return peer;
 			return peer;
 	}
 	}
 
 
@@ -176,16 +207,16 @@ static int give_skb_to_upper(struct sk_buff *skb, struct net_device *dev)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
 	ret = netif_rx(skb_cp);
 	ret = netif_rx(skb_cp);
-
-	BT_DBG("receive skb %d", ret);
-	if (ret < 0)
+	if (ret < 0) {
+		BT_DBG("receive skb %d", ret);
 		return NET_RX_DROP;
 		return NET_RX_DROP;
+	}
 
 
 	return ret;
 	return ret;
 }
 }
 
 
 static int process_data(struct sk_buff *skb, struct net_device *netdev,
 static int process_data(struct sk_buff *skb, struct net_device *netdev,
-			struct l2cap_conn *conn)
+			struct l2cap_chan *chan)
 {
 {
 	const u8 *saddr, *daddr;
 	const u8 *saddr, *daddr;
 	u8 iphc0, iphc1;
 	u8 iphc0, iphc1;
@@ -196,7 +227,7 @@ static int process_data(struct sk_buff *skb, struct net_device *netdev,
 	dev = lowpan_dev(netdev);
 	dev = lowpan_dev(netdev);
 
 
 	read_lock_irqsave(&devices_lock, flags);
 	read_lock_irqsave(&devices_lock, flags);
-	peer = peer_lookup_conn(dev, conn);
+	peer = peer_lookup_chan(dev, chan);
 	read_unlock_irqrestore(&devices_lock, flags);
 	read_unlock_irqrestore(&devices_lock, flags);
 	if (!peer)
 	if (!peer)
 		goto drop;
 		goto drop;
@@ -225,7 +256,7 @@ drop:
 }
 }
 
 
 static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
 static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
-		    struct l2cap_conn *conn)
+		    struct l2cap_chan *chan)
 {
 {
 	struct sk_buff *local_skb;
 	struct sk_buff *local_skb;
 	int ret;
 	int ret;
@@ -269,7 +300,7 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
 			if (!local_skb)
 			if (!local_skb)
 				goto drop;
 				goto drop;
 
 
-			ret = process_data(local_skb, dev, conn);
+			ret = process_data(local_skb, dev, chan);
 			if (ret != NET_RX_SUCCESS)
 			if (ret != NET_RX_SUCCESS)
 				goto drop;
 				goto drop;
 
 
@@ -286,147 +317,39 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
 	return NET_RX_SUCCESS;
 	return NET_RX_SUCCESS;
 
 
 drop:
 drop:
+	dev->stats.rx_dropped++;
 	kfree_skb(skb);
 	kfree_skb(skb);
 	return NET_RX_DROP;
 	return NET_RX_DROP;
 }
 }
 
 
 /* Packet from BT LE device */
 /* Packet from BT LE device */
-int bt_6lowpan_recv(struct l2cap_conn *conn, struct sk_buff *skb)
+static int chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
 {
 {
 	struct lowpan_dev *dev;
 	struct lowpan_dev *dev;
 	struct lowpan_peer *peer;
 	struct lowpan_peer *peer;
 	int err;
 	int err;
 
 
-	peer = lookup_peer(conn);
+	peer = lookup_peer(chan->conn);
 	if (!peer)
 	if (!peer)
 		return -ENOENT;
 		return -ENOENT;
 
 
-	dev = lookup_dev(conn);
+	dev = lookup_dev(chan->conn);
 	if (!dev || !dev->netdev)
 	if (!dev || !dev->netdev)
 		return -ENOENT;
 		return -ENOENT;
 
 
-	err = recv_pkt(skb, dev->netdev, conn);
-	BT_DBG("recv pkt %d", err);
-
-	return err;
-}
-
-static inline int skbuff_copy(void *msg, int len, int count, int mtu,
-			      struct sk_buff *skb, struct net_device *dev)
-{
-	struct sk_buff **frag;
-	int sent = 0;
-
-	memcpy(skb_put(skb, count), msg, count);
-
-	sent += count;
-	msg  += count;
-	len  -= count;
-
-	dev->stats.tx_bytes += count;
-	dev->stats.tx_packets++;
-
-	raw_dump_table(__func__, "Sending", skb->data, skb->len);
-
-	/* Continuation fragments (no L2CAP header) */
-	frag = &skb_shinfo(skb)->frag_list;
-	while (len > 0) {
-		struct sk_buff *tmp;
-
-		count = min_t(unsigned int, mtu, len);
-
-		tmp = bt_skb_alloc(count, GFP_ATOMIC);
-		if (!tmp)
-			return -ENOMEM;
-
-		*frag = tmp;
-
-		memcpy(skb_put(*frag, count), msg, count);
-
-		raw_dump_table(__func__, "Sending fragment",
-			       (*frag)->data, count);
-
-		(*frag)->priority = skb->priority;
-
-		sent += count;
-		msg  += count;
-		len  -= count;
-
-		skb->len += (*frag)->len;
-		skb->data_len += (*frag)->len;
-
-		frag = &(*frag)->next;
-
-		dev->stats.tx_bytes += count;
-		dev->stats.tx_packets++;
+	err = recv_pkt(skb, dev->netdev, chan);
+	if (err) {
+		BT_DBG("recv pkt %d", err);
+		err = -EAGAIN;
 	}
 	}
 
 
-	return sent;
-}
-
-static struct sk_buff *create_pdu(struct l2cap_conn *conn, void *msg,
-				  size_t len, u32 priority,
-				  struct net_device *dev)
-{
-	struct sk_buff *skb;
-	int err, count;
-	struct l2cap_hdr *lh;
-
-	/* FIXME: This mtu check should be not needed and atm is only used for
-	 * testing purposes
-	 */
-	if (conn->mtu > (L2CAP_LE_MIN_MTU + L2CAP_HDR_SIZE))
-		conn->mtu = L2CAP_LE_MIN_MTU + L2CAP_HDR_SIZE;
-
-	count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
-
-	BT_DBG("conn %p len %zu mtu %d count %d", conn, len, conn->mtu, count);
-
-	skb = bt_skb_alloc(count + L2CAP_HDR_SIZE, GFP_ATOMIC);
-	if (!skb)
-		return ERR_PTR(-ENOMEM);
-
-	skb->priority = priority;
-
-	lh = (struct l2cap_hdr *)skb_put(skb, L2CAP_HDR_SIZE);
-	lh->cid = cpu_to_le16(L2CAP_FC_6LOWPAN);
-	lh->len = cpu_to_le16(len);
-
-	err = skbuff_copy(msg, len, count, conn->mtu, skb, dev);
-	if (unlikely(err < 0)) {
-		kfree_skb(skb);
-		BT_DBG("skbuff copy %d failed", err);
-		return ERR_PTR(err);
-	}
-
-	return skb;
-}
-
-static int conn_send(struct l2cap_conn *conn,
-		     void *msg, size_t len, u32 priority,
-		     struct net_device *dev)
-{
-	struct sk_buff *skb;
-
-	skb = create_pdu(conn, msg, len, priority, dev);
-	if (IS_ERR(skb))
-		return -EINVAL;
-
-	BT_DBG("conn %p skb %p len %d priority %u", conn, skb, skb->len,
-	       skb->priority);
-
-	hci_send_acl(conn->hchan, skb, ACL_START);
-
-	return 0;
+	return err;
 }
 }
 
 
 static u8 get_addr_type_from_eui64(u8 byte)
 static u8 get_addr_type_from_eui64(u8 byte)
 {
 {
-	/* Is universal(0) or local(1) bit,  */
-	if (byte & 0x02)
-		return ADDR_LE_DEV_RANDOM;
-
-	return ADDR_LE_DEV_PUBLIC;
+	/* Is universal(0) or local(1) bit */
+	return ((byte & 0x02) ? BDADDR_LE_RANDOM : BDADDR_LE_PUBLIC);
 }
 }
 
 
 static void copy_to_bdaddr(struct in6_addr *ip6_daddr, bdaddr_t *addr)
 static void copy_to_bdaddr(struct in6_addr *ip6_daddr, bdaddr_t *addr)
@@ -475,7 +398,7 @@ static int header_create(struct sk_buff *skb, struct net_device *netdev,
 	if (ipv6_addr_is_multicast(&hdr->daddr)) {
 	if (ipv6_addr_is_multicast(&hdr->daddr)) {
 		memcpy(&lowpan_cb(skb)->addr, &hdr->daddr,
 		memcpy(&lowpan_cb(skb)->addr, &hdr->daddr,
 		       sizeof(struct in6_addr));
 		       sizeof(struct in6_addr));
-		lowpan_cb(skb)->conn = NULL;
+		lowpan_cb(skb)->chan = NULL;
 	} else {
 	} else {
 		unsigned long flags;
 		unsigned long flags;
 
 
@@ -484,9 +407,8 @@ static int header_create(struct sk_buff *skb, struct net_device *netdev,
 		 */
 		 */
 		convert_dest_bdaddr(&hdr->daddr, &addr, &addr_type);
 		convert_dest_bdaddr(&hdr->daddr, &addr, &addr_type);
 
 
-		BT_DBG("dest addr %pMR type %s IP %pI6c", &addr,
-		       addr_type == ADDR_LE_DEV_PUBLIC ? "PUBLIC" : "RANDOM",
-		       &hdr->daddr);
+		BT_DBG("dest addr %pMR type %d IP %pI6c", &addr,
+		       addr_type, &hdr->daddr);
 
 
 		read_lock_irqsave(&devices_lock, flags);
 		read_lock_irqsave(&devices_lock, flags);
 		peer = peer_lookup_ba(dev, &addr, addr_type);
 		peer = peer_lookup_ba(dev, &addr, addr_type);
@@ -501,7 +423,7 @@ static int header_create(struct sk_buff *skb, struct net_device *netdev,
 
 
 		memcpy(&lowpan_cb(skb)->addr, &hdr->daddr,
 		memcpy(&lowpan_cb(skb)->addr, &hdr->daddr,
 		       sizeof(struct in6_addr));
 		       sizeof(struct in6_addr));
-		lowpan_cb(skb)->conn = peer->conn;
+		lowpan_cb(skb)->chan = peer->chan;
 	}
 	}
 
 
 	saddr = dev->netdev->dev_addr;
 	saddr = dev->netdev->dev_addr;
@@ -510,14 +432,42 @@ static int header_create(struct sk_buff *skb, struct net_device *netdev,
 }
 }
 
 
 /* Packet to BT LE device */
 /* Packet to BT LE device */
-static int send_pkt(struct l2cap_conn *conn, const void *saddr,
-		    const void *daddr, struct sk_buff *skb,
+static int send_pkt(struct l2cap_chan *chan, struct sk_buff *skb,
 		    struct net_device *netdev)
 		    struct net_device *netdev)
 {
 {
-	raw_dump_table(__func__, "raw skb data dump before fragmentation",
-		       skb->data, skb->len);
+	struct msghdr msg;
+	struct kvec iv;
+	int err;
+
+	/* Remember the skb so that we can send EAGAIN to the caller if
+	 * we run out of credits.
+	 */
+	chan->data = skb;
+
+	memset(&msg, 0, sizeof(msg));
+	msg.msg_iov = (struct iovec *) &iv;
+	msg.msg_iovlen = 1;
+	iv.iov_base = skb->data;
+	iv.iov_len = skb->len;
+
+	err = l2cap_chan_send(chan, &msg, skb->len);
+	if (err > 0) {
+		netdev->stats.tx_bytes += err;
+		netdev->stats.tx_packets++;
+		return 0;
+	}
+
+	if (!err)
+		err = lowpan_cb(skb)->status;
 
 
-	return conn_send(conn, skb->data, skb->len, 0, netdev);
+	if (err < 0) {
+		if (err == -EAGAIN)
+			netdev->stats.tx_dropped++;
+		else
+			netdev->stats.tx_errors++;
+	}
+
+	return err;
 }
 }
 
 
 static void send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev)
 static void send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev)
@@ -540,8 +490,7 @@ static void send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev)
 		list_for_each_entry_safe(pentry, ptmp, &dev->peers, list) {
 		list_for_each_entry_safe(pentry, ptmp, &dev->peers, list) {
 			local_skb = skb_clone(skb, GFP_ATOMIC);
 			local_skb = skb_clone(skb, GFP_ATOMIC);
 
 
-			send_pkt(pentry->conn, netdev->dev_addr,
-				 pentry->eui64_addr, local_skb, netdev);
+			send_pkt(pentry->chan, local_skb, netdev);
 
 
 			kfree_skb(local_skb);
 			kfree_skb(local_skb);
 		}
 		}
@@ -553,7 +502,6 @@ static void send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev)
 static netdev_tx_t bt_xmit(struct sk_buff *skb, struct net_device *netdev)
 static netdev_tx_t bt_xmit(struct sk_buff *skb, struct net_device *netdev)
 {
 {
 	int err = 0;
 	int err = 0;
-	unsigned char *eui64_addr;
 	struct lowpan_dev *dev;
 	struct lowpan_dev *dev;
 	struct lowpan_peer *peer;
 	struct lowpan_peer *peer;
 	bdaddr_t addr;
 	bdaddr_t addr;
@@ -568,21 +516,20 @@ static netdev_tx_t bt_xmit(struct sk_buff *skb, struct net_device *netdev)
 		unsigned long flags;
 		unsigned long flags;
 
 
 		convert_dest_bdaddr(&lowpan_cb(skb)->addr, &addr, &addr_type);
 		convert_dest_bdaddr(&lowpan_cb(skb)->addr, &addr, &addr_type);
-		eui64_addr = lowpan_cb(skb)->addr.s6_addr + 8;
 		dev = lowpan_dev(netdev);
 		dev = lowpan_dev(netdev);
 
 
 		read_lock_irqsave(&devices_lock, flags);
 		read_lock_irqsave(&devices_lock, flags);
 		peer = peer_lookup_ba(dev, &addr, addr_type);
 		peer = peer_lookup_ba(dev, &addr, addr_type);
 		read_unlock_irqrestore(&devices_lock, flags);
 		read_unlock_irqrestore(&devices_lock, flags);
 
 
-		BT_DBG("xmit %s to %pMR type %s IP %pI6c peer %p",
-		       netdev->name, &addr,
-		       addr_type == ADDR_LE_DEV_PUBLIC ? "PUBLIC" : "RANDOM",
+		BT_DBG("xmit %s to %pMR type %d IP %pI6c peer %p",
+		       netdev->name, &addr, addr_type,
 		       &lowpan_cb(skb)->addr, peer);
 		       &lowpan_cb(skb)->addr, peer);
 
 
-		if (peer && peer->conn)
-			err = send_pkt(peer->conn, netdev->dev_addr,
-				       eui64_addr, skb, netdev);
+		if (peer && peer->chan)
+			err = send_pkt(peer->chan, skb, netdev);
+		else
+			err = -ENOENT;
 	}
 	}
 	dev_kfree_skb(skb);
 	dev_kfree_skb(skb);
 
 
@@ -634,7 +581,7 @@ static void set_addr(u8 *eui, u8 *addr, u8 addr_type)
 	eui[7] = addr[0];
 	eui[7] = addr[0];
 
 
 	/* Universal/local bit set, BT 6lowpan draft ch. 3.2.1 */
 	/* Universal/local bit set, BT 6lowpan draft ch. 3.2.1 */
-	if (addr_type == ADDR_LE_DEV_PUBLIC)
+	if (addr_type == BDADDR_LE_PUBLIC)
 		eui[0] &= ~0x02;
 		eui[0] &= ~0x02;
 	else
 	else
 		eui[0] |= 0x02;
 		eui[0] |= 0x02;
@@ -660,6 +607,17 @@ static void ifup(struct net_device *netdev)
 	rtnl_unlock();
 	rtnl_unlock();
 }
 }
 
 
+static void ifdown(struct net_device *netdev)
+{
+	int err;
+
+	rtnl_lock();
+	err = dev_close(netdev);
+	if (err < 0)
+		BT_INFO("iface %s cannot be closed (%d)", netdev->name, err);
+	rtnl_unlock();
+}
+
 static void do_notify_peers(struct work_struct *work)
 static void do_notify_peers(struct work_struct *work)
 {
 {
 	struct lowpan_dev *dev = container_of(work, struct lowpan_dev,
 	struct lowpan_dev *dev = container_of(work, struct lowpan_dev,
@@ -673,26 +631,64 @@ static bool is_bt_6lowpan(struct hci_conn *hcon)
 	if (hcon->type != LE_LINK)
 	if (hcon->type != LE_LINK)
 		return false;
 		return false;
 
 
-	return test_bit(HCI_CONN_6LOWPAN, &hcon->flags);
+	if (!psm_6lowpan)
+		return false;
+
+	return true;
+}
+
+static struct l2cap_chan *chan_create(void)
+{
+	struct l2cap_chan *chan;
+
+	chan = l2cap_chan_create();
+	if (!chan)
+		return NULL;
+
+	l2cap_chan_set_defaults(chan);
+
+	chan->chan_type = L2CAP_CHAN_CONN_ORIENTED;
+	chan->mode = L2CAP_MODE_LE_FLOWCTL;
+	chan->omtu = 65535;
+	chan->imtu = chan->omtu;
+
+	return chan;
 }
 }
 
 
-static int add_peer_conn(struct l2cap_conn *conn, struct lowpan_dev *dev)
+static struct l2cap_chan *chan_open(struct l2cap_chan *pchan)
+{
+	struct l2cap_chan *chan;
+
+	chan = chan_create();
+	if (!chan)
+		return NULL;
+
+	chan->remote_mps = chan->omtu;
+	chan->mps = chan->omtu;
+
+	chan->state = BT_CONNECTED;
+
+	return chan;
+}
+
+static struct l2cap_chan *add_peer_chan(struct l2cap_chan *chan,
+					struct lowpan_dev *dev)
 {
 {
 	struct lowpan_peer *peer;
 	struct lowpan_peer *peer;
 	unsigned long flags;
 	unsigned long flags;
 
 
 	peer = kzalloc(sizeof(*peer), GFP_ATOMIC);
 	peer = kzalloc(sizeof(*peer), GFP_ATOMIC);
 	if (!peer)
 	if (!peer)
-		return -ENOMEM;
+		return NULL;
 
 
-	peer->conn = conn;
+	peer->chan = chan;
 	memset(&peer->peer_addr, 0, sizeof(struct in6_addr));
 	memset(&peer->peer_addr, 0, sizeof(struct in6_addr));
 
 
 	/* RFC 2464 ch. 5 */
 	/* RFC 2464 ch. 5 */
 	peer->peer_addr.s6_addr[0] = 0xFE;
 	peer->peer_addr.s6_addr[0] = 0xFE;
 	peer->peer_addr.s6_addr[1] = 0x80;
 	peer->peer_addr.s6_addr[1] = 0x80;
-	set_addr((u8 *)&peer->peer_addr.s6_addr + 8, conn->hcon->dst.b,
-	         conn->hcon->dst_type);
+	set_addr((u8 *)&peer->peer_addr.s6_addr + 8, chan->dst.b,
+		 chan->dst_type);
 
 
 	memcpy(&peer->eui64_addr, (u8 *)&peer->peer_addr.s6_addr + 8,
 	memcpy(&peer->eui64_addr, (u8 *)&peer->peer_addr.s6_addr + 8,
 	       EUI64_ADDR_LEN);
 	       EUI64_ADDR_LEN);
@@ -706,40 +702,24 @@ static int add_peer_conn(struct l2cap_conn *conn, struct lowpan_dev *dev)
 	INIT_DELAYED_WORK(&dev->notify_peers, do_notify_peers);
 	INIT_DELAYED_WORK(&dev->notify_peers, do_notify_peers);
 	schedule_delayed_work(&dev->notify_peers, msecs_to_jiffies(100));
 	schedule_delayed_work(&dev->notify_peers, msecs_to_jiffies(100));
 
 
-	return 0;
+	return peer->chan;
 }
 }
 
 
-/* This gets called when BT LE 6LoWPAN device is connected. We then
- * create network device that acts as a proxy between BT LE device
- * and kernel network stack.
- */
-int bt_6lowpan_add_conn(struct l2cap_conn *conn)
+static int setup_netdev(struct l2cap_chan *chan, struct lowpan_dev **dev)
 {
 {
-	struct lowpan_peer *peer = NULL;
-	struct lowpan_dev *dev;
 	struct net_device *netdev;
 	struct net_device *netdev;
 	int err = 0;
 	int err = 0;
 	unsigned long flags;
 	unsigned long flags;
 
 
-	if (!is_bt_6lowpan(conn->hcon))
-		return 0;
-
-	peer = lookup_peer(conn);
-	if (peer)
-		return -EEXIST;
-
-	dev = lookup_dev(conn);
-	if (dev)
-		return add_peer_conn(conn, dev);
-
-	netdev = alloc_netdev(sizeof(*dev), IFACE_NAME_TEMPLATE, netdev_setup);
+	netdev = alloc_netdev(sizeof(struct lowpan_dev), IFACE_NAME_TEMPLATE,
+			      netdev_setup);
 	if (!netdev)
 	if (!netdev)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	set_dev_addr(netdev, &conn->hcon->src, conn->hcon->src_type);
+	set_dev_addr(netdev, &chan->src, chan->src_type);
 
 
 	netdev->netdev_ops = &netdev_ops;
 	netdev->netdev_ops = &netdev_ops;
-	SET_NETDEV_DEV(netdev, &conn->hcon->dev);
+	SET_NETDEV_DEV(netdev, &chan->conn->hcon->dev);
 	SET_NETDEV_DEVTYPE(netdev, &bt_type);
 	SET_NETDEV_DEVTYPE(netdev, &bt_type);
 
 
 	err = register_netdev(netdev);
 	err = register_netdev(netdev);
@@ -749,28 +729,61 @@ int bt_6lowpan_add_conn(struct l2cap_conn *conn)
 		goto out;
 		goto out;
 	}
 	}
 
 
-	BT_DBG("ifindex %d peer bdaddr %pMR my addr %pMR",
-	       netdev->ifindex, &conn->hcon->dst, &conn->hcon->src);
+	BT_DBG("ifindex %d peer bdaddr %pMR type %d my addr %pMR type %d",
+	       netdev->ifindex, &chan->dst, chan->dst_type,
+	       &chan->src, chan->src_type);
 	set_bit(__LINK_STATE_PRESENT, &netdev->state);
 	set_bit(__LINK_STATE_PRESENT, &netdev->state);
 
 
-	dev = netdev_priv(netdev);
-	dev->netdev = netdev;
-	dev->hdev = conn->hcon->hdev;
-	INIT_LIST_HEAD(&dev->peers);
+	*dev = netdev_priv(netdev);
+	(*dev)->netdev = netdev;
+	(*dev)->hdev = chan->conn->hcon->hdev;
+	INIT_LIST_HEAD(&(*dev)->peers);
 
 
 	write_lock_irqsave(&devices_lock, flags);
 	write_lock_irqsave(&devices_lock, flags);
-	INIT_LIST_HEAD(&dev->list);
-	list_add(&dev->list, &bt_6lowpan_devices);
+	INIT_LIST_HEAD(&(*dev)->list);
+	list_add(&(*dev)->list, &bt_6lowpan_devices);
 	write_unlock_irqrestore(&devices_lock, flags);
 	write_unlock_irqrestore(&devices_lock, flags);
 
 
-	ifup(netdev);
-
-	return add_peer_conn(conn, dev);
+	return 0;
 
 
 out:
 out:
 	return err;
 	return err;
 }
 }
 
 
+static inline void chan_ready_cb(struct l2cap_chan *chan)
+{
+	struct lowpan_dev *dev;
+
+	dev = lookup_dev(chan->conn);
+
+	BT_DBG("chan %p conn %p dev %p", chan, chan->conn, dev);
+
+	if (!dev) {
+		if (setup_netdev(chan, &dev) < 0) {
+			l2cap_chan_del(chan, -ENOENT);
+			return;
+		}
+	}
+
+	if (!try_module_get(THIS_MODULE))
+		return;
+
+	add_peer_chan(chan, dev);
+	ifup(dev->netdev);
+}
+
+static inline struct l2cap_chan *chan_new_conn_cb(struct l2cap_chan *chan)
+{
+	struct l2cap_chan *pchan;
+
+	pchan = chan_open(chan);
+	pchan->ops = chan->ops;
+
+	BT_DBG("chan %p pchan %p", chan, pchan);
+
+	return pchan;
+}
+
 static void delete_netdev(struct work_struct *work)
 static void delete_netdev(struct work_struct *work)
 {
 {
 	struct lowpan_dev *entry = container_of(work, struct lowpan_dev,
 	struct lowpan_dev *entry = container_of(work, struct lowpan_dev,
@@ -781,26 +794,43 @@ static void delete_netdev(struct work_struct *work)
 	/* The entry pointer is deleted in device_event() */
 	/* The entry pointer is deleted in device_event() */
 }
 }
 
 
-int bt_6lowpan_del_conn(struct l2cap_conn *conn)
+static void chan_close_cb(struct l2cap_chan *chan)
 {
 {
 	struct lowpan_dev *entry, *tmp;
 	struct lowpan_dev *entry, *tmp;
 	struct lowpan_dev *dev = NULL;
 	struct lowpan_dev *dev = NULL;
 	struct lowpan_peer *peer;
 	struct lowpan_peer *peer;
 	int err = -ENOENT;
 	int err = -ENOENT;
 	unsigned long flags;
 	unsigned long flags;
-	bool last = false;
+	bool last = false, removed = true;
 
 
-	if (!conn || !is_bt_6lowpan(conn->hcon))
-		return 0;
+	BT_DBG("chan %p conn %p", chan, chan->conn);
+
+	if (chan->conn && chan->conn->hcon) {
+		if (!is_bt_6lowpan(chan->conn->hcon))
+			return;
+
+		/* If conn is set, then the netdev is also there and we should
+		 * not remove it.
+		 */
+		removed = false;
+	}
 
 
 	write_lock_irqsave(&devices_lock, flags);
 	write_lock_irqsave(&devices_lock, flags);
 
 
 	list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, list) {
 	list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, list) {
 		dev = lowpan_dev(entry->netdev);
 		dev = lowpan_dev(entry->netdev);
-		peer = peer_lookup_conn(dev, conn);
+		peer = peer_lookup_chan(dev, chan);
 		if (peer) {
 		if (peer) {
 			last = peer_del(dev, peer);
 			last = peer_del(dev, peer);
 			err = 0;
 			err = 0;
+
+			BT_DBG("dev %p removing %speer %p", dev,
+			       last ? "last " : "1 ", peer);
+			BT_DBG("chan %p orig refcnt %d", chan,
+			       atomic_read(&chan->kref.refcount));
+
+			l2cap_chan_put(chan);
+			kfree(peer);
 			break;
 			break;
 		}
 		}
 	}
 	}
@@ -810,18 +840,402 @@ int bt_6lowpan_del_conn(struct l2cap_conn *conn)
 
 
 		cancel_delayed_work_sync(&dev->notify_peers);
 		cancel_delayed_work_sync(&dev->notify_peers);
 
 
-		/* bt_6lowpan_del_conn() is called with hci dev lock held which
-		 * means that we must delete the netdevice in worker thread.
-		 */
-		INIT_WORK(&entry->delete_netdev, delete_netdev);
-		schedule_work(&entry->delete_netdev);
+		ifdown(dev->netdev);
+
+		if (!removed) {
+			INIT_WORK(&entry->delete_netdev, delete_netdev);
+			schedule_work(&entry->delete_netdev);
+		}
 	} else {
 	} else {
 		write_unlock_irqrestore(&devices_lock, flags);
 		write_unlock_irqrestore(&devices_lock, flags);
 	}
 	}
 
 
+	return;
+}
+
+static void chan_state_change_cb(struct l2cap_chan *chan, int state, int err)
+{
+	BT_DBG("chan %p conn %p state %s err %d", chan, chan->conn,
+	       state_to_string(state), err);
+}
+
+static struct sk_buff *chan_alloc_skb_cb(struct l2cap_chan *chan,
+					 unsigned long hdr_len,
+					 unsigned long len, int nb)
+{
+	/* Note that we must allocate using GFP_ATOMIC here as
+	 * this function is called originally from netdev hard xmit
+	 * function in atomic context.
+	 */
+	return bt_skb_alloc(hdr_len + len, GFP_ATOMIC);
+}
+
+static void chan_suspend_cb(struct l2cap_chan *chan)
+{
+	struct sk_buff *skb = chan->data;
+
+	BT_DBG("chan %p conn %p skb %p", chan, chan->conn, skb);
+
+	lowpan_cb(skb)->status = -EAGAIN;
+}
+
+static void chan_resume_cb(struct l2cap_chan *chan)
+{
+	struct sk_buff *skb = chan->data;
+
+	BT_DBG("chan %p conn %p skb %p", chan, chan->conn, skb);
+
+	lowpan_cb(skb)->status = 0;
+}
+
+static long chan_get_sndtimeo_cb(struct l2cap_chan *chan)
+{
+	return msecs_to_jiffies(1000);
+}
+
+static const struct l2cap_ops bt_6lowpan_chan_ops = {
+	.name			= "L2CAP 6LoWPAN channel",
+	.new_connection		= chan_new_conn_cb,
+	.recv			= chan_recv_cb,
+	.close			= chan_close_cb,
+	.state_change		= chan_state_change_cb,
+	.ready			= chan_ready_cb,
+	.resume			= chan_resume_cb,
+	.suspend		= chan_suspend_cb,
+	.get_sndtimeo		= chan_get_sndtimeo_cb,
+	.alloc_skb		= chan_alloc_skb_cb,
+	.memcpy_fromiovec	= l2cap_chan_no_memcpy_fromiovec,
+
+	.teardown		= l2cap_chan_no_teardown,
+	.defer			= l2cap_chan_no_defer,
+	.set_shutdown		= l2cap_chan_no_set_shutdown,
+};
+
+static inline __u8 bdaddr_type(__u8 type)
+{
+	if (type == ADDR_LE_DEV_PUBLIC)
+		return BDADDR_LE_PUBLIC;
+	else
+		return BDADDR_LE_RANDOM;
+}
+
+static struct l2cap_chan *chan_get(void)
+{
+	struct l2cap_chan *pchan;
+
+	pchan = chan_create();
+	if (!pchan)
+		return NULL;
+
+	pchan->ops = &bt_6lowpan_chan_ops;
+
+	return pchan;
+}
+
+static int bt_6lowpan_connect(bdaddr_t *addr, u8 dst_type)
+{
+	struct l2cap_chan *pchan;
+	int err;
+
+	pchan = chan_get();
+	if (!pchan)
+		return -EINVAL;
+
+	err = l2cap_chan_connect(pchan, cpu_to_le16(psm_6lowpan), 0,
+				 addr, dst_type);
+
+	BT_DBG("chan %p err %d", pchan, err);
+	if (err < 0)
+		l2cap_chan_put(pchan);
+
 	return err;
 	return err;
 }
 }
 
 
+static int bt_6lowpan_disconnect(struct l2cap_conn *conn, u8 dst_type)
+{
+	struct lowpan_peer *peer;
+
+	BT_DBG("conn %p dst type %d", conn, dst_type);
+
+	peer = lookup_peer(conn);
+	if (!peer)
+		return -ENOENT;
+
+	BT_DBG("peer %p chan %p", peer, peer->chan);
+
+	l2cap_chan_close(peer->chan, ENOENT);
+
+	return 0;
+}
+
+static struct l2cap_chan *bt_6lowpan_listen(void)
+{
+	bdaddr_t *addr = BDADDR_ANY;
+	struct l2cap_chan *pchan;
+	int err;
+
+	if (psm_6lowpan == 0)
+		return NULL;
+
+	pchan = chan_get();
+	if (!pchan)
+		return NULL;
+
+	pchan->state = BT_LISTEN;
+	pchan->src_type = BDADDR_LE_PUBLIC;
+
+	BT_DBG("psm 0x%04x chan %p src type %d", psm_6lowpan, pchan,
+	       pchan->src_type);
+
+	err = l2cap_add_psm(pchan, addr, cpu_to_le16(psm_6lowpan));
+	if (err) {
+		l2cap_chan_put(pchan);
+		BT_ERR("psm cannot be added err %d", err);
+		return NULL;
+	}
+
+	return pchan;
+}
+
+static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,
+			  struct l2cap_conn **conn)
+{
+	struct hci_conn *hcon;
+	struct hci_dev *hdev;
+	bdaddr_t *src = BDADDR_ANY;
+	int n;
+
+	n = sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx %hhu",
+		   &addr->b[5], &addr->b[4], &addr->b[3],
+		   &addr->b[2], &addr->b[1], &addr->b[0],
+		   addr_type);
+
+	if (n < 7)
+		return -EINVAL;
+
+	hdev = hci_get_route(addr, src);
+	if (!hdev)
+		return -ENOENT;
+
+	hci_dev_lock(hdev);
+	hcon = hci_conn_hash_lookup_ba(hdev, LE_LINK, addr);
+	hci_dev_unlock(hdev);
+
+	if (!hcon)
+		return -ENOENT;
+
+	*conn = (struct l2cap_conn *)hcon->l2cap_data;
+
+	BT_DBG("conn %p dst %pMR type %d", *conn, &hcon->dst, hcon->dst_type);
+
+	return 0;
+}
+
+static void disconnect_all_peers(void)
+{
+	struct lowpan_dev *entry, *tmp_dev;
+	struct lowpan_peer *peer, *tmp_peer, *new_peer;
+	struct list_head peers;
+	unsigned long flags;
+
+	INIT_LIST_HEAD(&peers);
+
+	/* We make a separate list of peers as the close_cb() will
+	 * modify the device peers list so it is better not to mess
+	 * with the same list at the same time.
+	 */
+
+	read_lock_irqsave(&devices_lock, flags);
+
+	list_for_each_entry_safe(entry, tmp_dev, &bt_6lowpan_devices, list) {
+		list_for_each_entry_safe(peer, tmp_peer, &entry->peers, list) {
+			new_peer = kmalloc(sizeof(*new_peer), GFP_ATOMIC);
+			if (!new_peer)
+				break;
+
+			new_peer->chan = peer->chan;
+			INIT_LIST_HEAD(&new_peer->list);
+
+			list_add(&new_peer->list, &peers);
+		}
+	}
+
+	read_unlock_irqrestore(&devices_lock, flags);
+
+	list_for_each_entry_safe(peer, tmp_peer, &peers, list) {
+		l2cap_chan_close(peer->chan, ENOENT);
+		kfree(peer);
+	}
+}
+
+static int lowpan_psm_set(void *data, u64 val)
+{
+	u16 psm;
+
+	psm = val;
+	if (psm == 0 || psm_6lowpan != psm)
+		/* Disconnect existing connections if 6lowpan is
+		 * disabled (psm = 0), or if psm changes.
+		 */
+		disconnect_all_peers();
+
+	psm_6lowpan = psm;
+
+	if (listen_chan) {
+		l2cap_chan_close(listen_chan, 0);
+		l2cap_chan_put(listen_chan);
+	}
+
+	listen_chan = bt_6lowpan_listen();
+
+	return 0;
+}
+
+static int lowpan_psm_get(void *data, u64 *val)
+{
+	*val = psm_6lowpan;
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(lowpan_psm_fops, lowpan_psm_get,
+			lowpan_psm_set, "%llu\n");
+
+static ssize_t lowpan_control_write(struct file *fp,
+				    const char __user *user_buffer,
+				    size_t count,
+				    loff_t *position)
+{
+	char buf[32];
+	size_t buf_size = min(count, sizeof(buf) - 1);
+	int ret;
+	bdaddr_t addr;
+	u8 addr_type;
+	struct l2cap_conn *conn = NULL;
+
+	if (copy_from_user(buf, user_buffer, buf_size))
+		return -EFAULT;
+
+	buf[buf_size] = '\0';
+
+	if (memcmp(buf, "connect ", 8) == 0) {
+		ret = get_l2cap_conn(&buf[8], &addr, &addr_type, &conn);
+		if (ret == -EINVAL)
+			return ret;
+
+		if (listen_chan) {
+			l2cap_chan_close(listen_chan, 0);
+			l2cap_chan_put(listen_chan);
+			listen_chan = NULL;
+		}
+
+		if (conn) {
+			struct lowpan_peer *peer;
+
+			if (!is_bt_6lowpan(conn->hcon))
+				return -EINVAL;
+
+			peer = lookup_peer(conn);
+			if (peer) {
+				BT_DBG("6LoWPAN connection already exists");
+				return -EALREADY;
+			}
+
+			BT_DBG("conn %p dst %pMR type %d user %d", conn,
+			       &conn->hcon->dst, conn->hcon->dst_type,
+			       addr_type);
+		}
+
+		ret = bt_6lowpan_connect(&addr, addr_type);
+		if (ret < 0)
+			return ret;
+
+		return count;
+	}
+
+	if (memcmp(buf, "disconnect ", 11) == 0) {
+		ret = get_l2cap_conn(&buf[11], &addr, &addr_type, &conn);
+		if (ret < 0)
+			return ret;
+
+		ret = bt_6lowpan_disconnect(conn, addr_type);
+		if (ret < 0)
+			return ret;
+
+		return count;
+	}
+
+	return count;
+}
+
+static int lowpan_control_show(struct seq_file *f, void *ptr)
+{
+	struct lowpan_dev *entry, *tmp_dev;
+	struct lowpan_peer *peer, *tmp_peer;
+	unsigned long flags;
+
+	read_lock_irqsave(&devices_lock, flags);
+
+	list_for_each_entry_safe(entry, tmp_dev, &bt_6lowpan_devices, list) {
+		list_for_each_entry_safe(peer, tmp_peer, &entry->peers, list)
+			seq_printf(f, "%pMR (type %u)\n",
+				   &peer->chan->dst, peer->chan->dst_type);
+	}
+
+	read_unlock_irqrestore(&devices_lock, flags);
+
+	return 0;
+}
+
+static int lowpan_control_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, lowpan_control_show, inode->i_private);
+}
+
+static const struct file_operations lowpan_control_fops = {
+	.open		= lowpan_control_open,
+	.read		= seq_read,
+	.write		= lowpan_control_write,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static void disconnect_devices(void)
+{
+	struct lowpan_dev *entry, *tmp, *new_dev;
+	struct list_head devices;
+	unsigned long flags;
+
+	INIT_LIST_HEAD(&devices);
+
+	/* We make a separate list of devices because the unregister_netdev()
+	 * will call device_event() which will also want to modify the same
+	 * devices list.
+	 */
+
+	read_lock_irqsave(&devices_lock, flags);
+
+	list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, list) {
+		new_dev = kmalloc(sizeof(*new_dev), GFP_ATOMIC);
+		if (!new_dev)
+			break;
+
+		new_dev->netdev = entry->netdev;
+		INIT_LIST_HEAD(&new_dev->list);
+
+		list_add(&new_dev->list, &devices);
+	}
+
+	read_unlock_irqrestore(&devices_lock, flags);
+
+	list_for_each_entry_safe(entry, tmp, &devices, list) {
+		ifdown(entry->netdev);
+		BT_DBG("Unregistering netdev %s %p",
+		       entry->netdev->name, entry->netdev);
+		unregister_netdev(entry->netdev);
+		kfree(entry);
+	}
+}
+
 static int device_event(struct notifier_block *unused,
 static int device_event(struct notifier_block *unused,
 			unsigned long event, void *ptr)
 			unsigned long event, void *ptr)
 {
 {
@@ -838,6 +1252,8 @@ static int device_event(struct notifier_block *unused,
 		list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices,
 		list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices,
 					 list) {
 					 list) {
 			if (entry->netdev == netdev) {
 			if (entry->netdev == netdev) {
+				BT_DBG("Unregistered netdev %s %p",
+				       netdev->name, netdev);
 				list_del(&entry->list);
 				list_del(&entry->list);
 				kfree(entry);
 				kfree(entry);
 				break;
 				break;
@@ -854,12 +1270,37 @@ static struct notifier_block bt_6lowpan_dev_notifier = {
 	.notifier_call = device_event,
 	.notifier_call = device_event,
 };
 };
 
 
-int bt_6lowpan_init(void)
+static int __init bt_6lowpan_init(void)
 {
 {
+	lowpan_psm_debugfs = debugfs_create_file("6lowpan_psm", 0644,
+						 bt_debugfs, NULL,
+						 &lowpan_psm_fops);
+	lowpan_control_debugfs = debugfs_create_file("6lowpan_control", 0644,
+						     bt_debugfs, NULL,
+						     &lowpan_control_fops);
+
 	return register_netdevice_notifier(&bt_6lowpan_dev_notifier);
 	return register_netdevice_notifier(&bt_6lowpan_dev_notifier);
 }
 }
 
 
-void bt_6lowpan_cleanup(void)
+static void __exit bt_6lowpan_exit(void)
 {
 {
+	debugfs_remove(lowpan_psm_debugfs);
+	debugfs_remove(lowpan_control_debugfs);
+
+	if (listen_chan) {
+		l2cap_chan_close(listen_chan, 0);
+		l2cap_chan_put(listen_chan);
+	}
+
+	disconnect_devices();
+
 	unregister_netdevice_notifier(&bt_6lowpan_dev_notifier);
 	unregister_netdevice_notifier(&bt_6lowpan_dev_notifier);
 }
 }
+
+module_init(bt_6lowpan_init);
+module_exit(bt_6lowpan_exit);
+
+MODULE_AUTHOR("Jukka Rissanen <jukka.rissanen@linux.intel.com>");
+MODULE_DESCRIPTION("Bluetooth 6LoWPAN");
+MODULE_VERSION(VERSION);
+MODULE_LICENSE("GPL");

+ 0 - 47
net/bluetooth/6lowpan.h

@@ -1,47 +0,0 @@
-/*
-   Copyright (c) 2013 Intel Corp.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License version 2 and
-   only 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.
-*/
-
-#ifndef __6LOWPAN_H
-#define __6LOWPAN_H
-
-#include <linux/errno.h>
-#include <linux/skbuff.h>
-#include <net/bluetooth/l2cap.h>
-
-#if IS_ENABLED(CONFIG_BT_6LOWPAN)
-int bt_6lowpan_recv(struct l2cap_conn *conn, struct sk_buff *skb);
-int bt_6lowpan_add_conn(struct l2cap_conn *conn);
-int bt_6lowpan_del_conn(struct l2cap_conn *conn);
-int bt_6lowpan_init(void);
-void bt_6lowpan_cleanup(void);
-#else
-static int bt_6lowpan_recv(struct l2cap_conn *conn, struct sk_buff *skb)
-{
-	return -EOPNOTSUPP;
-}
-static int bt_6lowpan_add_conn(struct l2cap_conn *conn)
-{
-	return -EOPNOTSUPP;
-}
-int bt_6lowpan_del_conn(struct l2cap_conn *conn)
-{
-	return -EOPNOTSUPP;
-}
-static int bt_6lowpan_init(void)
-{
-	return -EOPNOTSUPP;
-}
-static void bt_6lowpan_cleanup(void) { }
-#endif
-
-#endif /* __6LOWPAN_H */

+ 3 - 3
net/bluetooth/Kconfig

@@ -6,7 +6,6 @@ menuconfig BT
 	tristate "Bluetooth subsystem support"
 	tristate "Bluetooth subsystem support"
 	depends on NET && !S390
 	depends on NET && !S390
 	depends on RFKILL || !RFKILL
 	depends on RFKILL || !RFKILL
-	select 6LOWPAN_IPHC if BT_6LOWPAN
 	select CRC16
 	select CRC16
 	select CRYPTO
 	select CRYPTO
 	select CRYPTO_BLKCIPHER
 	select CRYPTO_BLKCIPHER
@@ -41,10 +40,11 @@ menuconfig BT
 	  more information, see <http://www.bluez.org/>.
 	  more information, see <http://www.bluez.org/>.
 
 
 config BT_6LOWPAN
 config BT_6LOWPAN
-	bool "Bluetooth 6LoWPAN support"
+	tristate "Bluetooth 6LoWPAN support"
 	depends on BT && IPV6
 	depends on BT && IPV6
+	select 6LOWPAN_IPHC if BT_6LOWPAN
 	help
 	help
-	  IPv6 compression over Bluetooth.
+	  IPv6 compression over Bluetooth Low Energy.
 
 
 source "net/bluetooth/rfcomm/Kconfig"
 source "net/bluetooth/rfcomm/Kconfig"
 
 

+ 3 - 1
net/bluetooth/Makefile

@@ -7,10 +7,12 @@ obj-$(CONFIG_BT_RFCOMM)	+= rfcomm/
 obj-$(CONFIG_BT_BNEP)	+= bnep/
 obj-$(CONFIG_BT_BNEP)	+= bnep/
 obj-$(CONFIG_BT_CMTP)	+= cmtp/
 obj-$(CONFIG_BT_CMTP)	+= cmtp/
 obj-$(CONFIG_BT_HIDP)	+= hidp/
 obj-$(CONFIG_BT_HIDP)	+= hidp/
+obj-$(CONFIG_BT_6LOWPAN) += bluetooth_6lowpan.o
+
+bluetooth_6lowpan-y := 6lowpan.o
 
 
 bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o \
 bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o \
 	hci_sock.o hci_sysfs.o l2cap_core.o l2cap_sock.o smp.o sco.o lib.o \
 	hci_sock.o hci_sysfs.o l2cap_core.o l2cap_sock.o smp.o sco.o lib.o \
 	a2mp.o amp.o
 	a2mp.o amp.o
-bluetooth-$(CONFIG_BT_6LOWPAN) += 6lowpan.o
 
 
 subdir-ccflags-y += -D__CHECK_ENDIAN__
 subdir-ccflags-y += -D__CHECK_ENDIAN__

+ 5 - 3
net/bluetooth/a2mp.c

@@ -63,7 +63,7 @@ void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len, void *data)
 	msg.msg_iov = (struct iovec *) &iv;
 	msg.msg_iov = (struct iovec *) &iv;
 	msg.msg_iovlen = 1;
 	msg.msg_iovlen = 1;
 
 
-	l2cap_chan_send(chan, &msg, total_len, 0);
+	l2cap_chan_send(chan, &msg, total_len);
 
 
 	kfree(cmd);
 	kfree(cmd);
 }
 }
@@ -693,18 +693,19 @@ static void a2mp_chan_state_change_cb(struct l2cap_chan *chan, int state,
 }
 }
 
 
 static struct sk_buff *a2mp_chan_alloc_skb_cb(struct l2cap_chan *chan,
 static struct sk_buff *a2mp_chan_alloc_skb_cb(struct l2cap_chan *chan,
+					      unsigned long hdr_len,
 					      unsigned long len, int nb)
 					      unsigned long len, int nb)
 {
 {
 	struct sk_buff *skb;
 	struct sk_buff *skb;
 
 
-	skb = bt_skb_alloc(len, GFP_KERNEL);
+	skb = bt_skb_alloc(hdr_len + len, GFP_KERNEL);
 	if (!skb)
 	if (!skb)
 		return ERR_PTR(-ENOMEM);
 		return ERR_PTR(-ENOMEM);
 
 
 	return skb;
 	return skb;
 }
 }
 
 
-static struct l2cap_ops a2mp_chan_ops = {
+static const struct l2cap_ops a2mp_chan_ops = {
 	.name = "L2CAP A2MP channel",
 	.name = "L2CAP A2MP channel",
 	.recv = a2mp_chan_recv_cb,
 	.recv = a2mp_chan_recv_cb,
 	.close = a2mp_chan_close_cb,
 	.close = a2mp_chan_close_cb,
@@ -719,6 +720,7 @@ static struct l2cap_ops a2mp_chan_ops = {
 	.resume = l2cap_chan_no_resume,
 	.resume = l2cap_chan_no_resume,
 	.set_shutdown = l2cap_chan_no_set_shutdown,
 	.set_shutdown = l2cap_chan_no_set_shutdown,
 	.get_sndtimeo = l2cap_chan_no_get_sndtimeo,
 	.get_sndtimeo = l2cap_chan_no_get_sndtimeo,
+	.memcpy_fromiovec = l2cap_chan_no_memcpy_fromiovec,
 };
 };
 
 
 static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn, bool locked)
 static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn, bool locked)

+ 1 - 1
net/bluetooth/af_bluetooth.c

@@ -639,7 +639,7 @@ static int bt_seq_show(struct seq_file *seq, void *v)
 	return 0;
 	return 0;
 }
 }
 
 
-static struct seq_operations bt_seq_ops = {
+static const struct seq_operations bt_seq_ops = {
 	.start = bt_seq_start,
 	.start = bt_seq_start,
 	.next  = bt_seq_next,
 	.next  = bt_seq_next,
 	.stop  = bt_seq_stop,
 	.stop  = bt_seq_stop,

+ 127 - 49
net/bluetooth/hci_conn.c

@@ -67,7 +67,7 @@ static void hci_acl_create_connection(struct hci_conn *conn)
 	conn->state = BT_CONNECT;
 	conn->state = BT_CONNECT;
 	conn->out = true;
 	conn->out = true;
 
 
-	conn->link_mode = HCI_LM_MASTER;
+	set_bit(HCI_CONN_MASTER, &conn->flags);
 
 
 	conn->attempt++;
 	conn->attempt++;
 
 
@@ -136,7 +136,7 @@ void hci_disconnect(struct hci_conn *conn, __u8 reason)
 	hci_send_cmd(conn->hdev, HCI_OP_DISCONNECT, sizeof(cp), &cp);
 	hci_send_cmd(conn->hdev, HCI_OP_DISCONNECT, sizeof(cp), &cp);
 }
 }
 
 
-static void hci_amp_disconn(struct hci_conn *conn, __u8 reason)
+static void hci_amp_disconn(struct hci_conn *conn)
 {
 {
 	struct hci_cp_disconn_phy_link cp;
 	struct hci_cp_disconn_phy_link cp;
 
 
@@ -145,7 +145,7 @@ static void hci_amp_disconn(struct hci_conn *conn, __u8 reason)
 	conn->state = BT_DISCONN;
 	conn->state = BT_DISCONN;
 
 
 	cp.phy_handle = HCI_PHY_HANDLE(conn->handle);
 	cp.phy_handle = HCI_PHY_HANDLE(conn->handle);
-	cp.reason = reason;
+	cp.reason = hci_proto_disconn_ind(conn);
 	hci_send_cmd(conn->hdev, HCI_OP_DISCONN_PHY_LINK,
 	hci_send_cmd(conn->hdev, HCI_OP_DISCONN_PHY_LINK,
 		     sizeof(cp), &cp);
 		     sizeof(cp), &cp);
 }
 }
@@ -213,14 +213,26 @@ bool hci_setup_sync(struct hci_conn *conn, __u16 handle)
 	return true;
 	return true;
 }
 }
 
 
-void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
-			u16 latency, u16 to_multiplier)
+u8 hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, u16 latency,
+		      u16 to_multiplier)
 {
 {
-	struct hci_cp_le_conn_update cp;
 	struct hci_dev *hdev = conn->hdev;
 	struct hci_dev *hdev = conn->hdev;
+	struct hci_conn_params *params;
+	struct hci_cp_le_conn_update cp;
 
 
-	memset(&cp, 0, sizeof(cp));
+	hci_dev_lock(hdev);
+
+	params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
+	if (params) {
+		params->conn_min_interval = min;
+		params->conn_max_interval = max;
+		params->conn_latency = latency;
+		params->supervision_timeout = to_multiplier;
+	}
 
 
+	hci_dev_unlock(hdev);
+
+	memset(&cp, 0, sizeof(cp));
 	cp.handle		= cpu_to_le16(conn->handle);
 	cp.handle		= cpu_to_le16(conn->handle);
 	cp.conn_interval_min	= cpu_to_le16(min);
 	cp.conn_interval_min	= cpu_to_le16(min);
 	cp.conn_interval_max	= cpu_to_le16(max);
 	cp.conn_interval_max	= cpu_to_le16(max);
@@ -230,6 +242,11 @@ void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
 	cp.max_ce_len		= cpu_to_le16(0x0000);
 	cp.max_ce_len		= cpu_to_le16(0x0000);
 
 
 	hci_send_cmd(hdev, HCI_OP_LE_CONN_UPDATE, sizeof(cp), &cp);
 	hci_send_cmd(hdev, HCI_OP_LE_CONN_UPDATE, sizeof(cp), &cp);
+
+	if (params)
+		return 0x01;
+
+	return 0x00;
 }
 }
 
 
 void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __le64 rand,
 void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __le64 rand,
@@ -271,28 +288,24 @@ void hci_sco_setup(struct hci_conn *conn, __u8 status)
 	}
 	}
 }
 }
 
 
-static void hci_conn_disconnect(struct hci_conn *conn)
-{
-	__u8 reason = hci_proto_disconn_ind(conn);
-
-	switch (conn->type) {
-	case AMP_LINK:
-		hci_amp_disconn(conn, reason);
-		break;
-	default:
-		hci_disconnect(conn, reason);
-		break;
-	}
-}
-
 static void hci_conn_timeout(struct work_struct *work)
 static void hci_conn_timeout(struct work_struct *work)
 {
 {
 	struct hci_conn *conn = container_of(work, struct hci_conn,
 	struct hci_conn *conn = container_of(work, struct hci_conn,
 					     disc_work.work);
 					     disc_work.work);
+	int refcnt = atomic_read(&conn->refcnt);
 
 
 	BT_DBG("hcon %p state %s", conn, state_to_string(conn->state));
 	BT_DBG("hcon %p state %s", conn, state_to_string(conn->state));
 
 
-	if (atomic_read(&conn->refcnt))
+	WARN_ON(refcnt < 0);
+
+	/* FIXME: It was observed that in pairing failed scenario, refcnt
+	 * drops below 0. Probably this is because l2cap_conn_del calls
+	 * l2cap_chan_del for each channel, and inside l2cap_chan_del conn is
+	 * dropped. After that loop hci_chan_del is called which also drops
+	 * conn. For now make sure that ACL is alive if refcnt is higher then 0,
+	 * otherwise drop it.
+	 */
+	if (refcnt > 0)
 		return;
 		return;
 
 
 	switch (conn->state) {
 	switch (conn->state) {
@@ -309,7 +322,31 @@ static void hci_conn_timeout(struct work_struct *work)
 		break;
 		break;
 	case BT_CONFIG:
 	case BT_CONFIG:
 	case BT_CONNECTED:
 	case BT_CONNECTED:
-		hci_conn_disconnect(conn);
+		if (conn->type == AMP_LINK) {
+			hci_amp_disconn(conn);
+		} else {
+			__u8 reason = hci_proto_disconn_ind(conn);
+
+			/* When we are master of an established connection
+			 * and it enters the disconnect timeout, then go
+			 * ahead and try to read the current clock offset.
+			 *
+			 * Processing of the result is done within the
+			 * event handling and hci_clock_offset_evt function.
+			 */
+			if (conn->type == ACL_LINK &&
+			    test_bit(HCI_CONN_MASTER, &conn->flags)) {
+				struct hci_dev *hdev = conn->hdev;
+				struct hci_cp_read_clock_offset cp;
+
+				cp.handle = cpu_to_le16(conn->handle);
+
+				hci_send_cmd(hdev, HCI_OP_READ_CLOCK_OFFSET,
+					     sizeof(cp), &cp);
+			}
+
+			hci_disconnect(conn, reason);
+		}
 		break;
 		break;
 	default:
 	default:
 		conn->state = BT_CLOSED;
 		conn->state = BT_CLOSED;
@@ -326,9 +363,6 @@ static void hci_conn_idle(struct work_struct *work)
 
 
 	BT_DBG("hcon %p mode %d", conn, conn->mode);
 	BT_DBG("hcon %p mode %d", conn, conn->mode);
 
 
-	if (test_bit(HCI_RAW, &hdev->flags))
-		return;
-
 	if (!lmp_sniff_capable(hdev) || !lmp_sniff_capable(conn))
 	if (!lmp_sniff_capable(hdev) || !lmp_sniff_capable(conn))
 		return;
 		return;
 
 
@@ -519,7 +553,6 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
 
 
 	list_for_each_entry(d, &hci_dev_list, list) {
 	list_for_each_entry(d, &hci_dev_list, list) {
 		if (!test_bit(HCI_UP, &d->flags) ||
 		if (!test_bit(HCI_UP, &d->flags) ||
-		    test_bit(HCI_RAW, &d->flags) ||
 		    test_bit(HCI_USER_CHANNEL, &d->dev_flags) ||
 		    test_bit(HCI_USER_CHANNEL, &d->dev_flags) ||
 		    d->dev_type != HCI_BREDR)
 		    d->dev_type != HCI_BREDR)
 			continue;
 			continue;
@@ -617,7 +650,8 @@ static void hci_req_add_le_create_conn(struct hci_request *req,
 	cp.own_address_type = own_addr_type;
 	cp.own_address_type = own_addr_type;
 	cp.conn_interval_min = cpu_to_le16(conn->le_conn_min_interval);
 	cp.conn_interval_min = cpu_to_le16(conn->le_conn_min_interval);
 	cp.conn_interval_max = cpu_to_le16(conn->le_conn_max_interval);
 	cp.conn_interval_max = cpu_to_le16(conn->le_conn_max_interval);
-	cp.supervision_timeout = cpu_to_le16(0x002a);
+	cp.conn_latency = cpu_to_le16(conn->le_conn_latency);
+	cp.supervision_timeout = cpu_to_le16(conn->le_supv_timeout);
 	cp.min_ce_len = cpu_to_le16(0x0000);
 	cp.min_ce_len = cpu_to_le16(0x0000);
 	cp.max_ce_len = cpu_to_le16(0x0000);
 	cp.max_ce_len = cpu_to_le16(0x0000);
 
 
@@ -634,15 +668,12 @@ static void hci_req_directed_advertising(struct hci_request *req,
 	u8 own_addr_type;
 	u8 own_addr_type;
 	u8 enable;
 	u8 enable;
 
 
-	enable = 0x00;
-	hci_req_add(req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable);
-
-	/* Clear the HCI_ADVERTISING bit temporarily so that the
+	/* Clear the HCI_LE_ADV bit temporarily so that the
 	 * hci_update_random_address knows that it's safe to go ahead
 	 * 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
 	 * and write a new random address. The flag will be set back on
 	 * as soon as the SET_ADV_ENABLE HCI command completes.
 	 * as soon as the SET_ADV_ENABLE HCI command completes.
 	 */
 	 */
-	clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
+	clear_bit(HCI_LE_ADV, &hdev->dev_flags);
 
 
 	/* Set require_privacy to false so that the remote device has a
 	/* Set require_privacy to false so that the remote device has a
 	 * chance of identifying us.
 	 * chance of identifying us.
@@ -666,7 +697,8 @@ static void hci_req_directed_advertising(struct hci_request *req,
 }
 }
 
 
 struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
 struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
-				u8 dst_type, u8 sec_level, u8 auth_type)
+				u8 dst_type, u8 sec_level, u16 conn_timeout,
+				bool master)
 {
 {
 	struct hci_conn_params *params;
 	struct hci_conn_params *params;
 	struct hci_conn *conn;
 	struct hci_conn *conn;
@@ -686,7 +718,6 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
 	conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst);
 	conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst);
 	if (conn) {
 	if (conn) {
 		conn->pending_sec_level = sec_level;
 		conn->pending_sec_level = sec_level;
-		conn->auth_type = auth_type;
 		goto done;
 		goto done;
 	}
 	}
 
 
@@ -723,25 +754,52 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
 	conn->dst_type = dst_type;
 	conn->dst_type = dst_type;
 	conn->sec_level = BT_SECURITY_LOW;
 	conn->sec_level = BT_SECURITY_LOW;
 	conn->pending_sec_level = sec_level;
 	conn->pending_sec_level = sec_level;
-	conn->auth_type = auth_type;
+	conn->conn_timeout = conn_timeout;
 
 
 	hci_req_init(&req, hdev);
 	hci_req_init(&req, hdev);
 
 
-	if (test_bit(HCI_ADVERTISING, &hdev->dev_flags)) {
+	/* Disable advertising if we're active. For master role
+	 * connections most controllers will refuse to connect if
+	 * advertising is enabled, and for slave role connections we
+	 * anyway have to disable it in order to start directed
+	 * advertising.
+	 */
+	if (test_bit(HCI_LE_ADV, &hdev->dev_flags)) {
+		u8 enable = 0x00;
+		hci_req_add(&req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable),
+			    &enable);
+	}
+
+	/* If requested to connect as slave use directed advertising */
+	if (!master) {
+		/* If we're active scanning most controllers are unable
+		 * to initiate advertising. Simply reject the attempt.
+		 */
+		if (test_bit(HCI_LE_SCAN, &hdev->dev_flags) &&
+		    hdev->le_scan_type == LE_SCAN_ACTIVE) {
+			skb_queue_purge(&req.cmd_q);
+			hci_conn_del(conn);
+			return ERR_PTR(-EBUSY);
+		}
+
 		hci_req_directed_advertising(&req, conn);
 		hci_req_directed_advertising(&req, conn);
 		goto create_conn;
 		goto create_conn;
 	}
 	}
 
 
 	conn->out = true;
 	conn->out = true;
-	conn->link_mode |= HCI_LM_MASTER;
+	set_bit(HCI_CONN_MASTER, &conn->flags);
 
 
 	params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
 	params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
 	if (params) {
 	if (params) {
 		conn->le_conn_min_interval = params->conn_min_interval;
 		conn->le_conn_min_interval = params->conn_min_interval;
 		conn->le_conn_max_interval = params->conn_max_interval;
 		conn->le_conn_max_interval = params->conn_max_interval;
+		conn->le_conn_latency = params->conn_latency;
+		conn->le_supv_timeout = params->supervision_timeout;
 	} else {
 	} else {
 		conn->le_conn_min_interval = hdev->le_conn_min_interval;
 		conn->le_conn_min_interval = hdev->le_conn_min_interval;
 		conn->le_conn_max_interval = hdev->le_conn_max_interval;
 		conn->le_conn_max_interval = hdev->le_conn_max_interval;
+		conn->le_conn_latency = hdev->le_conn_latency;
+		conn->le_supv_timeout = hdev->le_supv_timeout;
 	}
 	}
 
 
 	/* If controller is scanning, we stop it since some controllers are
 	/* If controller is scanning, we stop it since some controllers are
@@ -855,7 +913,8 @@ int hci_conn_check_link_mode(struct hci_conn *conn)
 			return 0;
 			return 0;
 	}
 	}
 
 
-	if (hci_conn_ssp_enabled(conn) && !(conn->link_mode & HCI_LM_ENCRYPT))
+	if (hci_conn_ssp_enabled(conn) &&
+	    !test_bit(HCI_CONN_ENCRYPT, &conn->flags))
 		return 0;
 		return 0;
 
 
 	return 1;
 	return 1;
@@ -871,7 +930,7 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
 
 
 	if (sec_level > conn->sec_level)
 	if (sec_level > conn->sec_level)
 		conn->pending_sec_level = sec_level;
 		conn->pending_sec_level = sec_level;
-	else if (conn->link_mode & HCI_LM_AUTH)
+	else if (test_bit(HCI_CONN_AUTH, &conn->flags))
 		return 1;
 		return 1;
 
 
 	/* Make sure we preserve an existing MITM requirement*/
 	/* Make sure we preserve an existing MITM requirement*/
@@ -889,7 +948,7 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
 		/* If we're already encrypted set the REAUTH_PEND flag,
 		/* If we're already encrypted set the REAUTH_PEND flag,
 		 * otherwise set the ENCRYPT_PEND.
 		 * otherwise set the ENCRYPT_PEND.
 		 */
 		 */
-		if (conn->link_mode & HCI_LM_ENCRYPT)
+		if (test_bit(HCI_CONN_ENCRYPT, &conn->flags))
 			set_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
 			set_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
 		else
 		else
 			set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
 			set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
@@ -930,7 +989,7 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
 		return 1;
 		return 1;
 
 
 	/* For other security levels we need the link key. */
 	/* For other security levels we need the link key. */
-	if (!(conn->link_mode & HCI_LM_AUTH))
+	if (!test_bit(HCI_CONN_AUTH, &conn->flags))
 		goto auth;
 		goto auth;
 
 
 	/* An authenticated FIPS approved combination key has sufficient
 	/* An authenticated FIPS approved combination key has sufficient
@@ -970,7 +1029,7 @@ auth:
 		return 0;
 		return 0;
 
 
 encrypt:
 encrypt:
-	if (conn->link_mode & HCI_LM_ENCRYPT)
+	if (test_bit(HCI_CONN_ENCRYPT, &conn->flags))
 		return 1;
 		return 1;
 
 
 	hci_conn_encrypt(conn);
 	hci_conn_encrypt(conn);
@@ -1017,7 +1076,7 @@ int hci_conn_switch_role(struct hci_conn *conn, __u8 role)
 {
 {
 	BT_DBG("hcon %p", conn);
 	BT_DBG("hcon %p", conn);
 
 
-	if (!role && conn->link_mode & HCI_LM_MASTER)
+	if (!role && test_bit(HCI_CONN_MASTER, &conn->flags))
 		return 1;
 		return 1;
 
 
 	if (!test_and_set_bit(HCI_CONN_RSWITCH_PEND, &conn->flags)) {
 	if (!test_and_set_bit(HCI_CONN_RSWITCH_PEND, &conn->flags)) {
@@ -1038,9 +1097,6 @@ void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active)
 
 
 	BT_DBG("hcon %p mode %d", conn, conn->mode);
 	BT_DBG("hcon %p mode %d", conn, conn->mode);
 
 
-	if (test_bit(HCI_RAW, &hdev->flags))
-		return;
-
 	if (conn->mode != HCI_CM_SNIFF)
 	if (conn->mode != HCI_CM_SNIFF)
 		goto timer;
 		goto timer;
 
 
@@ -1091,6 +1147,28 @@ void hci_conn_check_pending(struct hci_dev *hdev)
 	hci_dev_unlock(hdev);
 	hci_dev_unlock(hdev);
 }
 }
 
 
+static u32 get_link_mode(struct hci_conn *conn)
+{
+	u32 link_mode = 0;
+
+	if (test_bit(HCI_CONN_MASTER, &conn->flags))
+		link_mode |= HCI_LM_MASTER;
+
+	if (test_bit(HCI_CONN_ENCRYPT, &conn->flags))
+		link_mode |= HCI_LM_ENCRYPT;
+
+	if (test_bit(HCI_CONN_AUTH, &conn->flags))
+		link_mode |= HCI_LM_AUTH;
+
+	if (test_bit(HCI_CONN_SECURE, &conn->flags))
+		link_mode |= HCI_LM_SECURE;
+
+	if (test_bit(HCI_CONN_FIPS, &conn->flags))
+		link_mode |= HCI_LM_FIPS;
+
+	return link_mode;
+}
+
 int hci_get_conn_list(void __user *arg)
 int hci_get_conn_list(void __user *arg)
 {
 {
 	struct hci_conn *c;
 	struct hci_conn *c;
@@ -1126,7 +1204,7 @@ int hci_get_conn_list(void __user *arg)
 		(ci + n)->type  = c->type;
 		(ci + n)->type  = c->type;
 		(ci + n)->out   = c->out;
 		(ci + n)->out   = c->out;
 		(ci + n)->state = c->state;
 		(ci + n)->state = c->state;
-		(ci + n)->link_mode = c->link_mode;
+		(ci + n)->link_mode = get_link_mode(c);
 		if (++n >= req.conn_num)
 		if (++n >= req.conn_num)
 			break;
 			break;
 	}
 	}
@@ -1162,7 +1240,7 @@ int hci_get_conn_info(struct hci_dev *hdev, void __user *arg)
 		ci.type  = conn->type;
 		ci.type  = conn->type;
 		ci.out   = conn->out;
 		ci.out   = conn->out;
 		ci.state = conn->state;
 		ci.state = conn->state;
-		ci.link_mode = conn->link_mode;
+		ci.link_mode = get_link_mode(conn);
 	}
 	}
 	hci_dev_unlock(hdev);
 	hci_dev_unlock(hdev);
 
 

+ 476 - 433
net/bluetooth/hci_core.c

@@ -35,6 +35,7 @@
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 #include <net/bluetooth/hci_core.h>
 #include <net/bluetooth/l2cap.h>
 #include <net/bluetooth/l2cap.h>
+#include <net/bluetooth/mgmt.h>
 
 
 #include "smp.h"
 #include "smp.h"
 
 
@@ -68,7 +69,7 @@ static ssize_t dut_mode_read(struct file *file, char __user *user_buf,
 	struct hci_dev *hdev = file->private_data;
 	struct hci_dev *hdev = file->private_data;
 	char buf[3];
 	char buf[3];
 
 
-	buf[0] = test_bit(HCI_DUT_MODE, &hdev->dev_flags) ? 'Y': 'N';
+	buf[0] = test_bit(HCI_DUT_MODE, &hdev->dbg_flags) ? 'Y': 'N';
 	buf[1] = '\n';
 	buf[1] = '\n';
 	buf[2] = '\0';
 	buf[2] = '\0';
 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
@@ -94,7 +95,7 @@ static ssize_t dut_mode_write(struct file *file, const char __user *user_buf,
 	if (strtobool(buf, &enable))
 	if (strtobool(buf, &enable))
 		return -EINVAL;
 		return -EINVAL;
 
 
-	if (enable == test_bit(HCI_DUT_MODE, &hdev->dev_flags))
+	if (enable == test_bit(HCI_DUT_MODE, &hdev->dbg_flags))
 		return -EALREADY;
 		return -EALREADY;
 
 
 	hci_req_lock(hdev);
 	hci_req_lock(hdev);
@@ -115,7 +116,7 @@ static ssize_t dut_mode_write(struct file *file, const char __user *user_buf,
 	if (err < 0)
 	if (err < 0)
 		return err;
 		return err;
 
 
-	change_bit(HCI_DUT_MODE, &hdev->dev_flags);
+	change_bit(HCI_DUT_MODE, &hdev->dbg_flags);
 
 
 	return count;
 	return count;
 }
 }
@@ -190,6 +191,31 @@ static const struct file_operations blacklist_fops = {
 	.release	= single_release,
 	.release	= single_release,
 };
 };
 
 
+static int whitelist_show(struct seq_file *f, void *p)
+{
+	struct hci_dev *hdev = f->private;
+	struct bdaddr_list *b;
+
+	hci_dev_lock(hdev);
+	list_for_each_entry(b, &hdev->whitelist, list)
+		seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type);
+	hci_dev_unlock(hdev);
+
+	return 0;
+}
+
+static int whitelist_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, whitelist_show, inode->i_private);
+}
+
+static const struct file_operations whitelist_fops = {
+	.open		= whitelist_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 static int uuids_show(struct seq_file *f, void *p)
 static int uuids_show(struct seq_file *f, void *p)
 {
 {
 	struct hci_dev *hdev = f->private;
 	struct hci_dev *hdev = f->private;
@@ -352,62 +378,13 @@ static int auto_accept_delay_get(void *data, u64 *val)
 DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get,
 DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get,
 			auto_accept_delay_set, "%llu\n");
 			auto_accept_delay_set, "%llu\n");
 
 
-static int ssp_debug_mode_set(void *data, u64 val)
-{
-	struct hci_dev *hdev = data;
-	struct sk_buff *skb;
-	__u8 mode;
-	int err;
-
-	if (val != 0 && val != 1)
-		return -EINVAL;
-
-	if (!test_bit(HCI_UP, &hdev->flags))
-		return -ENETDOWN;
-
-	hci_req_lock(hdev);
-	mode = val;
-	skb = __hci_cmd_sync(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE, sizeof(mode),
-			     &mode, HCI_CMD_TIMEOUT);
-	hci_req_unlock(hdev);
-
-	if (IS_ERR(skb))
-		return PTR_ERR(skb);
-
-	err = -bt_to_errno(skb->data[0]);
-	kfree_skb(skb);
-
-	if (err < 0)
-		return err;
-
-	hci_dev_lock(hdev);
-	hdev->ssp_debug_mode = val;
-	hci_dev_unlock(hdev);
-
-	return 0;
-}
-
-static int ssp_debug_mode_get(void *data, u64 *val)
-{
-	struct hci_dev *hdev = data;
-
-	hci_dev_lock(hdev);
-	*val = hdev->ssp_debug_mode;
-	hci_dev_unlock(hdev);
-
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(ssp_debug_mode_fops, ssp_debug_mode_get,
-			ssp_debug_mode_set, "%llu\n");
-
 static ssize_t force_sc_support_read(struct file *file, char __user *user_buf,
 static ssize_t force_sc_support_read(struct file *file, char __user *user_buf,
 				     size_t count, loff_t *ppos)
 				     size_t count, loff_t *ppos)
 {
 {
 	struct hci_dev *hdev = file->private_data;
 	struct hci_dev *hdev = file->private_data;
 	char buf[3];
 	char buf[3];
 
 
-	buf[0] = test_bit(HCI_FORCE_SC, &hdev->dev_flags) ? 'Y': 'N';
+	buf[0] = test_bit(HCI_FORCE_SC, &hdev->dbg_flags) ? 'Y': 'N';
 	buf[1] = '\n';
 	buf[1] = '\n';
 	buf[2] = '\0';
 	buf[2] = '\0';
 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
@@ -432,10 +409,10 @@ static ssize_t force_sc_support_write(struct file *file,
 	if (strtobool(buf, &enable))
 	if (strtobool(buf, &enable))
 		return -EINVAL;
 		return -EINVAL;
 
 
-	if (enable == test_bit(HCI_FORCE_SC, &hdev->dev_flags))
+	if (enable == test_bit(HCI_FORCE_SC, &hdev->dbg_flags))
 		return -EALREADY;
 		return -EALREADY;
 
 
-	change_bit(HCI_FORCE_SC, &hdev->dev_flags);
+	change_bit(HCI_FORCE_SC, &hdev->dbg_flags);
 
 
 	return count;
 	return count;
 }
 }
@@ -719,7 +696,7 @@ static ssize_t force_static_address_read(struct file *file,
 	struct hci_dev *hdev = file->private_data;
 	struct hci_dev *hdev = file->private_data;
 	char buf[3];
 	char buf[3];
 
 
-	buf[0] = test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags) ? 'Y': 'N';
+	buf[0] = test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) ? 'Y': 'N';
 	buf[1] = '\n';
 	buf[1] = '\n';
 	buf[2] = '\0';
 	buf[2] = '\0';
 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
@@ -744,10 +721,10 @@ static ssize_t force_static_address_write(struct file *file,
 	if (strtobool(buf, &enable))
 	if (strtobool(buf, &enable))
 		return -EINVAL;
 		return -EINVAL;
 
 
-	if (enable == test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags))
+	if (enable == test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags))
 		return -EALREADY;
 		return -EALREADY;
 
 
-	change_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags);
+	change_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags);
 
 
 	return count;
 	return count;
 }
 }
@@ -900,177 +877,113 @@ static int conn_max_interval_get(void *data, u64 *val)
 DEFINE_SIMPLE_ATTRIBUTE(conn_max_interval_fops, conn_max_interval_get,
 DEFINE_SIMPLE_ATTRIBUTE(conn_max_interval_fops, conn_max_interval_get,
 			conn_max_interval_set, "%llu\n");
 			conn_max_interval_set, "%llu\n");
 
 
-static int adv_channel_map_set(void *data, u64 val)
+static int conn_latency_set(void *data, u64 val)
 {
 {
 	struct hci_dev *hdev = data;
 	struct hci_dev *hdev = data;
 
 
-	if (val < 0x01 || val > 0x07)
+	if (val > 0x01f3)
 		return -EINVAL;
 		return -EINVAL;
 
 
 	hci_dev_lock(hdev);
 	hci_dev_lock(hdev);
-	hdev->le_adv_channel_map = val;
+	hdev->le_conn_latency = val;
 	hci_dev_unlock(hdev);
 	hci_dev_unlock(hdev);
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-static int adv_channel_map_get(void *data, u64 *val)
+static int conn_latency_get(void *data, u64 *val)
 {
 {
 	struct hci_dev *hdev = data;
 	struct hci_dev *hdev = data;
 
 
 	hci_dev_lock(hdev);
 	hci_dev_lock(hdev);
-	*val = hdev->le_adv_channel_map;
+	*val = hdev->le_conn_latency;
 	hci_dev_unlock(hdev);
 	hci_dev_unlock(hdev);
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-DEFINE_SIMPLE_ATTRIBUTE(adv_channel_map_fops, adv_channel_map_get,
-			adv_channel_map_set, "%llu\n");
+DEFINE_SIMPLE_ATTRIBUTE(conn_latency_fops, conn_latency_get,
+			conn_latency_set, "%llu\n");
 
 
-static ssize_t lowpan_read(struct file *file, char __user *user_buf,
-			   size_t count, loff_t *ppos)
+static int supervision_timeout_set(void *data, u64 val)
 {
 {
-	struct hci_dev *hdev = file->private_data;
-	char buf[3];
-
-	buf[0] = test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags) ? 'Y' : 'N';
-	buf[1] = '\n';
-	buf[2] = '\0';
-	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
-}
-
-static ssize_t lowpan_write(struct file *fp, const char __user *user_buffer,
-			    size_t count, loff_t *position)
-{
-	struct hci_dev *hdev = fp->private_data;
-	bool enable;
-	char buf[32];
-	size_t buf_size = min(count, (sizeof(buf)-1));
-
-	if (copy_from_user(buf, user_buffer, buf_size))
-		return -EFAULT;
-
-	buf[buf_size] = '\0';
+	struct hci_dev *hdev = data;
 
 
-	if (strtobool(buf, &enable) < 0)
+	if (val < 0x000a || val > 0x0c80)
 		return -EINVAL;
 		return -EINVAL;
 
 
-	if (enable == test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags))
-		return -EALREADY;
-
-	change_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags);
+	hci_dev_lock(hdev);
+	hdev->le_supv_timeout = val;
+	hci_dev_unlock(hdev);
 
 
-	return count;
+	return 0;
 }
 }
 
 
-static const struct file_operations lowpan_debugfs_fops = {
-	.open		= simple_open,
-	.read		= lowpan_read,
-	.write		= lowpan_write,
-	.llseek		= default_llseek,
-};
-
-static int le_auto_conn_show(struct seq_file *sf, void *ptr)
+static int supervision_timeout_get(void *data, u64 *val)
 {
 {
-	struct hci_dev *hdev = sf->private;
-	struct hci_conn_params *p;
+	struct hci_dev *hdev = data;
 
 
 	hci_dev_lock(hdev);
 	hci_dev_lock(hdev);
-
-	list_for_each_entry(p, &hdev->le_conn_params, list) {
-		seq_printf(sf, "%pMR %u %u\n", &p->addr, p->addr_type,
-			   p->auto_connect);
-	}
-
+	*val = hdev->le_supv_timeout;
 	hci_dev_unlock(hdev);
 	hci_dev_unlock(hdev);
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-static int le_auto_conn_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, le_auto_conn_show, inode->i_private);
-}
+DEFINE_SIMPLE_ATTRIBUTE(supervision_timeout_fops, supervision_timeout_get,
+			supervision_timeout_set, "%llu\n");
 
 
-static ssize_t le_auto_conn_write(struct file *file, const char __user *data,
-				  size_t count, loff_t *offset)
+static int adv_channel_map_set(void *data, u64 val)
 {
 {
-	struct seq_file *sf = file->private_data;
-	struct hci_dev *hdev = sf->private;
-	u8 auto_connect = 0;
-	bdaddr_t addr;
-	u8 addr_type;
-	char *buf;
-	int err = 0;
-	int n;
+	struct hci_dev *hdev = data;
 
 
-	/* Don't allow partial write */
-	if (*offset != 0)
+	if (val < 0x01 || val > 0x07)
 		return -EINVAL;
 		return -EINVAL;
 
 
-	if (count < 3)
-		return -EINVAL;
+	hci_dev_lock(hdev);
+	hdev->le_adv_channel_map = val;
+	hci_dev_unlock(hdev);
 
 
-	buf = memdup_user(data, count);
-	if (IS_ERR(buf))
-		return PTR_ERR(buf);
+	return 0;
+}
 
 
-	if (memcmp(buf, "add", 3) == 0) {
-		n = sscanf(&buf[4], "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx %hhu %hhu",
-			   &addr.b[5], &addr.b[4], &addr.b[3], &addr.b[2],
-			   &addr.b[1], &addr.b[0], &addr_type,
-			   &auto_connect);
+static int adv_channel_map_get(void *data, u64 *val)
+{
+	struct hci_dev *hdev = data;
 
 
-		if (n < 7) {
-			err = -EINVAL;
-			goto done;
-		}
+	hci_dev_lock(hdev);
+	*val = hdev->le_adv_channel_map;
+	hci_dev_unlock(hdev);
 
 
-		hci_dev_lock(hdev);
-		err = hci_conn_params_add(hdev, &addr, addr_type, auto_connect,
-					  hdev->le_conn_min_interval,
-					  hdev->le_conn_max_interval);
-		hci_dev_unlock(hdev);
+	return 0;
+}
 
 
-		if (err)
-			goto done;
-	} else if (memcmp(buf, "del", 3) == 0) {
-		n = sscanf(&buf[4], "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx %hhu",
-			   &addr.b[5], &addr.b[4], &addr.b[3], &addr.b[2],
-			   &addr.b[1], &addr.b[0], &addr_type);
+DEFINE_SIMPLE_ATTRIBUTE(adv_channel_map_fops, adv_channel_map_get,
+			adv_channel_map_set, "%llu\n");
 
 
-		if (n < 7) {
-			err = -EINVAL;
-			goto done;
-		}
+static int device_list_show(struct seq_file *f, void *ptr)
+{
+	struct hci_dev *hdev = f->private;
+	struct hci_conn_params *p;
 
 
-		hci_dev_lock(hdev);
-		hci_conn_params_del(hdev, &addr, addr_type);
-		hci_dev_unlock(hdev);
-	} else if (memcmp(buf, "clr", 3) == 0) {
-		hci_dev_lock(hdev);
-		hci_conn_params_clear(hdev);
-		hci_pend_le_conns_clear(hdev);
-		hci_update_background_scan(hdev);
-		hci_dev_unlock(hdev);
-	} else {
-		err = -EINVAL;
+	hci_dev_lock(hdev);
+	list_for_each_entry(p, &hdev->le_conn_params, list) {
+		seq_printf(f, "%pMR %u %u\n", &p->addr, p->addr_type,
+			   p->auto_connect);
 	}
 	}
+	hci_dev_unlock(hdev);
 
 
-done:
-	kfree(buf);
+	return 0;
+}
 
 
-	if (err)
-		return err;
-	else
-		return count;
+static int device_list_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, device_list_show, inode->i_private);
 }
 }
 
 
-static const struct file_operations le_auto_conn_fops = {
-	.open		= le_auto_conn_open,
+static const struct file_operations device_list_fops = {
+	.open		= device_list_open,
 	.read		= seq_read,
 	.read		= seq_read,
-	.write		= le_auto_conn_write,
 	.llseek		= seq_lseek,
 	.llseek		= seq_lseek,
 	.release	= single_release,
 	.release	= single_release,
 };
 };
@@ -1549,13 +1462,6 @@ static void hci_setup_event_mask(struct hci_request *req)
 		events[7] |= 0x20;	/* LE Meta-Event */
 		events[7] |= 0x20;	/* LE Meta-Event */
 
 
 	hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
 	hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
-
-	if (lmp_le_capable(hdev)) {
-		memset(events, 0, sizeof(events));
-		events[0] = 0x1f;
-		hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK,
-			    sizeof(events), events);
-	}
 }
 }
 
 
 static void hci_init2_req(struct hci_request *req, unsigned long opt)
 static void hci_init2_req(struct hci_request *req, unsigned long opt)
@@ -1688,7 +1594,7 @@ static void hci_set_event_mask_page_2(struct hci_request *req)
 	}
 	}
 
 
 	/* Enable Authenticated Payload Timeout Expired event if supported */
 	/* Enable Authenticated Payload Timeout Expired event if supported */
-	if (lmp_ping_capable(hdev))
+	if (lmp_ping_capable(hdev) || hdev->le_features[0] & HCI_LE_PING)
 		events[2] |= 0x80;
 		events[2] |= 0x80;
 
 
 	hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events);
 	hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events);
@@ -1725,8 +1631,25 @@ static void hci_init3_req(struct hci_request *req, unsigned long opt)
 	if (hdev->commands[5] & 0x10)
 	if (hdev->commands[5] & 0x10)
 		hci_setup_link_policy(req);
 		hci_setup_link_policy(req);
 
 
-	if (lmp_le_capable(hdev))
+	if (lmp_le_capable(hdev)) {
+		u8 events[8];
+
+		memset(events, 0, sizeof(events));
+		events[0] = 0x1f;
+
+		/* If controller supports the Connection Parameters Request
+		 * Link Layer Procedure, enable the corresponding event.
+		 */
+		if (hdev->le_features[0] & HCI_LE_CONN_PARAM_REQ_PROC)
+			events[0] |= 0x20;	/* LE Remote Connection
+						 * Parameter Request
+						 */
+
+		hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, sizeof(events),
+			    events);
+
 		hci_set_le_support(req);
 		hci_set_le_support(req);
+	}
 
 
 	/* Read features beyond page 1 if available */
 	/* Read features beyond page 1 if available */
 	for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
 	for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
@@ -1752,7 +1675,7 @@ static void hci_init4_req(struct hci_request *req, unsigned long opt)
 
 
 	/* Enable Secure Connections if supported and configured */
 	/* Enable Secure Connections if supported and configured */
 	if ((lmp_sc_capable(hdev) ||
 	if ((lmp_sc_capable(hdev) ||
-	     test_bit(HCI_FORCE_SC, &hdev->dev_flags)) &&
+	     test_bit(HCI_FORCE_SC, &hdev->dbg_flags)) &&
 	    test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
 	    test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
 		u8 support = 0x01;
 		u8 support = 0x01;
 		hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT,
 		hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT,
@@ -1809,6 +1732,8 @@ static int __hci_init(struct hci_dev *hdev)
 	debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev);
 	debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev);
 	debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev,
 	debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev,
 			    &blacklist_fops);
 			    &blacklist_fops);
+	debugfs_create_file("whitelist", 0444, hdev->debugfs, hdev,
+			    &whitelist_fops);
 	debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops);
 	debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops);
 
 
 	debugfs_create_file("conn_info_min_age", 0644, hdev->debugfs, hdev,
 	debugfs_create_file("conn_info_min_age", 0644, hdev->debugfs, hdev,
@@ -1830,8 +1755,6 @@ static int __hci_init(struct hci_dev *hdev)
 	if (lmp_ssp_capable(hdev)) {
 	if (lmp_ssp_capable(hdev)) {
 		debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs,
 		debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs,
 				    hdev, &auto_accept_delay_fops);
 				    hdev, &auto_accept_delay_fops);
-		debugfs_create_file("ssp_debug_mode", 0644, hdev->debugfs,
-				    hdev, &ssp_debug_mode_fops);
 		debugfs_create_file("force_sc_support", 0644, hdev->debugfs,
 		debugfs_create_file("force_sc_support", 0644, hdev->debugfs,
 				    hdev, &force_sc_support_fops);
 				    hdev, &force_sc_support_fops);
 		debugfs_create_file("sc_only_mode", 0444, hdev->debugfs,
 		debugfs_create_file("sc_only_mode", 0444, hdev->debugfs,
@@ -1879,12 +1802,14 @@ static int __hci_init(struct hci_dev *hdev)
 				    hdev, &conn_min_interval_fops);
 				    hdev, &conn_min_interval_fops);
 		debugfs_create_file("conn_max_interval", 0644, hdev->debugfs,
 		debugfs_create_file("conn_max_interval", 0644, hdev->debugfs,
 				    hdev, &conn_max_interval_fops);
 				    hdev, &conn_max_interval_fops);
+		debugfs_create_file("conn_latency", 0644, hdev->debugfs,
+				    hdev, &conn_latency_fops);
+		debugfs_create_file("supervision_timeout", 0644, hdev->debugfs,
+				    hdev, &supervision_timeout_fops);
 		debugfs_create_file("adv_channel_map", 0644, hdev->debugfs,
 		debugfs_create_file("adv_channel_map", 0644, hdev->debugfs,
 				    hdev, &adv_channel_map_fops);
 				    hdev, &adv_channel_map_fops);
-		debugfs_create_file("6lowpan", 0644, hdev->debugfs, hdev,
-				    &lowpan_debugfs_fops);
-		debugfs_create_file("le_auto_conn", 0644, hdev->debugfs, hdev,
-				    &le_auto_conn_fops);
+		debugfs_create_file("device_list", 0444, hdev->debugfs, hdev,
+				    &device_list_fops);
 		debugfs_create_u16("discov_interleaved_timeout", 0644,
 		debugfs_create_u16("discov_interleaved_timeout", 0644,
 				   hdev->debugfs,
 				   hdev->debugfs,
 				   &hdev->discov_interleaved_timeout);
 				   &hdev->discov_interleaved_timeout);
@@ -1893,6 +1818,38 @@ static int __hci_init(struct hci_dev *hdev)
 	return 0;
 	return 0;
 }
 }
 
 
+static void hci_init0_req(struct hci_request *req, unsigned long opt)
+{
+	struct hci_dev *hdev = req->hdev;
+
+	BT_DBG("%s %ld", hdev->name, opt);
+
+	/* Reset */
+	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
+		hci_reset_req(req, 0);
+
+	/* Read Local Version */
+	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
+
+	/* Read BD Address */
+	if (hdev->set_bdaddr)
+		hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
+}
+
+static int __hci_unconf_init(struct hci_dev *hdev)
+{
+	int err;
+
+	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
+		return 0;
+
+	err = __hci_req_sync(hdev, hci_init0_req, 0, HCI_INIT_TIMEOUT);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
 static void hci_scan_req(struct hci_request *req, unsigned long opt)
 static void hci_scan_req(struct hci_request *req, unsigned long opt)
 {
 {
 	__u8 scan = opt;
 	__u8 scan = opt;
@@ -1973,16 +1930,20 @@ bool hci_discovery_active(struct hci_dev *hdev)
 
 
 void hci_discovery_set_state(struct hci_dev *hdev, int state)
 void hci_discovery_set_state(struct hci_dev *hdev, int state)
 {
 {
+	int old_state = hdev->discovery.state;
+
 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
 
 
-	if (hdev->discovery.state == state)
+	if (old_state == state)
 		return;
 		return;
 
 
+	hdev->discovery.state = state;
+
 	switch (state) {
 	switch (state) {
 	case DISCOVERY_STOPPED:
 	case DISCOVERY_STOPPED:
 		hci_update_background_scan(hdev);
 		hci_update_background_scan(hdev);
 
 
-		if (hdev->discovery.state != DISCOVERY_STARTING)
+		if (old_state != DISCOVERY_STARTING)
 			mgmt_discovering(hdev, 0);
 			mgmt_discovering(hdev, 0);
 		break;
 		break;
 	case DISCOVERY_STARTING:
 	case DISCOVERY_STARTING:
@@ -1995,8 +1956,6 @@ void hci_discovery_set_state(struct hci_dev *hdev, int state)
 	case DISCOVERY_STOPPING:
 	case DISCOVERY_STOPPING:
 		break;
 		break;
 	}
 	}
-
-	hdev->discovery.state = state;
 }
 }
 
 
 void hci_inquiry_cache_flush(struct hci_dev *hdev)
 void hci_inquiry_cache_flush(struct hci_dev *hdev)
@@ -2083,22 +2042,24 @@ void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
 	list_add(&ie->list, pos);
 	list_add(&ie->list, pos);
 }
 }
 
 
-bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
-			      bool name_known, bool *ssp)
+u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
+			     bool name_known)
 {
 {
 	struct discovery_state *cache = &hdev->discovery;
 	struct discovery_state *cache = &hdev->discovery;
 	struct inquiry_entry *ie;
 	struct inquiry_entry *ie;
+	u32 flags = 0;
 
 
 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
 
 
 	hci_remove_remote_oob_data(hdev, &data->bdaddr);
 	hci_remove_remote_oob_data(hdev, &data->bdaddr);
 
 
-	*ssp = data->ssp_mode;
+	if (!data->ssp_mode)
+		flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
 
 
 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
 	if (ie) {
 	if (ie) {
-		if (ie->data.ssp_mode)
-			*ssp = true;
+		if (!ie->data.ssp_mode)
+			flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
 
 
 		if (ie->name_state == NAME_NEEDED &&
 		if (ie->name_state == NAME_NEEDED &&
 		    data->rssi != ie->data.rssi) {
 		    data->rssi != ie->data.rssi) {
@@ -2111,8 +2072,10 @@ bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
 
 
 	/* Entry not in the cache. Add new one. */
 	/* Entry not in the cache. Add new one. */
 	ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
 	ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
-	if (!ie)
-		return false;
+	if (!ie) {
+		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
+		goto done;
+	}
 
 
 	list_add(&ie->all, &cache->all);
 	list_add(&ie->all, &cache->all);
 
 
@@ -2135,9 +2098,10 @@ update:
 	cache->timestamp = jiffies;
 	cache->timestamp = jiffies;
 
 
 	if (ie->name_state == NAME_NOT_KNOWN)
 	if (ie->name_state == NAME_NOT_KNOWN)
-		return false;
+		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
 
 
-	return true;
+done:
+	return flags;
 }
 }
 
 
 static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
 static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
@@ -2213,6 +2177,11 @@ int hci_inquiry(void __user *arg)
 		goto done;
 		goto done;
 	}
 	}
 
 
+	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
+		err = -EOPNOTSUPP;
+		goto done;
+	}
+
 	if (hdev->dev_type != HCI_BREDR) {
 	if (hdev->dev_type != HCI_BREDR) {
 		err = -EOPNOTSUPP;
 		err = -EOPNOTSUPP;
 		goto done;
 		goto done;
@@ -2295,7 +2264,8 @@ static int hci_dev_do_open(struct hci_dev *hdev)
 		goto done;
 		goto done;
 	}
 	}
 
 
-	if (!test_bit(HCI_SETUP, &hdev->dev_flags)) {
+	if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
+	    !test_bit(HCI_CONFIG, &hdev->dev_flags)) {
 		/* Check for rfkill but allow the HCI setup stage to
 		/* Check for rfkill but allow the HCI setup stage to
 		 * proceed (which in itself doesn't cause any RF activity).
 		 * proceed (which in itself doesn't cause any RF activity).
 		 */
 		 */
@@ -2338,14 +2308,47 @@ static int hci_dev_do_open(struct hci_dev *hdev)
 	atomic_set(&hdev->cmd_cnt, 1);
 	atomic_set(&hdev->cmd_cnt, 1);
 	set_bit(HCI_INIT, &hdev->flags);
 	set_bit(HCI_INIT, &hdev->flags);
 
 
-	if (hdev->setup && test_bit(HCI_SETUP, &hdev->dev_flags))
-		ret = hdev->setup(hdev);
+	if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
+		if (hdev->setup)
+			ret = hdev->setup(hdev);
 
 
-	if (!ret) {
-		if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
-			set_bit(HCI_RAW, &hdev->flags);
+		/* The transport driver can set these quirks before
+		 * creating the HCI device or in its setup callback.
+		 *
+		 * In case any of them is set, the controller has to
+		 * start up as unconfigured.
+		 */
+		if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) ||
+		    test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks))
+			set_bit(HCI_UNCONFIGURED, &hdev->dev_flags);
 
 
-		if (!test_bit(HCI_RAW, &hdev->flags) &&
+		/* For an unconfigured controller it is required to
+		 * read at least the version information provided by
+		 * the Read Local Version Information command.
+		 *
+		 * If the set_bdaddr driver callback is provided, then
+		 * also the original Bluetooth public device address
+		 * will be read using the Read BD Address command.
+		 */
+		if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
+			ret = __hci_unconf_init(hdev);
+	}
+
+	if (test_bit(HCI_CONFIG, &hdev->dev_flags)) {
+		/* If public address change is configured, ensure that
+		 * the address gets programmed. If the driver does not
+		 * support changing the public address, fail the power
+		 * on procedure.
+		 */
+		if (bacmp(&hdev->public_addr, BDADDR_ANY) &&
+		    hdev->set_bdaddr)
+			ret = hdev->set_bdaddr(hdev, &hdev->public_addr);
+		else
+			ret = -EADDRNOTAVAIL;
+	}
+
+	if (!ret) {
+		if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) &&
 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
 			ret = __hci_init(hdev);
 			ret = __hci_init(hdev);
 	}
 	}
@@ -2358,6 +2361,8 @@ static int hci_dev_do_open(struct hci_dev *hdev)
 		set_bit(HCI_UP, &hdev->flags);
 		set_bit(HCI_UP, &hdev->flags);
 		hci_notify(hdev, HCI_DEV_UP);
 		hci_notify(hdev, HCI_DEV_UP);
 		if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
 		if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
+		    !test_bit(HCI_CONFIG, &hdev->dev_flags) &&
+		    !test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) &&
 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
 		    hdev->dev_type == HCI_BREDR) {
 		    hdev->dev_type == HCI_BREDR) {
 			hci_dev_lock(hdev);
 			hci_dev_lock(hdev);
@@ -2382,7 +2387,7 @@ static int hci_dev_do_open(struct hci_dev *hdev)
 		}
 		}
 
 
 		hdev->close(hdev);
 		hdev->close(hdev);
-		hdev->flags = 0;
+		hdev->flags &= BIT(HCI_RAW);
 	}
 	}
 
 
 done:
 done:
@@ -2401,6 +2406,21 @@ int hci_dev_open(__u16 dev)
 	if (!hdev)
 	if (!hdev)
 		return -ENODEV;
 		return -ENODEV;
 
 
+	/* Devices that are marked as unconfigured can only be powered
+	 * up as user channel. Trying to bring them up as normal devices
+	 * will result into a failure. Only user channel operation is
+	 * possible.
+	 *
+	 * When this function is called for a user channel, the flag
+	 * HCI_USER_CHANNEL will be set first before attempting to
+	 * open the device.
+	 */
+	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) &&
+	    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
+		err = -EOPNOTSUPP;
+		goto done;
+	}
+
 	/* We need to ensure that no other power on/off work is pending
 	/* We need to ensure that no other power on/off work is pending
 	 * before proceeding to call hci_dev_do_open. This is
 	 * before proceeding to call hci_dev_do_open. This is
 	 * particularly important if the setup procedure has not yet
 	 * particularly important if the setup procedure has not yet
@@ -2417,11 +2437,22 @@ int hci_dev_open(__u16 dev)
 
 
 	err = hci_dev_do_open(hdev);
 	err = hci_dev_do_open(hdev);
 
 
+done:
 	hci_dev_put(hdev);
 	hci_dev_put(hdev);
-
 	return err;
 	return err;
 }
 }
 
 
+/* This function requires the caller holds hdev->lock */
+static void hci_pend_le_actions_clear(struct hci_dev *hdev)
+{
+	struct hci_conn_params *p;
+
+	list_for_each_entry(p, &hdev->le_conn_params, list)
+		list_del_init(&p->action);
+
+	BT_DBG("All LE pending actions cleared");
+}
+
 static int hci_dev_do_close(struct hci_dev *hdev)
 static int hci_dev_do_close(struct hci_dev *hdev)
 {
 {
 	BT_DBG("%s %p", hdev->name, hdev);
 	BT_DBG("%s %p", hdev->name, hdev);
@@ -2432,7 +2463,7 @@ static int hci_dev_do_close(struct hci_dev *hdev)
 	hci_req_lock(hdev);
 	hci_req_lock(hdev);
 
 
 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
-		del_timer_sync(&hdev->cmd_timer);
+		cancel_delayed_work_sync(&hdev->cmd_timer);
 		hci_req_unlock(hdev);
 		hci_req_unlock(hdev);
 		return 0;
 		return 0;
 	}
 	}
@@ -2459,7 +2490,7 @@ static int hci_dev_do_close(struct hci_dev *hdev)
 	hci_dev_lock(hdev);
 	hci_dev_lock(hdev);
 	hci_inquiry_cache_flush(hdev);
 	hci_inquiry_cache_flush(hdev);
 	hci_conn_hash_flush(hdev);
 	hci_conn_hash_flush(hdev);
-	hci_pend_le_conns_clear(hdev);
+	hci_pend_le_actions_clear(hdev);
 	hci_dev_unlock(hdev);
 	hci_dev_unlock(hdev);
 
 
 	hci_notify(hdev, HCI_DEV_DOWN);
 	hci_notify(hdev, HCI_DEV_DOWN);
@@ -2470,8 +2501,8 @@ static int hci_dev_do_close(struct hci_dev *hdev)
 	/* Reset device */
 	/* Reset device */
 	skb_queue_purge(&hdev->cmd_q);
 	skb_queue_purge(&hdev->cmd_q);
 	atomic_set(&hdev->cmd_cnt, 1);
 	atomic_set(&hdev->cmd_cnt, 1);
-	if (!test_bit(HCI_RAW, &hdev->flags) &&
-	    !test_bit(HCI_AUTO_OFF, &hdev->dev_flags) &&
+	if (!test_bit(HCI_AUTO_OFF, &hdev->dev_flags) &&
+	    !test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) &&
 	    test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
 	    test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
 		set_bit(HCI_INIT, &hdev->flags);
 		set_bit(HCI_INIT, &hdev->flags);
 		__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
 		__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
@@ -2488,7 +2519,7 @@ static int hci_dev_do_close(struct hci_dev *hdev)
 
 
 	/* Drop last sent command */
 	/* Drop last sent command */
 	if (hdev->sent_cmd) {
 	if (hdev->sent_cmd) {
-		del_timer_sync(&hdev->cmd_timer);
+		cancel_delayed_work_sync(&hdev->cmd_timer);
 		kfree_skb(hdev->sent_cmd);
 		kfree_skb(hdev->sent_cmd);
 		hdev->sent_cmd = NULL;
 		hdev->sent_cmd = NULL;
 	}
 	}
@@ -2501,7 +2532,7 @@ static int hci_dev_do_close(struct hci_dev *hdev)
 	hdev->close(hdev);
 	hdev->close(hdev);
 
 
 	/* Clear flags */
 	/* Clear flags */
-	hdev->flags = 0;
+	hdev->flags &= BIT(HCI_RAW);
 	hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
 	hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
 
 
 	if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
 	if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
@@ -2570,6 +2601,11 @@ int hci_dev_reset(__u16 dev)
 		goto done;
 		goto done;
 	}
 	}
 
 
+	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
+		ret = -EOPNOTSUPP;
+		goto done;
+	}
+
 	/* Drop queues */
 	/* Drop queues */
 	skb_queue_purge(&hdev->rx_q);
 	skb_queue_purge(&hdev->rx_q);
 	skb_queue_purge(&hdev->cmd_q);
 	skb_queue_purge(&hdev->cmd_q);
@@ -2585,8 +2621,7 @@ int hci_dev_reset(__u16 dev)
 	atomic_set(&hdev->cmd_cnt, 1);
 	atomic_set(&hdev->cmd_cnt, 1);
 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
 
 
-	if (!test_bit(HCI_RAW, &hdev->flags))
-		ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
+	ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
 
 
 done:
 done:
 	hci_req_unlock(hdev);
 	hci_req_unlock(hdev);
@@ -2608,6 +2643,11 @@ int hci_dev_reset_stat(__u16 dev)
 		goto done;
 		goto done;
 	}
 	}
 
 
+	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
+		ret = -EOPNOTSUPP;
+		goto done;
+	}
+
 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
 
 
 done:
 done:
@@ -2633,6 +2673,11 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg)
 		goto done;
 		goto done;
 	}
 	}
 
 
+	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
+		err = -EOPNOTSUPP;
+		goto done;
+	}
+
 	if (hdev->dev_type != HCI_BREDR) {
 	if (hdev->dev_type != HCI_BREDR) {
 		err = -EOPNOTSUPP;
 		err = -EOPNOTSUPP;
 		goto done;
 		goto done;
@@ -2670,6 +2715,23 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg)
 	case HCISETSCAN:
 	case HCISETSCAN:
 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
 				   HCI_INIT_TIMEOUT);
 				   HCI_INIT_TIMEOUT);
+
+		/* Ensure that the connectable state gets correctly
+		 * notified if the whitelist is in use.
+		 */
+		if (!err && !list_empty(&hdev->whitelist)) {
+			bool changed;
+
+			if ((dr.dev_opt & SCAN_PAGE))
+				changed = !test_and_set_bit(HCI_CONNECTABLE,
+							    &hdev->dev_flags);
+			else
+				changed = test_and_set_bit(HCI_CONNECTABLE,
+							   &hdev->dev_flags);
+
+			if (changed)
+				mgmt_new_settings(hdev);
+		}
 		break;
 		break;
 
 
 	case HCISETLINKPOL:
 	case HCISETLINKPOL:
@@ -2815,7 +2877,8 @@ static int hci_rfkill_set_block(void *data, bool blocked)
 
 
 	if (blocked) {
 	if (blocked) {
 		set_bit(HCI_RFKILLED, &hdev->dev_flags);
 		set_bit(HCI_RFKILLED, &hdev->dev_flags);
-		if (!test_bit(HCI_SETUP, &hdev->dev_flags))
+		if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
+		    !test_bit(HCI_CONFIG, &hdev->dev_flags))
 			hci_dev_do_close(hdev);
 			hci_dev_do_close(hdev);
 	} else {
 	} else {
 		clear_bit(HCI_RFKILLED, &hdev->dev_flags);
 		clear_bit(HCI_RFKILLED, &hdev->dev_flags);
@@ -2846,6 +2909,7 @@ static void hci_power_on(struct work_struct *work)
 	 * valid, it is important to turn the device back off.
 	 * valid, it is important to turn the device back off.
 	 */
 	 */
 	if (test_bit(HCI_RFKILLED, &hdev->dev_flags) ||
 	if (test_bit(HCI_RFKILLED, &hdev->dev_flags) ||
+	    test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) ||
 	    (hdev->dev_type == HCI_BREDR &&
 	    (hdev->dev_type == HCI_BREDR &&
 	     !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
 	     !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
 	     !bacmp(&hdev->static_addr, BDADDR_ANY))) {
 	     !bacmp(&hdev->static_addr, BDADDR_ANY))) {
@@ -2856,8 +2920,34 @@ static void hci_power_on(struct work_struct *work)
 				   HCI_AUTO_OFF_TIMEOUT);
 				   HCI_AUTO_OFF_TIMEOUT);
 	}
 	}
 
 
-	if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags))
+	if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) {
+		/* For unconfigured devices, set the HCI_RAW flag
+		 * so that userspace can easily identify them.
+		 */
+		if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
+			set_bit(HCI_RAW, &hdev->flags);
+
+		/* For fully configured devices, this will send
+		 * the Index Added event. For unconfigured devices,
+		 * it will send Unconfigued Index Added event.
+		 *
+		 * Devices with HCI_QUIRK_RAW_DEVICE are ignored
+		 * and no event will be send.
+		 */
 		mgmt_index_added(hdev);
 		mgmt_index_added(hdev);
+	} else if (test_and_clear_bit(HCI_CONFIG, &hdev->dev_flags)) {
+		/* When the controller is now configured, then it
+		 * is important to clear the HCI_RAW flag.
+		 */
+		if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
+			clear_bit(HCI_RAW, &hdev->flags);
+
+		/* Powering on the controller with HCI_CONFIG set only
+		 * happens with the transition from unconfigured to
+		 * configured. This will send the Index Added event.
+		 */
+		mgmt_index_added(hdev);
+	}
 }
 }
 
 
 static void hci_power_off(struct work_struct *work)
 static void hci_power_off(struct work_struct *work)
@@ -2974,10 +3064,7 @@ static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
 
 
 static bool ltk_type_master(u8 type)
 static bool ltk_type_master(u8 type)
 {
 {
-	if (type == HCI_SMP_STK || type == HCI_SMP_LTK)
-		return true;
-
-	return false;
+	return (type == SMP_LTK);
 }
 }
 
 
 struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, __le64 rand,
 struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, __le64 rand,
@@ -3049,12 +3136,12 @@ struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
 	return NULL;
 	return NULL;
 }
 }
 
 
-int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
-		     bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
+struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn,
+				  bdaddr_t *bdaddr, u8 *val, u8 type,
+				  u8 pin_len, bool *persistent)
 {
 {
 	struct link_key *key, *old_key;
 	struct link_key *key, *old_key;
 	u8 old_key_type;
 	u8 old_key_type;
-	bool persistent;
 
 
 	old_key = hci_find_link_key(hdev, bdaddr);
 	old_key = hci_find_link_key(hdev, bdaddr);
 	if (old_key) {
 	if (old_key) {
@@ -3064,7 +3151,7 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
 		old_key_type = conn ? conn->key_type : 0xff;
 		old_key_type = conn ? conn->key_type : 0xff;
 		key = kzalloc(sizeof(*key), GFP_KERNEL);
 		key = kzalloc(sizeof(*key), GFP_KERNEL);
 		if (!key)
 		if (!key)
-			return -ENOMEM;
+			return NULL;
 		list_add(&key->list, &hdev->link_keys);
 		list_add(&key->list, &hdev->link_keys);
 	}
 	}
 
 
@@ -3089,17 +3176,11 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
 	else
 	else
 		key->type = type;
 		key->type = type;
 
 
-	if (!new_key)
-		return 0;
+	if (persistent)
+		*persistent = hci_persistent_key(hdev, conn, type,
+						 old_key_type);
 
 
-	persistent = hci_persistent_key(hdev, conn, type, old_key_type);
-
-	mgmt_new_link_key(hdev, key, persistent);
-
-	if (conn)
-		conn->flush_key = !persistent;
-
-	return 0;
+	return key;
 }
 }
 
 
 struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
 struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
@@ -3205,9 +3286,10 @@ void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type)
 }
 }
 
 
 /* HCI command timer function */
 /* HCI command timer function */
-static void hci_cmd_timeout(unsigned long arg)
+static void hci_cmd_timeout(struct work_struct *work)
 {
 {
-	struct hci_dev *hdev = (void *) arg;
+	struct hci_dev *hdev = container_of(work, struct hci_dev,
+					    cmd_timer.work);
 
 
 	if (hdev->sent_cmd) {
 	if (hdev->sent_cmd) {
 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
@@ -3313,12 +3395,12 @@ int hci_add_remote_oob_ext_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
 	return 0;
 	return 0;
 }
 }
 
 
-struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev,
+struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list,
 					 bdaddr_t *bdaddr, u8 type)
 					 bdaddr_t *bdaddr, u8 type)
 {
 {
 	struct bdaddr_list *b;
 	struct bdaddr_list *b;
 
 
-	list_for_each_entry(b, &hdev->blacklist, list) {
+	list_for_each_entry(b, bdaddr_list, list) {
 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
 			return b;
 			return b;
 	}
 	}
@@ -3326,11 +3408,11 @@ struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev,
 	return NULL;
 	return NULL;
 }
 }
 
 
-static void hci_blacklist_clear(struct hci_dev *hdev)
+void hci_bdaddr_list_clear(struct list_head *bdaddr_list)
 {
 {
 	struct list_head *p, *n;
 	struct list_head *p, *n;
 
 
-	list_for_each_safe(p, n, &hdev->blacklist) {
+	list_for_each_safe(p, n, bdaddr_list) {
 		struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list);
 		struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list);
 
 
 		list_del(p);
 		list_del(p);
@@ -3338,14 +3420,14 @@ static void hci_blacklist_clear(struct hci_dev *hdev)
 	}
 	}
 }
 }
 
 
-int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
+int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type)
 {
 {
 	struct bdaddr_list *entry;
 	struct bdaddr_list *entry;
 
 
 	if (!bacmp(bdaddr, BDADDR_ANY))
 	if (!bacmp(bdaddr, BDADDR_ANY))
 		return -EBADF;
 		return -EBADF;
 
 
-	if (hci_blacklist_lookup(hdev, bdaddr, type))
+	if (hci_bdaddr_list_lookup(list, bdaddr, type))
 		return -EEXIST;
 		return -EEXIST;
 
 
 	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
 	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
@@ -3355,82 +3437,21 @@ int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
 	bacpy(&entry->bdaddr, bdaddr);
 	bacpy(&entry->bdaddr, bdaddr);
 	entry->bdaddr_type = type;
 	entry->bdaddr_type = type;
 
 
-	list_add(&entry->list, &hdev->blacklist);
+	list_add(&entry->list, list);
 
 
-	return mgmt_device_blocked(hdev, bdaddr, type);
+	return 0;
 }
 }
 
 
-int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
+int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type)
 {
 {
 	struct bdaddr_list *entry;
 	struct bdaddr_list *entry;
 
 
 	if (!bacmp(bdaddr, BDADDR_ANY)) {
 	if (!bacmp(bdaddr, BDADDR_ANY)) {
-		hci_blacklist_clear(hdev);
+		hci_bdaddr_list_clear(list);
 		return 0;
 		return 0;
 	}
 	}
 
 
-	entry = hci_blacklist_lookup(hdev, bdaddr, type);
-	if (!entry)
-		return -ENOENT;
-
-	list_del(&entry->list);
-	kfree(entry);
-
-	return mgmt_device_unblocked(hdev, bdaddr, type);
-}
-
-struct bdaddr_list *hci_white_list_lookup(struct hci_dev *hdev,
-					  bdaddr_t *bdaddr, u8 type)
-{
-	struct bdaddr_list *b;
-
-	list_for_each_entry(b, &hdev->le_white_list, list) {
-		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
-			return b;
-	}
-
-	return NULL;
-}
-
-void hci_white_list_clear(struct hci_dev *hdev)
-{
-	struct list_head *p, *n;
-
-	list_for_each_safe(p, n, &hdev->le_white_list) {
-		struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list);
-
-		list_del(p);
-		kfree(b);
-	}
-}
-
-int hci_white_list_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
-{
-	struct bdaddr_list *entry;
-
-	if (!bacmp(bdaddr, BDADDR_ANY))
-		return -EBADF;
-
-	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
-	if (!entry)
-		return -ENOMEM;
-
-	bacpy(&entry->bdaddr, bdaddr);
-	entry->bdaddr_type = type;
-
-	list_add(&entry->list, &hdev->le_white_list);
-
-	return 0;
-}
-
-int hci_white_list_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
-{
-	struct bdaddr_list *entry;
-
-	if (!bacmp(bdaddr, BDADDR_ANY))
-		return -EBADF;
-
-	entry = hci_white_list_lookup(hdev, bdaddr, type);
+	entry = hci_bdaddr_list_lookup(list, bdaddr, type);
 	if (!entry)
 	if (!entry)
 		return -ENOENT;
 		return -ENOENT;
 
 
@@ -3446,6 +3467,10 @@ struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
 {
 {
 	struct hci_conn_params *params;
 	struct hci_conn_params *params;
 
 
+	/* The conn params list only contains identity addresses */
+	if (!hci_is_identity_address(addr, addr_type))
+		return NULL;
+
 	list_for_each_entry(params, &hdev->le_conn_params, list) {
 	list_for_each_entry(params, &hdev->le_conn_params, list) {
 		if (bacmp(&params->addr, addr) == 0 &&
 		if (bacmp(&params->addr, addr) == 0 &&
 		    params->addr_type == addr_type) {
 		    params->addr_type == addr_type) {
@@ -3473,62 +3498,97 @@ static bool is_connected(struct hci_dev *hdev, bdaddr_t *addr, u8 type)
 	return true;
 	return true;
 }
 }
 
 
-static bool is_identity_address(bdaddr_t *addr, u8 addr_type)
+/* This function requires the caller holds hdev->lock */
+struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list,
+						  bdaddr_t *addr, u8 addr_type)
 {
 {
-	if (addr_type == ADDR_LE_DEV_PUBLIC)
-		return true;
+	struct hci_conn_params *param;
 
 
-	/* Check for Random Static address type */
-	if ((addr->b[5] & 0xc0) == 0xc0)
-		return true;
+	/* The list only contains identity addresses */
+	if (!hci_is_identity_address(addr, addr_type))
+		return NULL;
 
 
-	return false;
+	list_for_each_entry(param, list, action) {
+		if (bacmp(&param->addr, addr) == 0 &&
+		    param->addr_type == addr_type)
+			return param;
+	}
+
+	return NULL;
 }
 }
 
 
 /* This function requires the caller holds hdev->lock */
 /* This function requires the caller holds hdev->lock */
-int hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
-			u8 auto_connect, u16 conn_min_interval,
-			u16 conn_max_interval)
+struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev,
+					    bdaddr_t *addr, u8 addr_type)
 {
 {
 	struct hci_conn_params *params;
 	struct hci_conn_params *params;
 
 
-	if (!is_identity_address(addr, addr_type))
-		return -EINVAL;
+	if (!hci_is_identity_address(addr, addr_type))
+		return NULL;
 
 
 	params = hci_conn_params_lookup(hdev, addr, addr_type);
 	params = hci_conn_params_lookup(hdev, addr, addr_type);
 	if (params)
 	if (params)
-		goto update;
+		return params;
 
 
 	params = kzalloc(sizeof(*params), GFP_KERNEL);
 	params = kzalloc(sizeof(*params), GFP_KERNEL);
 	if (!params) {
 	if (!params) {
 		BT_ERR("Out of memory");
 		BT_ERR("Out of memory");
-		return -ENOMEM;
+		return NULL;
 	}
 	}
 
 
 	bacpy(&params->addr, addr);
 	bacpy(&params->addr, addr);
 	params->addr_type = addr_type;
 	params->addr_type = addr_type;
 
 
 	list_add(&params->list, &hdev->le_conn_params);
 	list_add(&params->list, &hdev->le_conn_params);
+	INIT_LIST_HEAD(&params->action);
 
 
-update:
-	params->conn_min_interval = conn_min_interval;
-	params->conn_max_interval = conn_max_interval;
-	params->auto_connect = auto_connect;
+	params->conn_min_interval = hdev->le_conn_min_interval;
+	params->conn_max_interval = hdev->le_conn_max_interval;
+	params->conn_latency = hdev->le_conn_latency;
+	params->supervision_timeout = hdev->le_supv_timeout;
+	params->auto_connect = HCI_AUTO_CONN_DISABLED;
+
+	BT_DBG("addr %pMR (type %u)", addr, addr_type);
+
+	return params;
+}
+
+/* This function requires the caller holds hdev->lock */
+int hci_conn_params_set(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
+			u8 auto_connect)
+{
+	struct hci_conn_params *params;
+
+	params = hci_conn_params_add(hdev, addr, addr_type);
+	if (!params)
+		return -EIO;
+
+	if (params->auto_connect == auto_connect)
+		return 0;
+
+	list_del_init(&params->action);
 
 
 	switch (auto_connect) {
 	switch (auto_connect) {
 	case HCI_AUTO_CONN_DISABLED:
 	case HCI_AUTO_CONN_DISABLED:
 	case HCI_AUTO_CONN_LINK_LOSS:
 	case HCI_AUTO_CONN_LINK_LOSS:
-		hci_pend_le_conn_del(hdev, addr, addr_type);
+		hci_update_background_scan(hdev);
+		break;
+	case HCI_AUTO_CONN_REPORT:
+		list_add(&params->action, &hdev->pend_le_reports);
+		hci_update_background_scan(hdev);
 		break;
 		break;
 	case HCI_AUTO_CONN_ALWAYS:
 	case HCI_AUTO_CONN_ALWAYS:
-		if (!is_connected(hdev, addr, addr_type))
-			hci_pend_le_conn_add(hdev, addr, addr_type);
+		if (!is_connected(hdev, addr, addr_type)) {
+			list_add(&params->action, &hdev->pend_le_conns);
+			hci_update_background_scan(hdev);
+		}
 		break;
 		break;
 	}
 	}
 
 
-	BT_DBG("addr %pMR (type %u) auto_connect %u conn_min_interval 0x%.4x "
-	       "conn_max_interval 0x%.4x", addr, addr_type, auto_connect,
-	       conn_min_interval, conn_max_interval);
+	params->auto_connect = auto_connect;
+
+	BT_DBG("addr %pMR (type %u) auto_connect %u", addr, addr_type,
+	       auto_connect);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -3542,97 +3602,44 @@ void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
 	if (!params)
 	if (!params)
 		return;
 		return;
 
 
-	hci_pend_le_conn_del(hdev, addr, addr_type);
-
+	list_del(&params->action);
 	list_del(&params->list);
 	list_del(&params->list);
 	kfree(params);
 	kfree(params);
 
 
+	hci_update_background_scan(hdev);
+
 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
 }
 }
 
 
 /* This function requires the caller holds hdev->lock */
 /* This function requires the caller holds hdev->lock */
-void hci_conn_params_clear(struct hci_dev *hdev)
+void hci_conn_params_clear_disabled(struct hci_dev *hdev)
 {
 {
 	struct hci_conn_params *params, *tmp;
 	struct hci_conn_params *params, *tmp;
 
 
 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
+		if (params->auto_connect != HCI_AUTO_CONN_DISABLED)
+			continue;
 		list_del(&params->list);
 		list_del(&params->list);
 		kfree(params);
 		kfree(params);
 	}
 	}
 
 
-	BT_DBG("All LE connection parameters were removed");
+	BT_DBG("All LE disabled connection parameters were removed");
 }
 }
 
 
 /* This function requires the caller holds hdev->lock */
 /* This function requires the caller holds hdev->lock */
-struct bdaddr_list *hci_pend_le_conn_lookup(struct hci_dev *hdev,
-					    bdaddr_t *addr, u8 addr_type)
+void hci_conn_params_clear_all(struct hci_dev *hdev)
 {
 {
-	struct bdaddr_list *entry;
-
-	list_for_each_entry(entry, &hdev->pend_le_conns, list) {
-		if (bacmp(&entry->bdaddr, addr) == 0 &&
-		    entry->bdaddr_type == addr_type)
-			return entry;
-	}
-
-	return NULL;
-}
-
-/* This function requires the caller holds hdev->lock */
-void hci_pend_le_conn_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
-{
-	struct bdaddr_list *entry;
-
-	entry = hci_pend_le_conn_lookup(hdev, addr, addr_type);
-	if (entry)
-		goto done;
+	struct hci_conn_params *params, *tmp;
 
 
-	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
-	if (!entry) {
-		BT_ERR("Out of memory");
-		return;
+	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
+		list_del(&params->action);
+		list_del(&params->list);
+		kfree(params);
 	}
 	}
 
 
-	bacpy(&entry->bdaddr, addr);
-	entry->bdaddr_type = addr_type;
-
-	list_add(&entry->list, &hdev->pend_le_conns);
-
-	BT_DBG("addr %pMR (type %u)", addr, addr_type);
-
-done:
 	hci_update_background_scan(hdev);
 	hci_update_background_scan(hdev);
-}
 
 
-/* This function requires the caller holds hdev->lock */
-void hci_pend_le_conn_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
-{
-	struct bdaddr_list *entry;
-
-	entry = hci_pend_le_conn_lookup(hdev, addr, addr_type);
-	if (!entry)
-		goto done;
-
-	list_del(&entry->list);
-	kfree(entry);
-
-	BT_DBG("addr %pMR (type %u)", addr, addr_type);
-
-done:
-	hci_update_background_scan(hdev);
-}
-
-/* This function requires the caller holds hdev->lock */
-void hci_pend_le_conns_clear(struct hci_dev *hdev)
-{
-	struct bdaddr_list *entry, *tmp;
-
-	list_for_each_entry_safe(entry, tmp, &hdev->pend_le_conns, list) {
-		list_del(&entry->list);
-		kfree(entry);
-	}
-
-	BT_DBG("All LE pending connections cleared");
+	BT_DBG("All LE connection parameters were removed");
 }
 }
 
 
 static void inquiry_complete(struct hci_dev *hdev, u8 status)
 static void inquiry_complete(struct hci_dev *hdev, u8 status)
@@ -3722,7 +3729,7 @@ static void set_random_addr(struct hci_request *req, bdaddr_t *rpa)
 	 * In this kind of scenario skip the update and let the random
 	 * In this kind of scenario skip the update and let the random
 	 * address be updated at the next cycle.
 	 * address be updated at the next cycle.
 	 */
 	 */
-	if (test_bit(HCI_ADVERTISING, &hdev->dev_flags) ||
+	if (test_bit(HCI_LE_ADV, &hdev->dev_flags) ||
 	    hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT)) {
 	    hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT)) {
 		BT_DBG("Deferring random address update");
 		BT_DBG("Deferring random address update");
 		return;
 		return;
@@ -3784,7 +3791,7 @@ int hci_update_random_address(struct hci_request *req, bool require_privacy,
 	 * the HCI command if the current random address is already the
 	 * the HCI command if the current random address is already the
 	 * static one.
 	 * static one.
 	 */
 	 */
-	if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags) ||
+	if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) ||
 	    !bacmp(&hdev->bdaddr, BDADDR_ANY)) {
 	    !bacmp(&hdev->bdaddr, BDADDR_ANY)) {
 		*own_addr_type = ADDR_LE_DEV_RANDOM;
 		*own_addr_type = ADDR_LE_DEV_RANDOM;
 		if (bacmp(&hdev->static_addr, &hdev->random_addr))
 		if (bacmp(&hdev->static_addr, &hdev->random_addr))
@@ -3813,7 +3820,7 @@ int hci_update_random_address(struct hci_request *req, bool require_privacy,
 void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
 void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
 			       u8 *bdaddr_type)
 			       u8 *bdaddr_type)
 {
 {
-	if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags) ||
+	if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) ||
 	    !bacmp(&hdev->bdaddr, BDADDR_ANY)) {
 	    !bacmp(&hdev->bdaddr, BDADDR_ANY)) {
 		bacpy(bdaddr, &hdev->static_addr);
 		bacpy(bdaddr, &hdev->static_addr);
 		*bdaddr_type = ADDR_LE_DEV_RANDOM;
 		*bdaddr_type = ADDR_LE_DEV_RANDOM;
@@ -3837,6 +3844,7 @@ struct hci_dev *hci_alloc_dev(void)
 	hdev->link_mode = (HCI_LM_ACCEPT);
 	hdev->link_mode = (HCI_LM_ACCEPT);
 	hdev->num_iac = 0x01;		/* One IAC support is mandatory */
 	hdev->num_iac = 0x01;		/* One IAC support is mandatory */
 	hdev->io_capability = 0x03;	/* No Input No Output */
 	hdev->io_capability = 0x03;	/* No Input No Output */
+	hdev->manufacturer = 0xffff;	/* Default to internal use */
 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
 
 
@@ -3848,6 +3856,8 @@ struct hci_dev *hci_alloc_dev(void)
 	hdev->le_scan_window = 0x0030;
 	hdev->le_scan_window = 0x0030;
 	hdev->le_conn_min_interval = 0x0028;
 	hdev->le_conn_min_interval = 0x0028;
 	hdev->le_conn_max_interval = 0x0038;
 	hdev->le_conn_max_interval = 0x0038;
+	hdev->le_conn_latency = 0x0000;
+	hdev->le_supv_timeout = 0x002a;
 
 
 	hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT;
 	hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT;
 	hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT;
 	hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT;
@@ -3859,6 +3869,7 @@ struct hci_dev *hci_alloc_dev(void)
 
 
 	INIT_LIST_HEAD(&hdev->mgmt_pending);
 	INIT_LIST_HEAD(&hdev->mgmt_pending);
 	INIT_LIST_HEAD(&hdev->blacklist);
 	INIT_LIST_HEAD(&hdev->blacklist);
+	INIT_LIST_HEAD(&hdev->whitelist);
 	INIT_LIST_HEAD(&hdev->uuids);
 	INIT_LIST_HEAD(&hdev->uuids);
 	INIT_LIST_HEAD(&hdev->link_keys);
 	INIT_LIST_HEAD(&hdev->link_keys);
 	INIT_LIST_HEAD(&hdev->long_term_keys);
 	INIT_LIST_HEAD(&hdev->long_term_keys);
@@ -3867,6 +3878,7 @@ struct hci_dev *hci_alloc_dev(void)
 	INIT_LIST_HEAD(&hdev->le_white_list);
 	INIT_LIST_HEAD(&hdev->le_white_list);
 	INIT_LIST_HEAD(&hdev->le_conn_params);
 	INIT_LIST_HEAD(&hdev->le_conn_params);
 	INIT_LIST_HEAD(&hdev->pend_le_conns);
 	INIT_LIST_HEAD(&hdev->pend_le_conns);
+	INIT_LIST_HEAD(&hdev->pend_le_reports);
 	INIT_LIST_HEAD(&hdev->conn_hash.list);
 	INIT_LIST_HEAD(&hdev->conn_hash.list);
 
 
 	INIT_WORK(&hdev->rx_work, hci_rx_work);
 	INIT_WORK(&hdev->rx_work, hci_rx_work);
@@ -3884,7 +3896,7 @@ struct hci_dev *hci_alloc_dev(void)
 
 
 	init_waitqueue_head(&hdev->req_wait_q);
 	init_waitqueue_head(&hdev->req_wait_q);
 
 
-	setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev);
+	INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout);
 
 
 	hci_init_sysfs(hdev);
 	hci_init_sysfs(hdev);
 	discovery_init(hdev);
 	discovery_init(hdev);
@@ -3906,7 +3918,7 @@ int hci_register_dev(struct hci_dev *hdev)
 {
 {
 	int id, error;
 	int id, error;
 
 
-	if (!hdev->open || !hdev->close)
+	if (!hdev->open || !hdev->close || !hdev->send)
 		return -EINVAL;
 		return -EINVAL;
 
 
 	/* Do not allow HCI_AMP devices to register at index 0,
 	/* Do not allow HCI_AMP devices to register at index 0,
@@ -3991,6 +4003,12 @@ int hci_register_dev(struct hci_dev *hdev)
 	list_add(&hdev->list, &hci_dev_list);
 	list_add(&hdev->list, &hci_dev_list);
 	write_unlock(&hci_dev_list_lock);
 	write_unlock(&hci_dev_list_lock);
 
 
+	/* Devices that are marked for raw-only usage are unconfigured
+	 * and should not be included in normal operation.
+	 */
+	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
+		set_bit(HCI_UNCONFIGURED, &hdev->dev_flags);
+
 	hci_notify(hdev, HCI_DEV_REG);
 	hci_notify(hdev, HCI_DEV_REG);
 	hci_dev_hold(hdev);
 	hci_dev_hold(hdev);
 
 
@@ -4033,7 +4051,8 @@ void hci_unregister_dev(struct hci_dev *hdev)
 	cancel_work_sync(&hdev->power_on);
 	cancel_work_sync(&hdev->power_on);
 
 
 	if (!test_bit(HCI_INIT, &hdev->flags) &&
 	if (!test_bit(HCI_INIT, &hdev->flags) &&
-	    !test_bit(HCI_SETUP, &hdev->dev_flags)) {
+	    !test_bit(HCI_SETUP, &hdev->dev_flags) &&
+	    !test_bit(HCI_CONFIG, &hdev->dev_flags)) {
 		hci_dev_lock(hdev);
 		hci_dev_lock(hdev);
 		mgmt_index_removed(hdev);
 		mgmt_index_removed(hdev);
 		hci_dev_unlock(hdev);
 		hci_dev_unlock(hdev);
@@ -4061,15 +4080,15 @@ void hci_unregister_dev(struct hci_dev *hdev)
 	destroy_workqueue(hdev->req_workqueue);
 	destroy_workqueue(hdev->req_workqueue);
 
 
 	hci_dev_lock(hdev);
 	hci_dev_lock(hdev);
-	hci_blacklist_clear(hdev);
+	hci_bdaddr_list_clear(&hdev->blacklist);
+	hci_bdaddr_list_clear(&hdev->whitelist);
 	hci_uuids_clear(hdev);
 	hci_uuids_clear(hdev);
 	hci_link_keys_clear(hdev);
 	hci_link_keys_clear(hdev);
 	hci_smp_ltks_clear(hdev);
 	hci_smp_ltks_clear(hdev);
 	hci_smp_irks_clear(hdev);
 	hci_smp_irks_clear(hdev);
 	hci_remote_oob_data_clear(hdev);
 	hci_remote_oob_data_clear(hdev);
-	hci_white_list_clear(hdev);
-	hci_conn_params_clear(hdev);
-	hci_pend_le_conns_clear(hdev);
+	hci_bdaddr_list_clear(&hdev->le_white_list);
+	hci_conn_params_clear_all(hdev);
 	hci_dev_unlock(hdev);
 	hci_dev_unlock(hdev);
 
 
 	hci_dev_put(hdev);
 	hci_dev_put(hdev);
@@ -4307,6 +4326,8 @@ EXPORT_SYMBOL(hci_unregister_cb);
 
 
 static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
 {
+	int err;
+
 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
 
 
 	/* Time stamp */
 	/* Time stamp */
@@ -4323,8 +4344,11 @@ static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 	/* Get rid of skb owner, prior to sending to the driver. */
 	/* Get rid of skb owner, prior to sending to the driver. */
 	skb_orphan(skb);
 	skb_orphan(skb);
 
 
-	if (hdev->send(hdev, skb) < 0)
-		BT_ERR("%s sending frame failed", hdev->name);
+	err = hdev->send(hdev, skb);
+	if (err < 0) {
+		BT_ERR("%s sending frame failed (%d)", hdev->name, err);
+		kfree_skb(skb);
+	}
 }
 }
 
 
 void hci_req_init(struct hci_request *req, struct hci_dev *hdev)
 void hci_req_init(struct hci_request *req, struct hci_dev *hdev)
@@ -4798,7 +4822,7 @@ static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
 
 
 static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
 static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
 {
 {
-	if (!test_bit(HCI_RAW, &hdev->flags)) {
+	if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
 		/* ACL tx timeout must be longer than maximum
 		/* ACL tx timeout must be longer than maximum
 		 * link supervision timeout (40.9 seconds) */
 		 * link supervision timeout (40.9 seconds) */
 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
@@ -4981,7 +5005,7 @@ static void hci_sched_le(struct hci_dev *hdev)
 	if (!hci_conn_num(hdev, LE_LINK))
 	if (!hci_conn_num(hdev, LE_LINK))
 		return;
 		return;
 
 
-	if (!test_bit(HCI_RAW, &hdev->flags)) {
+	if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
 		/* LE tx timeout must be longer than maximum
 		/* LE tx timeout must be longer than maximum
 		 * link supervision timeout (40.9 seconds) */
 		 * link supervision timeout (40.9 seconds) */
 		if (!hdev->le_cnt && hdev->le_pkts &&
 		if (!hdev->le_cnt && hdev->le_pkts &&
@@ -5226,8 +5250,7 @@ static void hci_rx_work(struct work_struct *work)
 			hci_send_to_sock(hdev, skb);
 			hci_send_to_sock(hdev, skb);
 		}
 		}
 
 
-		if (test_bit(HCI_RAW, &hdev->flags) ||
-		    test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
+		if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
 			kfree_skb(skb);
 			kfree_skb(skb);
 			continue;
 			continue;
 		}
 		}
@@ -5287,10 +5310,10 @@ static void hci_cmd_work(struct work_struct *work)
 			atomic_dec(&hdev->cmd_cnt);
 			atomic_dec(&hdev->cmd_cnt);
 			hci_send_frame(hdev, skb);
 			hci_send_frame(hdev, skb);
 			if (test_bit(HCI_RESET, &hdev->flags))
 			if (test_bit(HCI_RESET, &hdev->flags))
-				del_timer(&hdev->cmd_timer);
+				cancel_delayed_work(&hdev->cmd_timer);
 			else
 			else
-				mod_timer(&hdev->cmd_timer,
-					  jiffies + HCI_CMD_TIMEOUT);
+				schedule_delayed_work(&hdev->cmd_timer,
+						      HCI_CMD_TIMEOUT);
 		} else {
 		} else {
 			skb_queue_head(&hdev->cmd_q, skb);
 			skb_queue_head(&hdev->cmd_q, skb);
 			queue_work(hdev->workqueue, &hdev->cmd_work);
 			queue_work(hdev->workqueue, &hdev->cmd_work);
@@ -5314,12 +5337,13 @@ void hci_req_add_le_passive_scan(struct hci_request *req)
 	struct hci_dev *hdev = req->hdev;
 	struct hci_dev *hdev = req->hdev;
 	u8 own_addr_type;
 	u8 own_addr_type;
 
 
-	/* Set require_privacy to true to avoid identification from
-	 * unknown peer devices. Since this is passive scanning, no
-	 * SCAN_REQ using the local identity should be sent. Mandating
-	 * privacy is just an extra precaution.
+	/* Set require_privacy to false since no SCAN_REQ are send
+	 * during passive scanning. Not using an unresolvable address
+	 * here is important so that peer devices using direct
+	 * advertising with our address will be correctly reported
+	 * by the controller.
 	 */
 	 */
-	if (hci_update_random_address(req, true, &own_addr_type))
+	if (hci_update_random_address(req, false, &own_addr_type))
 		return;
 		return;
 
 
 	memset(&param_cp, 0, sizeof(param_cp));
 	memset(&param_cp, 0, sizeof(param_cp));
@@ -5356,11 +5380,30 @@ void hci_update_background_scan(struct hci_dev *hdev)
 	struct hci_conn *conn;
 	struct hci_conn *conn;
 	int err;
 	int err;
 
 
+	if (!test_bit(HCI_UP, &hdev->flags) ||
+	    test_bit(HCI_INIT, &hdev->flags) ||
+	    test_bit(HCI_SETUP, &hdev->dev_flags) ||
+	    test_bit(HCI_CONFIG, &hdev->dev_flags) ||
+	    test_bit(HCI_AUTO_OFF, &hdev->dev_flags) ||
+	    test_bit(HCI_UNREGISTER, &hdev->dev_flags))
+		return;
+
+	/* No point in doing scanning if LE support hasn't been enabled */
+	if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags))
+		return;
+
+	/* If discovery is active don't interfere with it */
+	if (hdev->discovery.state != DISCOVERY_STOPPED)
+		return;
+
 	hci_req_init(&req, hdev);
 	hci_req_init(&req, hdev);
 
 
-	if (list_empty(&hdev->pend_le_conns)) {
-		/* If there is no pending LE connections, we should stop
-		 * the background scanning.
+	if (!test_bit(HCI_CONNECTABLE, &hdev->dev_flags) &&
+	    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 controller is not scanning we are done. */

+ 515 - 183
net/bluetooth/hci_event.c

@@ -32,6 +32,7 @@
 
 
 #include "a2mp.h"
 #include "a2mp.h"
 #include "amp.h"
 #include "amp.h"
+#include "smp.h"
 
 
 /* Handle HCI Event packets */
 /* Handle HCI Event packets */
 
 
@@ -102,9 +103,9 @@ static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
 	if (conn) {
 	if (conn) {
 		if (rp->role)
 		if (rp->role)
-			conn->link_mode &= ~HCI_LM_MASTER;
+			clear_bit(HCI_CONN_MASTER, &conn->flags);
 		else
 		else
-			conn->link_mode |= HCI_LM_MASTER;
+			set_bit(HCI_CONN_MASTER, &conn->flags);
 	}
 	}
 
 
 	hci_dev_unlock(hdev);
 	hci_dev_unlock(hdev);
@@ -174,12 +175,14 @@ static void hci_cc_write_def_link_policy(struct hci_dev *hdev,
 
 
 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
 
 
+	if (status)
+		return;
+
 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
 	if (!sent)
 	if (!sent)
 		return;
 		return;
 
 
-	if (!status)
-		hdev->link_policy = get_unaligned_le16(sent);
+	hdev->link_policy = get_unaligned_le16(sent);
 }
 }
 
 
 static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
 static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
@@ -269,27 +272,30 @@ static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
 static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
 static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
 {
 {
 	__u8 status = *((__u8 *) skb->data);
 	__u8 status = *((__u8 *) skb->data);
+	__u8 param;
 	void *sent;
 	void *sent;
 
 
 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
 
 
+	if (status)
+		return;
+
 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
 	if (!sent)
 	if (!sent)
 		return;
 		return;
 
 
-	if (!status) {
-		__u8 param = *((__u8 *) sent);
+	param = *((__u8 *) sent);
 
 
-		if (param)
-			set_bit(HCI_ENCRYPT, &hdev->flags);
-		else
-			clear_bit(HCI_ENCRYPT, &hdev->flags);
-	}
+	if (param)
+		set_bit(HCI_ENCRYPT, &hdev->flags);
+	else
+		clear_bit(HCI_ENCRYPT, &hdev->flags);
 }
 }
 
 
 static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
 static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
 {
 {
-	__u8 param, status = *((__u8 *) skb->data);
+	__u8 status = *((__u8 *) skb->data);
+	__u8 param;
 	int old_pscan, old_iscan;
 	int old_pscan, old_iscan;
 	void *sent;
 	void *sent;
 
 
@@ -601,8 +607,10 @@ static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
 
 
 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
 
 
-	if (!rp->status)
-		hdev->flow_ctl_mode = rp->mode;
+	if (rp->status)
+		return;
+
+	hdev->flow_ctl_mode = rp->mode;
 }
 }
 
 
 static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
 static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
@@ -637,8 +645,14 @@ static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
 
 
 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
 
 
-	if (!rp->status)
+	if (rp->status)
+		return;
+
+	if (test_bit(HCI_INIT, &hdev->flags))
 		bacpy(&hdev->bdaddr, &rp->bdaddr);
 		bacpy(&hdev->bdaddr, &rp->bdaddr);
+
+	if (test_bit(HCI_SETUP, &hdev->dev_flags))
+		bacpy(&hdev->setup_addr, &rp->bdaddr);
 }
 }
 
 
 static void hci_cc_read_page_scan_activity(struct hci_dev *hdev,
 static void hci_cc_read_page_scan_activity(struct hci_dev *hdev,
@@ -648,7 +662,10 @@ static void hci_cc_read_page_scan_activity(struct hci_dev *hdev,
 
 
 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
 
 
-	if (test_bit(HCI_INIT, &hdev->flags) && !rp->status) {
+	if (rp->status)
+		return;
+
+	if (test_bit(HCI_INIT, &hdev->flags)) {
 		hdev->page_scan_interval = __le16_to_cpu(rp->interval);
 		hdev->page_scan_interval = __le16_to_cpu(rp->interval);
 		hdev->page_scan_window = __le16_to_cpu(rp->window);
 		hdev->page_scan_window = __le16_to_cpu(rp->window);
 	}
 	}
@@ -680,7 +697,10 @@ static void hci_cc_read_page_scan_type(struct hci_dev *hdev,
 
 
 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
 
 
-	if (test_bit(HCI_INIT, &hdev->flags) && !rp->status)
+	if (rp->status)
+		return;
+
+	if (test_bit(HCI_INIT, &hdev->flags))
 		hdev->page_scan_type = rp->type;
 		hdev->page_scan_type = rp->type;
 }
 }
 
 
@@ -720,6 +740,41 @@ static void hci_cc_read_data_block_size(struct hci_dev *hdev,
 	       hdev->block_cnt, hdev->block_len);
 	       hdev->block_cnt, hdev->block_len);
 }
 }
 
 
+static void hci_cc_read_clock(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_rp_read_clock *rp = (void *) skb->data;
+	struct hci_cp_read_clock *cp;
+	struct hci_conn *conn;
+
+	BT_DBG("%s", hdev->name);
+
+	if (skb->len < sizeof(*rp))
+		return;
+
+	if (rp->status)
+		return;
+
+	hci_dev_lock(hdev);
+
+	cp = hci_sent_cmd_data(hdev, HCI_OP_READ_CLOCK);
+	if (!cp)
+		goto unlock;
+
+	if (cp->which == 0x00) {
+		hdev->clock = le32_to_cpu(rp->clock);
+		goto unlock;
+	}
+
+	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
+	if (conn) {
+		conn->clock = le32_to_cpu(rp->clock);
+		conn->clock_accuracy = le16_to_cpu(rp->accuracy);
+	}
+
+unlock:
+	hci_dev_unlock(hdev);
+}
+
 static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
 static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
 				       struct sk_buff *skb)
 				       struct sk_buff *skb)
 {
 {
@@ -789,8 +844,10 @@ static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
 
 
 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
 
 
-	if (!rp->status)
-		hdev->inq_tx_power = rp->tx_power;
+	if (rp->status)
+		return;
+
+	hdev->inq_tx_power = rp->tx_power;
 }
 }
 
 
 static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
 static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
@@ -861,8 +918,10 @@ static void hci_cc_le_read_local_features(struct hci_dev *hdev,
 
 
 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
 
 
-	if (!rp->status)
-		memcpy(hdev->le_features, rp->features, 8);
+	if (rp->status)
+		return;
+
+	memcpy(hdev->le_features, rp->features, 8);
 }
 }
 
 
 static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
 static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
@@ -872,8 +931,10 @@ static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
 
 
 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
 
 
-	if (!rp->status)
-		hdev->adv_tx_power = rp->tx_power;
+	if (rp->status)
+		return;
+
+	hdev->adv_tx_power = rp->tx_power;
 }
 }
 
 
 static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
 static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
@@ -973,14 +1034,16 @@ static void hci_cc_le_set_random_addr(struct hci_dev *hdev, struct sk_buff *skb)
 
 
 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
 
 
+	if (status)
+		return;
+
 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_RANDOM_ADDR);
 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_RANDOM_ADDR);
 	if (!sent)
 	if (!sent)
 		return;
 		return;
 
 
 	hci_dev_lock(hdev);
 	hci_dev_lock(hdev);
 
 
-	if (!status)
-		bacpy(&hdev->random_addr, sent);
+	bacpy(&hdev->random_addr, sent);
 
 
 	hci_dev_unlock(hdev);
 	hci_dev_unlock(hdev);
 }
 }
@@ -991,11 +1054,11 @@ static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
 
 
 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
 
 
-	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
-	if (!sent)
+	if (status)
 		return;
 		return;
 
 
-	if (status)
+	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
+	if (!sent)
 		return;
 		return;
 
 
 	hci_dev_lock(hdev);
 	hci_dev_lock(hdev);
@@ -1006,15 +1069,17 @@ static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
 	if (*sent) {
 	if (*sent) {
 		struct hci_conn *conn;
 		struct hci_conn *conn;
 
 
+		set_bit(HCI_LE_ADV, &hdev->dev_flags);
+
 		conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
 		conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
 		if (conn)
 		if (conn)
 			queue_delayed_work(hdev->workqueue,
 			queue_delayed_work(hdev->workqueue,
 					   &conn->le_conn_timeout,
 					   &conn->le_conn_timeout,
-					   HCI_LE_CONN_TIMEOUT);
+					   conn->conn_timeout);
+	} else {
+		clear_bit(HCI_LE_ADV, &hdev->dev_flags);
 	}
 	}
 
 
-	mgmt_advertising(hdev, *sent);
-
 	hci_dev_unlock(hdev);
 	hci_dev_unlock(hdev);
 }
 }
 
 
@@ -1025,14 +1090,16 @@ static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
 
 
 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
 
 
+	if (status)
+		return;
+
 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_PARAM);
 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_PARAM);
 	if (!cp)
 	if (!cp)
 		return;
 		return;
 
 
 	hci_dev_lock(hdev);
 	hci_dev_lock(hdev);
 
 
-	if (!status)
-		hdev->le_scan_type = cp->type;
+	hdev->le_scan_type = cp->type;
 
 
 	hci_dev_unlock(hdev);
 	hci_dev_unlock(hdev);
 }
 }
@@ -1053,13 +1120,15 @@ static void clear_pending_adv_report(struct hci_dev *hdev)
 }
 }
 
 
 static void store_pending_adv_report(struct hci_dev *hdev, bdaddr_t *bdaddr,
 static void store_pending_adv_report(struct hci_dev *hdev, bdaddr_t *bdaddr,
-				     u8 bdaddr_type, s8 rssi, u8 *data, u8 len)
+				     u8 bdaddr_type, s8 rssi, u32 flags,
+				     u8 *data, u8 len)
 {
 {
 	struct discovery_state *d = &hdev->discovery;
 	struct discovery_state *d = &hdev->discovery;
 
 
 	bacpy(&d->last_adv_addr, bdaddr);
 	bacpy(&d->last_adv_addr, bdaddr);
 	d->last_adv_addr_type = bdaddr_type;
 	d->last_adv_addr_type = bdaddr_type;
 	d->last_adv_rssi = rssi;
 	d->last_adv_rssi = rssi;
+	d->last_adv_flags = flags;
 	memcpy(d->last_adv_data, data, len);
 	memcpy(d->last_adv_data, data, len);
 	d->last_adv_data_len = len;
 	d->last_adv_data_len = len;
 }
 }
@@ -1072,11 +1141,11 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
 
 
 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
 
 
-	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
-	if (!cp)
+	if (status)
 		return;
 		return;
 
 
-	if (status)
+	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
+	if (!cp)
 		return;
 		return;
 
 
 	switch (cp->enable) {
 	switch (cp->enable) {
@@ -1096,7 +1165,7 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
 
 
 			mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
 			mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
 					  d->last_adv_addr_type, NULL,
 					  d->last_adv_addr_type, NULL,
-					  d->last_adv_rssi, 0, 1,
+					  d->last_adv_rssi, d->last_adv_flags,
 					  d->last_adv_data,
 					  d->last_adv_data,
 					  d->last_adv_data_len, NULL, 0);
 					  d->last_adv_data_len, NULL, 0);
 		}
 		}
@@ -1107,13 +1176,21 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
 		cancel_delayed_work(&hdev->le_scan_disable);
 		cancel_delayed_work(&hdev->le_scan_disable);
 
 
 		clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
 		clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
+
 		/* The HCI_LE_SCAN_INTERRUPTED flag indicates that we
 		/* The HCI_LE_SCAN_INTERRUPTED flag indicates that we
 		 * interrupted scanning due to a connect request. Mark
 		 * interrupted scanning due to a connect request. Mark
-		 * therefore discovery as stopped.
+		 * therefore discovery as stopped. If this was not
+		 * because of a connect request advertising might have
+		 * been disabled because of active scanning, so
+		 * re-enable it again if necessary.
 		 */
 		 */
 		if (test_and_clear_bit(HCI_LE_SCAN_INTERRUPTED,
 		if (test_and_clear_bit(HCI_LE_SCAN_INTERRUPTED,
 				       &hdev->dev_flags))
 				       &hdev->dev_flags))
 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
+		else if (!test_bit(HCI_LE_ADV, &hdev->dev_flags) &&
+			 hdev->discovery.state == DISCOVERY_FINDING)
+			mgmt_reenable_advertising(hdev);
+
 		break;
 		break;
 
 
 	default:
 	default:
@@ -1129,8 +1206,10 @@ static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
 
 
 	BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
 	BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
 
 
-	if (!rp->status)
-		hdev->le_white_list_size = rp->size;
+	if (rp->status)
+		return;
+
+	hdev->le_white_list_size = rp->size;
 }
 }
 
 
 static void hci_cc_le_clear_white_list(struct hci_dev *hdev,
 static void hci_cc_le_clear_white_list(struct hci_dev *hdev,
@@ -1140,8 +1219,10 @@ static void hci_cc_le_clear_white_list(struct hci_dev *hdev,
 
 
 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
 
 
-	if (!status)
-		hci_white_list_clear(hdev);
+	if (status)
+		return;
+
+	hci_bdaddr_list_clear(&hdev->le_white_list);
 }
 }
 
 
 static void hci_cc_le_add_to_white_list(struct hci_dev *hdev,
 static void hci_cc_le_add_to_white_list(struct hci_dev *hdev,
@@ -1152,12 +1233,15 @@ static void hci_cc_le_add_to_white_list(struct hci_dev *hdev,
 
 
 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
 
 
+	if (status)
+		return;
+
 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_WHITE_LIST);
 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_WHITE_LIST);
 	if (!sent)
 	if (!sent)
 		return;
 		return;
 
 
-	if (!status)
-		hci_white_list_add(hdev, &sent->bdaddr, sent->bdaddr_type);
+	hci_bdaddr_list_add(&hdev->le_white_list, &sent->bdaddr,
+			   sent->bdaddr_type);
 }
 }
 
 
 static void hci_cc_le_del_from_white_list(struct hci_dev *hdev,
 static void hci_cc_le_del_from_white_list(struct hci_dev *hdev,
@@ -1168,12 +1252,15 @@ static void hci_cc_le_del_from_white_list(struct hci_dev *hdev,
 
 
 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
 
 
+	if (status)
+		return;
+
 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_WHITE_LIST);
 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_WHITE_LIST);
 	if (!sent)
 	if (!sent)
 		return;
 		return;
 
 
-	if (!status)
-		hci_white_list_del(hdev, &sent->bdaddr, sent->bdaddr_type);
+	hci_bdaddr_list_del(&hdev->le_white_list, &sent->bdaddr,
+			    sent->bdaddr_type);
 }
 }
 
 
 static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
 static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
@@ -1183,8 +1270,10 @@ static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
 
 
 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
 
 
-	if (!rp->status)
-		memcpy(hdev->le_states, rp->le_states, 8);
+	if (rp->status)
+		return;
+
+	memcpy(hdev->le_states, rp->le_states, 8);
 }
 }
 
 
 static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
 static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
@@ -1195,25 +1284,26 @@ static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
 
 
 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
 
 
+	if (status)
+		return;
+
 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
 	if (!sent)
 	if (!sent)
 		return;
 		return;
 
 
-	if (!status) {
-		if (sent->le) {
-			hdev->features[1][0] |= LMP_HOST_LE;
-			set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
-		} else {
-			hdev->features[1][0] &= ~LMP_HOST_LE;
-			clear_bit(HCI_LE_ENABLED, &hdev->dev_flags);
-			clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
-		}
-
-		if (sent->simul)
-			hdev->features[1][0] |= LMP_HOST_LE_BREDR;
-		else
-			hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
+	if (sent->le) {
+		hdev->features[1][0] |= LMP_HOST_LE;
+		set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
+	} else {
+		hdev->features[1][0] &= ~LMP_HOST_LE;
+		clear_bit(HCI_LE_ENABLED, &hdev->dev_flags);
+		clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
 	}
 	}
+
+	if (sent->simul)
+		hdev->features[1][0] |= LMP_HOST_LE_BREDR;
+	else
+		hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
 }
 }
 
 
 static void hci_cc_set_adv_param(struct hci_dev *hdev, struct sk_buff *skb)
 static void hci_cc_set_adv_param(struct hci_dev *hdev, struct sk_buff *skb)
@@ -1345,7 +1435,7 @@ static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
 			conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
 			conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
 			if (conn) {
 			if (conn) {
 				conn->out = true;
 				conn->out = true;
-				conn->link_mode |= HCI_LM_MASTER;
+				set_bit(HCI_CONN_MASTER, &conn->flags);
 			} else
 			} else
 				BT_ERR("No memory for new connection");
 				BT_ERR("No memory for new connection");
 		}
 		}
@@ -1835,7 +1925,7 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status)
 	if (cp->filter_policy == HCI_LE_USE_PEER_ADDR)
 	if (cp->filter_policy == HCI_LE_USE_PEER_ADDR)
 		queue_delayed_work(conn->hdev->workqueue,
 		queue_delayed_work(conn->hdev->workqueue,
 				   &conn->le_conn_timeout,
 				   &conn->le_conn_timeout,
-				   HCI_LE_CONN_TIMEOUT);
+				   conn->conn_timeout);
 
 
 unlock:
 unlock:
 	hci_dev_unlock(hdev);
 	hci_dev_unlock(hdev);
@@ -1929,7 +2019,7 @@ static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	hci_dev_lock(hdev);
 	hci_dev_lock(hdev);
 
 
 	for (; num_rsp; num_rsp--, info++) {
 	for (; num_rsp; num_rsp--, info++) {
-		bool name_known, ssp;
+		u32 flags;
 
 
 		bacpy(&data.bdaddr, &info->bdaddr);
 		bacpy(&data.bdaddr, &info->bdaddr);
 		data.pscan_rep_mode	= info->pscan_rep_mode;
 		data.pscan_rep_mode	= info->pscan_rep_mode;
@@ -1940,10 +2030,10 @@ static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
 		data.rssi		= 0x00;
 		data.rssi		= 0x00;
 		data.ssp_mode		= 0x00;
 		data.ssp_mode		= 0x00;
 
 
-		name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
+		flags = hci_inquiry_cache_update(hdev, &data, false);
+
 		mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
 		mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
-				  info->dev_class, 0, !name_known, ssp, NULL,
-				  0, NULL, 0);
+				  info->dev_class, 0, flags, NULL, 0, NULL, 0);
 	}
 	}
 
 
 	hci_dev_unlock(hdev);
 	hci_dev_unlock(hdev);
@@ -1988,10 +2078,10 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 		hci_conn_add_sysfs(conn);
 		hci_conn_add_sysfs(conn);
 
 
 		if (test_bit(HCI_AUTH, &hdev->flags))
 		if (test_bit(HCI_AUTH, &hdev->flags))
-			conn->link_mode |= HCI_LM_AUTH;
+			set_bit(HCI_CONN_AUTH, &conn->flags);
 
 
 		if (test_bit(HCI_ENCRYPT, &hdev->flags))
 		if (test_bit(HCI_ENCRYPT, &hdev->flags))
-			conn->link_mode |= HCI_LM_ENCRYPT;
+			set_bit(HCI_CONN_ENCRYPT, &conn->flags);
 
 
 		/* Get remote features */
 		/* Get remote features */
 		if (conn->type == ACL_LINK) {
 		if (conn->type == ACL_LINK) {
@@ -2031,10 +2121,21 @@ unlock:
 	hci_conn_check_pending(hdev);
 	hci_conn_check_pending(hdev);
 }
 }
 
 
+static void hci_reject_conn(struct hci_dev *hdev, bdaddr_t *bdaddr)
+{
+	struct hci_cp_reject_conn_req cp;
+
+	bacpy(&cp.bdaddr, bdaddr);
+	cp.reason = HCI_ERROR_REJ_BAD_ADDR;
+	hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
+}
+
 static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
 static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
 {
 	struct hci_ev_conn_request *ev = (void *) skb->data;
 	struct hci_ev_conn_request *ev = (void *) skb->data;
 	int mask = hdev->link_mode;
 	int mask = hdev->link_mode;
+	struct inquiry_entry *ie;
+	struct hci_conn *conn;
 	__u8 flags = 0;
 	__u8 flags = 0;
 
 
 	BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
 	BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
@@ -2043,73 +2144,79 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
 	mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
 				      &flags);
 				      &flags);
 
 
-	if ((mask & HCI_LM_ACCEPT) &&
-	    !hci_blacklist_lookup(hdev, &ev->bdaddr, BDADDR_BREDR)) {
-		/* Connection accepted */
-		struct inquiry_entry *ie;
-		struct hci_conn *conn;
+	if (!(mask & HCI_LM_ACCEPT)) {
+		hci_reject_conn(hdev, &ev->bdaddr);
+		return;
+	}
 
 
-		hci_dev_lock(hdev);
+	if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags)) {
+		if (hci_bdaddr_list_lookup(&hdev->blacklist, &ev->bdaddr,
+					   BDADDR_BREDR)) {
+			hci_reject_conn(hdev, &ev->bdaddr);
+			return;
+		}
+	} else {
+		if (!hci_bdaddr_list_lookup(&hdev->whitelist, &ev->bdaddr,
+					    BDADDR_BREDR)) {
+			hci_reject_conn(hdev, &ev->bdaddr);
+			return;
+		}
+	}
 
 
-		ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
-		if (ie)
-			memcpy(ie->data.dev_class, ev->dev_class, 3);
+	/* Connection accepted */
 
 
-		conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
-					       &ev->bdaddr);
+	hci_dev_lock(hdev);
+
+	ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
+	if (ie)
+		memcpy(ie->data.dev_class, ev->dev_class, 3);
+
+	conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
+			&ev->bdaddr);
+	if (!conn) {
+		conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
 		if (!conn) {
 		if (!conn) {
-			conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
-			if (!conn) {
-				BT_ERR("No memory for new connection");
-				hci_dev_unlock(hdev);
-				return;
-			}
+			BT_ERR("No memory for new connection");
+			hci_dev_unlock(hdev);
+			return;
 		}
 		}
+	}
 
 
-		memcpy(conn->dev_class, ev->dev_class, 3);
+	memcpy(conn->dev_class, ev->dev_class, 3);
 
 
-		hci_dev_unlock(hdev);
+	hci_dev_unlock(hdev);
 
 
-		if (ev->link_type == ACL_LINK ||
-		    (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
-			struct hci_cp_accept_conn_req cp;
-			conn->state = BT_CONNECT;
+	if (ev->link_type == ACL_LINK ||
+	    (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
+		struct hci_cp_accept_conn_req cp;
+		conn->state = BT_CONNECT;
 
 
-			bacpy(&cp.bdaddr, &ev->bdaddr);
+		bacpy(&cp.bdaddr, &ev->bdaddr);
 
 
-			if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
-				cp.role = 0x00; /* Become master */
-			else
-				cp.role = 0x01; /* Remain slave */
+		if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
+			cp.role = 0x00; /* Become master */
+		else
+			cp.role = 0x01; /* Remain slave */
 
 
-			hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
-				     &cp);
-		} else if (!(flags & HCI_PROTO_DEFER)) {
-			struct hci_cp_accept_sync_conn_req cp;
-			conn->state = BT_CONNECT;
+		hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp);
+	} else if (!(flags & HCI_PROTO_DEFER)) {
+		struct hci_cp_accept_sync_conn_req cp;
+		conn->state = BT_CONNECT;
 
 
-			bacpy(&cp.bdaddr, &ev->bdaddr);
-			cp.pkt_type = cpu_to_le16(conn->pkt_type);
+		bacpy(&cp.bdaddr, &ev->bdaddr);
+		cp.pkt_type = cpu_to_le16(conn->pkt_type);
 
 
-			cp.tx_bandwidth   = cpu_to_le32(0x00001f40);
-			cp.rx_bandwidth   = cpu_to_le32(0x00001f40);
-			cp.max_latency    = cpu_to_le16(0xffff);
-			cp.content_format = cpu_to_le16(hdev->voice_setting);
-			cp.retrans_effort = 0xff;
+		cp.tx_bandwidth   = cpu_to_le32(0x00001f40);
+		cp.rx_bandwidth   = cpu_to_le32(0x00001f40);
+		cp.max_latency    = cpu_to_le16(0xffff);
+		cp.content_format = cpu_to_le16(hdev->voice_setting);
+		cp.retrans_effort = 0xff;
 
 
-			hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
-				     sizeof(cp), &cp);
-		} else {
-			conn->state = BT_CONNECT2;
-			hci_proto_connect_cfm(conn, 0);
-		}
+		hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, sizeof(cp),
+			     &cp);
 	} else {
 	} else {
-		/* Connection rejected */
-		struct hci_cp_reject_conn_req cp;
-
-		bacpy(&cp.bdaddr, &ev->bdaddr);
-		cp.reason = HCI_ERROR_REJ_BAD_ADDR;
-		hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
+		conn->state = BT_CONNECT2;
+		hci_proto_connect_cfm(conn, 0);
 	}
 	}
 }
 }
 
 
@@ -2158,7 +2265,8 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type,
 	mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type,
 				reason, mgmt_connected);
 				reason, mgmt_connected);
 
 
-	if (conn->type == ACL_LINK && conn->flush_key)
+	if (conn->type == ACL_LINK &&
+	    test_bit(HCI_CONN_FLUSH_KEY, &conn->flags))
 		hci_remove_link_key(hdev, &conn->dst);
 		hci_remove_link_key(hdev, &conn->dst);
 
 
 	params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
 	params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
@@ -2170,7 +2278,9 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 			/* Fall through */
 			/* Fall through */
 
 
 		case HCI_AUTO_CONN_ALWAYS:
 		case HCI_AUTO_CONN_ALWAYS:
-			hci_pend_le_conn_add(hdev, &conn->dst, conn->dst_type);
+			list_del_init(&params->action);
+			list_add(&params->action, &hdev->pend_le_conns);
+			hci_update_background_scan(hdev);
 			break;
 			break;
 
 
 		default:
 		default:
@@ -2218,7 +2328,7 @@ static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 		    test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
 		    test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
 			BT_INFO("re-auth of legacy device is not possible.");
 			BT_INFO("re-auth of legacy device is not possible.");
 		} else {
 		} else {
-			conn->link_mode |= HCI_LM_AUTH;
+			set_bit(HCI_CONN_AUTH, &conn->flags);
 			conn->sec_level = conn->pending_sec_level;
 			conn->sec_level = conn->pending_sec_level;
 		}
 		}
 	} else {
 	} else {
@@ -2321,19 +2431,19 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	if (!ev->status) {
 	if (!ev->status) {
 		if (ev->encrypt) {
 		if (ev->encrypt) {
 			/* Encryption implies authentication */
 			/* Encryption implies authentication */
-			conn->link_mode |= HCI_LM_AUTH;
-			conn->link_mode |= HCI_LM_ENCRYPT;
+			set_bit(HCI_CONN_AUTH, &conn->flags);
+			set_bit(HCI_CONN_ENCRYPT, &conn->flags);
 			conn->sec_level = conn->pending_sec_level;
 			conn->sec_level = conn->pending_sec_level;
 
 
 			/* P-256 authentication key implies FIPS */
 			/* P-256 authentication key implies FIPS */
 			if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256)
 			if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256)
-				conn->link_mode |= HCI_LM_FIPS;
+				set_bit(HCI_CONN_FIPS, &conn->flags);
 
 
 			if ((conn->type == ACL_LINK && ev->encrypt == 0x02) ||
 			if ((conn->type == ACL_LINK && ev->encrypt == 0x02) ||
 			    conn->type == LE_LINK)
 			    conn->type == LE_LINK)
 				set_bit(HCI_CONN_AES_CCM, &conn->flags);
 				set_bit(HCI_CONN_AES_CCM, &conn->flags);
 		} else {
 		} else {
-			conn->link_mode &= ~HCI_LM_ENCRYPT;
+			clear_bit(HCI_CONN_ENCRYPT, &conn->flags);
 			clear_bit(HCI_CONN_AES_CCM, &conn->flags);
 			clear_bit(HCI_CONN_AES_CCM, &conn->flags);
 		}
 		}
 	}
 	}
@@ -2384,7 +2494,7 @@ static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
 	if (conn) {
 	if (conn) {
 		if (!ev->status)
 		if (!ev->status)
-			conn->link_mode |= HCI_LM_SECURE;
+			set_bit(HCI_CONN_SECURE, &conn->flags);
 
 
 		clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
 		clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
 
 
@@ -2595,6 +2705,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 		hci_cc_read_local_amp_info(hdev, skb);
 		hci_cc_read_local_amp_info(hdev, skb);
 		break;
 		break;
 
 
+	case HCI_OP_READ_CLOCK:
+		hci_cc_read_clock(hdev, skb);
+		break;
+
 	case HCI_OP_READ_LOCAL_AMP_ASSOC:
 	case HCI_OP_READ_LOCAL_AMP_ASSOC:
 		hci_cc_read_local_amp_assoc(hdev, skb);
 		hci_cc_read_local_amp_assoc(hdev, skb);
 		break;
 		break;
@@ -2709,7 +2823,7 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	}
 	}
 
 
 	if (opcode != HCI_OP_NOP)
 	if (opcode != HCI_OP_NOP)
-		del_timer(&hdev->cmd_timer);
+		cancel_delayed_work(&hdev->cmd_timer);
 
 
 	hci_req_cmd_complete(hdev, opcode, status);
 	hci_req_cmd_complete(hdev, opcode, status);
 
 
@@ -2800,7 +2914,7 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	}
 	}
 
 
 	if (opcode != HCI_OP_NOP)
 	if (opcode != HCI_OP_NOP)
-		del_timer(&hdev->cmd_timer);
+		cancel_delayed_work(&hdev->cmd_timer);
 
 
 	if (ev->status ||
 	if (ev->status ||
 	    (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
 	    (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
@@ -2826,9 +2940,9 @@ static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	if (conn) {
 	if (conn) {
 		if (!ev->status) {
 		if (!ev->status) {
 			if (ev->role)
 			if (ev->role)
-				conn->link_mode &= ~HCI_LM_MASTER;
+				clear_bit(HCI_CONN_MASTER, &conn->flags);
 			else
 			else
-				conn->link_mode |= HCI_LM_MASTER;
+				set_bit(HCI_CONN_MASTER, &conn->flags);
 		}
 		}
 
 
 		clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
 		clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
@@ -3065,12 +3179,6 @@ static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
 	BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
 	       &ev->bdaddr);
 	       &ev->bdaddr);
 
 
-	if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
-	    key->type == HCI_LK_DEBUG_COMBINATION) {
-		BT_DBG("%s ignoring debug key", hdev->name);
-		goto not_found;
-	}
-
 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
 	if (conn) {
 	if (conn) {
 		if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 ||
 		if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 ||
@@ -3110,6 +3218,8 @@ static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
 {
 	struct hci_ev_link_key_notify *ev = (void *) skb->data;
 	struct hci_ev_link_key_notify *ev = (void *) skb->data;
 	struct hci_conn *conn;
 	struct hci_conn *conn;
+	struct link_key *key;
+	bool persistent;
 	u8 pin_len = 0;
 	u8 pin_len = 0;
 
 
 	BT_DBG("%s", hdev->name);
 	BT_DBG("%s", hdev->name);
@@ -3128,10 +3238,33 @@ static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
 		hci_conn_drop(conn);
 		hci_conn_drop(conn);
 	}
 	}
 
 
-	if (test_bit(HCI_MGMT, &hdev->dev_flags))
-		hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
-				 ev->key_type, pin_len);
+	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
+		goto unlock;
+
+	key = hci_add_link_key(hdev, conn, &ev->bdaddr, ev->link_key,
+			        ev->key_type, pin_len, &persistent);
+	if (!key)
+		goto unlock;
 
 
+	mgmt_new_link_key(hdev, key, persistent);
+
+	/* Keep debug keys around only if the HCI_KEEP_DEBUG_KEYS flag
+	 * is set. If it's not set simply remove the key from the kernel
+	 * list (we've still notified user space about it but with
+	 * store_hint being 0).
+	 */
+	if (key->type == HCI_LK_DEBUG_COMBINATION &&
+	    !test_bit(HCI_KEEP_DEBUG_KEYS, &hdev->dev_flags)) {
+		list_del(&key->list);
+		kfree(key);
+	} else if (conn) {
+		if (persistent)
+			clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags);
+		else
+			set_bit(HCI_CONN_FLUSH_KEY, &conn->flags);
+	}
+
+unlock:
 	hci_dev_unlock(hdev);
 	hci_dev_unlock(hdev);
 }
 }
 
 
@@ -3197,7 +3330,6 @@ static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
 {
 {
 	struct inquiry_data data;
 	struct inquiry_data data;
 	int num_rsp = *((__u8 *) skb->data);
 	int num_rsp = *((__u8 *) skb->data);
-	bool name_known, ssp;
 
 
 	BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
 	BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
 
 
@@ -3214,6 +3346,8 @@ static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
 		info = (void *) (skb->data + 1);
 		info = (void *) (skb->data + 1);
 
 
 		for (; num_rsp; num_rsp--, info++) {
 		for (; num_rsp; num_rsp--, info++) {
+			u32 flags;
+
 			bacpy(&data.bdaddr, &info->bdaddr);
 			bacpy(&data.bdaddr, &info->bdaddr);
 			data.pscan_rep_mode	= info->pscan_rep_mode;
 			data.pscan_rep_mode	= info->pscan_rep_mode;
 			data.pscan_period_mode	= info->pscan_period_mode;
 			data.pscan_period_mode	= info->pscan_period_mode;
@@ -3223,16 +3357,18 @@ static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
 			data.rssi		= info->rssi;
 			data.rssi		= info->rssi;
 			data.ssp_mode		= 0x00;
 			data.ssp_mode		= 0x00;
 
 
-			name_known = hci_inquiry_cache_update(hdev, &data,
-							      false, &ssp);
+			flags = hci_inquiry_cache_update(hdev, &data, false);
+
 			mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
 			mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
 					  info->dev_class, info->rssi,
 					  info->dev_class, info->rssi,
-					  !name_known, ssp, NULL, 0, NULL, 0);
+					  flags, NULL, 0, NULL, 0);
 		}
 		}
 	} else {
 	} else {
 		struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
 		struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
 
 
 		for (; num_rsp; num_rsp--, info++) {
 		for (; num_rsp; num_rsp--, info++) {
+			u32 flags;
+
 			bacpy(&data.bdaddr, &info->bdaddr);
 			bacpy(&data.bdaddr, &info->bdaddr);
 			data.pscan_rep_mode	= info->pscan_rep_mode;
 			data.pscan_rep_mode	= info->pscan_rep_mode;
 			data.pscan_period_mode	= info->pscan_period_mode;
 			data.pscan_period_mode	= info->pscan_period_mode;
@@ -3241,11 +3377,12 @@ static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
 			data.clock_offset	= info->clock_offset;
 			data.clock_offset	= info->clock_offset;
 			data.rssi		= info->rssi;
 			data.rssi		= info->rssi;
 			data.ssp_mode		= 0x00;
 			data.ssp_mode		= 0x00;
-			name_known = hci_inquiry_cache_update(hdev, &data,
-							      false, &ssp);
+
+			flags = hci_inquiry_cache_update(hdev, &data, false);
+
 			mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
 			mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
 					  info->dev_class, info->rssi,
 					  info->dev_class, info->rssi,
-					  !name_known, ssp, NULL, 0, NULL, 0);
+					  flags, NULL, 0, NULL, 0);
 		}
 		}
 	}
 	}
 
 
@@ -3348,6 +3485,7 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
 		hci_conn_add_sysfs(conn);
 		hci_conn_add_sysfs(conn);
 		break;
 		break;
 
 
+	case 0x10:	/* Connection Accept Timeout */
 	case 0x0d:	/* Connection Rejected due to Limited Resources */
 	case 0x0d:	/* Connection Rejected due to Limited Resources */
 	case 0x11:	/* Unsupported Feature or Parameter Value */
 	case 0x11:	/* Unsupported Feature or Parameter Value */
 	case 0x1c:	/* SCO interval rejected */
 	case 0x1c:	/* SCO interval rejected */
@@ -3411,7 +3549,8 @@ static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
 	hci_dev_lock(hdev);
 	hci_dev_lock(hdev);
 
 
 	for (; num_rsp; num_rsp--, info++) {
 	for (; num_rsp; num_rsp--, info++) {
-		bool name_known, ssp;
+		u32 flags;
+		bool name_known;
 
 
 		bacpy(&data.bdaddr, &info->bdaddr);
 		bacpy(&data.bdaddr, &info->bdaddr);
 		data.pscan_rep_mode	= info->pscan_rep_mode;
 		data.pscan_rep_mode	= info->pscan_rep_mode;
@@ -3429,12 +3568,13 @@ static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
 		else
 		else
 			name_known = true;
 			name_known = true;
 
 
-		name_known = hci_inquiry_cache_update(hdev, &data, name_known,
-						      &ssp);
+		flags = hci_inquiry_cache_update(hdev, &data, name_known);
+
 		eir_len = eir_get_length(info->data, sizeof(info->data));
 		eir_len = eir_get_length(info->data, sizeof(info->data));
+
 		mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
 		mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
-				  info->dev_class, info->rssi, !name_known,
-				  ssp, info->data, eir_len, NULL, 0);
+				  info->dev_class, info->rssi,
+				  flags, info->data, eir_len, NULL, 0);
 	}
 	}
 
 
 	hci_dev_unlock(hdev);
 	hci_dev_unlock(hdev);
@@ -3967,13 +4107,20 @@ static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
 static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
 {
 	struct hci_ev_le_conn_complete *ev = (void *) skb->data;
 	struct hci_ev_le_conn_complete *ev = (void *) skb->data;
+	struct hci_conn_params *params;
 	struct hci_conn *conn;
 	struct hci_conn *conn;
 	struct smp_irk *irk;
 	struct smp_irk *irk;
+	u8 addr_type;
 
 
 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
 
 
 	hci_dev_lock(hdev);
 	hci_dev_lock(hdev);
 
 
+	/* All controllers implicitly stop advertising in the event of a
+	 * connection, so ensure that the state bit is cleared.
+	 */
+	clear_bit(HCI_LE_ADV, &hdev->dev_flags);
+
 	conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
 	conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
 	if (!conn) {
 	if (!conn) {
 		conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
 		conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
@@ -3986,7 +4133,7 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 
 
 		if (ev->role == LE_CONN_ROLE_MASTER) {
 		if (ev->role == LE_CONN_ROLE_MASTER) {
 			conn->out = true;
 			conn->out = true;
-			conn->link_mode |= HCI_LM_MASTER;
+			set_bit(HCI_CONN_MASTER, &conn->flags);
 		}
 		}
 
 
 		/* If we didn't have a hci_conn object previously
 		/* If we didn't have a hci_conn object previously
@@ -4025,6 +4172,14 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 
 
 		conn->init_addr_type = ev->bdaddr_type;
 		conn->init_addr_type = ev->bdaddr_type;
 		bacpy(&conn->init_addr, &ev->bdaddr);
 		bacpy(&conn->init_addr, &ev->bdaddr);
+
+		/* For incoming connections, set the default minimum
+		 * and maximum connection interval. They will be used
+		 * to check if the parameters are in range and if not
+		 * trigger the connection update procedure.
+		 */
+		conn->le_conn_min_interval = hdev->le_conn_min_interval;
+		conn->le_conn_max_interval = hdev->le_conn_max_interval;
 	}
 	}
 
 
 	/* Lookup the identity address from the stored connection
 	/* Lookup the identity address from the stored connection
@@ -4042,6 +4197,17 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 		conn->dst_type = irk->addr_type;
 		conn->dst_type = irk->addr_type;
 	}
 	}
 
 
+	if (conn->dst_type == ADDR_LE_DEV_PUBLIC)
+		addr_type = BDADDR_LE_PUBLIC;
+	else
+		addr_type = BDADDR_LE_RANDOM;
+
+	/* Drop the connection if he device is blocked */
+	if (hci_bdaddr_list_lookup(&hdev->blacklist, &conn->dst, addr_type)) {
+		hci_conn_drop(conn);
+		goto unlock;
+	}
+
 	if (ev->status) {
 	if (ev->status) {
 		hci_le_conn_failed(conn, ev->status);
 		hci_le_conn_failed(conn, ev->status);
 		goto unlock;
 		goto unlock;
@@ -4055,40 +4221,75 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	conn->handle = __le16_to_cpu(ev->handle);
 	conn->handle = __le16_to_cpu(ev->handle);
 	conn->state = BT_CONNECTED;
 	conn->state = BT_CONNECTED;
 
 
-	if (test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags))
-		set_bit(HCI_CONN_6LOWPAN, &conn->flags);
+	conn->le_conn_interval = le16_to_cpu(ev->interval);
+	conn->le_conn_latency = le16_to_cpu(ev->latency);
+	conn->le_supv_timeout = le16_to_cpu(ev->supervision_timeout);
 
 
 	hci_conn_add_sysfs(conn);
 	hci_conn_add_sysfs(conn);
 
 
 	hci_proto_connect_cfm(conn, ev->status);
 	hci_proto_connect_cfm(conn, ev->status);
 
 
-	hci_pend_le_conn_del(hdev, &conn->dst, conn->dst_type);
+	params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
+	if (params)
+		list_del_init(&params->action);
 
 
 unlock:
 unlock:
+	hci_update_background_scan(hdev);
+	hci_dev_unlock(hdev);
+}
+
+static void hci_le_conn_update_complete_evt(struct hci_dev *hdev,
+					    struct sk_buff *skb)
+{
+	struct hci_ev_le_conn_update_complete *ev = (void *) skb->data;
+	struct hci_conn *conn;
+
+	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
+
+	if (ev->status)
+		return;
+
+	hci_dev_lock(hdev);
+
+	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
+	if (conn) {
+		conn->le_conn_interval = le16_to_cpu(ev->interval);
+		conn->le_conn_latency = le16_to_cpu(ev->latency);
+		conn->le_supv_timeout = le16_to_cpu(ev->supervision_timeout);
+	}
+
 	hci_dev_unlock(hdev);
 	hci_dev_unlock(hdev);
 }
 }
 
 
 /* This function requires the caller holds hdev->lock */
 /* This function requires the caller holds hdev->lock */
 static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
 static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
-				  u8 addr_type)
+				  u8 addr_type, u8 adv_type)
 {
 {
 	struct hci_conn *conn;
 	struct hci_conn *conn;
-	struct smp_irk *irk;
 
 
-	/* If this is a resolvable address, we should resolve it and then
-	 * update address and address type variables.
-	 */
-	irk = hci_get_irk(hdev, addr, addr_type);
-	if (irk) {
-		addr = &irk->bdaddr;
-		addr_type = irk->addr_type;
-	}
+	/* If the event is not connectable don't proceed further */
+	if (adv_type != LE_ADV_IND && adv_type != LE_ADV_DIRECT_IND)
+		return;
 
 
-	if (!hci_pend_le_conn_lookup(hdev, addr, addr_type))
+	/* Ignore if the device is blocked */
+	if (hci_bdaddr_list_lookup(&hdev->blacklist, addr, addr_type))
 		return;
 		return;
 
 
+	/* If we're connectable, always connect any ADV_DIRECT_IND event */
+	if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags) &&
+	    adv_type == LE_ADV_DIRECT_IND)
+		goto connect;
+
+	/* If we're not connectable only connect devices that we have in
+	 * our pend_le_conns list.
+	 */
+	if (!hci_pend_le_action_lookup(&hdev->pend_le_conns, addr, addr_type))
+		return;
+
+connect:
+	/* Request connection in master = true role */
 	conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW,
 	conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW,
-			      HCI_AT_NO_BONDING);
+			      HCI_LE_AUTOCONN_TIMEOUT, true);
 	if (!IS_ERR(conn))
 	if (!IS_ERR(conn))
 		return;
 		return;
 
 
@@ -4109,15 +4310,65 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
 			       u8 bdaddr_type, s8 rssi, u8 *data, u8 len)
 			       u8 bdaddr_type, s8 rssi, u8 *data, u8 len)
 {
 {
 	struct discovery_state *d = &hdev->discovery;
 	struct discovery_state *d = &hdev->discovery;
+	struct smp_irk *irk;
 	bool match;
 	bool match;
+	u32 flags;
+
+	/* Check if we need to convert to identity address */
+	irk = hci_get_irk(hdev, bdaddr, bdaddr_type);
+	if (irk) {
+		bdaddr = &irk->bdaddr;
+		bdaddr_type = irk->addr_type;
+	}
+
+	/* Check if we have been requested to connect to this device */
+	check_pending_le_conn(hdev, bdaddr, bdaddr_type, type);
 
 
-	/* Passive scanning shouldn't trigger any device found events */
+	/* Passive scanning shouldn't trigger any device found events,
+	 * except for devices marked as CONN_REPORT for which we do send
+	 * device found events.
+	 */
 	if (hdev->le_scan_type == LE_SCAN_PASSIVE) {
 	if (hdev->le_scan_type == LE_SCAN_PASSIVE) {
-		if (type == LE_ADV_IND || type == LE_ADV_DIRECT_IND)
-			check_pending_le_conn(hdev, bdaddr, bdaddr_type);
+		struct hci_conn_params *param;
+
+		if (type == LE_ADV_DIRECT_IND)
+			return;
+
+		param = hci_pend_le_action_lookup(&hdev->pend_le_reports,
+						  bdaddr, bdaddr_type);
+		if (!param)
+			return;
+
+		if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND)
+			flags = MGMT_DEV_FOUND_NOT_CONNECTABLE;
+		else
+			flags = 0;
+		mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
+				  rssi, flags, data, len, NULL, 0);
 		return;
 		return;
 	}
 	}
 
 
+	/* When receiving non-connectable or scannable undirected
+	 * advertising reports, this means that the remote device is
+	 * not connectable and then clearly indicate this in the
+	 * device found event.
+	 *
+	 * When receiving a scan response, then there is no way to
+	 * know if the remote device is connectable or not. However
+	 * since scan responses are merged with a previously seen
+	 * advertising report, the flags field from that report
+	 * will be used.
+	 *
+	 * In the really unlikely case that a controller get confused
+	 * and just sends a scan response event, then it is marked as
+	 * not connectable as well.
+	 */
+	if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND ||
+	    type == LE_ADV_SCAN_RSP)
+		flags = MGMT_DEV_FOUND_NOT_CONNECTABLE;
+	else
+		flags = 0;
+
 	/* If there's nothing pending either store the data from this
 	/* If there's nothing pending either store the data from this
 	 * event or send an immediate device found event if the data
 	 * event or send an immediate device found event if the data
 	 * should not be stored for later.
 	 * should not be stored for later.
@@ -4128,12 +4379,12 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
 		 */
 		 */
 		if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) {
 		if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) {
 			store_pending_adv_report(hdev, bdaddr, bdaddr_type,
 			store_pending_adv_report(hdev, bdaddr, bdaddr_type,
-						 rssi, data, len);
+						 rssi, flags, data, len);
 			return;
 			return;
 		}
 		}
 
 
 		mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
 		mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
-				  rssi, 0, 1, data, len, NULL, 0);
+				  rssi, flags, data, len, NULL, 0);
 		return;
 		return;
 	}
 	}
 
 
@@ -4150,7 +4401,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
 		if (!match)
 		if (!match)
 			mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
 			mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
 					  d->last_adv_addr_type, NULL,
 					  d->last_adv_addr_type, NULL,
-					  d->last_adv_rssi, 0, 1,
+					  d->last_adv_rssi, d->last_adv_flags,
 					  d->last_adv_data,
 					  d->last_adv_data,
 					  d->last_adv_data_len, NULL, 0);
 					  d->last_adv_data_len, NULL, 0);
 
 
@@ -4159,7 +4410,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
 		 */
 		 */
 		if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) {
 		if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) {
 			store_pending_adv_report(hdev, bdaddr, bdaddr_type,
 			store_pending_adv_report(hdev, bdaddr, bdaddr_type,
-						 rssi, data, len);
+						 rssi, flags, data, len);
 			return;
 			return;
 		}
 		}
 
 
@@ -4168,7 +4419,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
 		 */
 		 */
 		clear_pending_adv_report(hdev);
 		clear_pending_adv_report(hdev);
 		mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
 		mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
-				  rssi, 0, 1, data, len, NULL, 0);
+				  rssi, flags, data, len, NULL, 0);
 		return;
 		return;
 	}
 	}
 
 
@@ -4177,8 +4428,8 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
 	 * sending a merged device found event.
 	 * sending a merged device found event.
 	 */
 	 */
 	mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
 	mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
-			  d->last_adv_addr_type, NULL, rssi, 0, 1, data, len,
-			  d->last_adv_data, d->last_adv_data_len);
+			  d->last_adv_addr_type, NULL, rssi, d->last_adv_flags,
+			  d->last_adv_data, d->last_adv_data_len, data, len);
 	clear_pending_adv_report(hdev);
 	clear_pending_adv_report(hdev);
 }
 }
 
 
@@ -4241,9 +4492,12 @@ static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	 * distribute the keys. Later, security can be re-established
 	 * distribute the keys. Later, security can be re-established
 	 * using a distributed LTK.
 	 * using a distributed LTK.
 	 */
 	 */
-	if (ltk->type == HCI_SMP_STK_SLAVE) {
+	if (ltk->type == SMP_STK) {
+		set_bit(HCI_CONN_STK_ENCRYPT, &conn->flags);
 		list_del(&ltk->list);
 		list_del(&ltk->list);
 		kfree(ltk);
 		kfree(ltk);
+	} else {
+		clear_bit(HCI_CONN_STK_ENCRYPT, &conn->flags);
 	}
 	}
 
 
 	hci_dev_unlock(hdev);
 	hci_dev_unlock(hdev);
@@ -4256,6 +4510,76 @@ not_found:
 	hci_dev_unlock(hdev);
 	hci_dev_unlock(hdev);
 }
 }
 
 
+static void send_conn_param_neg_reply(struct hci_dev *hdev, u16 handle,
+				      u8 reason)
+{
+	struct hci_cp_le_conn_param_req_neg_reply cp;
+
+	cp.handle = cpu_to_le16(handle);
+	cp.reason = reason;
+
+	hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY, sizeof(cp),
+		     &cp);
+}
+
+static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev,
+					     struct sk_buff *skb)
+{
+	struct hci_ev_le_remote_conn_param_req *ev = (void *) skb->data;
+	struct hci_cp_le_conn_param_req_reply cp;
+	struct hci_conn *hcon;
+	u16 handle, min, max, latency, timeout;
+
+	handle = le16_to_cpu(ev->handle);
+	min = le16_to_cpu(ev->interval_min);
+	max = le16_to_cpu(ev->interval_max);
+	latency = le16_to_cpu(ev->latency);
+	timeout = le16_to_cpu(ev->timeout);
+
+	hcon = hci_conn_hash_lookup_handle(hdev, handle);
+	if (!hcon || hcon->state != BT_CONNECTED)
+		return send_conn_param_neg_reply(hdev, handle,
+						 HCI_ERROR_UNKNOWN_CONN_ID);
+
+	if (hci_check_conn_params(min, max, latency, timeout))
+		return send_conn_param_neg_reply(hdev, handle,
+						 HCI_ERROR_INVALID_LL_PARAMS);
+
+	if (test_bit(HCI_CONN_MASTER, &hcon->flags)) {
+		struct hci_conn_params *params;
+		u8 store_hint;
+
+		hci_dev_lock(hdev);
+
+		params = hci_conn_params_lookup(hdev, &hcon->dst,
+						hcon->dst_type);
+		if (params) {
+			params->conn_min_interval = min;
+			params->conn_max_interval = max;
+			params->conn_latency = latency;
+			params->supervision_timeout = timeout;
+			store_hint = 0x01;
+		} else{
+			store_hint = 0x00;
+		}
+
+		hci_dev_unlock(hdev);
+
+		mgmt_new_conn_param(hdev, &hcon->dst, hcon->dst_type,
+				    store_hint, min, max, latency, timeout);
+	}
+
+	cp.handle = ev->handle;
+	cp.interval_min = ev->interval_min;
+	cp.interval_max = ev->interval_max;
+	cp.latency = ev->latency;
+	cp.timeout = ev->timeout;
+	cp.min_ce_len = 0;
+	cp.max_ce_len = 0;
+
+	hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_REPLY, sizeof(cp), &cp);
+}
+
 static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
 static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
 {
 	struct hci_ev_le_meta *le_ev = (void *) skb->data;
 	struct hci_ev_le_meta *le_ev = (void *) skb->data;
@@ -4267,6 +4591,10 @@ static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
 		hci_le_conn_complete_evt(hdev, skb);
 		hci_le_conn_complete_evt(hdev, skb);
 		break;
 		break;
 
 
+	case HCI_EV_LE_CONN_UPDATE_COMPLETE:
+		hci_le_conn_update_complete_evt(hdev, skb);
+		break;
+
 	case HCI_EV_LE_ADVERTISING_REPORT:
 	case HCI_EV_LE_ADVERTISING_REPORT:
 		hci_le_adv_report_evt(hdev, skb);
 		hci_le_adv_report_evt(hdev, skb);
 		break;
 		break;
@@ -4275,6 +4603,10 @@ static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
 		hci_le_ltk_request_evt(hdev, skb);
 		hci_le_ltk_request_evt(hdev, skb);
 		break;
 		break;
 
 
+	case HCI_EV_LE_REMOTE_CONN_PARAM_REQ:
+		hci_le_remote_conn_param_req_evt(hdev, skb);
+		break;
+
 	default:
 	default:
 		break;
 		break;
 	}
 	}

+ 8 - 4
net/bluetooth/hci_sock.c

@@ -481,7 +481,7 @@ static int hci_sock_blacklist_add(struct hci_dev *hdev, void __user *arg)
 
 
 	hci_dev_lock(hdev);
 	hci_dev_lock(hdev);
 
 
-	err = hci_blacklist_add(hdev, &bdaddr, BDADDR_BREDR);
+	err = hci_bdaddr_list_add(&hdev->blacklist, &bdaddr, BDADDR_BREDR);
 
 
 	hci_dev_unlock(hdev);
 	hci_dev_unlock(hdev);
 
 
@@ -498,7 +498,7 @@ static int hci_sock_blacklist_del(struct hci_dev *hdev, void __user *arg)
 
 
 	hci_dev_lock(hdev);
 	hci_dev_lock(hdev);
 
 
-	err = hci_blacklist_del(hdev, &bdaddr, BDADDR_BREDR);
+	err = hci_bdaddr_list_del(&hdev->blacklist, &bdaddr, BDADDR_BREDR);
 
 
 	hci_dev_unlock(hdev);
 	hci_dev_unlock(hdev);
 
 
@@ -517,6 +517,9 @@ static int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd,
 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
 		return -EBUSY;
 		return -EBUSY;
 
 
+	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
+		return -EOPNOTSUPP;
+
 	if (hdev->dev_type != HCI_BREDR)
 	if (hdev->dev_type != HCI_BREDR)
 		return -EOPNOTSUPP;
 		return -EOPNOTSUPP;
 
 
@@ -690,7 +693,8 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr,
 
 
 		if (test_bit(HCI_UP, &hdev->flags) ||
 		if (test_bit(HCI_UP, &hdev->flags) ||
 		    test_bit(HCI_INIT, &hdev->flags) ||
 		    test_bit(HCI_INIT, &hdev->flags) ||
-		    test_bit(HCI_SETUP, &hdev->dev_flags)) {
+		    test_bit(HCI_SETUP, &hdev->dev_flags) ||
+		    test_bit(HCI_CONFIG, &hdev->dev_flags)) {
 			err = -EBUSY;
 			err = -EBUSY;
 			hci_dev_put(hdev);
 			hci_dev_put(hdev);
 			goto done;
 			goto done;
@@ -960,7 +964,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
 			goto drop;
 			goto drop;
 		}
 		}
 
 
-		if (test_bit(HCI_RAW, &hdev->flags) || (ogf == 0x3f)) {
+		if (ogf == 0x3f) {
 			skb_queue_tail(&hdev->raw_q, skb);
 			skb_queue_tail(&hdev->raw_q, skb);
 			queue_work(hdev->workqueue, &hdev->tx_work);
 			queue_work(hdev->workqueue, &hdev->tx_work);
 		} else {
 		} else {

+ 76 - 68
net/bluetooth/l2cap_core.c

@@ -40,7 +40,6 @@
 #include "smp.h"
 #include "smp.h"
 #include "a2mp.h"
 #include "a2mp.h"
 #include "amp.h"
 #include "amp.h"
-#include "6lowpan.h"
 
 
 #define LE_FLOWCTL_MAX_CREDITS 65535
 #define LE_FLOWCTL_MAX_CREDITS 65535
 
 
@@ -205,6 +204,7 @@ done:
 	write_unlock(&chan_list_lock);
 	write_unlock(&chan_list_lock);
 	return err;
 	return err;
 }
 }
+EXPORT_SYMBOL_GPL(l2cap_add_psm);
 
 
 int l2cap_add_scid(struct l2cap_chan *chan,  __u16 scid)
 int l2cap_add_scid(struct l2cap_chan *chan,  __u16 scid)
 {
 {
@@ -437,6 +437,7 @@ struct l2cap_chan *l2cap_chan_create(void)
 
 
 	return chan;
 	return chan;
 }
 }
+EXPORT_SYMBOL_GPL(l2cap_chan_create);
 
 
 static void l2cap_chan_destroy(struct kref *kref)
 static void l2cap_chan_destroy(struct kref *kref)
 {
 {
@@ -464,6 +465,7 @@ void l2cap_chan_put(struct l2cap_chan *c)
 
 
 	kref_put(&c->kref, l2cap_chan_destroy);
 	kref_put(&c->kref, l2cap_chan_destroy);
 }
 }
+EXPORT_SYMBOL_GPL(l2cap_chan_put);
 
 
 void l2cap_chan_set_defaults(struct l2cap_chan *chan)
 void l2cap_chan_set_defaults(struct l2cap_chan *chan)
 {
 {
@@ -482,6 +484,7 @@ void l2cap_chan_set_defaults(struct l2cap_chan *chan)
 
 
 	set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
 	set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
 }
 }
+EXPORT_SYMBOL_GPL(l2cap_chan_set_defaults);
 
 
 static void l2cap_le_flowctl_init(struct l2cap_chan *chan)
 static void l2cap_le_flowctl_init(struct l2cap_chan *chan)
 {
 {
@@ -614,6 +617,7 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
 
 
 	return;
 	return;
 }
 }
+EXPORT_SYMBOL_GPL(l2cap_chan_del);
 
 
 void l2cap_conn_update_id_addr(struct hci_conn *hcon)
 void l2cap_conn_update_id_addr(struct hci_conn *hcon)
 {
 {
@@ -717,6 +721,7 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason)
 		break;
 		break;
 	}
 	}
 }
 }
+EXPORT_SYMBOL(l2cap_chan_close);
 
 
 static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
 static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
 {
 {
@@ -1455,13 +1460,12 @@ static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
 static void l2cap_le_conn_ready(struct l2cap_conn *conn)
 static void l2cap_le_conn_ready(struct l2cap_conn *conn)
 {
 {
 	struct hci_conn *hcon = conn->hcon;
 	struct hci_conn *hcon = conn->hcon;
+	struct hci_dev *hdev = hcon->hdev;
 	struct l2cap_chan *chan, *pchan;
 	struct l2cap_chan *chan, *pchan;
 	u8 dst_type;
 	u8 dst_type;
 
 
 	BT_DBG("");
 	BT_DBG("");
 
 
-	bt_6lowpan_add_conn(conn);
-
 	/* Check if we have socket listening on cid */
 	/* Check if we have socket listening on cid */
 	pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT,
 	pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT,
 					  &hcon->src, &hcon->dst);
 					  &hcon->src, &hcon->dst);
@@ -1475,9 +1479,28 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
 	dst_type = bdaddr_type(hcon, hcon->dst_type);
 	dst_type = bdaddr_type(hcon, hcon->dst_type);
 
 
 	/* If device is blocked, do not create a channel for it */
 	/* If device is blocked, do not create a channel for it */
-	if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, dst_type))
+	if (hci_bdaddr_list_lookup(&hdev->blacklist, &hcon->dst, dst_type))
 		return;
 		return;
 
 
+	/* For LE slave connections, make sure the connection interval
+	 * is in the range of the minium and maximum interval that has
+	 * been configured for this connection. If not, then trigger
+	 * the connection update procedure.
+	 */
+	if (!test_bit(HCI_CONN_MASTER, &hcon->flags) &&
+	    (hcon->le_conn_interval < hcon->le_conn_min_interval ||
+	     hcon->le_conn_interval > hcon->le_conn_max_interval)) {
+		struct l2cap_conn_param_update_req req;
+
+		req.min = cpu_to_le16(hcon->le_conn_min_interval);
+		req.max = cpu_to_le16(hcon->le_conn_max_interval);
+		req.latency = cpu_to_le16(hcon->le_conn_latency);
+		req.to_multiplier = cpu_to_le16(hcon->le_supv_timeout);
+
+		l2cap_send_cmd(conn, l2cap_get_ident(conn),
+			       L2CAP_CONN_PARAM_UPDATE_REQ, sizeof(req), &req);
+	}
+
 	l2cap_chan_lock(pchan);
 	l2cap_chan_lock(pchan);
 
 
 	chan = pchan->ops->new_connection(pchan);
 	chan = pchan->ops->new_connection(pchan);
@@ -2118,7 +2141,8 @@ static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
 	struct sk_buff **frag;
 	struct sk_buff **frag;
 	int sent = 0;
 	int sent = 0;
 
 
-	if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
+	if (chan->ops->memcpy_fromiovec(chan, skb_put(skb, count),
+					msg->msg_iov, count))
 		return -EFAULT;
 		return -EFAULT;
 
 
 	sent += count;
 	sent += count;
@@ -2131,18 +2155,17 @@ static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
 
 
 		count = min_t(unsigned int, conn->mtu, len);
 		count = min_t(unsigned int, conn->mtu, len);
 
 
-		tmp = chan->ops->alloc_skb(chan, count,
+		tmp = chan->ops->alloc_skb(chan, 0, count,
 					   msg->msg_flags & MSG_DONTWAIT);
 					   msg->msg_flags & MSG_DONTWAIT);
 		if (IS_ERR(tmp))
 		if (IS_ERR(tmp))
 			return PTR_ERR(tmp);
 			return PTR_ERR(tmp);
 
 
 		*frag = tmp;
 		*frag = tmp;
 
 
-		if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
+		if (chan->ops->memcpy_fromiovec(chan, skb_put(*frag, count),
+						msg->msg_iov, count))
 			return -EFAULT;
 			return -EFAULT;
 
 
-		(*frag)->priority = skb->priority;
-
 		sent += count;
 		sent += count;
 		len  -= count;
 		len  -= count;
 
 
@@ -2156,26 +2179,23 @@ static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
 }
 }
 
 
 static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
 static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
-						 struct msghdr *msg, size_t len,
-						 u32 priority)
+						 struct msghdr *msg, size_t len)
 {
 {
 	struct l2cap_conn *conn = chan->conn;
 	struct l2cap_conn *conn = chan->conn;
 	struct sk_buff *skb;
 	struct sk_buff *skb;
 	int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
 	int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
 	struct l2cap_hdr *lh;
 	struct l2cap_hdr *lh;
 
 
-	BT_DBG("chan %p psm 0x%2.2x len %zu priority %u", chan,
-	       __le16_to_cpu(chan->psm), len, priority);
+	BT_DBG("chan %p psm 0x%2.2x len %zu", chan,
+	       __le16_to_cpu(chan->psm), len);
 
 
 	count = min_t(unsigned int, (conn->mtu - hlen), len);
 	count = min_t(unsigned int, (conn->mtu - hlen), len);
 
 
-	skb = chan->ops->alloc_skb(chan, count + hlen,
+	skb = chan->ops->alloc_skb(chan, hlen, count,
 				   msg->msg_flags & MSG_DONTWAIT);
 				   msg->msg_flags & MSG_DONTWAIT);
 	if (IS_ERR(skb))
 	if (IS_ERR(skb))
 		return skb;
 		return skb;
 
 
-	skb->priority = priority;
-
 	/* Create L2CAP header */
 	/* Create L2CAP header */
 	lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
 	lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
 	lh->cid = cpu_to_le16(chan->dcid);
 	lh->cid = cpu_to_le16(chan->dcid);
@@ -2191,8 +2211,7 @@ static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
 }
 }
 
 
 static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
 static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
-					      struct msghdr *msg, size_t len,
-					      u32 priority)
+					      struct msghdr *msg, size_t len)
 {
 {
 	struct l2cap_conn *conn = chan->conn;
 	struct l2cap_conn *conn = chan->conn;
 	struct sk_buff *skb;
 	struct sk_buff *skb;
@@ -2203,13 +2222,11 @@ static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
 
 
 	count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
 	count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
 
 
-	skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
+	skb = chan->ops->alloc_skb(chan, L2CAP_HDR_SIZE, count,
 				   msg->msg_flags & MSG_DONTWAIT);
 				   msg->msg_flags & MSG_DONTWAIT);
 	if (IS_ERR(skb))
 	if (IS_ERR(skb))
 		return skb;
 		return skb;
 
 
-	skb->priority = priority;
-
 	/* Create L2CAP header */
 	/* Create L2CAP header */
 	lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
 	lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
 	lh->cid = cpu_to_le16(chan->dcid);
 	lh->cid = cpu_to_le16(chan->dcid);
@@ -2247,7 +2264,7 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
 
 
 	count = min_t(unsigned int, (conn->mtu - hlen), len);
 	count = min_t(unsigned int, (conn->mtu - hlen), len);
 
 
-	skb = chan->ops->alloc_skb(chan, count + hlen,
+	skb = chan->ops->alloc_skb(chan, hlen, count,
 				   msg->msg_flags & MSG_DONTWAIT);
 				   msg->msg_flags & MSG_DONTWAIT);
 	if (IS_ERR(skb))
 	if (IS_ERR(skb))
 		return skb;
 		return skb;
@@ -2368,7 +2385,7 @@ static struct sk_buff *l2cap_create_le_flowctl_pdu(struct l2cap_chan *chan,
 
 
 	count = min_t(unsigned int, (conn->mtu - hlen), len);
 	count = min_t(unsigned int, (conn->mtu - hlen), len);
 
 
-	skb = chan->ops->alloc_skb(chan, count + hlen,
+	skb = chan->ops->alloc_skb(chan, hlen, count,
 				   msg->msg_flags & MSG_DONTWAIT);
 				   msg->msg_flags & MSG_DONTWAIT);
 	if (IS_ERR(skb))
 	if (IS_ERR(skb))
 		return skb;
 		return skb;
@@ -2430,8 +2447,7 @@ static int l2cap_segment_le_sdu(struct l2cap_chan *chan,
 	return 0;
 	return 0;
 }
 }
 
 
-int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
-		    u32 priority)
+int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
 {
 {
 	struct sk_buff *skb;
 	struct sk_buff *skb;
 	int err;
 	int err;
@@ -2442,7 +2458,7 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
 
 
 	/* Connectionless channel */
 	/* Connectionless channel */
 	if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
 	if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
-		skb = l2cap_create_connless_pdu(chan, msg, len, priority);
+		skb = l2cap_create_connless_pdu(chan, msg, len);
 		if (IS_ERR(skb))
 		if (IS_ERR(skb))
 			return PTR_ERR(skb);
 			return PTR_ERR(skb);
 
 
@@ -2499,7 +2515,7 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
 			return -EMSGSIZE;
 			return -EMSGSIZE;
 
 
 		/* Create a basic PDU */
 		/* Create a basic PDU */
-		skb = l2cap_create_basic_pdu(chan, msg, len, priority);
+		skb = l2cap_create_basic_pdu(chan, msg, len);
 		if (IS_ERR(skb))
 		if (IS_ERR(skb))
 			return PTR_ERR(skb);
 			return PTR_ERR(skb);
 
 
@@ -2562,6 +2578,7 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
 
 
 	return err;
 	return err;
 }
 }
+EXPORT_SYMBOL_GPL(l2cap_chan_send);
 
 
 static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
 static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
 {
 {
@@ -3217,6 +3234,9 @@ done:
 
 
 	switch (chan->mode) {
 	switch (chan->mode) {
 	case L2CAP_MODE_BASIC:
 	case L2CAP_MODE_BASIC:
+		if (disable_ertm)
+			break;
+
 		if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
 		if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
 		    !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
 		    !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
 			break;
 			break;
@@ -5197,27 +5217,6 @@ static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
 	return 0;
 	return 0;
 }
 }
 
 
-static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
-					 u16 to_multiplier)
-{
-	u16 max_latency;
-
-	if (min > max || min < 6 || max > 3200)
-		return -EINVAL;
-
-	if (to_multiplier < 10 || to_multiplier > 3200)
-		return -EINVAL;
-
-	if (max >= to_multiplier * 8)
-		return -EINVAL;
-
-	max_latency = (to_multiplier * 8 / max) - 1;
-	if (latency > 499 || latency > max_latency)
-		return -EINVAL;
-
-	return 0;
-}
-
 static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
 static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
 					      struct l2cap_cmd_hdr *cmd,
 					      struct l2cap_cmd_hdr *cmd,
 					      u16 cmd_len, u8 *data)
 					      u16 cmd_len, u8 *data)
@@ -5228,7 +5227,7 @@ static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
 	u16 min, max, latency, to_multiplier;
 	u16 min, max, latency, to_multiplier;
 	int err;
 	int err;
 
 
-	if (!(hcon->link_mode & HCI_LM_MASTER))
+	if (!test_bit(HCI_CONN_MASTER, &hcon->flags))
 		return -EINVAL;
 		return -EINVAL;
 
 
 	if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
 	if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
@@ -5245,7 +5244,7 @@ static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
 
 
 	memset(&rsp, 0, sizeof(rsp));
 	memset(&rsp, 0, sizeof(rsp));
 
 
-	err = l2cap_check_conn_param(min, max, latency, to_multiplier);
+	err = hci_check_conn_params(min, max, latency, to_multiplier);
 	if (err)
 	if (err)
 		rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
 		rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
 	else
 	else
@@ -5254,8 +5253,16 @@ static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
 	l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
 	l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
 		       sizeof(rsp), &rsp);
 		       sizeof(rsp), &rsp);
 
 
-	if (!err)
-		hci_le_conn_update(hcon, min, max, latency, to_multiplier);
+	if (!err) {
+		u8 store_hint;
+
+		store_hint = hci_le_conn_update(hcon, min, max, latency,
+						to_multiplier);
+		mgmt_new_conn_param(hcon->hdev, &hcon->dst, hcon->dst_type,
+				    store_hint, min, max, latency,
+				    to_multiplier);
+
+	}
 
 
 	return 0;
 	return 0;
 }
 }
@@ -6879,9 +6886,6 @@ static void l2cap_att_channel(struct l2cap_conn *conn,
 
 
 	BT_DBG("chan %p, len %d", chan, skb->len);
 	BT_DBG("chan %p, len %d", chan, skb->len);
 
 
-	if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, hcon->dst_type))
-		goto drop;
-
 	if (chan->imtu < skb->len)
 	if (chan->imtu < skb->len)
 		goto drop;
 		goto drop;
 
 
@@ -6914,6 +6918,16 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
 		return;
 		return;
 	}
 	}
 
 
+	/* Since we can't actively block incoming LE connections we must
+	 * at least ensure that we ignore incoming data from them.
+	 */
+	if (hcon->type == LE_LINK &&
+	    hci_bdaddr_list_lookup(&hcon->hdev->blacklist, &hcon->dst,
+				   bdaddr_type(hcon, hcon->dst_type))) {
+		kfree_skb(skb);
+		return;
+	}
+
 	BT_DBG("len %d, cid 0x%4.4x", len, cid);
 	BT_DBG("len %d, cid 0x%4.4x", len, cid);
 
 
 	switch (cid) {
 	switch (cid) {
@@ -6940,10 +6954,6 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
 			l2cap_conn_del(conn->hcon, EACCES);
 			l2cap_conn_del(conn->hcon, EACCES);
 		break;
 		break;
 
 
-	case L2CAP_FC_6LOWPAN:
-		bt_6lowpan_recv(conn, skb);
-		break;
-
 	default:
 	default:
 		l2cap_data_channel(conn, cid, skb);
 		l2cap_data_channel(conn, cid, skb);
 		break;
 		break;
@@ -7042,7 +7052,6 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
 	struct l2cap_conn *conn;
 	struct l2cap_conn *conn;
 	struct hci_conn *hcon;
 	struct hci_conn *hcon;
 	struct hci_dev *hdev;
 	struct hci_dev *hdev;
-	__u8 auth_type;
 	int err;
 	int err;
 
 
 	BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", &chan->src, dst,
 	BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", &chan->src, dst,
@@ -7118,9 +7127,9 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
 	chan->psm = psm;
 	chan->psm = psm;
 	chan->dcid = cid;
 	chan->dcid = cid;
 
 
-	auth_type = l2cap_get_auth_type(chan);
-
 	if (bdaddr_type_is_le(dst_type)) {
 	if (bdaddr_type_is_le(dst_type)) {
+		bool master;
+
 		/* Convert from L2CAP channel address type to HCI address type
 		/* Convert from L2CAP channel address type to HCI address type
 		 */
 		 */
 		if (dst_type == BDADDR_LE_PUBLIC)
 		if (dst_type == BDADDR_LE_PUBLIC)
@@ -7128,9 +7137,12 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
 		else
 		else
 			dst_type = ADDR_LE_DEV_RANDOM;
 			dst_type = ADDR_LE_DEV_RANDOM;
 
 
+		master = !test_bit(HCI_ADVERTISING, &hdev->dev_flags);
+
 		hcon = hci_connect_le(hdev, dst, dst_type, chan->sec_level,
 		hcon = hci_connect_le(hdev, dst, dst_type, chan->sec_level,
-				      auth_type);
+				      HCI_LE_CONN_TIMEOUT, master);
 	} else {
 	} else {
+		u8 auth_type = l2cap_get_auth_type(chan);
 		hcon = hci_connect_acl(hdev, dst, chan->sec_level, auth_type);
 		hcon = hci_connect_acl(hdev, dst, chan->sec_level, auth_type);
 	}
 	}
 
 
@@ -7190,6 +7202,7 @@ done:
 	hci_dev_put(hdev);
 	hci_dev_put(hdev);
 	return err;
 	return err;
 }
 }
+EXPORT_SYMBOL_GPL(l2cap_chan_connect);
 
 
 /* ---- L2CAP interface with lower layer (HCI) ---- */
 /* ---- L2CAP interface with lower layer (HCI) ---- */
 
 
@@ -7252,8 +7265,6 @@ void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
 {
 {
 	BT_DBG("hcon %p reason %d", hcon, reason);
 	BT_DBG("hcon %p reason %d", hcon, reason);
 
 
-	bt_6lowpan_del_conn(hcon->l2cap_data);
-
 	l2cap_conn_del(hcon, bt_to_errno(reason));
 	l2cap_conn_del(hcon, bt_to_errno(reason));
 }
 }
 
 
@@ -7536,14 +7547,11 @@ int __init l2cap_init(void)
 	debugfs_create_u16("l2cap_le_default_mps", 0644, bt_debugfs,
 	debugfs_create_u16("l2cap_le_default_mps", 0644, bt_debugfs,
 			   &le_default_mps);
 			   &le_default_mps);
 
 
-	bt_6lowpan_init();
-
 	return 0;
 	return 0;
 }
 }
 
 
 void l2cap_exit(void)
 void l2cap_exit(void)
 {
 {
-	bt_6lowpan_cleanup();
 	debugfs_remove(l2cap_debugfs);
 	debugfs_remove(l2cap_debugfs);
 	l2cap_cleanup_sockets();
 	l2cap_cleanup_sockets();
 }
 }

+ 29 - 17
net/bluetooth/l2cap_sock.c

@@ -361,7 +361,8 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr,
 	BT_DBG("sock %p, sk %p", sock, sk);
 	BT_DBG("sock %p, sk %p", sock, sk);
 
 
 	if (peer && sk->sk_state != BT_CONNECTED &&
 	if (peer && sk->sk_state != BT_CONNECTED &&
-	    sk->sk_state != BT_CONNECT && sk->sk_state != BT_CONNECT2)
+	    sk->sk_state != BT_CONNECT && sk->sk_state != BT_CONNECT2 &&
+	    sk->sk_state != BT_CONFIG)
 		return -ENOTCONN;
 		return -ENOTCONN;
 
 
 	memset(la, 0, sizeof(struct sockaddr_l2));
 	memset(la, 0, sizeof(struct sockaddr_l2));
@@ -964,7 +965,7 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
 		return err;
 		return err;
 
 
 	l2cap_chan_lock(chan);
 	l2cap_chan_lock(chan);
-	err = l2cap_chan_send(chan, msg, len, sk->sk_priority);
+	err = l2cap_chan_send(chan, msg, len);
 	l2cap_chan_unlock(chan);
 	l2cap_chan_unlock(chan);
 
 
 	return err;
 	return err;
@@ -1292,6 +1293,7 @@ static void l2cap_sock_state_change_cb(struct l2cap_chan *chan, int state,
 }
 }
 
 
 static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan,
 static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan,
+					       unsigned long hdr_len,
 					       unsigned long len, int nb)
 					       unsigned long len, int nb)
 {
 {
 	struct sock *sk = chan->data;
 	struct sock *sk = chan->data;
@@ -1299,17 +1301,26 @@ static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan,
 	int err;
 	int err;
 
 
 	l2cap_chan_unlock(chan);
 	l2cap_chan_unlock(chan);
-	skb = bt_skb_send_alloc(sk, len, nb, &err);
+	skb = bt_skb_send_alloc(sk, hdr_len + len, nb, &err);
 	l2cap_chan_lock(chan);
 	l2cap_chan_lock(chan);
 
 
 	if (!skb)
 	if (!skb)
 		return ERR_PTR(err);
 		return ERR_PTR(err);
 
 
+	skb->priority = sk->sk_priority;
+
 	bt_cb(skb)->chan = chan;
 	bt_cb(skb)->chan = chan;
 
 
 	return skb;
 	return skb;
 }
 }
 
 
+static int l2cap_sock_memcpy_fromiovec_cb(struct l2cap_chan *chan,
+					  unsigned char *kdata,
+					  struct iovec *iov, int len)
+{
+	return memcpy_fromiovec(kdata, iov, len);
+}
+
 static void l2cap_sock_ready_cb(struct l2cap_chan *chan)
 static void l2cap_sock_ready_cb(struct l2cap_chan *chan)
 {
 {
 	struct sock *sk = chan->data;
 	struct sock *sk = chan->data;
@@ -1375,20 +1386,21 @@ static void l2cap_sock_suspend_cb(struct l2cap_chan *chan)
 	sk->sk_state_change(sk);
 	sk->sk_state_change(sk);
 }
 }
 
 
-static struct l2cap_ops l2cap_chan_ops = {
-	.name		= "L2CAP Socket Interface",
-	.new_connection	= l2cap_sock_new_connection_cb,
-	.recv		= l2cap_sock_recv_cb,
-	.close		= l2cap_sock_close_cb,
-	.teardown	= l2cap_sock_teardown_cb,
-	.state_change	= l2cap_sock_state_change_cb,
-	.ready		= l2cap_sock_ready_cb,
-	.defer		= l2cap_sock_defer_cb,
-	.resume		= l2cap_sock_resume_cb,
-	.suspend	= l2cap_sock_suspend_cb,
-	.set_shutdown	= l2cap_sock_set_shutdown_cb,
-	.get_sndtimeo	= l2cap_sock_get_sndtimeo_cb,
-	.alloc_skb	= l2cap_sock_alloc_skb_cb,
+static const struct l2cap_ops l2cap_chan_ops = {
+	.name			= "L2CAP Socket Interface",
+	.new_connection		= l2cap_sock_new_connection_cb,
+	.recv			= l2cap_sock_recv_cb,
+	.close			= l2cap_sock_close_cb,
+	.teardown		= l2cap_sock_teardown_cb,
+	.state_change		= l2cap_sock_state_change_cb,
+	.ready			= l2cap_sock_ready_cb,
+	.defer			= l2cap_sock_defer_cb,
+	.resume			= l2cap_sock_resume_cb,
+	.suspend		= l2cap_sock_suspend_cb,
+	.set_shutdown		= l2cap_sock_set_shutdown_cb,
+	.get_sndtimeo		= l2cap_sock_get_sndtimeo_cb,
+	.alloc_skb		= l2cap_sock_alloc_skb_cb,
+	.memcpy_fromiovec	= l2cap_sock_memcpy_fromiovec_cb,
 };
 };
 
 
 static void l2cap_sock_destruct(struct sock *sk)
 static void l2cap_sock_destruct(struct sock *sk)

+ 1060 - 194
net/bluetooth/mgmt.c

@@ -35,7 +35,7 @@
 #include "smp.h"
 #include "smp.h"
 
 
 #define MGMT_VERSION	1
 #define MGMT_VERSION	1
-#define MGMT_REVISION	6
+#define MGMT_REVISION	7
 
 
 static const u16 mgmt_commands[] = {
 static const u16 mgmt_commands[] = {
 	MGMT_OP_READ_INDEX_LIST,
 	MGMT_OP_READ_INDEX_LIST,
@@ -85,6 +85,14 @@ static const u16 mgmt_commands[] = {
 	MGMT_OP_SET_PRIVACY,
 	MGMT_OP_SET_PRIVACY,
 	MGMT_OP_LOAD_IRKS,
 	MGMT_OP_LOAD_IRKS,
 	MGMT_OP_GET_CONN_INFO,
 	MGMT_OP_GET_CONN_INFO,
+	MGMT_OP_GET_CLOCK_INFO,
+	MGMT_OP_ADD_DEVICE,
+	MGMT_OP_REMOVE_DEVICE,
+	MGMT_OP_LOAD_CONN_PARAM,
+	MGMT_OP_READ_UNCONF_INDEX_LIST,
+	MGMT_OP_READ_CONFIG_INFO,
+	MGMT_OP_SET_EXTERNAL_CONFIG,
+	MGMT_OP_SET_PUBLIC_ADDRESS,
 };
 };
 
 
 static const u16 mgmt_events[] = {
 static const u16 mgmt_events[] = {
@@ -111,6 +119,12 @@ static const u16 mgmt_events[] = {
 	MGMT_EV_PASSKEY_NOTIFY,
 	MGMT_EV_PASSKEY_NOTIFY,
 	MGMT_EV_NEW_IRK,
 	MGMT_EV_NEW_IRK,
 	MGMT_EV_NEW_CSRK,
 	MGMT_EV_NEW_CSRK,
+	MGMT_EV_DEVICE_ADDED,
+	MGMT_EV_DEVICE_REMOVED,
+	MGMT_EV_NEW_CONN_PARAM,
+	MGMT_EV_UNCONF_INDEX_ADDED,
+	MGMT_EV_UNCONF_INDEX_REMOVED,
+	MGMT_EV_NEW_CONFIG_OPTIONS,
 };
 };
 
 
 #define CACHE_TIMEOUT	msecs_to_jiffies(2 * 1000)
 #define CACHE_TIMEOUT	msecs_to_jiffies(2 * 1000)
@@ -200,6 +214,36 @@ static u8 mgmt_status(u8 hci_status)
 	return MGMT_STATUS_FAILED;
 	return MGMT_STATUS_FAILED;
 }
 }
 
 
+static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, u16 data_len,
+		      struct sock *skip_sk)
+{
+	struct sk_buff *skb;
+	struct mgmt_hdr *hdr;
+
+	skb = alloc_skb(sizeof(*hdr) + data_len, GFP_KERNEL);
+	if (!skb)
+		return -ENOMEM;
+
+	hdr = (void *) skb_put(skb, sizeof(*hdr));
+	hdr->opcode = cpu_to_le16(event);
+	if (hdev)
+		hdr->index = cpu_to_le16(hdev->id);
+	else
+		hdr->index = cpu_to_le16(MGMT_INDEX_NONE);
+	hdr->len = cpu_to_le16(data_len);
+
+	if (data)
+		memcpy(skb_put(skb, data_len), data, data_len);
+
+	/* Time stamp */
+	__net_timestamp(skb);
+
+	hci_send_to_control(skb, skip_sk);
+	kfree_skb(skb);
+
+	return 0;
+}
+
 static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status)
 static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status)
 {
 {
 	struct sk_buff *skb;
 	struct sk_buff *skb;
@@ -327,7 +371,8 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data,
 
 
 	count = 0;
 	count = 0;
 	list_for_each_entry(d, &hci_dev_list, list) {
 	list_for_each_entry(d, &hci_dev_list, list) {
-		if (d->dev_type == HCI_BREDR)
+		if (d->dev_type == HCI_BREDR &&
+		    !test_bit(HCI_UNCONFIGURED, &d->dev_flags))
 			count++;
 			count++;
 	}
 	}
 
 
@@ -340,13 +385,19 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data,
 
 
 	count = 0;
 	count = 0;
 	list_for_each_entry(d, &hci_dev_list, list) {
 	list_for_each_entry(d, &hci_dev_list, list) {
-		if (test_bit(HCI_SETUP, &d->dev_flags))
+		if (test_bit(HCI_SETUP, &d->dev_flags) ||
+		    test_bit(HCI_CONFIG, &d->dev_flags) ||
+		    test_bit(HCI_USER_CHANNEL, &d->dev_flags))
 			continue;
 			continue;
 
 
-		if (test_bit(HCI_USER_CHANNEL, &d->dev_flags))
+		/* Devices marked as raw-only are neither configured
+		 * nor unconfigured controllers.
+		 */
+		if (test_bit(HCI_QUIRK_RAW_DEVICE, &d->quirks))
 			continue;
 			continue;
 
 
-		if (d->dev_type == HCI_BREDR) {
+		if (d->dev_type == HCI_BREDR &&
+		    !test_bit(HCI_UNCONFIGURED, &d->dev_flags)) {
 			rp->index[count++] = cpu_to_le16(d->id);
 			rp->index[count++] = cpu_to_le16(d->id);
 			BT_DBG("Added hci%u", d->id);
 			BT_DBG("Added hci%u", d->id);
 		}
 		}
@@ -365,6 +416,138 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data,
 	return err;
 	return err;
 }
 }
 
 
+static int read_unconf_index_list(struct sock *sk, struct hci_dev *hdev,
+				  void *data, u16 data_len)
+{
+	struct mgmt_rp_read_unconf_index_list *rp;
+	struct hci_dev *d;
+	size_t rp_len;
+	u16 count;
+	int err;
+
+	BT_DBG("sock %p", sk);
+
+	read_lock(&hci_dev_list_lock);
+
+	count = 0;
+	list_for_each_entry(d, &hci_dev_list, list) {
+		if (d->dev_type == HCI_BREDR &&
+		    test_bit(HCI_UNCONFIGURED, &d->dev_flags))
+			count++;
+	}
+
+	rp_len = sizeof(*rp) + (2 * count);
+	rp = kmalloc(rp_len, GFP_ATOMIC);
+	if (!rp) {
+		read_unlock(&hci_dev_list_lock);
+		return -ENOMEM;
+	}
+
+	count = 0;
+	list_for_each_entry(d, &hci_dev_list, list) {
+		if (test_bit(HCI_SETUP, &d->dev_flags) ||
+		    test_bit(HCI_CONFIG, &d->dev_flags) ||
+		    test_bit(HCI_USER_CHANNEL, &d->dev_flags))
+			continue;
+
+		/* Devices marked as raw-only are neither configured
+		 * nor unconfigured controllers.
+		 */
+		if (test_bit(HCI_QUIRK_RAW_DEVICE, &d->quirks))
+			continue;
+
+		if (d->dev_type == HCI_BREDR &&
+		    test_bit(HCI_UNCONFIGURED, &d->dev_flags)) {
+			rp->index[count++] = cpu_to_le16(d->id);
+			BT_DBG("Added hci%u", d->id);
+		}
+	}
+
+	rp->num_controllers = cpu_to_le16(count);
+	rp_len = sizeof(*rp) + (2 * count);
+
+	read_unlock(&hci_dev_list_lock);
+
+	err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_UNCONF_INDEX_LIST,
+			   0, rp, rp_len);
+
+	kfree(rp);
+
+	return err;
+}
+
+static bool is_configured(struct hci_dev *hdev)
+{
+	if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) &&
+	    !test_bit(HCI_EXT_CONFIGURED, &hdev->dev_flags))
+		return false;
+
+	if (test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks) &&
+	    !bacmp(&hdev->public_addr, BDADDR_ANY))
+		return false;
+
+	return true;
+}
+
+static __le32 get_missing_options(struct hci_dev *hdev)
+{
+	u32 options = 0;
+
+	if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) &&
+	    !test_bit(HCI_EXT_CONFIGURED, &hdev->dev_flags))
+		options |= MGMT_OPTION_EXTERNAL_CONFIG;
+
+	if (test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks) &&
+	    !bacmp(&hdev->public_addr, BDADDR_ANY))
+		options |= MGMT_OPTION_PUBLIC_ADDRESS;
+
+	return cpu_to_le32(options);
+}
+
+static int new_options(struct hci_dev *hdev, struct sock *skip)
+{
+	__le32 options = get_missing_options(hdev);
+
+	return mgmt_event(MGMT_EV_NEW_CONFIG_OPTIONS, hdev, &options,
+			  sizeof(options), skip);
+}
+
+static int send_options_rsp(struct sock *sk, u16 opcode, struct hci_dev *hdev)
+{
+	__le32 options = get_missing_options(hdev);
+
+	return cmd_complete(sk, hdev->id, opcode, 0, &options,
+			    sizeof(options));
+}
+
+static int read_config_info(struct sock *sk, struct hci_dev *hdev,
+			    void *data, u16 data_len)
+{
+	struct mgmt_rp_read_config_info rp;
+	u32 options = 0;
+
+	BT_DBG("sock %p %s", sk, hdev->name);
+
+	hci_dev_lock(hdev);
+
+	memset(&rp, 0, sizeof(rp));
+	rp.manufacturer = cpu_to_le16(hdev->manufacturer);
+
+	if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks))
+		options |= MGMT_OPTION_EXTERNAL_CONFIG;
+
+	if (hdev->set_bdaddr)
+		options |= MGMT_OPTION_PUBLIC_ADDRESS;
+
+	rp.supported_options = cpu_to_le32(options);
+	rp.missing_options = get_missing_options(hdev);
+
+	hci_dev_unlock(hdev);
+
+	return cmd_complete(sk, hdev->id, MGMT_OP_READ_CONFIG_INFO, 0, &rp,
+			    sizeof(rp));
+}
+
 static u32 get_supported_settings(struct hci_dev *hdev)
 static u32 get_supported_settings(struct hci_dev *hdev)
 {
 {
 	u32 settings = 0;
 	u32 settings = 0;
@@ -372,12 +555,12 @@ static u32 get_supported_settings(struct hci_dev *hdev)
 	settings |= MGMT_SETTING_POWERED;
 	settings |= MGMT_SETTING_POWERED;
 	settings |= MGMT_SETTING_PAIRABLE;
 	settings |= MGMT_SETTING_PAIRABLE;
 	settings |= MGMT_SETTING_DEBUG_KEYS;
 	settings |= MGMT_SETTING_DEBUG_KEYS;
+	settings |= MGMT_SETTING_CONNECTABLE;
+	settings |= MGMT_SETTING_DISCOVERABLE;
 
 
 	if (lmp_bredr_capable(hdev)) {
 	if (lmp_bredr_capable(hdev)) {
-		settings |= MGMT_SETTING_CONNECTABLE;
 		if (hdev->hci_ver >= BLUETOOTH_VER_1_2)
 		if (hdev->hci_ver >= BLUETOOTH_VER_1_2)
 			settings |= MGMT_SETTING_FAST_CONNECTABLE;
 			settings |= MGMT_SETTING_FAST_CONNECTABLE;
-		settings |= MGMT_SETTING_DISCOVERABLE;
 		settings |= MGMT_SETTING_BREDR;
 		settings |= MGMT_SETTING_BREDR;
 		settings |= MGMT_SETTING_LINK_SECURITY;
 		settings |= MGMT_SETTING_LINK_SECURITY;
 
 
@@ -387,7 +570,7 @@ static u32 get_supported_settings(struct hci_dev *hdev)
 		}
 		}
 
 
 		if (lmp_sc_capable(hdev) ||
 		if (lmp_sc_capable(hdev) ||
-		    test_bit(HCI_FORCE_SC, &hdev->dev_flags))
+		    test_bit(HCI_FORCE_SC, &hdev->dbg_flags))
 			settings |= MGMT_SETTING_SECURE_CONN;
 			settings |= MGMT_SETTING_SECURE_CONN;
 	}
 	}
 
 
@@ -397,6 +580,10 @@ static u32 get_supported_settings(struct hci_dev *hdev)
 		settings |= MGMT_SETTING_PRIVACY;
 		settings |= MGMT_SETTING_PRIVACY;
 	}
 	}
 
 
+	if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) ||
+	    hdev->set_bdaddr)
+		settings |= MGMT_SETTING_CONFIGURATION;
+
 	return settings;
 	return settings;
 }
 }
 
 
@@ -440,7 +627,7 @@ static u32 get_current_settings(struct hci_dev *hdev)
 	if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags))
 	if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags))
 		settings |= MGMT_SETTING_SECURE_CONN;
 		settings |= MGMT_SETTING_SECURE_CONN;
 
 
-	if (test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags))
+	if (test_bit(HCI_KEEP_DEBUG_KEYS, &hdev->dev_flags))
 		settings |= MGMT_SETTING_DEBUG_KEYS;
 		settings |= MGMT_SETTING_DEBUG_KEYS;
 
 
 	if (test_bit(HCI_PRIVACY, &hdev->dev_flags))
 	if (test_bit(HCI_PRIVACY, &hdev->dev_flags))
@@ -571,6 +758,22 @@ static struct pending_cmd *mgmt_pending_find(u16 opcode, struct hci_dev *hdev)
 	return NULL;
 	return NULL;
 }
 }
 
 
+static struct pending_cmd *mgmt_pending_find_data(u16 opcode,
+						  struct hci_dev *hdev,
+						  const void *data)
+{
+	struct pending_cmd *cmd;
+
+	list_for_each_entry(cmd, &hdev->mgmt_pending, list) {
+		if (cmd->user_data != data)
+			continue;
+		if (cmd->opcode == opcode)
+			return cmd;
+	}
+
+	return NULL;
+}
+
 static u8 create_scan_rsp_data(struct hci_dev *hdev, u8 *ptr)
 static u8 create_scan_rsp_data(struct hci_dev *hdev, u8 *ptr)
 {
 {
 	u8 ad_len = 0;
 	u8 ad_len = 0;
@@ -836,6 +1039,13 @@ static bool get_connectable(struct hci_dev *hdev)
 	return test_bit(HCI_CONNECTABLE, &hdev->dev_flags);
 	return test_bit(HCI_CONNECTABLE, &hdev->dev_flags);
 }
 }
 
 
+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)
 static void enable_advertising(struct hci_request *req)
 {
 {
 	struct hci_dev *hdev = req->hdev;
 	struct hci_dev *hdev = req->hdev;
@@ -843,12 +1053,18 @@ static void enable_advertising(struct hci_request *req)
 	u8 own_addr_type, enable = 0x01;
 	u8 own_addr_type, enable = 0x01;
 	bool connectable;
 	bool connectable;
 
 
-	/* Clear the HCI_ADVERTISING bit temporarily so that the
+	if (hci_conn_num(hdev, LE_LINK) > 0)
+		return;
+
+	if (test_bit(HCI_LE_ADV, &hdev->dev_flags))
+		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
 	 * 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
 	 * and write a new random address. The flag will be set back on
 	 * as soon as the SET_ADV_ENABLE HCI command completes.
 	 * as soon as the SET_ADV_ENABLE HCI command completes.
 	 */
 	 */
-	clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
+	clear_bit(HCI_LE_ADV, &hdev->dev_flags);
 
 
 	connectable = get_connectable(hdev);
 	connectable = get_connectable(hdev);
 
 
@@ -871,13 +1087,6 @@ static void enable_advertising(struct hci_request *req)
 	hci_req_add(req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable);
 	hci_req_add(req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable);
 }
 }
 
 
-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 service_cache_off(struct work_struct *work)
 static void service_cache_off(struct work_struct *work)
 {
 {
 	struct hci_dev *hdev = container_of(work, struct hci_dev,
 	struct hci_dev *hdev = container_of(work, struct hci_dev,
@@ -909,19 +1118,14 @@ static void rpa_expired(struct work_struct *work)
 
 
 	set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags);
 	set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags);
 
 
-	if (!test_bit(HCI_ADVERTISING, &hdev->dev_flags) ||
-	    hci_conn_num(hdev, LE_LINK) > 0)
+	if (!test_bit(HCI_ADVERTISING, &hdev->dev_flags))
 		return;
 		return;
 
 
 	/* The generation of a new RPA and programming it into the
 	/* The generation of a new RPA and programming it into the
 	 * controller happens in the enable_advertising() function.
 	 * controller happens in the enable_advertising() function.
 	 */
 	 */
-
 	hci_req_init(&req, hdev);
 	hci_req_init(&req, hdev);
-
-	disable_advertising(&req);
 	enable_advertising(&req);
 	enable_advertising(&req);
-
 	hci_req_run(&req, NULL);
 	hci_req_run(&req, NULL);
 }
 }
 
 
@@ -984,7 +1188,7 @@ static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode,
 {
 {
 	struct pending_cmd *cmd;
 	struct pending_cmd *cmd;
 
 
-	cmd = kmalloc(sizeof(*cmd), GFP_KERNEL);
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
 	if (!cmd)
 	if (!cmd)
 		return NULL;
 		return NULL;
 
 
@@ -1047,7 +1251,7 @@ static void clean_up_hci_complete(struct hci_dev *hdev, u8 status)
 	}
 	}
 }
 }
 
 
-static void hci_stop_discovery(struct hci_request *req)
+static bool hci_stop_discovery(struct hci_request *req)
 {
 {
 	struct hci_dev *hdev = req->hdev;
 	struct hci_dev *hdev = req->hdev;
 	struct hci_cp_remote_name_req_cancel cp;
 	struct hci_cp_remote_name_req_cancel cp;
@@ -1062,32 +1266,39 @@ static void hci_stop_discovery(struct hci_request *req)
 			hci_req_add_le_scan_disable(req);
 			hci_req_add_le_scan_disable(req);
 		}
 		}
 
 
-		break;
+		return true;
 
 
 	case DISCOVERY_RESOLVING:
 	case DISCOVERY_RESOLVING:
 		e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY,
 		e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY,
 						     NAME_PENDING);
 						     NAME_PENDING);
 		if (!e)
 		if (!e)
-			return;
+			break;
 
 
 		bacpy(&cp.bdaddr, &e->data.bdaddr);
 		bacpy(&cp.bdaddr, &e->data.bdaddr);
 		hci_req_add(req, HCI_OP_REMOTE_NAME_REQ_CANCEL, sizeof(cp),
 		hci_req_add(req, HCI_OP_REMOTE_NAME_REQ_CANCEL, sizeof(cp),
 			    &cp);
 			    &cp);
 
 
-		break;
+		return true;
 
 
 	default:
 	default:
 		/* Passive scanning */
 		/* Passive scanning */
-		if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
+		if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) {
 			hci_req_add_le_scan_disable(req);
 			hci_req_add_le_scan_disable(req);
+			return true;
+		}
+
 		break;
 		break;
 	}
 	}
+
+	return false;
 }
 }
 
 
 static int clean_up_hci_state(struct hci_dev *hdev)
 static int clean_up_hci_state(struct hci_dev *hdev)
 {
 {
 	struct hci_request req;
 	struct hci_request req;
 	struct hci_conn *conn;
 	struct hci_conn *conn;
+	bool discov_stopped;
+	int err;
 
 
 	hci_req_init(&req, hdev);
 	hci_req_init(&req, hdev);
 
 
@@ -1097,10 +1308,10 @@ static int clean_up_hci_state(struct hci_dev *hdev)
 		hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
 		hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
 	}
 	}
 
 
-	if (test_bit(HCI_ADVERTISING, &hdev->dev_flags))
+	if (test_bit(HCI_LE_ADV, &hdev->dev_flags))
 		disable_advertising(&req);
 		disable_advertising(&req);
 
 
-	hci_stop_discovery(&req);
+	discov_stopped = hci_stop_discovery(&req);
 
 
 	list_for_each_entry(conn, &hdev->conn_hash.list, list) {
 	list_for_each_entry(conn, &hdev->conn_hash.list, list) {
 		struct hci_cp_disconnect dc;
 		struct hci_cp_disconnect dc;
@@ -1134,7 +1345,11 @@ static int clean_up_hci_state(struct hci_dev *hdev)
 		}
 		}
 	}
 	}
 
 
-	return hci_req_run(&req, clean_up_hci_complete);
+	err = hci_req_run(&req, clean_up_hci_complete);
+	if (!err && discov_stopped)
+		hci_discovery_set_state(hdev, DISCOVERY_STOPPING);
+
+	return err;
 }
 }
 
 
 static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data,
 static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data,
@@ -1203,36 +1418,6 @@ failed:
 	return err;
 	return err;
 }
 }
 
 
-static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, u16 data_len,
-		      struct sock *skip_sk)
-{
-	struct sk_buff *skb;
-	struct mgmt_hdr *hdr;
-
-	skb = alloc_skb(sizeof(*hdr) + data_len, GFP_KERNEL);
-	if (!skb)
-		return -ENOMEM;
-
-	hdr = (void *) skb_put(skb, sizeof(*hdr));
-	hdr->opcode = cpu_to_le16(event);
-	if (hdev)
-		hdr->index = cpu_to_le16(hdev->id);
-	else
-		hdr->index = cpu_to_le16(MGMT_INDEX_NONE);
-	hdr->len = cpu_to_le16(data_len);
-
-	if (data)
-		memcpy(skb_put(skb, data_len), data, data_len);
-
-	/* Time stamp */
-	__net_timestamp(skb);
-
-	hci_send_to_control(skb, skip_sk);
-	kfree_skb(skb);
-
-	return 0;
-}
-
 static int new_settings(struct hci_dev *hdev, struct sock *skip)
 static int new_settings(struct hci_dev *hdev, struct sock *skip)
 {
 {
 	__le32 ev;
 	__le32 ev;
@@ -1242,6 +1427,11 @@ static int new_settings(struct hci_dev *hdev, struct sock *skip)
 	return mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev), skip);
 	return mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev), skip);
 }
 }
 
 
+int mgmt_new_settings(struct hci_dev *hdev)
+{
+	return new_settings(hdev, NULL);
+}
+
 struct cmd_lookup {
 struct cmd_lookup {
 	struct sock *sk;
 	struct sock *sk;
 	struct hci_dev *hdev;
 	struct hci_dev *hdev;
@@ -1577,8 +1767,10 @@ static void set_connectable_complete(struct hci_dev *hdev, u8 status)
 
 
 	send_settings_rsp(cmd->sk, MGMT_OP_SET_CONNECTABLE, hdev);
 	send_settings_rsp(cmd->sk, MGMT_OP_SET_CONNECTABLE, hdev);
 
 
-	if (changed)
+	if (changed) {
 		new_settings(hdev, cmd->sk);
 		new_settings(hdev, cmd->sk);
+		hci_update_background_scan(hdev);
+	}
 
 
 remove_cmd:
 remove_cmd:
 	mgmt_pending_remove(cmd);
 	mgmt_pending_remove(cmd);
@@ -1607,8 +1799,10 @@ static int set_connectable_update_settings(struct hci_dev *hdev,
 	if (err < 0)
 	if (err < 0)
 		return err;
 		return err;
 
 
-	if (changed)
+	if (changed) {
+		hci_update_background_scan(hdev);
 		return new_settings(hdev, sk);
 		return new_settings(hdev, sk);
+	}
 
 
 	return 0;
 	return 0;
 }
 }
@@ -1689,10 +1883,8 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data,
 		write_fast_connectable(&req, false);
 		write_fast_connectable(&req, false);
 
 
 	if (test_bit(HCI_ADVERTISING, &hdev->dev_flags) &&
 	if (test_bit(HCI_ADVERTISING, &hdev->dev_flags) &&
-	    hci_conn_num(hdev, LE_LINK) == 0) {
-		disable_advertising(&req);
+	    !test_bit(HCI_LE_ADV, &hdev->dev_flags))
 		enable_advertising(&req);
 		enable_advertising(&req);
-	}
 
 
 	err = hci_req_run(&req, set_connectable_complete);
 	err = hci_req_run(&req, set_connectable_complete);
 	if (err < 0) {
 	if (err < 0) {
@@ -1877,6 +2069,10 @@ static int set_ssp(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
 		goto failed;
 		goto failed;
 	}
 	}
 
 
+	if (!cp->val && test_bit(HCI_USE_DEBUG_KEYS, &hdev->dev_flags))
+		hci_send_cmd(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE,
+			     sizeof(cp->val), &cp->val);
+
 	err = hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, 1, &cp->val);
 	err = hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, 1, &cp->val);
 	if (err < 0) {
 	if (err < 0) {
 		mgmt_pending_remove(cmd);
 		mgmt_pending_remove(cmd);
@@ -1973,6 +2169,8 @@ static void le_enable_complete(struct hci_dev *hdev, u8 status)
 		update_scan_rsp_data(&req);
 		update_scan_rsp_data(&req);
 		hci_req_run(&req, NULL);
 		hci_req_run(&req, NULL);
 
 
+		hci_update_background_scan(hdev);
+
 		hci_dev_unlock(hdev);
 		hci_dev_unlock(hdev);
 	}
 	}
 }
 }
@@ -2050,7 +2248,7 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
 		hci_cp.le = val;
 		hci_cp.le = val;
 		hci_cp.simul = lmp_le_br_capable(hdev);
 		hci_cp.simul = lmp_le_br_capable(hdev);
 	} else {
 	} else {
-		if (test_bit(HCI_ADVERTISING, &hdev->dev_flags))
+		if (test_bit(HCI_LE_ADV, &hdev->dev_flags))
 			disable_advertising(&req);
 			disable_advertising(&req);
 	}
 	}
 
 
@@ -2373,6 +2571,8 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data,
 			  u16 len)
 			  u16 len)
 {
 {
 	struct mgmt_cp_load_link_keys *cp = data;
 	struct mgmt_cp_load_link_keys *cp = data;
+	const u16 max_key_count = ((U16_MAX - sizeof(*cp)) /
+				   sizeof(struct mgmt_link_key_info));
 	u16 key_count, expected_len;
 	u16 key_count, expected_len;
 	bool changed;
 	bool changed;
 	int i;
 	int i;
@@ -2384,6 +2584,12 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data,
 				  MGMT_STATUS_NOT_SUPPORTED);
 				  MGMT_STATUS_NOT_SUPPORTED);
 
 
 	key_count = __le16_to_cpu(cp->key_count);
 	key_count = __le16_to_cpu(cp->key_count);
+	if (key_count > max_key_count) {
+		BT_ERR("load_link_keys: too big key_count value %u",
+		       key_count);
+		return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS,
+				  MGMT_STATUS_INVALID_PARAMS);
+	}
 
 
 	expected_len = sizeof(*cp) + key_count *
 	expected_len = sizeof(*cp) + key_count *
 					sizeof(struct mgmt_link_key_info);
 					sizeof(struct mgmt_link_key_info);
@@ -2414,9 +2620,11 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data,
 	hci_link_keys_clear(hdev);
 	hci_link_keys_clear(hdev);
 
 
 	if (cp->debug_keys)
 	if (cp->debug_keys)
-		changed = !test_and_set_bit(HCI_DEBUG_KEYS, &hdev->dev_flags);
+		changed = !test_and_set_bit(HCI_KEEP_DEBUG_KEYS,
+					    &hdev->dev_flags);
 	else
 	else
-		changed = test_and_clear_bit(HCI_DEBUG_KEYS, &hdev->dev_flags);
+		changed = test_and_clear_bit(HCI_KEEP_DEBUG_KEYS,
+					     &hdev->dev_flags);
 
 
 	if (changed)
 	if (changed)
 		new_settings(hdev, NULL);
 		new_settings(hdev, NULL);
@@ -2424,8 +2632,14 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data,
 	for (i = 0; i < key_count; i++) {
 	for (i = 0; i < key_count; i++) {
 		struct mgmt_link_key_info *key = &cp->keys[i];
 		struct mgmt_link_key_info *key = &cp->keys[i];
 
 
-		hci_add_link_key(hdev, NULL, 0, &key->addr.bdaddr, key->val,
-				 key->type, key->pin_len);
+		/* Always ignore debug keys and require a new pairing if
+		 * the user wants to use them.
+		 */
+		if (key->type == HCI_LK_DEBUG_COMBINATION)
+			continue;
+
+		hci_add_link_key(hdev, NULL, &key->addr.bdaddr, key->val,
+				 key->type, key->pin_len, NULL);
 	}
 	}
 
 
 	cmd_complete(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS, 0, NULL, 0);
 	cmd_complete(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS, 0, NULL, 0);
@@ -2766,6 +2980,10 @@ static int set_io_capability(struct sock *sk, struct hci_dev *hdev, void *data,
 
 
 	BT_DBG("");
 	BT_DBG("");
 
 
+	if (cp->io_capability > SMP_IO_KEYBOARD_DISPLAY)
+		return cmd_complete(sk, hdev->id, MGMT_OP_SET_IO_CAPABILITY,
+				    MGMT_STATUS_INVALID_PARAMS, NULL, 0);
+
 	hci_dev_lock(hdev);
 	hci_dev_lock(hdev);
 
 
 	hdev->io_capability = cp->io_capability;
 	hdev->io_capability = cp->io_capability;
@@ -2878,6 +3096,11 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
 				    MGMT_STATUS_INVALID_PARAMS,
 				    MGMT_STATUS_INVALID_PARAMS,
 				    &rp, sizeof(rp));
 				    &rp, sizeof(rp));
 
 
+	if (cp->io_cap > SMP_IO_KEYBOARD_DISPLAY)
+		return cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE,
+				    MGMT_STATUS_INVALID_PARAMS,
+				    &rp, sizeof(rp));
+
 	hci_dev_lock(hdev);
 	hci_dev_lock(hdev);
 
 
 	if (!hdev_is_powered(hdev)) {
 	if (!hdev_is_powered(hdev)) {
@@ -2902,8 +3125,20 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
 		else
 		else
 			addr_type = ADDR_LE_DEV_RANDOM;
 			addr_type = ADDR_LE_DEV_RANDOM;
 
 
+		/* When pairing a new device, it is expected to remember
+		 * this device for future connections. Adding the connection
+		 * parameter information ahead of time allows tracking
+		 * of the slave preferred values and will speed up any
+		 * further connection establishment.
+		 *
+		 * If connection parameters already exist, then they
+		 * will be kept and this function does nothing.
+		 */
+		hci_conn_params_add(hdev, &cp->addr.bdaddr, addr_type);
+
+		/* Request a connection with master = true role */
 		conn = hci_connect_le(hdev, &cp->addr.bdaddr, addr_type,
 		conn = hci_connect_le(hdev, &cp->addr.bdaddr, addr_type,
-				      sec_level, auth_type);
+				      sec_level, HCI_LE_CONN_TIMEOUT, true);
 	}
 	}
 
 
 	if (IS_ERR(conn)) {
 	if (IS_ERR(conn)) {
@@ -3031,14 +3266,7 @@ static int user_pairing_resp(struct sock *sk, struct hci_dev *hdev,
 	}
 	}
 
 
 	if (addr->type == BDADDR_LE_PUBLIC || addr->type == BDADDR_LE_RANDOM) {
 	if (addr->type == BDADDR_LE_PUBLIC || addr->type == BDADDR_LE_RANDOM) {
-		/* Continue with pairing via SMP. The hdev lock must be
-		 * released as SMP may try to recquire it for crypto
-		 * purposes.
-		 */
-		hci_dev_unlock(hdev);
 		err = smp_user_confirm_reply(conn, mgmt_op, passkey);
 		err = smp_user_confirm_reply(conn, mgmt_op, passkey);
-		hci_dev_lock(hdev);
-
 		if (!err)
 		if (!err)
 			err = cmd_complete(sk, hdev->id, mgmt_op,
 			err = cmd_complete(sk, hdev->id, mgmt_op,
 					   MGMT_STATUS_SUCCESS, addr,
 					   MGMT_STATUS_SUCCESS, addr,
@@ -3516,11 +3744,21 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
 			goto failed;
 			goto failed;
 		}
 		}
 
 
-		if (test_bit(HCI_ADVERTISING, &hdev->dev_flags)) {
-			err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY,
-					 MGMT_STATUS_REJECTED);
-			mgmt_pending_remove(cmd);
-			goto failed;
+		if (test_bit(HCI_LE_ADV, &hdev->dev_flags)) {
+			/* Don't let discovery abort an outgoing
+			 * connection attempt that's using directed
+			 * advertising.
+			 */
+			if (hci_conn_hash_lookup_state(hdev, LE_LINK,
+						       BT_CONNECT)) {
+				err = cmd_status(sk, hdev->id,
+						 MGMT_OP_START_DISCOVERY,
+						 MGMT_STATUS_REJECTED);
+				mgmt_pending_remove(cmd);
+				goto failed;
+			}
+
+			disable_advertising(&req);
 		}
 		}
 
 
 		/* If controller is scanning, it means the background scanning
 		/* If controller is scanning, it means the background scanning
@@ -3723,12 +3961,18 @@ static int block_device(struct sock *sk, struct hci_dev *hdev, void *data,
 
 
 	hci_dev_lock(hdev);
 	hci_dev_lock(hdev);
 
 
-	err = hci_blacklist_add(hdev, &cp->addr.bdaddr, cp->addr.type);
-	if (err < 0)
+	err = hci_bdaddr_list_add(&hdev->blacklist, &cp->addr.bdaddr,
+				  cp->addr.type);
+	if (err < 0) {
 		status = MGMT_STATUS_FAILED;
 		status = MGMT_STATUS_FAILED;
-	else
-		status = MGMT_STATUS_SUCCESS;
+		goto done;
+	}
 
 
+	mgmt_event(MGMT_EV_DEVICE_BLOCKED, hdev, &cp->addr, sizeof(cp->addr),
+		   sk);
+	status = MGMT_STATUS_SUCCESS;
+
+done:
 	err = cmd_complete(sk, hdev->id, MGMT_OP_BLOCK_DEVICE, status,
 	err = cmd_complete(sk, hdev->id, MGMT_OP_BLOCK_DEVICE, status,
 			   &cp->addr, sizeof(cp->addr));
 			   &cp->addr, sizeof(cp->addr));
 
 
@@ -3753,12 +3997,18 @@ static int unblock_device(struct sock *sk, struct hci_dev *hdev, void *data,
 
 
 	hci_dev_lock(hdev);
 	hci_dev_lock(hdev);
 
 
-	err = hci_blacklist_del(hdev, &cp->addr.bdaddr, cp->addr.type);
-	if (err < 0)
+	err = hci_bdaddr_list_del(&hdev->blacklist, &cp->addr.bdaddr,
+				  cp->addr.type);
+	if (err < 0) {
 		status = MGMT_STATUS_INVALID_PARAMS;
 		status = MGMT_STATUS_INVALID_PARAMS;
-	else
-		status = MGMT_STATUS_SUCCESS;
+		goto done;
+	}
 
 
+	mgmt_event(MGMT_EV_DEVICE_UNBLOCKED, hdev, &cp->addr, sizeof(cp->addr),
+		   sk);
+	status = MGMT_STATUS_SUCCESS;
+
+done:
 	err = cmd_complete(sk, hdev->id, MGMT_OP_UNBLOCK_DEVICE, status,
 	err = cmd_complete(sk, hdev->id, MGMT_OP_UNBLOCK_DEVICE, status,
 			   &cp->addr, sizeof(cp->addr));
 			   &cp->addr, sizeof(cp->addr));
 
 
@@ -3813,8 +4063,13 @@ static void set_advertising_complete(struct hci_dev *hdev, u8 status)
 		return;
 		return;
 	}
 	}
 
 
-	mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, settings_rsp,
-			     &match);
+	if (test_bit(HCI_LE_ADV, &hdev->dev_flags))
+		set_bit(HCI_ADVERTISING, &hdev->dev_flags);
+	else
+		clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
+
+	mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, settings_rsp,
+			     &match);
 
 
 	new_settings(hdev, match.sk);
 	new_settings(hdev, match.sk);
 
 
@@ -3853,7 +4108,9 @@ static int set_advertising(struct sock *sk, struct hci_dev *hdev, void *data,
 	 * necessary).
 	 * necessary).
 	 */
 	 */
 	if (!hdev_is_powered(hdev) || val == enabled ||
 	if (!hdev_is_powered(hdev) || val == enabled ||
-	    hci_conn_num(hdev, LE_LINK) > 0) {
+	    hci_conn_num(hdev, LE_LINK) > 0 ||
+	    (test_bit(HCI_LE_SCAN, &hdev->dev_flags) &&
+	     hdev->le_scan_type == LE_SCAN_ACTIVE)) {
 		bool changed = false;
 		bool changed = false;
 
 
 		if (val != test_bit(HCI_ADVERTISING, &hdev->dev_flags)) {
 		if (val != test_bit(HCI_ADVERTISING, &hdev->dev_flags)) {
@@ -4105,7 +4362,8 @@ static void set_bredr_scan(struct hci_request *req)
 	 */
 	 */
 	write_fast_connectable(req, false);
 	write_fast_connectable(req, false);
 
 
-	if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags))
+	if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags) ||
+	    !list_empty(&hdev->whitelist))
 		scan |= SCAN_PAGE;
 		scan |= SCAN_PAGE;
 	if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
 	if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
 		scan |= SCAN_INQUIRY;
 		scan |= SCAN_INQUIRY;
@@ -4219,7 +4477,8 @@ static int set_bredr(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
 
 
 	hci_req_init(&req, hdev);
 	hci_req_init(&req, hdev);
 
 
-	if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags))
+	if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags) ||
+	    !list_empty(&hdev->whitelist))
 		set_bredr_scan(&req);
 		set_bredr_scan(&req);
 
 
 	/* Since only the advertising data flags will change, there
 	/* Since only the advertising data flags will change, there
@@ -4252,7 +4511,7 @@ static int set_secure_conn(struct sock *sk, struct hci_dev *hdev,
 				  status);
 				  status);
 
 
 	if (!lmp_sc_capable(hdev) &&
 	if (!lmp_sc_capable(hdev) &&
-	    !test_bit(HCI_FORCE_SC, &hdev->dev_flags))
+	    !test_bit(HCI_FORCE_SC, &hdev->dbg_flags))
 		return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
 		return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
 				  MGMT_STATUS_NOT_SUPPORTED);
 				  MGMT_STATUS_NOT_SUPPORTED);
 
 
@@ -4328,21 +4587,37 @@ static int set_debug_keys(struct sock *sk, struct hci_dev *hdev,
 			  void *data, u16 len)
 			  void *data, u16 len)
 {
 {
 	struct mgmt_mode *cp = data;
 	struct mgmt_mode *cp = data;
-	bool changed;
+	bool changed, use_changed;
 	int err;
 	int err;
 
 
 	BT_DBG("request for %s", hdev->name);
 	BT_DBG("request for %s", hdev->name);
 
 
-	if (cp->val != 0x00 && cp->val != 0x01)
+	if (cp->val != 0x00 && cp->val != 0x01 && cp->val != 0x02)
 		return cmd_status(sk, hdev->id, MGMT_OP_SET_DEBUG_KEYS,
 		return cmd_status(sk, hdev->id, MGMT_OP_SET_DEBUG_KEYS,
 				  MGMT_STATUS_INVALID_PARAMS);
 				  MGMT_STATUS_INVALID_PARAMS);
 
 
 	hci_dev_lock(hdev);
 	hci_dev_lock(hdev);
 
 
 	if (cp->val)
 	if (cp->val)
-		changed = !test_and_set_bit(HCI_DEBUG_KEYS, &hdev->dev_flags);
+		changed = !test_and_set_bit(HCI_KEEP_DEBUG_KEYS,
+					    &hdev->dev_flags);
 	else
 	else
-		changed = test_and_clear_bit(HCI_DEBUG_KEYS, &hdev->dev_flags);
+		changed = test_and_clear_bit(HCI_KEEP_DEBUG_KEYS,
+					     &hdev->dev_flags);
+
+	if (cp->val == 0x02)
+		use_changed = !test_and_set_bit(HCI_USE_DEBUG_KEYS,
+						&hdev->dev_flags);
+	else
+		use_changed = test_and_clear_bit(HCI_USE_DEBUG_KEYS,
+						 &hdev->dev_flags);
+
+	if (hdev_is_powered(hdev) && use_changed &&
+	    test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
+		u8 mode = (cp->val == 0x02) ? 0x01 : 0x00;
+		hci_send_cmd(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE,
+			     sizeof(mode), &mode);
+	}
 
 
 	err = send_settings_rsp(sk, MGMT_OP_SET_DEBUG_KEYS, hdev);
 	err = send_settings_rsp(sk, MGMT_OP_SET_DEBUG_KEYS, hdev);
 	if (err < 0)
 	if (err < 0)
@@ -4426,6 +4701,8 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data,
 		     u16 len)
 		     u16 len)
 {
 {
 	struct mgmt_cp_load_irks *cp = cp_data;
 	struct mgmt_cp_load_irks *cp = cp_data;
+	const u16 max_irk_count = ((U16_MAX - sizeof(*cp)) /
+				   sizeof(struct mgmt_irk_info));
 	u16 irk_count, expected_len;
 	u16 irk_count, expected_len;
 	int i, err;
 	int i, err;
 
 
@@ -4436,6 +4713,11 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data,
 				  MGMT_STATUS_NOT_SUPPORTED);
 				  MGMT_STATUS_NOT_SUPPORTED);
 
 
 	irk_count = __le16_to_cpu(cp->irk_count);
 	irk_count = __le16_to_cpu(cp->irk_count);
+	if (irk_count > max_irk_count) {
+		BT_ERR("load_irks: too big irk_count value %u", irk_count);
+		return cmd_status(sk, hdev->id, MGMT_OP_LOAD_IRKS,
+				  MGMT_STATUS_INVALID_PARAMS);
+	}
 
 
 	expected_len = sizeof(*cp) + irk_count * sizeof(struct mgmt_irk_info);
 	expected_len = sizeof(*cp) + irk_count * sizeof(struct mgmt_irk_info);
 	if (expected_len != len) {
 	if (expected_len != len) {
@@ -4505,6 +4787,8 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
 			       void *cp_data, u16 len)
 			       void *cp_data, u16 len)
 {
 {
 	struct mgmt_cp_load_long_term_keys *cp = cp_data;
 	struct mgmt_cp_load_long_term_keys *cp = cp_data;
+	const u16 max_key_count = ((U16_MAX - sizeof(*cp)) /
+				   sizeof(struct mgmt_ltk_info));
 	u16 key_count, expected_len;
 	u16 key_count, expected_len;
 	int i, err;
 	int i, err;
 
 
@@ -4515,6 +4799,11 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
 				  MGMT_STATUS_NOT_SUPPORTED);
 				  MGMT_STATUS_NOT_SUPPORTED);
 
 
 	key_count = __le16_to_cpu(cp->key_count);
 	key_count = __le16_to_cpu(cp->key_count);
+	if (key_count > max_key_count) {
+		BT_ERR("load_ltks: too big key_count value %u", key_count);
+		return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS,
+				  MGMT_STATUS_INVALID_PARAMS);
+	}
 
 
 	expected_len = sizeof(*cp) + key_count *
 	expected_len = sizeof(*cp) + key_count *
 					sizeof(struct mgmt_ltk_info);
 					sizeof(struct mgmt_ltk_info);
@@ -4550,9 +4839,9 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
 			addr_type = ADDR_LE_DEV_RANDOM;
 			addr_type = ADDR_LE_DEV_RANDOM;
 
 
 		if (key->master)
 		if (key->master)
-			type = HCI_SMP_LTK;
+			type = SMP_LTK;
 		else
 		else
-			type = HCI_SMP_LTK_SLAVE;
+			type = SMP_LTK_SLAVE;
 
 
 		switch (key->type) {
 		switch (key->type) {
 		case MGMT_LTK_UNAUTHENTICATED:
 		case MGMT_LTK_UNAUTHENTICATED:
@@ -4790,6 +5079,559 @@ unlock:
 	return err;
 	return err;
 }
 }
 
 
+static void get_clock_info_complete(struct hci_dev *hdev, u8 status)
+{
+	struct mgmt_cp_get_clock_info *cp;
+	struct mgmt_rp_get_clock_info rp;
+	struct hci_cp_read_clock *hci_cp;
+	struct pending_cmd *cmd;
+	struct hci_conn *conn;
+
+	BT_DBG("%s status %u", hdev->name, status);
+
+	hci_dev_lock(hdev);
+
+	hci_cp = hci_sent_cmd_data(hdev, HCI_OP_READ_CLOCK);
+	if (!hci_cp)
+		goto unlock;
+
+	if (hci_cp->which) {
+		u16 handle = __le16_to_cpu(hci_cp->handle);
+		conn = hci_conn_hash_lookup_handle(hdev, handle);
+	} else {
+		conn = NULL;
+	}
+
+	cmd = mgmt_pending_find_data(MGMT_OP_GET_CLOCK_INFO, hdev, conn);
+	if (!cmd)
+		goto unlock;
+
+	cp = cmd->param;
+
+	memset(&rp, 0, sizeof(rp));
+	memcpy(&rp.addr, &cp->addr, sizeof(rp.addr));
+
+	if (status)
+		goto send_rsp;
+
+	rp.local_clock = cpu_to_le32(hdev->clock);
+
+	if (conn) {
+		rp.piconet_clock = cpu_to_le32(conn->clock);
+		rp.accuracy = cpu_to_le16(conn->clock_accuracy);
+	}
+
+send_rsp:
+	cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(status),
+		     &rp, sizeof(rp));
+	mgmt_pending_remove(cmd);
+	if (conn)
+		hci_conn_drop(conn);
+
+unlock:
+	hci_dev_unlock(hdev);
+}
+
+static int get_clock_info(struct sock *sk, struct hci_dev *hdev, void *data,
+			 u16 len)
+{
+	struct mgmt_cp_get_clock_info *cp = data;
+	struct mgmt_rp_get_clock_info rp;
+	struct hci_cp_read_clock hci_cp;
+	struct pending_cmd *cmd;
+	struct hci_request req;
+	struct hci_conn *conn;
+	int err;
+
+	BT_DBG("%s", hdev->name);
+
+	memset(&rp, 0, sizeof(rp));
+	bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
+	rp.addr.type = cp->addr.type;
+
+	if (cp->addr.type != BDADDR_BREDR)
+		return cmd_complete(sk, hdev->id, MGMT_OP_GET_CLOCK_INFO,
+				    MGMT_STATUS_INVALID_PARAMS,
+				    &rp, sizeof(rp));
+
+	hci_dev_lock(hdev);
+
+	if (!hdev_is_powered(hdev)) {
+		err = cmd_complete(sk, hdev->id, MGMT_OP_GET_CLOCK_INFO,
+				   MGMT_STATUS_NOT_POWERED, &rp, sizeof(rp));
+		goto unlock;
+	}
+
+	if (bacmp(&cp->addr.bdaddr, BDADDR_ANY)) {
+		conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
+					       &cp->addr.bdaddr);
+		if (!conn || conn->state != BT_CONNECTED) {
+			err = cmd_complete(sk, hdev->id,
+					   MGMT_OP_GET_CLOCK_INFO,
+					   MGMT_STATUS_NOT_CONNECTED,
+					   &rp, sizeof(rp));
+			goto unlock;
+		}
+	} else {
+		conn = NULL;
+	}
+
+	cmd = mgmt_pending_add(sk, MGMT_OP_GET_CLOCK_INFO, hdev, data, len);
+	if (!cmd) {
+		err = -ENOMEM;
+		goto unlock;
+	}
+
+	hci_req_init(&req, hdev);
+
+	memset(&hci_cp, 0, sizeof(hci_cp));
+	hci_req_add(&req, HCI_OP_READ_CLOCK, sizeof(hci_cp), &hci_cp);
+
+	if (conn) {
+		hci_conn_hold(conn);
+		cmd->user_data = conn;
+
+		hci_cp.handle = cpu_to_le16(conn->handle);
+		hci_cp.which = 0x01; /* Piconet clock */
+		hci_req_add(&req, HCI_OP_READ_CLOCK, sizeof(hci_cp), &hci_cp);
+	}
+
+	err = hci_req_run(&req, get_clock_info_complete);
+	if (err < 0)
+		mgmt_pending_remove(cmd);
+
+unlock:
+	hci_dev_unlock(hdev);
+	return err;
+}
+
+/* Helper for Add/Remove Device commands */
+static void update_page_scan(struct hci_dev *hdev, u8 scan)
+{
+	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
+		return;
+
+	if (!hdev_is_powered(hdev))
+		return;
+
+	/* If HCI_CONNECTABLE is set then Add/Remove Device should not
+	 * make any changes to page scanning.
+	 */
+	if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags))
+		return;
+
+	if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
+		scan |= SCAN_INQUIRY;
+
+	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
+}
+
+static void device_added(struct sock *sk, struct hci_dev *hdev,
+			 bdaddr_t *bdaddr, u8 type, u8 action)
+{
+	struct mgmt_ev_device_added ev;
+
+	bacpy(&ev.addr.bdaddr, bdaddr);
+	ev.addr.type = type;
+	ev.action = action;
+
+	mgmt_event(MGMT_EV_DEVICE_ADDED, hdev, &ev, sizeof(ev), sk);
+}
+
+static int add_device(struct sock *sk, struct hci_dev *hdev,
+		      void *data, u16 len)
+{
+	struct mgmt_cp_add_device *cp = data;
+	u8 auto_conn, addr_type;
+	int err;
+
+	BT_DBG("%s", hdev->name);
+
+	if (!bdaddr_type_is_valid(cp->addr.type) ||
+	    !bacmp(&cp->addr.bdaddr, BDADDR_ANY))
+		return cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE,
+				    MGMT_STATUS_INVALID_PARAMS,
+				    &cp->addr, sizeof(cp->addr));
+
+	if (cp->action != 0x00 && cp->action != 0x01)
+		return cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE,
+				    MGMT_STATUS_INVALID_PARAMS,
+				    &cp->addr, sizeof(cp->addr));
+
+	hci_dev_lock(hdev);
+
+	if (cp->addr.type == BDADDR_BREDR) {
+		bool update_scan;
+
+		/* Only "connect" action supported for now */
+		if (cp->action != 0x01) {
+			err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE,
+					   MGMT_STATUS_INVALID_PARAMS,
+					   &cp->addr, sizeof(cp->addr));
+			goto unlock;
+		}
+
+		update_scan = list_empty(&hdev->whitelist);
+
+		err = hci_bdaddr_list_add(&hdev->whitelist, &cp->addr.bdaddr,
+					  cp->addr.type);
+		if (err)
+			goto unlock;
+
+		if (update_scan)
+			update_page_scan(hdev, SCAN_PAGE);
+
+		goto added;
+	}
+
+	if (cp->addr.type == BDADDR_LE_PUBLIC)
+		addr_type = ADDR_LE_DEV_PUBLIC;
+	else
+		addr_type = ADDR_LE_DEV_RANDOM;
+
+	if (cp->action)
+		auto_conn = HCI_AUTO_CONN_ALWAYS;
+	else
+		auto_conn = HCI_AUTO_CONN_REPORT;
+
+	/* If the connection parameters don't exist for this device,
+	 * they will be created and configured with defaults.
+	 */
+	if (hci_conn_params_set(hdev, &cp->addr.bdaddr, addr_type,
+				auto_conn) < 0) {
+		err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE,
+				   MGMT_STATUS_FAILED,
+				   &cp->addr, sizeof(cp->addr));
+		goto unlock;
+	}
+
+added:
+	device_added(sk, hdev, &cp->addr.bdaddr, cp->addr.type, cp->action);
+
+	err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE,
+			   MGMT_STATUS_SUCCESS, &cp->addr, sizeof(cp->addr));
+
+unlock:
+	hci_dev_unlock(hdev);
+	return err;
+}
+
+static void device_removed(struct sock *sk, struct hci_dev *hdev,
+			   bdaddr_t *bdaddr, u8 type)
+{
+	struct mgmt_ev_device_removed ev;
+
+	bacpy(&ev.addr.bdaddr, bdaddr);
+	ev.addr.type = type;
+
+	mgmt_event(MGMT_EV_DEVICE_REMOVED, hdev, &ev, sizeof(ev), sk);
+}
+
+static int remove_device(struct sock *sk, struct hci_dev *hdev,
+			 void *data, u16 len)
+{
+	struct mgmt_cp_remove_device *cp = data;
+	int err;
+
+	BT_DBG("%s", hdev->name);
+
+	hci_dev_lock(hdev);
+
+	if (bacmp(&cp->addr.bdaddr, BDADDR_ANY)) {
+		struct hci_conn_params *params;
+		u8 addr_type;
+
+		if (!bdaddr_type_is_valid(cp->addr.type)) {
+			err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_DEVICE,
+					   MGMT_STATUS_INVALID_PARAMS,
+					   &cp->addr, sizeof(cp->addr));
+			goto unlock;
+		}
+
+		if (cp->addr.type == BDADDR_BREDR) {
+			err = hci_bdaddr_list_del(&hdev->whitelist,
+						  &cp->addr.bdaddr,
+						  cp->addr.type);
+			if (err) {
+				err = cmd_complete(sk, hdev->id,
+						   MGMT_OP_REMOVE_DEVICE,
+						   MGMT_STATUS_INVALID_PARAMS,
+						   &cp->addr, sizeof(cp->addr));
+				goto unlock;
+			}
+
+			if (list_empty(&hdev->whitelist))
+				update_page_scan(hdev, SCAN_DISABLED);
+
+			device_removed(sk, hdev, &cp->addr.bdaddr,
+				       cp->addr.type);
+			goto complete;
+		}
+
+		if (cp->addr.type == BDADDR_LE_PUBLIC)
+			addr_type = ADDR_LE_DEV_PUBLIC;
+		else
+			addr_type = ADDR_LE_DEV_RANDOM;
+
+		params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
+						addr_type);
+		if (!params) {
+			err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_DEVICE,
+					   MGMT_STATUS_INVALID_PARAMS,
+					   &cp->addr, sizeof(cp->addr));
+			goto unlock;
+		}
+
+		if (params->auto_connect == HCI_AUTO_CONN_DISABLED) {
+			err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_DEVICE,
+					   MGMT_STATUS_INVALID_PARAMS,
+					   &cp->addr, sizeof(cp->addr));
+			goto unlock;
+		}
+
+		list_del(&params->action);
+		list_del(&params->list);
+		kfree(params);
+		hci_update_background_scan(hdev);
+
+		device_removed(sk, hdev, &cp->addr.bdaddr, cp->addr.type);
+	} else {
+		struct hci_conn_params *p, *tmp;
+		struct bdaddr_list *b, *btmp;
+
+		if (cp->addr.type) {
+			err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_DEVICE,
+					   MGMT_STATUS_INVALID_PARAMS,
+					   &cp->addr, sizeof(cp->addr));
+			goto unlock;
+		}
+
+		list_for_each_entry_safe(b, btmp, &hdev->whitelist, list) {
+			device_removed(sk, hdev, &b->bdaddr, b->bdaddr_type);
+			list_del(&b->list);
+			kfree(b);
+		}
+
+		update_page_scan(hdev, SCAN_DISABLED);
+
+		list_for_each_entry_safe(p, tmp, &hdev->le_conn_params, list) {
+			if (p->auto_connect == HCI_AUTO_CONN_DISABLED)
+				continue;
+			device_removed(sk, hdev, &p->addr, p->addr_type);
+			list_del(&p->action);
+			list_del(&p->list);
+			kfree(p);
+		}
+
+		BT_DBG("All LE connection parameters were removed");
+
+		hci_update_background_scan(hdev);
+	}
+
+complete:
+	err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_DEVICE,
+			   MGMT_STATUS_SUCCESS, &cp->addr, sizeof(cp->addr));
+
+unlock:
+	hci_dev_unlock(hdev);
+	return err;
+}
+
+static int load_conn_param(struct sock *sk, struct hci_dev *hdev, void *data,
+			   u16 len)
+{
+	struct mgmt_cp_load_conn_param *cp = data;
+	const u16 max_param_count = ((U16_MAX - sizeof(*cp)) /
+				     sizeof(struct mgmt_conn_param));
+	u16 param_count, expected_len;
+	int i;
+
+	if (!lmp_le_capable(hdev))
+		return cmd_status(sk, hdev->id, MGMT_OP_LOAD_CONN_PARAM,
+				  MGMT_STATUS_NOT_SUPPORTED);
+
+	param_count = __le16_to_cpu(cp->param_count);
+	if (param_count > max_param_count) {
+		BT_ERR("load_conn_param: too big param_count value %u",
+		       param_count);
+		return cmd_status(sk, hdev->id, MGMT_OP_LOAD_CONN_PARAM,
+				  MGMT_STATUS_INVALID_PARAMS);
+	}
+
+	expected_len = sizeof(*cp) + param_count *
+					sizeof(struct mgmt_conn_param);
+	if (expected_len != len) {
+		BT_ERR("load_conn_param: expected %u bytes, got %u bytes",
+		       expected_len, len);
+		return cmd_status(sk, hdev->id, MGMT_OP_LOAD_CONN_PARAM,
+				  MGMT_STATUS_INVALID_PARAMS);
+	}
+
+	BT_DBG("%s param_count %u", hdev->name, param_count);
+
+	hci_dev_lock(hdev);
+
+	hci_conn_params_clear_disabled(hdev);
+
+	for (i = 0; i < param_count; i++) {
+		struct mgmt_conn_param *param = &cp->params[i];
+		struct hci_conn_params *hci_param;
+		u16 min, max, latency, timeout;
+		u8 addr_type;
+
+		BT_DBG("Adding %pMR (type %u)", &param->addr.bdaddr,
+		       param->addr.type);
+
+		if (param->addr.type == BDADDR_LE_PUBLIC) {
+			addr_type = ADDR_LE_DEV_PUBLIC;
+		} else if (param->addr.type == BDADDR_LE_RANDOM) {
+			addr_type = ADDR_LE_DEV_RANDOM;
+		} else {
+			BT_ERR("Ignoring invalid connection parameters");
+			continue;
+		}
+
+		min = le16_to_cpu(param->min_interval);
+		max = le16_to_cpu(param->max_interval);
+		latency = le16_to_cpu(param->latency);
+		timeout = le16_to_cpu(param->timeout);
+
+		BT_DBG("min 0x%04x max 0x%04x latency 0x%04x timeout 0x%04x",
+		       min, max, latency, timeout);
+
+		if (hci_check_conn_params(min, max, latency, timeout) < 0) {
+			BT_ERR("Ignoring invalid connection parameters");
+			continue;
+		}
+
+		hci_param = hci_conn_params_add(hdev, &param->addr.bdaddr,
+						addr_type);
+		if (!hci_param) {
+			BT_ERR("Failed to add connection parameters");
+			continue;
+		}
+
+		hci_param->conn_min_interval = min;
+		hci_param->conn_max_interval = max;
+		hci_param->conn_latency = latency;
+		hci_param->supervision_timeout = timeout;
+	}
+
+	hci_dev_unlock(hdev);
+
+	return cmd_complete(sk, hdev->id, MGMT_OP_LOAD_CONN_PARAM, 0, NULL, 0);
+}
+
+static int set_external_config(struct sock *sk, struct hci_dev *hdev,
+			       void *data, u16 len)
+{
+	struct mgmt_cp_set_external_config *cp = data;
+	bool changed;
+	int err;
+
+	BT_DBG("%s", hdev->name);
+
+	if (hdev_is_powered(hdev))
+		return cmd_status(sk, hdev->id, MGMT_OP_SET_EXTERNAL_CONFIG,
+				  MGMT_STATUS_REJECTED);
+
+	if (cp->config != 0x00 && cp->config != 0x01)
+		return cmd_status(sk, hdev->id, MGMT_OP_SET_EXTERNAL_CONFIG,
+				    MGMT_STATUS_INVALID_PARAMS);
+
+	if (!test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks))
+		return cmd_status(sk, hdev->id, MGMT_OP_SET_EXTERNAL_CONFIG,
+				  MGMT_STATUS_NOT_SUPPORTED);
+
+	hci_dev_lock(hdev);
+
+	if (cp->config)
+		changed = !test_and_set_bit(HCI_EXT_CONFIGURED,
+					    &hdev->dev_flags);
+	else
+		changed = test_and_clear_bit(HCI_EXT_CONFIGURED,
+					     &hdev->dev_flags);
+
+	err = send_options_rsp(sk, MGMT_OP_SET_EXTERNAL_CONFIG, hdev);
+	if (err < 0)
+		goto unlock;
+
+	if (!changed)
+		goto unlock;
+
+	err = new_options(hdev, sk);
+
+	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) == is_configured(hdev)) {
+		mgmt_index_removed(hdev);
+
+		if (test_and_change_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
+			set_bit(HCI_CONFIG, &hdev->dev_flags);
+			set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
+
+			queue_work(hdev->req_workqueue, &hdev->power_on);
+		} else {
+			set_bit(HCI_RAW, &hdev->flags);
+			mgmt_index_added(hdev);
+		}
+	}
+
+unlock:
+	hci_dev_unlock(hdev);
+	return err;
+}
+
+static int set_public_address(struct sock *sk, struct hci_dev *hdev,
+			      void *data, u16 len)
+{
+	struct mgmt_cp_set_public_address *cp = data;
+	bool changed;
+	int err;
+
+	BT_DBG("%s", hdev->name);
+
+	if (hdev_is_powered(hdev))
+		return cmd_status(sk, hdev->id, MGMT_OP_SET_PUBLIC_ADDRESS,
+				  MGMT_STATUS_REJECTED);
+
+	if (!bacmp(&cp->bdaddr, BDADDR_ANY))
+		return cmd_status(sk, hdev->id, MGMT_OP_SET_PUBLIC_ADDRESS,
+				  MGMT_STATUS_INVALID_PARAMS);
+
+	if (!hdev->set_bdaddr)
+		return cmd_status(sk, hdev->id, MGMT_OP_SET_PUBLIC_ADDRESS,
+				  MGMT_STATUS_NOT_SUPPORTED);
+
+	hci_dev_lock(hdev);
+
+	changed = !!bacmp(&hdev->public_addr, &cp->bdaddr);
+	bacpy(&hdev->public_addr, &cp->bdaddr);
+
+	err = send_options_rsp(sk, MGMT_OP_SET_PUBLIC_ADDRESS, hdev);
+	if (err < 0)
+		goto unlock;
+
+	if (!changed)
+		goto unlock;
+
+	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
+		err = new_options(hdev, sk);
+
+	if (is_configured(hdev)) {
+		mgmt_index_removed(hdev);
+
+		clear_bit(HCI_UNCONFIGURED, &hdev->dev_flags);
+
+		set_bit(HCI_CONFIG, &hdev->dev_flags);
+		set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
+
+		queue_work(hdev->req_workqueue, &hdev->power_on);
+	}
+
+unlock:
+	hci_dev_unlock(hdev);
+	return err;
+}
+
 static const struct mgmt_handler {
 static const struct mgmt_handler {
 	int (*func) (struct sock *sk, struct hci_dev *hdev, void *data,
 	int (*func) (struct sock *sk, struct hci_dev *hdev, void *data,
 		     u16 data_len);
 		     u16 data_len);
@@ -4846,9 +5688,16 @@ static const struct mgmt_handler {
 	{ set_privacy,            false, MGMT_SET_PRIVACY_SIZE },
 	{ set_privacy,            false, MGMT_SET_PRIVACY_SIZE },
 	{ load_irks,              true,  MGMT_LOAD_IRKS_SIZE },
 	{ load_irks,              true,  MGMT_LOAD_IRKS_SIZE },
 	{ get_conn_info,          false, MGMT_GET_CONN_INFO_SIZE },
 	{ get_conn_info,          false, MGMT_GET_CONN_INFO_SIZE },
+	{ get_clock_info,         false, MGMT_GET_CLOCK_INFO_SIZE },
+	{ add_device,             false, MGMT_ADD_DEVICE_SIZE },
+	{ remove_device,          false, MGMT_REMOVE_DEVICE_SIZE },
+	{ load_conn_param,        true,  MGMT_LOAD_CONN_PARAM_SIZE },
+	{ read_unconf_index_list, false, MGMT_READ_UNCONF_INDEX_LIST_SIZE },
+	{ read_config_info,       false, MGMT_READ_CONFIG_INFO_SIZE },
+	{ set_external_config,    false, MGMT_SET_EXTERNAL_CONFIG_SIZE },
+	{ set_public_address,     false, MGMT_SET_PUBLIC_ADDRESS_SIZE },
 };
 };
 
 
-
 int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
 int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
 {
 {
 	void *buf;
 	void *buf;
@@ -4892,11 +5741,21 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
 		}
 		}
 
 
 		if (test_bit(HCI_SETUP, &hdev->dev_flags) ||
 		if (test_bit(HCI_SETUP, &hdev->dev_flags) ||
+		    test_bit(HCI_CONFIG, &hdev->dev_flags) ||
 		    test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
 		    test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
 			err = cmd_status(sk, index, opcode,
 			err = cmd_status(sk, index, opcode,
 					 MGMT_STATUS_INVALID_INDEX);
 					 MGMT_STATUS_INVALID_INDEX);
 			goto done;
 			goto done;
 		}
 		}
+
+		if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) &&
+		    opcode != MGMT_OP_READ_CONFIG_INFO &&
+		    opcode != MGMT_OP_SET_EXTERNAL_CONFIG &&
+		    opcode != MGMT_OP_SET_PUBLIC_ADDRESS) {
+			err = cmd_status(sk, index, opcode,
+					 MGMT_STATUS_INVALID_INDEX);
+			goto done;
+		}
 	}
 	}
 
 
 	if (opcode >= ARRAY_SIZE(mgmt_handlers) ||
 	if (opcode >= ARRAY_SIZE(mgmt_handlers) ||
@@ -4907,8 +5766,15 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
 		goto done;
 		goto done;
 	}
 	}
 
 
-	if ((hdev && opcode < MGMT_OP_READ_INFO) ||
-	    (!hdev && opcode >= MGMT_OP_READ_INFO)) {
+	if (hdev && (opcode <= MGMT_OP_READ_INDEX_LIST ||
+		     opcode == MGMT_OP_READ_UNCONF_INDEX_LIST)) {
+		err = cmd_status(sk, index, opcode,
+				 MGMT_STATUS_INVALID_INDEX);
+		goto done;
+	}
+
+	if (!hdev && (opcode > MGMT_OP_READ_INDEX_LIST &&
+		      opcode != MGMT_OP_READ_UNCONF_INDEX_LIST)) {
 		err = cmd_status(sk, index, opcode,
 		err = cmd_status(sk, index, opcode,
 				 MGMT_STATUS_INVALID_INDEX);
 				 MGMT_STATUS_INVALID_INDEX);
 		goto done;
 		goto done;
@@ -4947,7 +5813,13 @@ void mgmt_index_added(struct hci_dev *hdev)
 	if (hdev->dev_type != HCI_BREDR)
 	if (hdev->dev_type != HCI_BREDR)
 		return;
 		return;
 
 
-	mgmt_event(MGMT_EV_INDEX_ADDED, hdev, NULL, 0, NULL);
+	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
+		return;
+
+	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
+		mgmt_event(MGMT_EV_UNCONF_INDEX_ADDED, hdev, NULL, 0, NULL);
+	else
+		mgmt_event(MGMT_EV_INDEX_ADDED, hdev, NULL, 0, NULL);
 }
 }
 
 
 void mgmt_index_removed(struct hci_dev *hdev)
 void mgmt_index_removed(struct hci_dev *hdev)
@@ -4957,20 +5829,41 @@ void mgmt_index_removed(struct hci_dev *hdev)
 	if (hdev->dev_type != HCI_BREDR)
 	if (hdev->dev_type != HCI_BREDR)
 		return;
 		return;
 
 
+	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
+		return;
+
 	mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status);
 	mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status);
 
 
-	mgmt_event(MGMT_EV_INDEX_REMOVED, hdev, NULL, 0, NULL);
+	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
+		mgmt_event(MGMT_EV_UNCONF_INDEX_REMOVED, hdev, NULL, 0, NULL);
+	else
+		mgmt_event(MGMT_EV_INDEX_REMOVED, hdev, NULL, 0, NULL);
 }
 }
 
 
 /* This function requires the caller holds hdev->lock */
 /* This function requires the caller holds hdev->lock */
-static void restart_le_auto_conns(struct hci_dev *hdev)
+static void restart_le_actions(struct hci_dev *hdev)
 {
 {
 	struct hci_conn_params *p;
 	struct hci_conn_params *p;
 
 
 	list_for_each_entry(p, &hdev->le_conn_params, list) {
 	list_for_each_entry(p, &hdev->le_conn_params, list) {
-		if (p->auto_connect == HCI_AUTO_CONN_ALWAYS)
-			hci_pend_le_conn_add(hdev, &p->addr, p->addr_type);
+		/* Needed for AUTO_OFF case where might not "really"
+		 * have been powered off.
+		 */
+		list_del_init(&p->action);
+
+		switch (p->auto_connect) {
+		case HCI_AUTO_CONN_ALWAYS:
+			list_add(&p->action, &hdev->pend_le_conns);
+			break;
+		case HCI_AUTO_CONN_REPORT:
+			list_add(&p->action, &hdev->pend_le_reports);
+			break;
+		default:
+			break;
+		}
 	}
 	}
+
+	hci_update_background_scan(hdev);
 }
 }
 
 
 static void powered_complete(struct hci_dev *hdev, u8 status)
 static void powered_complete(struct hci_dev *hdev, u8 status)
@@ -4981,7 +5874,7 @@ static void powered_complete(struct hci_dev *hdev, u8 status)
 
 
 	hci_dev_lock(hdev);
 	hci_dev_lock(hdev);
 
 
-	restart_le_auto_conns(hdev);
+	restart_le_actions(hdev);
 
 
 	mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
 	mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
 
 
@@ -5190,6 +6083,14 @@ void mgmt_connectable(struct hci_dev *hdev, u8 connectable)
 	if (!connectable && mgmt_pending_find(MGMT_OP_SET_POWERED, hdev))
 	if (!connectable && mgmt_pending_find(MGMT_OP_SET_POWERED, hdev))
 		return;
 		return;
 
 
+	/* If something else than mgmt changed the page scan state we
+	 * can't differentiate this from a change triggered by adding
+	 * the first element to the whitelist. Therefore, avoid
+	 * incorrectly setting HCI_CONNECTABLE.
+	 */
+	if (connectable && !list_empty(&hdev->whitelist))
+		return;
+
 	if (connectable)
 	if (connectable)
 		changed = !test_and_set_bit(HCI_CONNECTABLE, &hdev->dev_flags);
 		changed = !test_and_set_bit(HCI_CONNECTABLE, &hdev->dev_flags);
 	else
 	else
@@ -5199,18 +6100,6 @@ void mgmt_connectable(struct hci_dev *hdev, u8 connectable)
 		new_settings(hdev, NULL);
 		new_settings(hdev, NULL);
 }
 }
 
 
-void mgmt_advertising(struct hci_dev *hdev, u8 advertising)
-{
-	/* Powering off may stop advertising - don't let that interfere */
-	if (!advertising && mgmt_pending_find(MGMT_OP_SET_POWERED, hdev))
-		return;
-
-	if (advertising)
-		set_bit(HCI_ADVERTISING, &hdev->dev_flags);
-	else
-		clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
-}
-
 void mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status)
 void mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status)
 {
 {
 	u8 mgmt_err = mgmt_status(status);
 	u8 mgmt_err = mgmt_status(status);
@@ -5279,7 +6168,7 @@ void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent)
 	ev.key.ediv = key->ediv;
 	ev.key.ediv = key->ediv;
 	ev.key.rand = key->rand;
 	ev.key.rand = key->rand;
 
 
-	if (key->type == HCI_SMP_LTK)
+	if (key->type == SMP_LTK)
 		ev.key.master = 1;
 		ev.key.master = 1;
 
 
 	memcpy(ev.key.val, key->val, sizeof(key->val));
 	memcpy(ev.key.val, key->val, sizeof(key->val));
@@ -5347,6 +6236,27 @@ void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk,
 	mgmt_event(MGMT_EV_NEW_CSRK, hdev, &ev, sizeof(ev), NULL);
 	mgmt_event(MGMT_EV_NEW_CSRK, hdev, &ev, sizeof(ev), NULL);
 }
 }
 
 
+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)
+{
+	struct mgmt_ev_new_conn_param ev;
+
+	if (!hci_is_identity_address(bdaddr, bdaddr_type))
+		return;
+
+	memset(&ev, 0, sizeof(ev));
+	bacpy(&ev.addr.bdaddr, bdaddr);
+	ev.addr.type = link_to_bdaddr(LE_LINK, bdaddr_type);
+	ev.store_hint = store_hint;
+	ev.min_interval = cpu_to_le16(min_interval);
+	ev.max_interval = cpu_to_le16(max_interval);
+	ev.latency = cpu_to_le16(latency);
+	ev.timeout = cpu_to_le16(timeout);
+
+	mgmt_event(MGMT_EV_NEW_CONN_PARAM, hdev, &ev, sizeof(ev), NULL);
+}
+
 static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data,
 static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data,
 				  u8 data_len)
 				  u8 data_len)
 {
 {
@@ -5765,10 +6675,14 @@ void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status)
 
 
 	hci_req_init(&req, hdev);
 	hci_req_init(&req, hdev);
 
 
-	if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags))
+	if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
+		if (test_bit(HCI_USE_DEBUG_KEYS, &hdev->dev_flags))
+			hci_req_add(&req, HCI_OP_WRITE_SSP_DEBUG_MODE,
+				    sizeof(enable), &enable);
 		update_eir(&req);
 		update_eir(&req);
-	else
+	} else {
 		clear_eir(&req);
 		clear_eir(&req);
+	}
 
 
 	hci_req_run(&req, NULL);
 	hci_req_run(&req, NULL);
 }
 }
@@ -5912,17 +6826,23 @@ void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192,
 }
 }
 
 
 void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
 void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
-		       u8 addr_type, u8 *dev_class, s8 rssi, u8 cfm_name,
-		       u8 ssp, u8 *eir, u16 eir_len, u8 *scan_rsp,
-		       u8 scan_rsp_len)
+		       u8 addr_type, u8 *dev_class, s8 rssi, u32 flags,
+		       u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len)
 {
 {
 	char buf[512];
 	char buf[512];
 	struct mgmt_ev_device_found *ev = (void *) buf;
 	struct mgmt_ev_device_found *ev = (void *) buf;
-	struct smp_irk *irk;
 	size_t ev_size;
 	size_t ev_size;
 
 
-	if (!hci_discovery_active(hdev))
-		return;
+	/* Don't send events for a non-kernel initiated discovery. With
+	 * LE one exception is if we have pend_le_reports > 0 in which
+	 * case we're doing passive scanning and want these events.
+	 */
+	if (!hci_discovery_active(hdev)) {
+		if (link_type == ACL_LINK)
+			return;
+		if (link_type == LE_LINK && list_empty(&hdev->pend_le_reports))
+			return;
+	}
 
 
 	/* Make sure that the buffer is big enough. The 5 extra bytes
 	/* Make sure that the buffer is big enough. The 5 extra bytes
 	 * are for the potential CoD field.
 	 * are for the potential CoD field.
@@ -5932,20 +6852,10 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
 
 
 	memset(buf, 0, sizeof(buf));
 	memset(buf, 0, sizeof(buf));
 
 
-	irk = hci_get_irk(hdev, bdaddr, addr_type);
-	if (irk) {
-		bacpy(&ev->addr.bdaddr, &irk->bdaddr);
-		ev->addr.type = link_to_bdaddr(link_type, irk->addr_type);
-	} else {
-		bacpy(&ev->addr.bdaddr, bdaddr);
-		ev->addr.type = link_to_bdaddr(link_type, addr_type);
-	}
-
+	bacpy(&ev->addr.bdaddr, bdaddr);
+	ev->addr.type = link_to_bdaddr(link_type, addr_type);
 	ev->rssi = rssi;
 	ev->rssi = rssi;
-	if (cfm_name)
-		ev->flags |= cpu_to_le32(MGMT_DEV_FOUND_CONFIRM_NAME);
-	if (!ssp)
-		ev->flags |= cpu_to_le32(MGMT_DEV_FOUND_LEGACY_PAIRING);
+	ev->flags = cpu_to_le32(flags);
 
 
 	if (eir_len > 0)
 	if (eir_len > 0)
 		memcpy(ev->eir, eir, eir_len);
 		memcpy(ev->eir, eir, eir_len);
@@ -6013,63 +6923,19 @@ void mgmt_discovering(struct hci_dev *hdev, u8 discovering)
 	mgmt_event(MGMT_EV_DISCOVERING, hdev, &ev, sizeof(ev), NULL);
 	mgmt_event(MGMT_EV_DISCOVERING, hdev, &ev, sizeof(ev), NULL);
 }
 }
 
 
-int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
-{
-	struct pending_cmd *cmd;
-	struct mgmt_ev_device_blocked ev;
-
-	cmd = mgmt_pending_find(MGMT_OP_BLOCK_DEVICE, hdev);
-
-	bacpy(&ev.addr.bdaddr, bdaddr);
-	ev.addr.type = type;
-
-	return mgmt_event(MGMT_EV_DEVICE_BLOCKED, hdev, &ev, sizeof(ev),
-			  cmd ? cmd->sk : NULL);
-}
-
-int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
-{
-	struct pending_cmd *cmd;
-	struct mgmt_ev_device_unblocked ev;
-
-	cmd = mgmt_pending_find(MGMT_OP_UNBLOCK_DEVICE, hdev);
-
-	bacpy(&ev.addr.bdaddr, bdaddr);
-	ev.addr.type = type;
-
-	return mgmt_event(MGMT_EV_DEVICE_UNBLOCKED, hdev, &ev, sizeof(ev),
-			  cmd ? cmd->sk : NULL);
-}
-
 static void adv_enable_complete(struct hci_dev *hdev, u8 status)
 static void adv_enable_complete(struct hci_dev *hdev, u8 status)
 {
 {
 	BT_DBG("%s status %u", hdev->name, status);
 	BT_DBG("%s status %u", hdev->name, status);
-
-	/* Clear the advertising mgmt setting if we failed to re-enable it */
-	if (status) {
-		clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
-		new_settings(hdev, NULL);
-	}
 }
 }
 
 
 void mgmt_reenable_advertising(struct hci_dev *hdev)
 void mgmt_reenable_advertising(struct hci_dev *hdev)
 {
 {
 	struct hci_request req;
 	struct hci_request req;
 
 
-	if (hci_conn_num(hdev, LE_LINK) > 0)
-		return;
-
 	if (!test_bit(HCI_ADVERTISING, &hdev->dev_flags))
 	if (!test_bit(HCI_ADVERTISING, &hdev->dev_flags))
 		return;
 		return;
 
 
 	hci_req_init(&req, hdev);
 	hci_req_init(&req, hdev);
 	enable_advertising(&req);
 	enable_advertising(&req);
-
-	/* If this fails we have no option but to let user space know
-	 * that we've disabled advertising.
-	 */
-	if (hci_req_run(&req, adv_enable_complete) < 0) {
-		clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
-		new_settings(hdev, NULL);
-	}
+	hci_req_run(&req, adv_enable_complete);
 }
 }

+ 144 - 93
net/bluetooth/smp.c

@@ -35,11 +35,13 @@
 
 
 #define AUTH_REQ_MASK   0x07
 #define AUTH_REQ_MASK   0x07
 
 
-#define SMP_FLAG_TK_VALID	1
-#define SMP_FLAG_CFM_PENDING	2
-#define SMP_FLAG_MITM_AUTH	3
-#define SMP_FLAG_COMPLETE	4
-#define SMP_FLAG_INITIATOR	5
+enum {
+	SMP_FLAG_TK_VALID,
+	SMP_FLAG_CFM_PENDING,
+	SMP_FLAG_MITM_AUTH,
+	SMP_FLAG_COMPLETE,
+	SMP_FLAG_INITIATOR,
+};
 
 
 struct smp_chan {
 struct smp_chan {
 	struct l2cap_conn *conn;
 	struct l2cap_conn *conn;
@@ -60,20 +62,16 @@ struct smp_chan {
 	struct smp_ltk	*slave_ltk;
 	struct smp_ltk	*slave_ltk;
 	struct smp_irk	*remote_irk;
 	struct smp_irk	*remote_irk;
 	unsigned long	flags;
 	unsigned long	flags;
+
+	struct crypto_blkcipher	*tfm_aes;
 };
 };
 
 
-static inline void swap128(const u8 src[16], u8 dst[16])
+static inline void swap_buf(const u8 *src, u8 *dst, size_t len)
 {
 {
-	int i;
-	for (i = 0; i < 16; i++)
-		dst[15 - i] = src[i];
-}
+	size_t i;
 
 
-static inline void swap56(const u8 src[7], u8 dst[7])
-{
-	int i;
-	for (i = 0; i < 7; i++)
-		dst[6 - i] = src[i];
+	for (i = 0; i < len; i++)
+		dst[len - 1 - i] = src[i];
 }
 }
 
 
 static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
 static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
@@ -92,7 +90,7 @@ static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
 	desc.flags = 0;
 	desc.flags = 0;
 
 
 	/* The most significant octet of key corresponds to k[0] */
 	/* The most significant octet of key corresponds to k[0] */
-	swap128(k, tmp);
+	swap_buf(k, tmp, 16);
 
 
 	err = crypto_blkcipher_setkey(tfm, tmp, 16);
 	err = crypto_blkcipher_setkey(tfm, tmp, 16);
 	if (err) {
 	if (err) {
@@ -101,7 +99,7 @@ static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
 	}
 	}
 
 
 	/* Most significant octet of plaintextData corresponds to data[0] */
 	/* Most significant octet of plaintextData corresponds to data[0] */
-	swap128(r, data);
+	swap_buf(r, data, 16);
 
 
 	sg_init_one(&sg, data, 16);
 	sg_init_one(&sg, data, 16);
 
 
@@ -110,7 +108,7 @@ static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
 		BT_ERR("Encrypt data error %d", err);
 		BT_ERR("Encrypt data error %d", err);
 
 
 	/* Most significant octet of encryptedData corresponds to data[0] */
 	/* Most significant octet of encryptedData corresponds to data[0] */
-	swap128(data, r);
+	swap_buf(data, r, 16);
 
 
 	return err;
 	return err;
 }
 }
@@ -174,13 +172,16 @@ int smp_generate_rpa(struct crypto_blkcipher *tfm, u8 irk[16], bdaddr_t *rpa)
 	return 0;
 	return 0;
 }
 }
 
 
-static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16],
-		  u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia,
-		  u8 _rat, bdaddr_t *ra, u8 res[16])
+static int smp_c1(struct smp_chan *smp, u8 k[16], u8 r[16], u8 preq[7],
+		  u8 pres[7], u8 _iat, bdaddr_t *ia, u8 _rat, bdaddr_t *ra,
+		  u8 res[16])
 {
 {
+	struct hci_dev *hdev = smp->conn->hcon->hdev;
 	u8 p1[16], p2[16];
 	u8 p1[16], p2[16];
 	int err;
 	int err;
 
 
+	BT_DBG("%s", hdev->name);
+
 	memset(p1, 0, 16);
 	memset(p1, 0, 16);
 
 
 	/* p1 = pres || preq || _rat || _iat */
 	/* p1 = pres || preq || _rat || _iat */
@@ -198,7 +199,7 @@ static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16],
 	u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);
 	u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);
 
 
 	/* res = e(k, res) */
 	/* res = e(k, res) */
-	err = smp_e(tfm, k, res);
+	err = smp_e(smp->tfm_aes, k, res);
 	if (err) {
 	if (err) {
 		BT_ERR("Encrypt data error");
 		BT_ERR("Encrypt data error");
 		return err;
 		return err;
@@ -208,23 +209,26 @@ static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16],
 	u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);
 	u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);
 
 
 	/* res = e(k, res) */
 	/* res = e(k, res) */
-	err = smp_e(tfm, k, res);
+	err = smp_e(smp->tfm_aes, k, res);
 	if (err)
 	if (err)
 		BT_ERR("Encrypt data error");
 		BT_ERR("Encrypt data error");
 
 
 	return err;
 	return err;
 }
 }
 
 
-static int smp_s1(struct crypto_blkcipher *tfm, u8 k[16], u8 r1[16],
-		  u8 r2[16], u8 _r[16])
+static int smp_s1(struct smp_chan *smp, u8 k[16], u8 r1[16], u8 r2[16],
+		  u8 _r[16])
 {
 {
+	struct hci_dev *hdev = smp->conn->hcon->hdev;
 	int err;
 	int err;
 
 
+	BT_DBG("%s", hdev->name);
+
 	/* Just least significant octets from r1 and r2 are considered */
 	/* Just least significant octets from r1 and r2 are considered */
 	memcpy(_r, r2, 8);
 	memcpy(_r, r2, 8);
 	memcpy(_r + 8, r1, 8);
 	memcpy(_r + 8, r1, 8);
 
 
-	err = smp_e(tfm, k, _r);
+	err = smp_e(smp->tfm_aes, k, _r);
 	if (err)
 	if (err)
 		BT_ERR("Encrypt data error");
 		BT_ERR("Encrypt data error");
 
 
@@ -385,6 +389,16 @@ static const u8 gen_method[5][5] = {
 	{ CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP     },
 	{ CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP     },
 };
 };
 
 
+static u8 get_auth_method(struct smp_chan *smp, u8 local_io, u8 remote_io)
+{
+	/* If either side has unknown io_caps, use JUST WORKS */
+	if (local_io > SMP_IO_KEYBOARD_DISPLAY ||
+	    remote_io > SMP_IO_KEYBOARD_DISPLAY)
+		return JUST_WORKS;
+
+	return gen_method[remote_io][local_io];
+}
+
 static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
 static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
 						u8 local_io, u8 remote_io)
 						u8 local_io, u8 remote_io)
 {
 {
@@ -401,14 +415,11 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
 	BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io);
 	BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io);
 
 
 	/* If neither side wants MITM, use JUST WORKS */
 	/* If neither side wants MITM, use JUST WORKS */
-	/* If either side has unknown io_caps, use JUST WORKS */
 	/* Otherwise, look up method from the table */
 	/* Otherwise, look up method from the table */
-	if (!(auth & SMP_AUTH_MITM) ||
-	    local_io > SMP_IO_KEYBOARD_DISPLAY ||
-	    remote_io > SMP_IO_KEYBOARD_DISPLAY)
+	if (!(auth & SMP_AUTH_MITM))
 		method = JUST_WORKS;
 		method = JUST_WORKS;
 	else
 	else
-		method = gen_method[remote_io][local_io];
+		method = get_auth_method(smp, local_io, remote_io);
 
 
 	/* If not bonding, don't ask user to confirm a Zero TK */
 	/* If not bonding, don't ask user to confirm a Zero TK */
 	if (!(auth & SMP_AUTH_BONDING) && method == JUST_CFM)
 	if (!(auth & SMP_AUTH_BONDING) && method == JUST_CFM)
@@ -432,7 +443,7 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
 	 * Confirms and the slave Enters the passkey.
 	 * Confirms and the slave Enters the passkey.
 	 */
 	 */
 	if (method == OVERLAP) {
 	if (method == OVERLAP) {
-		if (hcon->link_mode & HCI_LM_MASTER)
+		if (test_bit(HCI_CONN_MASTER, &hcon->flags))
 			method = CFM_PASSKEY;
 			method = CFM_PASSKEY;
 		else
 		else
 			method = REQ_PASSKEY;
 			method = REQ_PASSKEY;
@@ -470,23 +481,15 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
 static u8 smp_confirm(struct smp_chan *smp)
 static u8 smp_confirm(struct smp_chan *smp)
 {
 {
 	struct l2cap_conn *conn = smp->conn;
 	struct l2cap_conn *conn = smp->conn;
-	struct hci_dev *hdev = conn->hcon->hdev;
-	struct crypto_blkcipher *tfm = hdev->tfm_aes;
 	struct smp_cmd_pairing_confirm cp;
 	struct smp_cmd_pairing_confirm cp;
 	int ret;
 	int ret;
 
 
 	BT_DBG("conn %p", conn);
 	BT_DBG("conn %p", conn);
 
 
-	/* Prevent mutual access to hdev->tfm_aes */
-	hci_dev_lock(hdev);
-
-	ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp,
+	ret = smp_c1(smp, smp->tk, smp->prnd, smp->preq, smp->prsp,
 		     conn->hcon->init_addr_type, &conn->hcon->init_addr,
 		     conn->hcon->init_addr_type, &conn->hcon->init_addr,
 		     conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
 		     conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
 		     cp.confirm_val);
 		     cp.confirm_val);
-
-	hci_dev_unlock(hdev);
-
 	if (ret)
 	if (ret)
 		return SMP_UNSPECIFIED;
 		return SMP_UNSPECIFIED;
 
 
@@ -501,25 +504,17 @@ static u8 smp_random(struct smp_chan *smp)
 {
 {
 	struct l2cap_conn *conn = smp->conn;
 	struct l2cap_conn *conn = smp->conn;
 	struct hci_conn *hcon = conn->hcon;
 	struct hci_conn *hcon = conn->hcon;
-	struct hci_dev *hdev = hcon->hdev;
-	struct crypto_blkcipher *tfm = hdev->tfm_aes;
 	u8 confirm[16];
 	u8 confirm[16];
 	int ret;
 	int ret;
 
 
-	if (IS_ERR_OR_NULL(tfm))
+	if (IS_ERR_OR_NULL(smp->tfm_aes))
 		return SMP_UNSPECIFIED;
 		return SMP_UNSPECIFIED;
 
 
 	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
 	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
 
 
-	/* Prevent mutual access to hdev->tfm_aes */
-	hci_dev_lock(hdev);
-
-	ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp,
+	ret = smp_c1(smp, smp->tk, smp->rrnd, smp->preq, smp->prsp,
 		     hcon->init_addr_type, &hcon->init_addr,
 		     hcon->init_addr_type, &hcon->init_addr,
 		     hcon->resp_addr_type, &hcon->resp_addr, confirm);
 		     hcon->resp_addr_type, &hcon->resp_addr, confirm);
-
-	hci_dev_unlock(hdev);
-
 	if (ret)
 	if (ret)
 		return SMP_UNSPECIFIED;
 		return SMP_UNSPECIFIED;
 
 
@@ -533,7 +528,7 @@ static u8 smp_random(struct smp_chan *smp)
 		__le64 rand = 0;
 		__le64 rand = 0;
 		__le16 ediv = 0;
 		__le16 ediv = 0;
 
 
-		smp_s1(tfm, smp->tk, smp->rrnd, smp->prnd, stk);
+		smp_s1(smp, smp->tk, smp->rrnd, smp->prnd, stk);
 
 
 		memset(stk + smp->enc_key_size, 0,
 		memset(stk + smp->enc_key_size, 0,
 		       SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
 		       SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
@@ -543,6 +538,7 @@ static u8 smp_random(struct smp_chan *smp)
 
 
 		hci_le_start_enc(hcon, ediv, rand, stk);
 		hci_le_start_enc(hcon, ediv, rand, stk);
 		hcon->enc_key_size = smp->enc_key_size;
 		hcon->enc_key_size = smp->enc_key_size;
+		set_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
 	} else {
 	} else {
 		u8 stk[16], auth;
 		u8 stk[16], auth;
 		__le64 rand = 0;
 		__le64 rand = 0;
@@ -551,7 +547,7 @@ static u8 smp_random(struct smp_chan *smp)
 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
 			     smp->prnd);
 			     smp->prnd);
 
 
-		smp_s1(tfm, smp->tk, smp->prnd, smp->rrnd, stk);
+		smp_s1(smp, smp->tk, smp->prnd, smp->rrnd, stk);
 
 
 		memset(stk + smp->enc_key_size, 0,
 		memset(stk + smp->enc_key_size, 0,
 		       SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
 		       SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
@@ -561,9 +557,12 @@ static u8 smp_random(struct smp_chan *smp)
 		else
 		else
 			auth = 0;
 			auth = 0;
 
 
+		/* Even though there's no _SLAVE suffix this is the
+		 * slave STK we're adding for later lookup (the master
+		 * STK never needs to be stored).
+		 */
 		hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
 		hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
-			    HCI_SMP_STK_SLAVE, auth, stk, smp->enc_key_size,
-			    ediv, rand);
+			    SMP_STK, auth, stk, smp->enc_key_size, ediv, rand);
 	}
 	}
 
 
 	return 0;
 	return 0;
@@ -577,9 +576,15 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
 	if (!smp)
 	if (!smp)
 		return NULL;
 		return NULL;
 
 
+	smp->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
+	if (IS_ERR(smp->tfm_aes)) {
+		BT_ERR("Unable to create ECB crypto context");
+		kfree(smp);
+		return NULL;
+	}
+
 	smp->conn = conn;
 	smp->conn = conn;
 	conn->smp_chan = smp;
 	conn->smp_chan = smp;
-	conn->hcon->smp_conn = conn;
 
 
 	hci_conn_hold(conn->hcon);
 	hci_conn_hold(conn->hcon);
 
 
@@ -599,6 +604,8 @@ void smp_chan_destroy(struct l2cap_conn *conn)
 	kfree(smp->csrk);
 	kfree(smp->csrk);
 	kfree(smp->slave_csrk);
 	kfree(smp->slave_csrk);
 
 
+	crypto_free_blkcipher(smp->tfm_aes);
+
 	/* If pairing failed clean up any keys we might have */
 	/* If pairing failed clean up any keys we might have */
 	if (!complete) {
 	if (!complete) {
 		if (smp->ltk) {
 		if (smp->ltk) {
@@ -619,19 +626,18 @@ void smp_chan_destroy(struct l2cap_conn *conn)
 
 
 	kfree(smp);
 	kfree(smp);
 	conn->smp_chan = NULL;
 	conn->smp_chan = NULL;
-	conn->hcon->smp_conn = NULL;
 	hci_conn_drop(conn->hcon);
 	hci_conn_drop(conn->hcon);
 }
 }
 
 
 int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
 int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
 {
 {
-	struct l2cap_conn *conn = hcon->smp_conn;
+	struct l2cap_conn *conn = hcon->l2cap_data;
 	struct smp_chan *smp;
 	struct smp_chan *smp;
 	u32 value;
 	u32 value;
 
 
 	BT_DBG("");
 	BT_DBG("");
 
 
-	if (!conn)
+	if (!conn || !test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
 		return -ENOTCONN;
 		return -ENOTCONN;
 
 
 	smp = conn->smp_chan;
 	smp = conn->smp_chan;
@@ -669,7 +675,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 {
 {
 	struct smp_cmd_pairing rsp, *req = (void *) skb->data;
 	struct smp_cmd_pairing rsp, *req = (void *) skb->data;
 	struct smp_chan *smp;
 	struct smp_chan *smp;
-	u8 key_size, auth;
+	u8 key_size, auth, sec_level;
 	int ret;
 	int ret;
 
 
 	BT_DBG("conn %p", conn);
 	BT_DBG("conn %p", conn);
@@ -677,7 +683,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 	if (skb->len < sizeof(*req))
 	if (skb->len < sizeof(*req))
 		return SMP_INVALID_PARAMS;
 		return SMP_INVALID_PARAMS;
 
 
-	if (conn->hcon->link_mode & HCI_LM_MASTER)
+	if (test_bit(HCI_CONN_MASTER, &conn->hcon->flags))
 		return SMP_CMD_NOTSUPP;
 		return SMP_CMD_NOTSUPP;
 
 
 	if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
 	if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
@@ -695,7 +701,19 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 	/* We didn't start the pairing, so match remote */
 	/* We didn't start the pairing, so match remote */
 	auth = req->auth_req;
 	auth = req->auth_req;
 
 
-	conn->hcon->pending_sec_level = authreq_to_seclevel(auth);
+	sec_level = authreq_to_seclevel(auth);
+	if (sec_level > conn->hcon->pending_sec_level)
+		conn->hcon->pending_sec_level = sec_level;
+
+	/* If we need MITM check that it can be acheived */
+	if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
+		u8 method;
+
+		method = get_auth_method(smp, conn->hcon->io_capability,
+					 req->io_capability);
+		if (method == JUST_WORKS || method == JUST_CFM)
+			return SMP_AUTH_REQUIREMENTS;
+	}
 
 
 	build_pairing_cmd(conn, req, &rsp, auth);
 	build_pairing_cmd(conn, req, &rsp, auth);
 
 
@@ -732,7 +750,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
 	if (skb->len < sizeof(*rsp))
 	if (skb->len < sizeof(*rsp))
 		return SMP_INVALID_PARAMS;
 		return SMP_INVALID_PARAMS;
 
 
-	if (!(conn->hcon->link_mode & HCI_LM_MASTER))
+	if (!test_bit(HCI_CONN_MASTER, &conn->hcon->flags))
 		return SMP_CMD_NOTSUPP;
 		return SMP_CMD_NOTSUPP;
 
 
 	skb_pull(skb, sizeof(*rsp));
 	skb_pull(skb, sizeof(*rsp));
@@ -743,6 +761,16 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
 	if (check_enc_key_size(conn, key_size))
 	if (check_enc_key_size(conn, key_size))
 		return SMP_ENC_KEY_SIZE;
 		return SMP_ENC_KEY_SIZE;
 
 
+	/* If we need MITM check that it can be acheived */
+	if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
+		u8 method;
+
+		method = get_auth_method(smp, req->io_capability,
+					 rsp->io_capability);
+		if (method == JUST_WORKS || method == JUST_CFM)
+			return SMP_AUTH_REQUIREMENTS;
+	}
+
 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
 
 
 	smp->prsp[0] = SMP_CMD_PAIRING_RSP;
 	smp->prsp[0] = SMP_CMD_PAIRING_RSP;
@@ -810,7 +838,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
 	return smp_random(smp);
 	return smp_random(smp);
 }
 }
 
 
-static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
+static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
 {
 {
 	struct smp_ltk *key;
 	struct smp_ltk *key;
 	struct hci_conn *hcon = conn->hcon;
 	struct hci_conn *hcon = conn->hcon;
@@ -818,18 +846,40 @@ static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
 	key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
 	key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
 				   hcon->out);
 				   hcon->out);
 	if (!key)
 	if (!key)
-		return 0;
+		return false;
 
 
 	if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated)
 	if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated)
-		return 0;
+		return false;
 
 
 	if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
 	if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
-		return 1;
+		return true;
 
 
 	hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
 	hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
 	hcon->enc_key_size = key->enc_size;
 	hcon->enc_key_size = key->enc_size;
 
 
-	return 1;
+	/* We never store STKs for master role, so clear this flag */
+	clear_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
+
+	return true;
+}
+
+bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level)
+{
+	if (sec_level == BT_SECURITY_LOW)
+		return true;
+
+	/* If we're encrypted with an STK always claim insufficient
+	 * security. This way we allow the connection to be re-encrypted
+	 * with an LTK, even if the LTK provides the same level of
+	 * security.
+	 */
+	if (test_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags))
+		return false;
+
+	if (hcon->sec_level >= sec_level)
+		return true;
+
+	return false;
 }
 }
 
 
 static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
 static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
@@ -838,16 +888,22 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
 	struct smp_cmd_pairing cp;
 	struct smp_cmd_pairing cp;
 	struct hci_conn *hcon = conn->hcon;
 	struct hci_conn *hcon = conn->hcon;
 	struct smp_chan *smp;
 	struct smp_chan *smp;
+	u8 sec_level;
 
 
 	BT_DBG("conn %p", conn);
 	BT_DBG("conn %p", conn);
 
 
 	if (skb->len < sizeof(*rp))
 	if (skb->len < sizeof(*rp))
 		return SMP_INVALID_PARAMS;
 		return SMP_INVALID_PARAMS;
 
 
-	if (!(conn->hcon->link_mode & HCI_LM_MASTER))
+	if (!test_bit(HCI_CONN_MASTER, &conn->hcon->flags))
 		return SMP_CMD_NOTSUPP;
 		return SMP_CMD_NOTSUPP;
 
 
-	hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req);
+	sec_level = authreq_to_seclevel(rp->auth_req);
+	if (smp_sufficient_security(hcon, sec_level))
+		return 0;
+
+	if (sec_level > hcon->pending_sec_level)
+		hcon->pending_sec_level = sec_level;
 
 
 	if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
 	if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
 		return 0;
 		return 0;
@@ -856,6 +912,8 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
 		return 0;
 		return 0;
 
 
 	smp = smp_chan_create(conn);
 	smp = smp_chan_create(conn);
+	if (!smp)
+		return SMP_UNSPECIFIED;
 
 
 	skb_pull(skb, sizeof(*rp));
 	skb_pull(skb, sizeof(*rp));
 
 
@@ -872,17 +930,6 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
 	return 0;
 	return 0;
 }
 }
 
 
-bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level)
-{
-	if (sec_level == BT_SECURITY_LOW)
-		return true;
-
-	if (hcon->sec_level >= sec_level)
-		return true;
-
-	return false;
-}
-
 int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
 int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
 {
 {
 	struct l2cap_conn *conn = hcon->l2cap_data;
 	struct l2cap_conn *conn = hcon->l2cap_data;
@@ -901,9 +948,12 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
 	if (smp_sufficient_security(hcon, sec_level))
 	if (smp_sufficient_security(hcon, sec_level))
 		return 1;
 		return 1;
 
 
-	if (hcon->link_mode & HCI_LM_MASTER)
-		if (smp_ltk_encrypt(conn, sec_level))
-			goto done;
+	if (sec_level > hcon->pending_sec_level)
+		hcon->pending_sec_level = sec_level;
+
+	if (test_bit(HCI_CONN_MASTER, &hcon->flags))
+		if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
+			return 0;
 
 
 	if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
 	if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
 		return 0;
 		return 0;
@@ -918,10 +968,10 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
 	 * requires it.
 	 * requires it.
 	 */
 	 */
 	if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT ||
 	if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT ||
-	    sec_level > BT_SECURITY_MEDIUM)
+	    hcon->pending_sec_level > BT_SECURITY_MEDIUM)
 		authreq |= SMP_AUTH_MITM;
 		authreq |= SMP_AUTH_MITM;
 
 
-	if (hcon->link_mode & HCI_LM_MASTER) {
+	if (test_bit(HCI_CONN_MASTER, &hcon->flags)) {
 		struct smp_cmd_pairing cp;
 		struct smp_cmd_pairing cp;
 
 
 		build_pairing_cmd(conn, &cp, NULL, authreq);
 		build_pairing_cmd(conn, &cp, NULL, authreq);
@@ -937,9 +987,6 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
 
 
 	set_bit(SMP_FLAG_INITIATOR, &smp->flags);
 	set_bit(SMP_FLAG_INITIATOR, &smp->flags);
 
 
-done:
-	hcon->pending_sec_level = sec_level;
-
 	return 0;
 	return 0;
 }
 }
 
 
@@ -989,7 +1036,7 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
 
 
 	hci_dev_lock(hdev);
 	hci_dev_lock(hdev);
 	authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
 	authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
-	ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, HCI_SMP_LTK,
+	ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, SMP_LTK,
 			  authenticated, smp->tk, smp->enc_key_size,
 			  authenticated, smp->tk, smp->enc_key_size,
 			  rp->ediv, rp->rand);
 			  rp->ediv, rp->rand);
 	smp->ltk = ltk;
 	smp->ltk = ltk;
@@ -1043,6 +1090,8 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
 
 
 	skb_pull(skb, sizeof(*info));
 	skb_pull(skb, sizeof(*info));
 
 
+	hci_dev_lock(hcon->hdev);
+
 	/* Strictly speaking the Core Specification (4.1) allows sending
 	/* Strictly speaking the Core Specification (4.1) allows sending
 	 * an empty address which would force us to rely on just the IRK
 	 * an empty address which would force us to rely on just the IRK
 	 * as "identity information". However, since such
 	 * as "identity information". However, since such
@@ -1052,8 +1101,7 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
 	 */
 	 */
 	if (!bacmp(&info->bdaddr, BDADDR_ANY)) {
 	if (!bacmp(&info->bdaddr, BDADDR_ANY)) {
 		BT_ERR("Ignoring IRK with no identity address");
 		BT_ERR("Ignoring IRK with no identity address");
-		smp_distribute_keys(conn);
-		return 0;
+		goto distribute;
 	}
 	}
 
 
 	bacpy(&smp->id_addr, &info->bdaddr);
 	bacpy(&smp->id_addr, &info->bdaddr);
@@ -1067,8 +1115,11 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
 	smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
 	smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
 				      smp->id_addr_type, smp->irk, &rpa);
 				      smp->id_addr_type, smp->irk, &rpa);
 
 
+distribute:
 	smp_distribute_keys(conn);
 	smp_distribute_keys(conn);
 
 
+	hci_dev_unlock(hcon->hdev);
+
 	return 0;
 	return 0;
 }
 }
 
 
@@ -1305,7 +1356,7 @@ int smp_distribute_keys(struct l2cap_conn *conn)
 
 
 		authenticated = hcon->sec_level == BT_SECURITY_HIGH;
 		authenticated = hcon->sec_level == BT_SECURITY_HIGH;
 		ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
 		ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
-				  HCI_SMP_LTK_SLAVE, authenticated, enc.ltk,
+				  SMP_LTK_SLAVE, authenticated, enc.ltk,
 				  smp->enc_key_size, ediv, rand);
 				  smp->enc_key_size, ediv, rand);
 		smp->slave_ltk = ltk;
 		smp->slave_ltk = ltk;
 
 

+ 7 - 0
net/bluetooth/smp.h

@@ -116,6 +116,13 @@ struct smp_cmd_security_req {
 #define SMP_MIN_ENC_KEY_SIZE		7
 #define SMP_MIN_ENC_KEY_SIZE		7
 #define SMP_MAX_ENC_KEY_SIZE		16
 #define SMP_MAX_ENC_KEY_SIZE		16
 
 
+/* LTK types used in internal storage (struct smp_ltk) */
+enum {
+	SMP_STK,
+	SMP_LTK,
+	SMP_LTK_SLAVE,
+};
+
 /* SMP Commands */
 /* SMP Commands */
 bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level);
 bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level);
 int smp_conn_security(struct hci_conn *hcon, __u8 sec_level);
 int smp_conn_security(struct hci_conn *hcon, __u8 sec_level);

+ 3 - 2
net/mac80211/util.c

@@ -1150,11 +1150,12 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
 	int err;
 	int err;
 
 
 	/* 24 + 6 = header + auth_algo + auth_transaction + status_code */
 	/* 24 + 6 = header + auth_algo + auth_transaction + status_code */
-	skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24 + 6 + extra_len);
+	skb = dev_alloc_skb(local->hw.extra_tx_headroom + IEEE80211_WEP_IV_LEN +
+			    24 + 6 + extra_len + IEEE80211_WEP_ICV_LEN);
 	if (!skb)
 	if (!skb)
 		return;
 		return;
 
 
-	skb_reserve(skb, local->hw.extra_tx_headroom);
+	skb_reserve(skb, local->hw.extra_tx_headroom + IEEE80211_WEP_IV_LEN);
 
 
 	mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24 + 6);
 	mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24 + 6);
 	memset(mgmt, 0, 24 + 6);
 	memset(mgmt, 0, 24 + 6);

+ 1 - 1
net/wireless/core.h

@@ -424,7 +424,7 @@ static inline unsigned int elapsed_jiffies_msecs(unsigned long start)
 	if (end >= start)
 	if (end >= start)
 		return jiffies_to_msecs(end - start);
 		return jiffies_to_msecs(end - start);
 
 
-	return jiffies_to_msecs(end + (MAX_JIFFY_OFFSET - start) + 1);
+	return jiffies_to_msecs(end + (ULONG_MAX - start) + 1);
 }
 }
 
 
 void
 void

+ 5 - 6
net/wireless/nl80211.c

@@ -1498,18 +1498,17 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
 		}
 		}
 		CMD(start_p2p_device, START_P2P_DEVICE);
 		CMD(start_p2p_device, START_P2P_DEVICE);
 		CMD(set_mcast_rate, SET_MCAST_RATE);
 		CMD(set_mcast_rate, SET_MCAST_RATE);
+#ifdef CONFIG_NL80211_TESTMODE
+		CMD(testmode_cmd, TESTMODE);
+#endif
 		if (state->split) {
 		if (state->split) {
 			CMD(crit_proto_start, CRIT_PROTOCOL_START);
 			CMD(crit_proto_start, CRIT_PROTOCOL_START);
 			CMD(crit_proto_stop, CRIT_PROTOCOL_STOP);
 			CMD(crit_proto_stop, CRIT_PROTOCOL_STOP);
 			if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)
 			if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)
 				CMD(channel_switch, CHANNEL_SWITCH);
 				CMD(channel_switch, CHANNEL_SWITCH);
+			CMD(set_qos_map, SET_QOS_MAP);
 		}
 		}
-		CMD(set_qos_map, SET_QOS_MAP);
-
-#ifdef CONFIG_NL80211_TESTMODE
-		CMD(testmode_cmd, TESTMODE);
-#endif
-
+		/* add into the if now */
 #undef CMD
 #undef CMD
 
 
 		if (rdev->ops->connect || rdev->ops->auth) {
 		if (rdev->ops->connect || rdev->ops->auth) {

+ 7 - 15
net/wireless/reg.c

@@ -935,7 +935,7 @@ freq_reg_info_regd(struct wiphy *wiphy, u32 center_freq,
 		if (!band_rule_found)
 		if (!band_rule_found)
 			band_rule_found = freq_in_rule_band(fr, center_freq);
 			band_rule_found = freq_in_rule_band(fr, center_freq);
 
 
-		bw_fits = reg_does_bw_fit(fr, center_freq, MHZ_TO_KHZ(5));
+		bw_fits = reg_does_bw_fit(fr, center_freq, MHZ_TO_KHZ(20));
 
 
 		if (band_rule_found && bw_fits)
 		if (band_rule_found && bw_fits)
 			return rr;
 			return rr;
@@ -1019,10 +1019,10 @@ static void chan_reg_rule_print_dbg(const struct ieee80211_regdomain *regd,
 }
 }
 #endif
 #endif
 
 
-/* Find an ieee80211_reg_rule such that a 5MHz channel with frequency
- * chan->center_freq fits there.
- * If there is no such reg_rule, disable the channel, otherwise set the
- * flags corresponding to the bandwidths allowed in the particular reg_rule
+/*
+ * Note that right now we assume the desired channel bandwidth
+ * is always 20 MHz for each individual channel (HT40 uses 20 MHz
+ * per channel, the primary and the extension channel).
  */
  */
 static void handle_channel(struct wiphy *wiphy,
 static void handle_channel(struct wiphy *wiphy,
 			   enum nl80211_reg_initiator initiator,
 			   enum nl80211_reg_initiator initiator,
@@ -1083,12 +1083,8 @@ static void handle_channel(struct wiphy *wiphy,
 	if (reg_rule->flags & NL80211_RRF_AUTO_BW)
 	if (reg_rule->flags & NL80211_RRF_AUTO_BW)
 		max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule);
 		max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule);
 
 
-	if (max_bandwidth_khz < MHZ_TO_KHZ(10))
-		bw_flags = IEEE80211_CHAN_NO_10MHZ;
-	if (max_bandwidth_khz < MHZ_TO_KHZ(20))
-		bw_flags |= IEEE80211_CHAN_NO_20MHZ;
 	if (max_bandwidth_khz < MHZ_TO_KHZ(40))
 	if (max_bandwidth_khz < MHZ_TO_KHZ(40))
-		bw_flags |= IEEE80211_CHAN_NO_HT40;
+		bw_flags = IEEE80211_CHAN_NO_HT40;
 	if (max_bandwidth_khz < MHZ_TO_KHZ(80))
 	if (max_bandwidth_khz < MHZ_TO_KHZ(80))
 		bw_flags |= IEEE80211_CHAN_NO_80MHZ;
 		bw_flags |= IEEE80211_CHAN_NO_80MHZ;
 	if (max_bandwidth_khz < MHZ_TO_KHZ(160))
 	if (max_bandwidth_khz < MHZ_TO_KHZ(160))
@@ -1522,12 +1518,8 @@ static void handle_channel_custom(struct wiphy *wiphy,
 	if (reg_rule->flags & NL80211_RRF_AUTO_BW)
 	if (reg_rule->flags & NL80211_RRF_AUTO_BW)
 		max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule);
 		max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule);
 
 
-	if (max_bandwidth_khz < MHZ_TO_KHZ(10))
-		bw_flags = IEEE80211_CHAN_NO_10MHZ;
-	if (max_bandwidth_khz < MHZ_TO_KHZ(20))
-		bw_flags |= IEEE80211_CHAN_NO_20MHZ;
 	if (max_bandwidth_khz < MHZ_TO_KHZ(40))
 	if (max_bandwidth_khz < MHZ_TO_KHZ(40))
-		bw_flags |= IEEE80211_CHAN_NO_HT40;
+		bw_flags = IEEE80211_CHAN_NO_HT40;
 	if (max_bandwidth_khz < MHZ_TO_KHZ(80))
 	if (max_bandwidth_khz < MHZ_TO_KHZ(80))
 		bw_flags |= IEEE80211_CHAN_NO_80MHZ;
 		bw_flags |= IEEE80211_CHAN_NO_80MHZ;
 	if (max_bandwidth_khz < MHZ_TO_KHZ(160))
 	if (max_bandwidth_khz < MHZ_TO_KHZ(160))