diff options
-rw-r--r-- | MAINTAINERS | 4 | ||||
-rw-r--r-- | drivers/bluetooth/Kconfig | 3 | ||||
-rw-r--r-- | drivers/bluetooth/btintel.c | 2 | ||||
-rw-r--r-- | drivers/bluetooth/btusb.c | 4 | ||||
-rw-r--r-- | drivers/bluetooth/btwilink.c | 1 | ||||
-rw-r--r-- | drivers/bluetooth/hci_ldisc.c | 40 | ||||
-rw-r--r-- | drivers/bluetooth/hci_ll.c | 1 | ||||
-rw-r--r-- | drivers/bluetooth/hci_uart.h | 1 | ||||
-rw-r--r-- | drivers/net/ieee802154/ca8210.c | 12 | ||||
-rw-r--r-- | include/net/bluetooth/hci.h | 8 | ||||
-rw-r--r-- | net/bluetooth/ecdh_helper.c | 11 | ||||
-rw-r--r-- | net/bluetooth/hci_core.c | 46 | ||||
-rw-r--r-- | net/ieee802154/socket.c | 10 |
13 files changed, 107 insertions, 36 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index ea074d92cc2c..553dbbddf3e4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -155,7 +155,7 @@ S: Maintained F: drivers/scsi/53c700* 6LOWPAN GENERIC (BTLE/IEEE 802.15.4) -M: Alexander Aring <aar@pengutronix.de> +M: Alexander Aring <alex.aring@gmail.com> M: Jukka Rissanen <jukka.rissanen@linux.intel.com> L: linux-bluetooth@vger.kernel.org L: linux-wpan@vger.kernel.org @@ -6427,7 +6427,7 @@ F: Documentation/cdrom/ide-cd F: drivers/ide/ide-cd* IEEE 802.15.4 SUBSYSTEM -M: Alexander Aring <aar@pengutronix.de> +M: Alexander Aring <alex.aring@gmail.com> M: Stefan Schmidt <stefan@osg.samsung.com> L: linux-wpan@vger.kernel.org W: http://wpan.cakelab.org/ diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig index 737d93ef27c5..35952a94875e 100644 --- a/drivers/bluetooth/Kconfig +++ b/drivers/bluetooth/Kconfig @@ -97,6 +97,7 @@ config BT_HCIUART_NOKIA depends on BT_HCIUART depends on BT_HCIUART_SERDEV depends on PM + select BT_HCIUART_H4 help Nokia H4+ is serial protocol for communication between Bluetooth device and host. This protocol is required for Bluetooth devices @@ -131,7 +132,7 @@ config BT_HCIUART_ATH3K config BT_HCIUART_LL bool "HCILL protocol support" - depends on BT_HCIUART + depends on BT_HCIUART_SERDEV help HCILL (HCI Low Level) is a serial protocol for communication between Bluetooth device and host. This protocol is required for diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c index fce154855718..d32e109bd5cb 100644 --- a/drivers/bluetooth/btintel.c +++ b/drivers/bluetooth/btintel.c @@ -575,3 +575,5 @@ MODULE_VERSION(VERSION); MODULE_LICENSE("GPL"); MODULE_FIRMWARE("intel/ibt-11-5.sfi"); MODULE_FIRMWARE("intel/ibt-11-5.ddc"); +MODULE_FIRMWARE("intel/ibt-12-16.sfi"); +MODULE_FIRMWARE("intel/ibt-12-16.ddc"); diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 7fa373b428f8..278e81186150 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -336,6 +336,7 @@ static const struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x8087, 0x0a2a), .driver_info = BTUSB_INTEL }, { USB_DEVICE(0x8087, 0x0a2b), .driver_info = BTUSB_INTEL_NEW }, { USB_DEVICE(0x8087, 0x0aa7), .driver_info = BTUSB_INTEL }, + { USB_DEVICE(0x8087, 0x0aaa), .driver_info = BTUSB_INTEL_NEW }, /* Other Intel Bluetooth devices */ { USB_VENDOR_AND_INTERFACE_INFO(0x8087, 0xe0, 0x01, 0x01), @@ -2036,6 +2037,7 @@ static int btusb_setup_intel_new(struct hci_dev *hdev) switch (ver.hw_variant) { case 0x0b: /* SfP */ case 0x0c: /* WsP */ + case 0x11: /* JfP */ case 0x12: /* ThP */ break; default: @@ -2138,6 +2140,8 @@ static int btusb_setup_intel_new(struct hci_dev *hdev) * Currently the supported hardware variants are: * 11 (0x0b) for iBT3.0 (LnP/SfP) * 12 (0x0c) for iBT3.5 (WsP) + * 17 (0x11) for iBT3.5 (JfP) + * 18 (0x12) for iBT3.5 (ThP) */ snprintf(fwname, sizeof(fwname), "intel/ibt-%u-%u.sfi", le16_to_cpu(ver.hw_variant), diff --git a/drivers/bluetooth/btwilink.c b/drivers/bluetooth/btwilink.c index b6bb58c41df5..85a3978b064f 100644 --- a/drivers/bluetooth/btwilink.c +++ b/drivers/bluetooth/btwilink.c @@ -262,7 +262,6 @@ static int ti_st_send_frame(struct hci_dev *hdev, struct sk_buff *skb) pkt_type = hci_skb_pkt_type(skb); len = hst->st_write(skb); if (len < 0) { - kfree_skb(skb); BT_ERR("ST write failed (%ld)", len); /* Try Again, would only fail if UART has gone bad */ return -EAGAIN; diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 2edd30556956..8397b716fa65 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -114,8 +114,12 @@ static inline struct sk_buff *hci_uart_dequeue(struct hci_uart *hu) struct sk_buff *skb = hu->tx_skb; if (!skb) { + read_lock(&hu->proto_lock); + if (test_bit(HCI_UART_PROTO_READY, &hu->flags)) skb = hu->proto->dequeue(hu); + + read_unlock(&hu->proto_lock); } else { hu->tx_skb = NULL; } @@ -125,18 +129,23 @@ static inline struct sk_buff *hci_uart_dequeue(struct hci_uart *hu) int hci_uart_tx_wakeup(struct hci_uart *hu) { + read_lock(&hu->proto_lock); + if (!test_bit(HCI_UART_PROTO_READY, &hu->flags)) - return 0; + goto no_schedule; if (test_and_set_bit(HCI_UART_SENDING, &hu->tx_state)) { set_bit(HCI_UART_TX_WAKEUP, &hu->tx_state); - return 0; + goto no_schedule; } BT_DBG(""); schedule_work(&hu->write_work); +no_schedule: + read_unlock(&hu->proto_lock); + return 0; } EXPORT_SYMBOL_GPL(hci_uart_tx_wakeup); @@ -237,9 +246,13 @@ static int hci_uart_flush(struct hci_dev *hdev) tty_ldisc_flush(tty); tty_driver_flush_buffer(tty); + read_lock(&hu->proto_lock); + if (test_bit(HCI_UART_PROTO_READY, &hu->flags)) hu->proto->flush(hu); + read_unlock(&hu->proto_lock); + return 0; } @@ -261,10 +274,15 @@ static int hci_uart_send_frame(struct hci_dev *hdev, struct sk_buff *skb) BT_DBG("%s: type %d len %d", hdev->name, hci_skb_pkt_type(skb), skb->len); - if (!test_bit(HCI_UART_PROTO_READY, &hu->flags)) + read_lock(&hu->proto_lock); + + if (!test_bit(HCI_UART_PROTO_READY, &hu->flags)) { + read_unlock(&hu->proto_lock); return -EUNATCH; + } hu->proto->enqueue(hu, skb); + read_unlock(&hu->proto_lock); hci_uart_tx_wakeup(hu); @@ -460,6 +478,8 @@ static int hci_uart_tty_open(struct tty_struct *tty) INIT_WORK(&hu->init_ready, hci_uart_init_work); INIT_WORK(&hu->write_work, hci_uart_write_work); + rwlock_init(&hu->proto_lock); + /* Flush any pending characters in the driver */ tty_driver_flush_buffer(tty); @@ -475,6 +495,7 @@ static void hci_uart_tty_close(struct tty_struct *tty) { struct hci_uart *hu = tty->disc_data; struct hci_dev *hdev; + unsigned long flags; BT_DBG("tty %p", tty); @@ -490,7 +511,11 @@ static void hci_uart_tty_close(struct tty_struct *tty) cancel_work_sync(&hu->write_work); - if (test_and_clear_bit(HCI_UART_PROTO_READY, &hu->flags)) { + if (test_bit(HCI_UART_PROTO_READY, &hu->flags)) { + write_lock_irqsave(&hu->proto_lock, flags); + clear_bit(HCI_UART_PROTO_READY, &hu->flags); + write_unlock_irqrestore(&hu->proto_lock, flags); + if (hdev) { if (test_bit(HCI_UART_REGISTERED, &hu->flags)) hci_unregister_dev(hdev); @@ -549,13 +574,18 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, if (!hu || tty != hu->tty) return; - if (!test_bit(HCI_UART_PROTO_READY, &hu->flags)) + read_lock(&hu->proto_lock); + + if (!test_bit(HCI_UART_PROTO_READY, &hu->flags)) { + read_unlock(&hu->proto_lock); return; + } /* It does not need a lock here as it is already protected by a mutex in * tty caller */ hu->proto->recv(hu, data, count); + read_unlock(&hu->proto_lock); if (hu->hdev) hu->hdev->stat.byte_rx += count; diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c index adc444f309a3..200288c87fc4 100644 --- a/drivers/bluetooth/hci_ll.c +++ b/drivers/bluetooth/hci_ll.c @@ -624,6 +624,7 @@ static int download_firmware(struct ll_device *lldev) skb = __hci_cmd_sync(lldev->hu.hdev, cmd->opcode, cmd->plen, &cmd->speed, HCI_INIT_TIMEOUT); if (IS_ERR(skb)) { bt_dev_err(lldev->hu.hdev, "send command failed\n"); + err = PTR_ERR(skb); goto out_rel_fw; } kfree_skb(skb); diff --git a/drivers/bluetooth/hci_uart.h b/drivers/bluetooth/hci_uart.h index 2b05e557fad0..c6e9e1cf63f8 100644 --- a/drivers/bluetooth/hci_uart.h +++ b/drivers/bluetooth/hci_uart.h @@ -87,6 +87,7 @@ struct hci_uart { struct work_struct write_work; const struct hci_uart_proto *proto; + rwlock_t proto_lock; /* Stop work for proto close */ void *priv; struct sk_buff *tx_skb; diff --git a/drivers/net/ieee802154/ca8210.c b/drivers/net/ieee802154/ca8210.c index 25fd3b04b3c0..7a218549c80a 100644 --- a/drivers/net/ieee802154/ca8210.c +++ b/drivers/net/ieee802154/ca8210.c @@ -912,7 +912,7 @@ static int ca8210_spi_transfer( ) { int i, status = 0; - struct ca8210_priv *priv = spi_get_drvdata(spi); + struct ca8210_priv *priv; struct cas_control *cas_ctl; if (!spi) { @@ -923,6 +923,7 @@ static int ca8210_spi_transfer( return -ENODEV; } + priv = spi_get_drvdata(spi); reinit_completion(&priv->spi_transfer_complete); dev_dbg(&spi->dev, "ca8210_spi_transfer called\n"); @@ -1808,10 +1809,9 @@ static int ca8210_skb_rx( /* Allocate mtu size buffer for every rx packet */ skb = dev_alloc_skb(IEEE802154_MTU + sizeof(hdr)); - if (!skb) { - dev_crit(&priv->spi->dev, "dev_alloc_skb failed\n"); + if (!skb) return -ENOMEM; - } + skb_reserve(skb, sizeof(hdr)); msdulen = data_ind[22]; /* msdu_length */ @@ -3143,10 +3143,6 @@ static int ca8210_probe(struct spi_device *spi_device) pdata = kmalloc(sizeof(*pdata), GFP_KERNEL); if (!pdata) { - dev_crit( - &spi_device->dev, - "Could not allocate platform data\n" - ); ret = -ENOMEM; goto error; } diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 99aa5e5e3100..fe98f0a5bef0 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -399,6 +399,7 @@ enum { #define HCI_LE_PING 0x10 #define HCI_LE_DATA_LEN_EXT 0x20 #define HCI_LE_EXT_SCAN_POLICY 0x80 +#define HCI_LE_CHAN_SEL_ALG2 0x40 /* Connection modes */ #define HCI_CM_ACTIVE 0x0000 @@ -1498,6 +1499,13 @@ struct hci_rp_le_read_max_data_len { __le16 rx_time; } __packed; +#define HCI_OP_LE_SET_DEFAULT_PHY 0x2031 +struct hci_cp_le_set_default_phy { + __u8 all_phys; + __u8 tx_phys; + __u8 rx_phys; +} __packed; + /* ---- HCI Events ---- */ #define HCI_EV_INQUIRY_COMPLETE 0x01 diff --git a/net/bluetooth/ecdh_helper.c b/net/bluetooth/ecdh_helper.c index 24d4e60f8c48..c7b1a9aee579 100644 --- a/net/bluetooth/ecdh_helper.c +++ b/net/bluetooth/ecdh_helper.c @@ -89,11 +89,9 @@ bool compute_ecdh_secret(const u8 public_key[64], const u8 private_key[32], p.curve_id = ECC_CURVE_NIST_P256; buf_len = crypto_ecdh_key_len(&p); buf = kmalloc(buf_len, GFP_KERNEL); - if (!buf) { - pr_err("alg: kpp: Failed to allocate %d bytes for buf\n", - buf_len); + if (!buf) goto free_req; - } + crypto_ecdh_encode_key(buf, buf_len, &p); /* Set A private Key */ @@ -170,11 +168,8 @@ bool generate_ecdh_keys(u8 public_key[64], u8 private_key[32]) p.key_size = 32; buf_len = crypto_ecdh_key_len(&p); buf = kmalloc(buf_len, GFP_KERNEL); - if (!buf) { - pr_err("alg: kpp: Failed to allocate %d bytes for buf\n", - buf_len); + if (!buf) goto free_req; - } do { if (tries++ >= max_tries) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 05686776a5fb..7655b4005dfb 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -148,13 +148,13 @@ static ssize_t vendor_diag_write(struct file *file, const char __user *user_buf, return -EINVAL; /* When the diagnostic flags are not persistent and the transport - * is not active, then there is no need for the vendor callback. - * - * Instead just store the desired value. If needed the setting - * will be programmed when the controller gets powered on. + * is not active or in user channel operation, then there is no need + * for the vendor callback. Instead just store the desired value and + * the setting will be programmed when the controller gets powered on. */ if (test_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks) && - !test_bit(HCI_RUNNING, &hdev->flags)) + (!test_bit(HCI_RUNNING, &hdev->flags) || + hci_dev_test_flag(hdev, HCI_USER_CHANNEL))) goto done; hci_req_sync_lock(hdev); @@ -635,6 +635,14 @@ static int hci_init3_req(struct hci_request *req, unsigned long opt) * Report */ + /* If the controller supports Channel Selection Algorithm #2 + * feature, enable the corresponding event. + */ + if (hdev->le_features[1] & HCI_LE_CHAN_SEL_ALG2) + events[2] |= 0x08; /* LE Channel Selection + * Algorithm + */ + /* If the controller supports the LE Set Scan Enable command, * enable the corresponding advertising report event. */ @@ -677,6 +685,12 @@ static int hci_init3_req(struct hci_request *req, unsigned long opt) if (hdev->commands[34] & 0x04) events[1] |= 0x01; /* LE Generate DHKey Complete */ + /* If the controller supports the LE Set Default PHY or + * LE Set PHY commands, enable the corresponding event. + */ + if (hdev->commands[35] & (0x20 | 0x40)) + events[1] |= 0x08; /* LE PHY Update Complete */ + hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, sizeof(events), events); @@ -771,6 +785,27 @@ static int hci_init4_req(struct hci_request *req, unsigned long opt) sizeof(support), &support); } + /* Set Suggested Default Data Length to maximum if supported */ + if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) { + struct hci_cp_le_write_def_data_len cp; + + cp.tx_len = hdev->le_max_tx_len; + cp.tx_time = hdev->le_max_tx_time; + hci_req_add(req, HCI_OP_LE_WRITE_DEF_DATA_LEN, sizeof(cp), &cp); + } + + /* Set Default PHY parameters if command is supported */ + if (hdev->commands[35] & 0x20) { + struct hci_cp_le_set_default_phy cp; + + /* No transmitter PHY or receiver PHY preferences */ + cp.all_phys = 0x03; + cp.tx_phys = 0; + cp.rx_phys = 0; + + hci_req_add(req, HCI_OP_LE_SET_DEFAULT_PHY, sizeof(cp), &cp); + } + return 0; } @@ -1384,6 +1419,7 @@ static int hci_dev_do_open(struct hci_dev *hdev) * completed. */ if (test_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks) && + !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && hci_dev_test_flag(hdev, HCI_VENDOR_DIAG) && hdev->set_diag) ret = hdev->set_diag(hdev, true); diff --git a/net/ieee802154/socket.c b/net/ieee802154/socket.c index eedba7670b51..a60658c85a9a 100644 --- a/net/ieee802154/socket.c +++ b/net/ieee802154/socket.c @@ -301,15 +301,14 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) goto out_skb; skb->dev = dev; - skb->sk = sk; skb->protocol = htons(ETH_P_IEEE802154); - dev_put(dev); - err = dev_queue_xmit(skb); if (err > 0) err = net_xmit_errno(err); + dev_put(dev); + return err ?: size; out_skb: @@ -690,15 +689,14 @@ static int dgram_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) goto out_skb; skb->dev = dev; - skb->sk = sk; skb->protocol = htons(ETH_P_IEEE802154); - dev_put(dev); - err = dev_queue_xmit(skb); if (err > 0) err = net_xmit_errno(err); + dev_put(dev); + return err ?: size; out_skb: |