Commit 2bc0a832 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge tag 'for-net-next-2022-03-04' of...

Merge tag 'for-net-next-2022-03-04' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next

Luiz Augusto von Dentz says:

====================
bluetooth-next pull request for net-next:

 - Add new PID/VID (0x13d3/0x3567) for MT7921
 - Add new PID/VID (0x2550/0x8761) for Realtek 8761BU
 - Add support for LG LGSBWAC02 (MT7663BUN)
 - Add support for BCM43430A0 and BCM43430A1
 - Add support for Intel Madison Peak (MsP2)

* tag 'for-net-next-2022-03-04' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next: (21 commits)
  Bluetooth: btusb: Add another Realtek 8761BU
  Bluetooth: hci_bcm: add BCM43430A0 & BCM43430A1
  Bluetooth: use memset avoid memory leaks
  Bluetooth: btmtksdio: Fix kernel oops when sdio suspend.
  Bluetooth: btusb: Add a new PID/VID 13d3/3567 for MT7921
  Bluetooth: move adv_instance_cnt read within the device lock
  Bluetooth: hci_event: Add missing locking on hdev in hci_le_ext_adv_term_evt
  Bluetooth: btusb: Make use of of BIT macro to declare flags
  Bluetooth: Fix not checking for valid hdev on bt_dev_{info,warn,err,dbg}
  Bluetooth: mediatek: fix the conflict between mtk and msft vendor event
  Bluetooth: mt7921s: support bluetooth reset mechanism
  Bluetooth: make array bt_uuid_any static const
  Bluetooth: 6lowpan: No need to clear memory twice
  Bluetooth: btusb: Improve stability for QCA devices
  Bluetooth: btusb: add support for LG LGSBWAC02 (MT7663BUN)
  Bluetooth: btusb: Add support for Intel Madison Peak (MsP2) device
  Bluetooth: Improve skb handling in mgmt_device_connected()
  Bluetooth: Fix skb allocation in mgmt_remote_name() & mgmt_device_connected()
  Bluetooth: mgmt: Remove unneeded variable
  Bluetooth: hci_sync: fix undefined return of hci_disconnect_all_sync()
  ...
====================

Link: https://lore.kernel.org/r/20220304193919.649815-1-luiz.dentz@gmail.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 6646dc24 6dfbe29f
...@@ -5,14 +5,21 @@ ...@@ -5,14 +5,21 @@
#define FIRMWARE_MT7668 "mediatek/mt7668pr2h.bin" #define FIRMWARE_MT7668 "mediatek/mt7668pr2h.bin"
#define FIRMWARE_MT7961 "mediatek/BT_RAM_CODE_MT7961_1_2_hdr.bin" #define FIRMWARE_MT7961 "mediatek/BT_RAM_CODE_MT7961_1_2_hdr.bin"
#define HCI_EV_WMT 0xe4
#define HCI_WMT_MAX_EVENT_SIZE 64 #define HCI_WMT_MAX_EVENT_SIZE 64
#define BTMTK_WMT_REG_WRITE 0x1 #define BTMTK_WMT_REG_WRITE 0x1
#define BTMTK_WMT_REG_READ 0x2 #define BTMTK_WMT_REG_READ 0x2
#define MT7921_BTSYS_RST 0x70002610
#define MT7921_BTSYS_RST_WITH_GPIO BIT(7)
#define MT7921_PINMUX_0 0x70005050 #define MT7921_PINMUX_0 0x70005050
#define MT7921_PINMUX_1 0x70005054 #define MT7921_PINMUX_1 0x70005054
#define MT7921_DLSTATUS 0x7c053c10
#define BT_DL_STATE BIT(1)
enum { enum {
BTMTK_WMT_PATCH_DWNLD = 0x1, BTMTK_WMT_PATCH_DWNLD = 0x1,
BTMTK_WMT_TEST = 0x2, BTMTK_WMT_TEST = 0x2,
......
...@@ -12,10 +12,12 @@ ...@@ -12,10 +12,12 @@
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include <linux/atomic.h> #include <linux/atomic.h>
#include <linux/gpio/consumer.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/iopoll.h> #include <linux/iopoll.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
...@@ -83,6 +85,7 @@ MODULE_DEVICE_TABLE(sdio, btmtksdio_table); ...@@ -83,6 +85,7 @@ MODULE_DEVICE_TABLE(sdio, btmtksdio_table);
#define MTK_REG_CHCR 0xc #define MTK_REG_CHCR 0xc
#define C_INT_CLR_CTRL BIT(1) #define C_INT_CLR_CTRL BIT(1)
#define BT_RST_DONE BIT(8)
/* CHISR have the same bits field definition with CHIER */ /* CHISR have the same bits field definition with CHIER */
#define MTK_REG_CHISR 0x10 #define MTK_REG_CHISR 0x10
...@@ -114,6 +117,7 @@ MODULE_DEVICE_TABLE(sdio, btmtksdio_table); ...@@ -114,6 +117,7 @@ MODULE_DEVICE_TABLE(sdio, btmtksdio_table);
#define BTMTKSDIO_HW_TX_READY 2 #define BTMTKSDIO_HW_TX_READY 2
#define BTMTKSDIO_FUNC_ENABLED 3 #define BTMTKSDIO_FUNC_ENABLED 3
#define BTMTKSDIO_PATCH_ENABLED 4 #define BTMTKSDIO_PATCH_ENABLED 4
#define BTMTKSDIO_HW_RESET_ACTIVE 5
struct mtkbtsdio_hdr { struct mtkbtsdio_hdr {
__le16 len; __le16 len;
...@@ -133,6 +137,8 @@ struct btmtksdio_dev { ...@@ -133,6 +137,8 @@ struct btmtksdio_dev {
struct sk_buff *evt_skb; struct sk_buff *evt_skb;
const struct btmtksdio_data *data; const struct btmtksdio_data *data;
struct gpio_desc *reset;
}; };
static int mtk_hci_wmt_sync(struct hci_dev *hdev, static int mtk_hci_wmt_sync(struct hci_dev *hdev,
...@@ -297,6 +303,11 @@ static u32 btmtksdio_drv_own_query_79xx(struct btmtksdio_dev *bdev) ...@@ -297,6 +303,11 @@ static u32 btmtksdio_drv_own_query_79xx(struct btmtksdio_dev *bdev)
return sdio_readl(bdev->func, MTK_REG_PD2HRM0R, NULL); return sdio_readl(bdev->func, MTK_REG_PD2HRM0R, NULL);
} }
static u32 btmtksdio_chcr_query(struct btmtksdio_dev *bdev)
{
return sdio_readl(bdev->func, MTK_REG_CHCR, NULL);
}
static int btmtksdio_fw_pmctrl(struct btmtksdio_dev *bdev) static int btmtksdio_fw_pmctrl(struct btmtksdio_dev *bdev)
{ {
u32 status; u32 status;
...@@ -370,13 +381,6 @@ static int btmtksdio_recv_event(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -370,13 +381,6 @@ static int btmtksdio_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
struct hci_event_hdr *hdr = (void *)skb->data; struct hci_event_hdr *hdr = (void *)skb->data;
int err; int err;
/* Fix up the vendor event id with 0xff for vendor specific instead
* of 0xe4 so that event send via monitoring socket can be parsed
* properly.
*/
if (hdr->evt == 0xe4)
hdr->evt = HCI_EV_VENDOR;
/* When someone waits for the WMT event, the skb is being cloned /* When someone waits for the WMT event, the skb is being cloned
* and being processed the events from there then. * and being processed the events from there then.
*/ */
...@@ -392,7 +396,7 @@ static int btmtksdio_recv_event(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -392,7 +396,7 @@ static int btmtksdio_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
if (err < 0) if (err < 0)
goto err_free_skb; goto err_free_skb;
if (hdr->evt == HCI_EV_VENDOR) { if (hdr->evt == HCI_EV_WMT) {
if (test_and_clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT, if (test_and_clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT,
&bdev->tx_state)) { &bdev->tx_state)) {
/* Barrier to sync with other CPUs */ /* Barrier to sync with other CPUs */
...@@ -967,6 +971,28 @@ static int btmtksdio_sco_setting(struct hci_dev *hdev) ...@@ -967,6 +971,28 @@ static int btmtksdio_sco_setting(struct hci_dev *hdev)
return btmtksdio_mtk_reg_write(hdev, MT7921_PINMUX_1, val, ~0); return btmtksdio_mtk_reg_write(hdev, MT7921_PINMUX_1, val, ~0);
} }
static int btmtksdio_reset_setting(struct hci_dev *hdev)
{
int err;
u32 val;
err = btmtksdio_mtk_reg_read(hdev, MT7921_PINMUX_1, &val);
if (err < 0)
return err;
val |= 0x20; /* set the pin (bit field 11:8) work as GPIO mode */
err = btmtksdio_mtk_reg_write(hdev, MT7921_PINMUX_1, val, ~0);
if (err < 0)
return err;
err = btmtksdio_mtk_reg_read(hdev, MT7921_BTSYS_RST, &val);
if (err < 0)
return err;
val |= MT7921_BTSYS_RST_WITH_GPIO;
return btmtksdio_mtk_reg_write(hdev, MT7921_BTSYS_RST, val, ~0);
}
static int btmtksdio_setup(struct hci_dev *hdev) static int btmtksdio_setup(struct hci_dev *hdev)
{ {
struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
...@@ -974,13 +1000,32 @@ static int btmtksdio_setup(struct hci_dev *hdev) ...@@ -974,13 +1000,32 @@ static int btmtksdio_setup(struct hci_dev *hdev)
unsigned long long duration; unsigned long long duration;
char fwname[64]; char fwname[64];
int err, dev_id; int err, dev_id;
u32 fw_version = 0; u32 fw_version = 0, val;
calltime = ktime_get(); calltime = ktime_get();
set_bit(BTMTKSDIO_HW_TX_READY, &bdev->tx_state); set_bit(BTMTKSDIO_HW_TX_READY, &bdev->tx_state);
switch (bdev->data->chipid) { switch (bdev->data->chipid) {
case 0x7921: case 0x7921:
if (test_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state)) {
err = btmtksdio_mtk_reg_read(hdev, MT7921_DLSTATUS,
&val);
if (err < 0)
return err;
val &= ~BT_DL_STATE;
err = btmtksdio_mtk_reg_write(hdev, MT7921_DLSTATUS,
val, ~0);
if (err < 0)
return err;
btmtksdio_fw_pmctrl(bdev);
msleep(20);
btmtksdio_drv_pmctrl(bdev);
clear_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state);
}
err = btmtksdio_mtk_reg_read(hdev, 0x70010200, &dev_id); err = btmtksdio_mtk_reg_read(hdev, 0x70010200, &dev_id);
if (err < 0) { if (err < 0) {
bt_dev_err(hdev, "Failed to get device id (%d)", err); bt_dev_err(hdev, "Failed to get device id (%d)", err);
...@@ -1015,6 +1060,16 @@ static int btmtksdio_setup(struct hci_dev *hdev) ...@@ -1015,6 +1060,16 @@ static int btmtksdio_setup(struct hci_dev *hdev)
return err; return err;
} }
/* Enable GPIO reset mechanism */
if (bdev->reset) {
err = btmtksdio_reset_setting(hdev);
if (err < 0) {
bt_dev_err(hdev, "Failed to enable Reset setting (%d)", err);
devm_gpiod_put(bdev->dev, bdev->reset);
bdev->reset = NULL;
}
}
break; break;
case 0x7663: case 0x7663:
case 0x7668: case 0x7668:
...@@ -1111,6 +1166,47 @@ static int btmtksdio_send_frame(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -1111,6 +1166,47 @@ static int btmtksdio_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
return 0; return 0;
} }
static void btmtksdio_cmd_timeout(struct hci_dev *hdev)
{
struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
u32 status;
int err;
if (!bdev->reset || bdev->data->chipid != 0x7921)
return;
pm_runtime_get_sync(bdev->dev);
if (test_and_set_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state))
return;
sdio_claim_host(bdev->func);
sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, NULL);
skb_queue_purge(&bdev->txq);
cancel_work_sync(&bdev->txrx_work);
gpiod_set_value_cansleep(bdev->reset, 1);
msleep(100);
gpiod_set_value_cansleep(bdev->reset, 0);
err = readx_poll_timeout(btmtksdio_chcr_query, bdev, status,
status & BT_RST_DONE, 100000, 2000000);
if (err < 0) {
bt_dev_err(hdev, "Failed to reset (%d)", err);
goto err;
}
clear_bit(BTMTKSDIO_PATCH_ENABLED, &bdev->tx_state);
err:
sdio_release_host(bdev->func);
pm_runtime_put_noidle(bdev->dev);
pm_runtime_disable(bdev->dev);
hci_reset_dev(hdev);
}
static bool btmtksdio_sdio_wakeup(struct hci_dev *hdev) static bool btmtksdio_sdio_wakeup(struct hci_dev *hdev)
{ {
struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
...@@ -1130,8 +1226,8 @@ static bool btmtksdio_sdio_wakeup(struct hci_dev *hdev) ...@@ -1130,8 +1226,8 @@ static bool btmtksdio_sdio_wakeup(struct hci_dev *hdev)
&bt_awake, HCI_CMD_TIMEOUT); &bt_awake, HCI_CMD_TIMEOUT);
if (IS_ERR(skb)) if (IS_ERR(skb))
may_wakeup = false; may_wakeup = false;
else
kfree_skb(skb); kfree_skb(skb);
} }
return may_wakeup; return may_wakeup;
...@@ -1172,6 +1268,7 @@ static int btmtksdio_probe(struct sdio_func *func, ...@@ -1172,6 +1268,7 @@ static int btmtksdio_probe(struct sdio_func *func,
hdev->open = btmtksdio_open; hdev->open = btmtksdio_open;
hdev->close = btmtksdio_close; hdev->close = btmtksdio_close;
hdev->cmd_timeout = btmtksdio_cmd_timeout;
hdev->flush = btmtksdio_flush; hdev->flush = btmtksdio_flush;
hdev->setup = btmtksdio_setup; hdev->setup = btmtksdio_setup;
hdev->shutdown = btmtksdio_shutdown; hdev->shutdown = btmtksdio_shutdown;
...@@ -1216,6 +1313,13 @@ static int btmtksdio_probe(struct sdio_func *func, ...@@ -1216,6 +1313,13 @@ static int btmtksdio_probe(struct sdio_func *func,
if (err) if (err)
bt_dev_err(hdev, "failed to initialize device wakeup"); bt_dev_err(hdev, "failed to initialize device wakeup");
bdev->dev->of_node = of_find_compatible_node(NULL, NULL,
"mediatek,mt7921s-bluetooth");
bdev->reset = devm_gpiod_get_optional(bdev->dev, "reset",
GPIOD_OUT_LOW);
if (IS_ERR(bdev->reset))
err = PTR_ERR(bdev->reset);
return err; return err;
} }
......
...@@ -36,33 +36,33 @@ static bool reset = true; ...@@ -36,33 +36,33 @@ static bool reset = true;
static struct usb_driver btusb_driver; static struct usb_driver btusb_driver;
#define BTUSB_IGNORE 0x01 #define BTUSB_IGNORE BIT(0)
#define BTUSB_DIGIANSWER 0x02 #define BTUSB_DIGIANSWER BIT(1)
#define BTUSB_CSR 0x04 #define BTUSB_CSR BIT(2)
#define BTUSB_SNIFFER 0x08 #define BTUSB_SNIFFER BIT(3)
#define BTUSB_BCM92035 0x10 #define BTUSB_BCM92035 BIT(4)
#define BTUSB_BROKEN_ISOC 0x20 #define BTUSB_BROKEN_ISOC BIT(5)
#define BTUSB_WRONG_SCO_MTU 0x40 #define BTUSB_WRONG_SCO_MTU BIT(6)
#define BTUSB_ATH3012 0x80 #define BTUSB_ATH3012 BIT(7)
#define BTUSB_INTEL_COMBINED 0x100 #define BTUSB_INTEL_COMBINED BIT(8)
#define BTUSB_INTEL_BOOT 0x200 #define BTUSB_INTEL_BOOT BIT(9)
#define BTUSB_BCM_PATCHRAM 0x400 #define BTUSB_BCM_PATCHRAM BIT(10)
#define BTUSB_MARVELL 0x800 #define BTUSB_MARVELL BIT(11)
#define BTUSB_SWAVE 0x1000 #define BTUSB_SWAVE BIT(12)
#define BTUSB_AMP 0x4000 #define BTUSB_AMP BIT(13)
#define BTUSB_QCA_ROME 0x8000 #define BTUSB_QCA_ROME BIT(14)
#define BTUSB_BCM_APPLE 0x10000 #define BTUSB_BCM_APPLE BIT(15)
#define BTUSB_REALTEK 0x20000 #define BTUSB_REALTEK BIT(16)
#define BTUSB_BCM2045 0x40000 #define BTUSB_BCM2045 BIT(17)
#define BTUSB_IFNUM_2 0x80000 #define BTUSB_IFNUM_2 BIT(18)
#define BTUSB_CW6622 0x100000 #define BTUSB_CW6622 BIT(19)
#define BTUSB_MEDIATEK 0x200000 #define BTUSB_MEDIATEK BIT(20)
#define BTUSB_WIDEBAND_SPEECH 0x400000 #define BTUSB_WIDEBAND_SPEECH BIT(21)
#define BTUSB_VALID_LE_STATES 0x800000 #define BTUSB_VALID_LE_STATES BIT(22)
#define BTUSB_QCA_WCN6855 0x1000000 #define BTUSB_QCA_WCN6855 BIT(23)
#define BTUSB_INTEL_BROKEN_SHUTDOWN_LED 0x2000000 #define BTUSB_INTEL_BROKEN_SHUTDOWN_LED BIT(24)
#define BTUSB_INTEL_BROKEN_INITIAL_NCMD 0x4000000 #define BTUSB_INTEL_BROKEN_INITIAL_NCMD BIT(25)
#define BTUSB_INTEL_NO_WBS_SUPPORT 0x8000000 #define BTUSB_INTEL_NO_WBS_SUPPORT BIT(26)
static const struct usb_device_id btusb_table[] = { static const struct usb_device_id btusb_table[] = {
/* Generic Bluetooth USB device */ /* Generic Bluetooth USB device */
...@@ -384,6 +384,7 @@ static const struct usb_device_id blacklist_table[] = { ...@@ -384,6 +384,7 @@ static const struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x8087, 0x0029), .driver_info = BTUSB_INTEL_COMBINED }, { USB_DEVICE(0x8087, 0x0029), .driver_info = BTUSB_INTEL_COMBINED },
{ USB_DEVICE(0x8087, 0x0032), .driver_info = BTUSB_INTEL_COMBINED }, { USB_DEVICE(0x8087, 0x0032), .driver_info = BTUSB_INTEL_COMBINED },
{ USB_DEVICE(0x8087, 0x0033), .driver_info = BTUSB_INTEL_COMBINED }, { USB_DEVICE(0x8087, 0x0033), .driver_info = BTUSB_INTEL_COMBINED },
{ USB_DEVICE(0x8087, 0x0035), .driver_info = BTUSB_INTEL_COMBINED },
{ USB_DEVICE(0x8087, 0x07da), .driver_info = BTUSB_CSR }, { USB_DEVICE(0x8087, 0x07da), .driver_info = BTUSB_CSR },
{ USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL_COMBINED | { USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL_COMBINED |
BTUSB_INTEL_NO_WBS_SUPPORT | BTUSB_INTEL_NO_WBS_SUPPORT |
...@@ -434,6 +435,11 @@ static const struct usb_device_id blacklist_table[] = { ...@@ -434,6 +435,11 @@ static const struct usb_device_id blacklist_table[] = {
/* Additional MediaTek MT7615E Bluetooth devices */ /* Additional MediaTek MT7615E Bluetooth devices */
{ USB_DEVICE(0x13d3, 0x3560), .driver_info = BTUSB_MEDIATEK}, { USB_DEVICE(0x13d3, 0x3560), .driver_info = BTUSB_MEDIATEK},
/* Additional MediaTek MT7663 Bluetooth devices */
{ USB_DEVICE(0x043e, 0x310c), .driver_info = BTUSB_MEDIATEK |
BTUSB_WIDEBAND_SPEECH |
BTUSB_VALID_LE_STATES },
/* Additional MediaTek MT7668 Bluetooth devices */ /* Additional MediaTek MT7668 Bluetooth devices */
{ USB_DEVICE(0x043e, 0x3109), .driver_info = BTUSB_MEDIATEK | { USB_DEVICE(0x043e, 0x3109), .driver_info = BTUSB_MEDIATEK |
BTUSB_WIDEBAND_SPEECH | BTUSB_WIDEBAND_SPEECH |
...@@ -449,6 +455,9 @@ static const struct usb_device_id blacklist_table[] = { ...@@ -449,6 +455,9 @@ static const struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x13d3, 0x3564), .driver_info = BTUSB_MEDIATEK | { USB_DEVICE(0x13d3, 0x3564), .driver_info = BTUSB_MEDIATEK |
BTUSB_WIDEBAND_SPEECH | BTUSB_WIDEBAND_SPEECH |
BTUSB_VALID_LE_STATES }, BTUSB_VALID_LE_STATES },
{ USB_DEVICE(0x13d3, 0x3567), .driver_info = BTUSB_MEDIATEK |
BTUSB_WIDEBAND_SPEECH |
BTUSB_VALID_LE_STATES },
{ USB_DEVICE(0x0489, 0xe0cd), .driver_info = BTUSB_MEDIATEK | { USB_DEVICE(0x0489, 0xe0cd), .driver_info = BTUSB_MEDIATEK |
BTUSB_WIDEBAND_SPEECH | BTUSB_WIDEBAND_SPEECH |
BTUSB_VALID_LE_STATES }, BTUSB_VALID_LE_STATES },
...@@ -487,6 +496,8 @@ static const struct usb_device_id blacklist_table[] = { ...@@ -487,6 +496,8 @@ static const struct usb_device_id blacklist_table[] = {
/* Additional Realtek 8761BU Bluetooth devices */ /* Additional Realtek 8761BU Bluetooth devices */
{ USB_DEVICE(0x0b05, 0x190e), .driver_info = BTUSB_REALTEK | { USB_DEVICE(0x0b05, 0x190e), .driver_info = BTUSB_REALTEK |
BTUSB_WIDEBAND_SPEECH }, BTUSB_WIDEBAND_SPEECH },
{ USB_DEVICE(0x2550, 0x8761), .driver_info = BTUSB_REALTEK |
BTUSB_WIDEBAND_SPEECH },
/* Additional Realtek 8821AE Bluetooth devices */ /* Additional Realtek 8821AE Bluetooth devices */
{ USB_DEVICE(0x0b05, 0x17dc), .driver_info = BTUSB_REALTEK }, { USB_DEVICE(0x0b05, 0x17dc), .driver_info = BTUSB_REALTEK },
...@@ -2250,7 +2261,6 @@ static void btusb_mtk_wmt_recv(struct urb *urb) ...@@ -2250,7 +2261,6 @@ static void btusb_mtk_wmt_recv(struct urb *urb)
{ {
struct hci_dev *hdev = urb->context; struct hci_dev *hdev = urb->context;
struct btusb_data *data = hci_get_drvdata(hdev); struct btusb_data *data = hci_get_drvdata(hdev);
struct hci_event_hdr *hdr;
struct sk_buff *skb; struct sk_buff *skb;
int err; int err;
...@@ -2270,13 +2280,6 @@ static void btusb_mtk_wmt_recv(struct urb *urb) ...@@ -2270,13 +2280,6 @@ static void btusb_mtk_wmt_recv(struct urb *urb)
hci_skb_pkt_type(skb) = HCI_EVENT_PKT; hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
skb_put_data(skb, urb->transfer_buffer, urb->actual_length); skb_put_data(skb, urb->transfer_buffer, urb->actual_length);
hdr = (void *)skb->data;
/* Fix up the vendor event id with 0xff for vendor specific
* instead of 0xe4 so that event send via monitoring socket can
* be parsed properly.
*/
hdr->evt = 0xff;
/* When someone waits for the WMT event, the skb is being cloned /* When someone waits for the WMT event, the skb is being cloned
* and being processed the events from there then. * and being processed the events from there then.
*/ */
...@@ -2993,6 +2996,7 @@ static int btusb_set_bdaddr_wcn6855(struct hci_dev *hdev, ...@@ -2993,6 +2996,7 @@ static int btusb_set_bdaddr_wcn6855(struct hci_dev *hdev,
#define QCA_PATCH_UPDATED 0x80 #define QCA_PATCH_UPDATED 0x80
#define QCA_DFU_TIMEOUT 3000 #define QCA_DFU_TIMEOUT 3000
#define QCA_FLAG_MULTI_NVM 0x80 #define QCA_FLAG_MULTI_NVM 0x80
#define QCA_BT_RESET_WAIT_MS 100
#define WCN6855_2_0_RAM_VERSION_GF 0x400c1200 #define WCN6855_2_0_RAM_VERSION_GF 0x400c1200
#define WCN6855_2_1_RAM_VERSION_GF 0x400c1211 #define WCN6855_2_1_RAM_VERSION_GF 0x400c1211
...@@ -3319,6 +3323,13 @@ static int btusb_setup_qca(struct hci_dev *hdev) ...@@ -3319,6 +3323,13 @@ static int btusb_setup_qca(struct hci_dev *hdev)
err = btusb_setup_qca_load_nvm(hdev, &ver, info); err = btusb_setup_qca_load_nvm(hdev, &ver, info);
if (err < 0) if (err < 0)
return err; return err;
/* WCN6855 2.1 will reset to apply firmware downloaded here, so
* wait ~100ms for reset Done then go ahead, otherwise, it maybe
* cause potential enable failure.
*/
if (info->rom_version == 0x00130201)
msleep(QCA_BT_RESET_WAIT_MS);
} }
return 0; return 0;
......
...@@ -1513,6 +1513,8 @@ static const struct of_device_id bcm_bluetooth_of_match[] = { ...@@ -1513,6 +1513,8 @@ static const struct of_device_id bcm_bluetooth_of_match[] = {
{ .compatible = "brcm,bcm4330-bt" }, { .compatible = "brcm,bcm4330-bt" },
{ .compatible = "brcm,bcm4334-bt" }, { .compatible = "brcm,bcm4334-bt" },
{ .compatible = "brcm,bcm4345c5" }, { .compatible = "brcm,bcm4345c5" },
{ .compatible = "brcm,bcm43430a0-bt" },
{ .compatible = "brcm,bcm43430a1-bt" },
{ .compatible = "brcm,bcm43438-bt", .data = &bcm43438_device_data }, { .compatible = "brcm,bcm43438-bt", .data = &bcm43438_device_data },
{ .compatible = "brcm,bcm43540-bt", .data = &bcm4354_device_data }, { .compatible = "brcm,bcm43540-bt", .data = &bcm4354_device_data },
{ .compatible = "brcm,bcm4335a0" }, { .compatible = "brcm,bcm4335a0" },
......
...@@ -204,19 +204,21 @@ void bt_err_ratelimited(const char *fmt, ...); ...@@ -204,19 +204,21 @@ void bt_err_ratelimited(const char *fmt, ...);
#define BT_DBG(fmt, ...) pr_debug(fmt "\n", ##__VA_ARGS__) #define BT_DBG(fmt, ...) pr_debug(fmt "\n", ##__VA_ARGS__)
#endif #endif
#define bt_dev_name(hdev) ((hdev) ? (hdev)->name : "null")
#define bt_dev_info(hdev, fmt, ...) \ #define bt_dev_info(hdev, fmt, ...) \
BT_INFO("%s: " fmt, (hdev)->name, ##__VA_ARGS__) BT_INFO("%s: " fmt, bt_dev_name(hdev), ##__VA_ARGS__)
#define bt_dev_warn(hdev, fmt, ...) \ #define bt_dev_warn(hdev, fmt, ...) \
BT_WARN("%s: " fmt, (hdev)->name, ##__VA_ARGS__) BT_WARN("%s: " fmt, bt_dev_name(hdev), ##__VA_ARGS__)
#define bt_dev_err(hdev, fmt, ...) \ #define bt_dev_err(hdev, fmt, ...) \
BT_ERR("%s: " fmt, (hdev)->name, ##__VA_ARGS__) BT_ERR("%s: " fmt, bt_dev_name(hdev), ##__VA_ARGS__)
#define bt_dev_dbg(hdev, fmt, ...) \ #define bt_dev_dbg(hdev, fmt, ...) \
BT_DBG("%s: " fmt, (hdev)->name, ##__VA_ARGS__) BT_DBG("%s: " fmt, bt_dev_name(hdev), ##__VA_ARGS__)
#define bt_dev_warn_ratelimited(hdev, fmt, ...) \ #define bt_dev_warn_ratelimited(hdev, fmt, ...) \
bt_warn_ratelimited("%s: " fmt, (hdev)->name, ##__VA_ARGS__) bt_warn_ratelimited("%s: " fmt, bt_dev_name(hdev), ##__VA_ARGS__)
#define bt_dev_err_ratelimited(hdev, fmt, ...) \ #define bt_dev_err_ratelimited(hdev, fmt, ...) \
bt_err_ratelimited("%s: " fmt, (hdev)->name, ##__VA_ARGS__) bt_err_ratelimited("%s: " fmt, bt_dev_name(hdev), ##__VA_ARGS__)
/* Connection and socket states */ /* Connection and socket states */
enum { enum {
......
...@@ -1112,7 +1112,7 @@ struct mgmt_ev_adv_monitor_device_found { ...@@ -1112,7 +1112,7 @@ struct mgmt_ev_adv_monitor_device_found {
__s8 rssi; __s8 rssi;
__le32 flags; __le32 flags;
__le16 eir_len; __le16 eir_len;
__u8 eir[0]; __u8 eir[];
} __packed; } __packed;
#define MGMT_EV_ADV_MONITOR_DEVICE_LOST 0x0030 #define MGMT_EV_ADV_MONITOR_DEVICE_LOST 0x0030
......
...@@ -641,7 +641,6 @@ static struct l2cap_chan *add_peer_chan(struct l2cap_chan *chan, ...@@ -641,7 +641,6 @@ static struct l2cap_chan *add_peer_chan(struct l2cap_chan *chan,
return NULL; return NULL;
peer->chan = chan; peer->chan = chan;
memset(&peer->peer_addr, 0, sizeof(struct in6_addr));
baswap((void *)peer->lladdr, &chan->dst); baswap((void *)peer->lladdr, &chan->dst);
......
...@@ -15,6 +15,11 @@ u8 eir_create_scan_rsp(struct hci_dev *hdev, u8 instance, u8 *ptr); ...@@ -15,6 +15,11 @@ u8 eir_create_scan_rsp(struct hci_dev *hdev, u8 instance, u8 *ptr);
u8 eir_append_local_name(struct hci_dev *hdev, u8 *eir, u8 ad_len); u8 eir_append_local_name(struct hci_dev *hdev, u8 *eir, u8 ad_len);
u8 eir_append_appearance(struct hci_dev *hdev, u8 *ptr, u8 ad_len); u8 eir_append_appearance(struct hci_dev *hdev, u8 *ptr, u8 ad_len);
static inline u16 eir_precalc_len(u8 data_len)
{
return sizeof(u8) * 2 + data_len;
}
static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type,
u8 *data, u8 data_len) u8 *data, u8 data_len)
{ {
...@@ -36,6 +41,21 @@ static inline u16 eir_append_le16(u8 *eir, u16 eir_len, u8 type, u16 data) ...@@ -36,6 +41,21 @@ static inline u16 eir_append_le16(u8 *eir, u16 eir_len, u8 type, u16 data)
return eir_len; return eir_len;
} }
static inline u16 eir_skb_put_data(struct sk_buff *skb, u8 type, u8 *data, u8 data_len)
{
u8 *eir;
u16 eir_len;
eir_len = eir_precalc_len(data_len);
eir = skb_put(skb, eir_len);
WARN_ON(sizeof(type) + data_len > U8_MAX);
eir[0] = sizeof(type) + data_len;
eir[1] = type;
memcpy(&eir[2], data, data_len);
return eir_len;
}
static inline void *eir_get_data(u8 *eir, size_t eir_len, u8 type, static inline void *eir_get_data(u8 *eir, size_t eir_len, u8 type,
size_t *data_len) size_t *data_len)
{ {
......
...@@ -5716,8 +5716,6 @@ static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, void *data, ...@@ -5716,8 +5716,6 @@ static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, void *data,
bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
adv = hci_find_adv_instance(hdev, ev->handle);
/* The Bluetooth Core 5.3 specification clearly states that this event /* The Bluetooth Core 5.3 specification clearly states that this event
* shall not be sent when the Host disables the advertising set. So in * shall not be sent when the Host disables the advertising set. So in
* case of HCI_ERROR_CANCELLED_BY_HOST, just ignore the event. * case of HCI_ERROR_CANCELLED_BY_HOST, just ignore the event.
...@@ -5730,9 +5728,13 @@ static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, void *data, ...@@ -5730,9 +5728,13 @@ static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, void *data,
return; return;
} }
hci_dev_lock(hdev);
adv = hci_find_adv_instance(hdev, ev->handle);
if (ev->status) { if (ev->status) {
if (!adv) if (!adv)
return; goto unlock;
/* Remove advertising as it has been terminated */ /* Remove advertising as it has been terminated */
hci_remove_adv_instance(hdev, ev->handle); hci_remove_adv_instance(hdev, ev->handle);
...@@ -5740,12 +5742,12 @@ static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, void *data, ...@@ -5740,12 +5742,12 @@ static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, void *data,
list_for_each_entry_safe(adv, n, &hdev->adv_instances, list) { list_for_each_entry_safe(adv, n, &hdev->adv_instances, list) {
if (adv->enabled) if (adv->enabled)
return; goto unlock;
} }
/* We are no longer advertising, clear HCI_LE_ADV */ /* We are no longer advertising, clear HCI_LE_ADV */
hci_dev_clear_flag(hdev, HCI_LE_ADV); hci_dev_clear_flag(hdev, HCI_LE_ADV);
return; goto unlock;
} }
if (adv) if (adv)
...@@ -5760,16 +5762,19 @@ static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, void *data, ...@@ -5760,16 +5762,19 @@ static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, void *data,
if (hdev->adv_addr_type != ADDR_LE_DEV_RANDOM || if (hdev->adv_addr_type != ADDR_LE_DEV_RANDOM ||
bacmp(&conn->resp_addr, BDADDR_ANY)) bacmp(&conn->resp_addr, BDADDR_ANY))
return; goto unlock;
if (!ev->handle) { if (!ev->handle) {
bacpy(&conn->resp_addr, &hdev->random_addr); bacpy(&conn->resp_addr, &hdev->random_addr);
return; goto unlock;
} }
if (adv) if (adv)
bacpy(&conn->resp_addr, &adv->random_addr); bacpy(&conn->resp_addr, &adv->random_addr);
} }
unlock:
hci_dev_unlock(hdev);
} }
static void hci_le_conn_update_complete_evt(struct hci_dev *hdev, void *data, static void hci_le_conn_update_complete_evt(struct hci_dev *hdev, void *data,
......
...@@ -4428,7 +4428,7 @@ static int hci_disconnect_all_sync(struct hci_dev *hdev, u8 reason) ...@@ -4428,7 +4428,7 @@ static int hci_disconnect_all_sync(struct hci_dev *hdev, u8 reason)
return err; return err;
} }
return err; return 0;
} }
/* This function perform power off HCI command sequence as follows: /* This function perform power off HCI command sequence as follows:
......
...@@ -1436,6 +1436,7 @@ static void l2cap_ecred_connect(struct l2cap_chan *chan) ...@@ -1436,6 +1436,7 @@ static void l2cap_ecred_connect(struct l2cap_chan *chan)
l2cap_ecred_init(chan, 0); l2cap_ecred_init(chan, 0);
memset(&data, 0, sizeof(data));
data.pdu.req.psm = chan->psm; data.pdu.req.psm = chan->psm;
data.pdu.req.mtu = cpu_to_le16(chan->imtu); data.pdu.req.mtu = cpu_to_le16(chan->imtu);
data.pdu.req.mps = cpu_to_le16(chan->mps); data.pdu.req.mps = cpu_to_le16(chan->mps);
......
...@@ -2298,7 +2298,9 @@ static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data, ...@@ -2298,7 +2298,9 @@ static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data,
struct mgmt_cp_remove_uuid *cp = data; struct mgmt_cp_remove_uuid *cp = data;
struct mgmt_pending_cmd *cmd; struct mgmt_pending_cmd *cmd;
struct bt_uuid *match, *tmp; struct bt_uuid *match, *tmp;
u8 bt_uuid_any[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; static const u8 bt_uuid_any[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
int err, found; int err, found;
bt_dev_dbg(hdev, "sock %p", sk); bt_dev_dbg(hdev, "sock %p", sk);
...@@ -8077,7 +8079,7 @@ static int add_advertising(struct sock *sk, struct hci_dev *hdev, ...@@ -8077,7 +8079,7 @@ static int add_advertising(struct sock *sk, struct hci_dev *hdev,
u32 flags; u32 flags;
u8 status; u8 status;
u16 timeout, duration; u16 timeout, duration;
unsigned int prev_instance_cnt = hdev->adv_instance_cnt; unsigned int prev_instance_cnt;
u8 schedule_instance = 0; u8 schedule_instance = 0;
struct adv_info *next_instance; struct adv_info *next_instance;
int err; int err;
...@@ -8128,6 +8130,8 @@ static int add_advertising(struct sock *sk, struct hci_dev *hdev, ...@@ -8128,6 +8130,8 @@ static int add_advertising(struct sock *sk, struct hci_dev *hdev,
goto unlock; goto unlock;
} }
prev_instance_cnt = hdev->adv_instance_cnt;
err = hci_add_adv_instance(hdev, cp->instance, flags, err = hci_add_adv_instance(hdev, cp->instance, flags,
cp->adv_data_len, cp->data, cp->adv_data_len, cp->data,
cp->scan_rsp_len, cp->scan_rsp_len,
...@@ -8630,7 +8634,6 @@ static int get_adv_size_info(struct sock *sk, struct hci_dev *hdev, ...@@ -8630,7 +8634,6 @@ static int get_adv_size_info(struct sock *sk, struct hci_dev *hdev,
struct mgmt_cp_get_adv_size_info *cp = data; struct mgmt_cp_get_adv_size_info *cp = data;
struct mgmt_rp_get_adv_size_info rp; struct mgmt_rp_get_adv_size_info rp;
u32 flags, supported_flags; u32 flags, supported_flags;
int err;
bt_dev_dbg(hdev, "sock %p", sk); bt_dev_dbg(hdev, "sock %p", sk);
...@@ -8657,10 +8660,8 @@ static int get_adv_size_info(struct sock *sk, struct hci_dev *hdev, ...@@ -8657,10 +8660,8 @@ static int get_adv_size_info(struct sock *sk, struct hci_dev *hdev,
rp.max_adv_data_len = tlv_data_max_len(hdev, flags, true); rp.max_adv_data_len = tlv_data_max_len(hdev, flags, true);
rp.max_scan_rsp_len = tlv_data_max_len(hdev, flags, false); rp.max_scan_rsp_len = tlv_data_max_len(hdev, flags, false);
err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_ADV_SIZE_INFO, return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_ADV_SIZE_INFO,
MGMT_STATUS_SUCCESS, &rp, sizeof(rp)); MGMT_STATUS_SUCCESS, &rp, sizeof(rp));
return err;
} }
static const struct hci_mgmt_handler mgmt_handlers[] = { static const struct hci_mgmt_handler mgmt_handlers[] = {
...@@ -9088,12 +9089,14 @@ void mgmt_device_connected(struct hci_dev *hdev, struct hci_conn *conn, ...@@ -9088,12 +9089,14 @@ void mgmt_device_connected(struct hci_dev *hdev, struct hci_conn *conn,
u16 eir_len = 0; u16 eir_len = 0;
u32 flags = 0; u32 flags = 0;
/* allocate buff for LE or BR/EDR adv */
if (conn->le_adv_data_len > 0) if (conn->le_adv_data_len > 0)
skb = mgmt_alloc_skb(hdev, MGMT_EV_DEVICE_CONNECTED, skb = mgmt_alloc_skb(hdev, MGMT_EV_DEVICE_CONNECTED,
conn->le_adv_data_len); sizeof(*ev) + conn->le_adv_data_len);
else else
skb = mgmt_alloc_skb(hdev, MGMT_EV_DEVICE_CONNECTED, skb = mgmt_alloc_skb(hdev, MGMT_EV_DEVICE_CONNECTED,
2 + name_len + 5); sizeof(*ev) + (name ? eir_precalc_len(name_len) : 0) +
eir_precalc_len(sizeof(conn->dev_class)));
ev = skb_put(skb, sizeof(*ev)); ev = skb_put(skb, sizeof(*ev));
bacpy(&ev->addr.bdaddr, &conn->dst); bacpy(&ev->addr.bdaddr, &conn->dst);
...@@ -9112,18 +9115,12 @@ void mgmt_device_connected(struct hci_dev *hdev, struct hci_conn *conn, ...@@ -9112,18 +9115,12 @@ void mgmt_device_connected(struct hci_dev *hdev, struct hci_conn *conn,
skb_put_data(skb, conn->le_adv_data, conn->le_adv_data_len); skb_put_data(skb, conn->le_adv_data, conn->le_adv_data_len);
eir_len = conn->le_adv_data_len; eir_len = conn->le_adv_data_len;
} else { } else {
if (name_len > 0) { if (name)
eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE, eir_len += eir_skb_put_data(skb, EIR_NAME_COMPLETE, name, name_len);
name, name_len);
skb_put(skb, eir_len);
}
if (memcmp(conn->dev_class, "\0\0\0", 3) != 0) { if (memcmp(conn->dev_class, "\0\0\0", sizeof(conn->dev_class)))
eir_len = eir_append_data(ev->eir, eir_len, eir_len += eir_skb_put_data(skb, EIR_CLASS_OF_DEV,
EIR_CLASS_OF_DEV, conn->dev_class, sizeof(conn->dev_class));
conn->dev_class, 3);
skb_put(skb, 5);
}
} }
ev->eir_len = cpu_to_le16(eir_len); ev->eir_len = cpu_to_le16(eir_len);
...@@ -9812,28 +9809,21 @@ void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, ...@@ -9812,28 +9809,21 @@ void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
{ {
struct sk_buff *skb; struct sk_buff *skb;
struct mgmt_ev_device_found *ev; struct mgmt_ev_device_found *ev;
u16 eir_len; u16 eir_len = 0;
u32 flags; u32 flags = 0;
if (name_len) skb = mgmt_alloc_skb(hdev, MGMT_EV_DEVICE_FOUND,
skb = mgmt_alloc_skb(hdev, MGMT_EV_DEVICE_FOUND, 2 + name_len); sizeof(*ev) + (name ? eir_precalc_len(name_len) : 0));
else
skb = mgmt_alloc_skb(hdev, MGMT_EV_DEVICE_FOUND, 0);
ev = skb_put(skb, sizeof(*ev)); ev = skb_put(skb, sizeof(*ev));
bacpy(&ev->addr.bdaddr, bdaddr); bacpy(&ev->addr.bdaddr, bdaddr);
ev->addr.type = link_to_bdaddr(link_type, addr_type); ev->addr.type = link_to_bdaddr(link_type, addr_type);
ev->rssi = rssi; ev->rssi = rssi;
if (name) { if (name)
eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE, name, eir_len += eir_skb_put_data(skb, EIR_NAME_COMPLETE, name, name_len);
name_len); else
flags = 0;
skb_put(skb, eir_len);
} else {
eir_len = 0;
flags = MGMT_DEV_FOUND_NAME_REQUEST_FAILED; flags = MGMT_DEV_FOUND_NAME_REQUEST_FAILED;
}
ev->eir_len = cpu_to_le16(eir_len); ev->eir_len = cpu_to_le16(eir_len);
ev->flags = cpu_to_le32(flags); ev->flags = cpu_to_le32(flags);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment