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) -----BEGIN PGP SIGNATURE----- iQJNBAABCAA3FiEE7E6oRXp8w05ovYr/9JCA4xAyCykFAmIiaaUZHGx1aXoudm9u LmRlbnR6QGludGVsLmNvbQAKCRD0kIDjEDILKUXQD/9ZbabqpDtsIDPVEqJH1GHb Z1i0ID6FAUq9VnRHcs5PgrPlD3JaQhI3wMnF1FILu3NWqEyQnAf39LVlL8R0PvaQ pYtkf+BZI4TKjqa+e4Mw+8NbBLHV2EV8O2tVUQ2gb3OwYvq+2ped4oDC1CkXJ/pA 6LfAuH7z4FNNiWlHeg6wCwYnTFicZmHfwUFab+laThMJ8Pj1mWHNxAmsWRhA+tM/ 35WcHlocIPlXDNrY+tVOQNzme/pE91/yMUbI4ZWXIFf0vfMfjA7cbTS5mL9Tjgc8 1/HwiyOuCtPajp/uYAHMEveRK/W3O1FQGurVq3O7FfjfmzllIjm4aK3iLf3fwURe ZSeeMSLr/FF28stnD2v1CtFET4GWhZMO1zn0jUI7I0GA+YHa7NY0dkczUFavng4o P3UtkKtDhMgXLNU1vflBdtjjRYeiNw7G0PFsRJak/9x37MQIvUnR3pdN89fbS5Pl D7R6i1oCSzoGXz245zObHPUMDEJ6vmksH4vEq4+TZX+Ngml6UNEib10KrpoxT/h3 A3KyX40ORfslkAAT8YHZwEUM6pS7gqIQUBdRzHVCKBo89A9HGBs91ZK1rshyDDsO xfcp0gjr0hpoFhP0JNR7tj/jiGg+Lh8OjFCUGurNnWVLgi0hv3WRC8bBckIIWUVs WpIuoOUAuz7Qlo0aiZ8ogQ== =2uvT -----END PGP SIGNATURE----- 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.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Коммит
2bc0a832fa
|
@ -5,14 +5,21 @@
|
|||
#define FIRMWARE_MT7668 "mediatek/mt7668pr2h.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 BTMTK_WMT_REG_WRITE 0x1
|
||||
#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_1 0x70005054
|
||||
|
||||
#define MT7921_DLSTATUS 0x7c053c10
|
||||
#define BT_DL_STATE BIT(1)
|
||||
|
||||
enum {
|
||||
BTMTK_WMT_PATCH_DWNLD = 0x1,
|
||||
BTMTK_WMT_TEST = 0x2,
|
||||
|
|
|
@ -12,10 +12,12 @@
|
|||
|
||||
#include <asm/unaligned.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
|
@ -83,6 +85,7 @@ MODULE_DEVICE_TABLE(sdio, btmtksdio_table);
|
|||
|
||||
#define MTK_REG_CHCR 0xc
|
||||
#define C_INT_CLR_CTRL BIT(1)
|
||||
#define BT_RST_DONE BIT(8)
|
||||
|
||||
/* CHISR have the same bits field definition with CHIER */
|
||||
#define MTK_REG_CHISR 0x10
|
||||
|
@ -114,6 +117,7 @@ MODULE_DEVICE_TABLE(sdio, btmtksdio_table);
|
|||
#define BTMTKSDIO_HW_TX_READY 2
|
||||
#define BTMTKSDIO_FUNC_ENABLED 3
|
||||
#define BTMTKSDIO_PATCH_ENABLED 4
|
||||
#define BTMTKSDIO_HW_RESET_ACTIVE 5
|
||||
|
||||
struct mtkbtsdio_hdr {
|
||||
__le16 len;
|
||||
|
@ -133,6 +137,8 @@ struct btmtksdio_dev {
|
|||
struct sk_buff *evt_skb;
|
||||
|
||||
const struct btmtksdio_data *data;
|
||||
|
||||
struct gpio_desc *reset;
|
||||
};
|
||||
|
||||
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)
|
|||
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)
|
||||
{
|
||||
u32 status;
|
||||
|
@ -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;
|
||||
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
|
||||
* 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)
|
|||
if (err < 0)
|
||||
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,
|
||||
&bdev->tx_state)) {
|
||||
/* Barrier to sync with other CPUs */
|
||||
|
@ -967,6 +971,28 @@ static int btmtksdio_sco_setting(struct hci_dev *hdev)
|
|||
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)
|
||||
{
|
||||
struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
|
||||
|
@ -974,13 +1000,32 @@ static int btmtksdio_setup(struct hci_dev *hdev)
|
|||
unsigned long long duration;
|
||||
char fwname[64];
|
||||
int err, dev_id;
|
||||
u32 fw_version = 0;
|
||||
u32 fw_version = 0, val;
|
||||
|
||||
calltime = ktime_get();
|
||||
set_bit(BTMTKSDIO_HW_TX_READY, &bdev->tx_state);
|
||||
|
||||
switch (bdev->data->chipid) {
|
||||
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);
|
||||
if (err < 0) {
|
||||
bt_dev_err(hdev, "Failed to get device id (%d)", err);
|
||||
|
@ -1015,6 +1060,16 @@ static int btmtksdio_setup(struct hci_dev *hdev)
|
|||
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;
|
||||
case 0x7663:
|
||||
case 0x7668:
|
||||
|
@ -1111,6 +1166,47 @@ static int btmtksdio_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
|
|||
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)
|
||||
{
|
||||
struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
|
||||
|
@ -1130,8 +1226,8 @@ static bool btmtksdio_sdio_wakeup(struct hci_dev *hdev)
|
|||
&bt_awake, HCI_CMD_TIMEOUT);
|
||||
if (IS_ERR(skb))
|
||||
may_wakeup = false;
|
||||
|
||||
kfree_skb(skb);
|
||||
else
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
return may_wakeup;
|
||||
|
@ -1172,6 +1268,7 @@ static int btmtksdio_probe(struct sdio_func *func,
|
|||
|
||||
hdev->open = btmtksdio_open;
|
||||
hdev->close = btmtksdio_close;
|
||||
hdev->cmd_timeout = btmtksdio_cmd_timeout;
|
||||
hdev->flush = btmtksdio_flush;
|
||||
hdev->setup = btmtksdio_setup;
|
||||
hdev->shutdown = btmtksdio_shutdown;
|
||||
|
@ -1216,6 +1313,13 @@ static int btmtksdio_probe(struct sdio_func *func,
|
|||
if (err)
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,33 +36,33 @@ static bool reset = true;
|
|||
|
||||
static struct usb_driver btusb_driver;
|
||||
|
||||
#define BTUSB_IGNORE 0x01
|
||||
#define BTUSB_DIGIANSWER 0x02
|
||||
#define BTUSB_CSR 0x04
|
||||
#define BTUSB_SNIFFER 0x08
|
||||
#define BTUSB_BCM92035 0x10
|
||||
#define BTUSB_BROKEN_ISOC 0x20
|
||||
#define BTUSB_WRONG_SCO_MTU 0x40
|
||||
#define BTUSB_ATH3012 0x80
|
||||
#define BTUSB_INTEL_COMBINED 0x100
|
||||
#define BTUSB_INTEL_BOOT 0x200
|
||||
#define BTUSB_BCM_PATCHRAM 0x400
|
||||
#define BTUSB_MARVELL 0x800
|
||||
#define BTUSB_SWAVE 0x1000
|
||||
#define BTUSB_AMP 0x4000
|
||||
#define BTUSB_QCA_ROME 0x8000
|
||||
#define BTUSB_BCM_APPLE 0x10000
|
||||
#define BTUSB_REALTEK 0x20000
|
||||
#define BTUSB_BCM2045 0x40000
|
||||
#define BTUSB_IFNUM_2 0x80000
|
||||
#define BTUSB_CW6622 0x100000
|
||||
#define BTUSB_MEDIATEK 0x200000
|
||||
#define BTUSB_WIDEBAND_SPEECH 0x400000
|
||||
#define BTUSB_VALID_LE_STATES 0x800000
|
||||
#define BTUSB_QCA_WCN6855 0x1000000
|
||||
#define BTUSB_INTEL_BROKEN_SHUTDOWN_LED 0x2000000
|
||||
#define BTUSB_INTEL_BROKEN_INITIAL_NCMD 0x4000000
|
||||
#define BTUSB_INTEL_NO_WBS_SUPPORT 0x8000000
|
||||
#define BTUSB_IGNORE BIT(0)
|
||||
#define BTUSB_DIGIANSWER BIT(1)
|
||||
#define BTUSB_CSR BIT(2)
|
||||
#define BTUSB_SNIFFER BIT(3)
|
||||
#define BTUSB_BCM92035 BIT(4)
|
||||
#define BTUSB_BROKEN_ISOC BIT(5)
|
||||
#define BTUSB_WRONG_SCO_MTU BIT(6)
|
||||
#define BTUSB_ATH3012 BIT(7)
|
||||
#define BTUSB_INTEL_COMBINED BIT(8)
|
||||
#define BTUSB_INTEL_BOOT BIT(9)
|
||||
#define BTUSB_BCM_PATCHRAM BIT(10)
|
||||
#define BTUSB_MARVELL BIT(11)
|
||||
#define BTUSB_SWAVE BIT(12)
|
||||
#define BTUSB_AMP BIT(13)
|
||||
#define BTUSB_QCA_ROME BIT(14)
|
||||
#define BTUSB_BCM_APPLE BIT(15)
|
||||
#define BTUSB_REALTEK BIT(16)
|
||||
#define BTUSB_BCM2045 BIT(17)
|
||||
#define BTUSB_IFNUM_2 BIT(18)
|
||||
#define BTUSB_CW6622 BIT(19)
|
||||
#define BTUSB_MEDIATEK BIT(20)
|
||||
#define BTUSB_WIDEBAND_SPEECH BIT(21)
|
||||
#define BTUSB_VALID_LE_STATES BIT(22)
|
||||
#define BTUSB_QCA_WCN6855 BIT(23)
|
||||
#define BTUSB_INTEL_BROKEN_SHUTDOWN_LED BIT(24)
|
||||
#define BTUSB_INTEL_BROKEN_INITIAL_NCMD BIT(25)
|
||||
#define BTUSB_INTEL_NO_WBS_SUPPORT BIT(26)
|
||||
|
||||
static const struct usb_device_id btusb_table[] = {
|
||||
/* Generic Bluetooth USB device */
|
||||
|
@ -384,6 +384,7 @@ static const struct usb_device_id blacklist_table[] = {
|
|||
{ USB_DEVICE(0x8087, 0x0029), .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, 0x0035), .driver_info = BTUSB_INTEL_COMBINED },
|
||||
{ USB_DEVICE(0x8087, 0x07da), .driver_info = BTUSB_CSR },
|
||||
{ USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL_COMBINED |
|
||||
BTUSB_INTEL_NO_WBS_SUPPORT |
|
||||
|
@ -434,6 +435,11 @@ static const struct usb_device_id blacklist_table[] = {
|
|||
/* Additional MediaTek MT7615E Bluetooth devices */
|
||||
{ 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 */
|
||||
{ USB_DEVICE(0x043e, 0x3109), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
|
@ -449,6 +455,9 @@ static const struct usb_device_id blacklist_table[] = {
|
|||
{ USB_DEVICE(0x13d3, 0x3564), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
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 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
|
@ -487,6 +496,8 @@ static const struct usb_device_id blacklist_table[] = {
|
|||
/* Additional Realtek 8761BU Bluetooth devices */
|
||||
{ USB_DEVICE(0x0b05, 0x190e), .driver_info = BTUSB_REALTEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x2550, 0x8761), .driver_info = BTUSB_REALTEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
|
||||
/* Additional Realtek 8821AE Bluetooth devices */
|
||||
{ USB_DEVICE(0x0b05, 0x17dc), .driver_info = BTUSB_REALTEK },
|
||||
|
@ -2250,7 +2261,6 @@ static void btusb_mtk_wmt_recv(struct urb *urb)
|
|||
{
|
||||
struct hci_dev *hdev = urb->context;
|
||||
struct btusb_data *data = hci_get_drvdata(hdev);
|
||||
struct hci_event_hdr *hdr;
|
||||
struct sk_buff *skb;
|
||||
int err;
|
||||
|
||||
|
@ -2270,13 +2280,6 @@ static void btusb_mtk_wmt_recv(struct urb *urb)
|
|||
hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
|
||||
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
|
||||
* and being processed the events from there then.
|
||||
*/
|
||||
|
@ -2993,6 +2996,7 @@ static int btusb_set_bdaddr_wcn6855(struct hci_dev *hdev,
|
|||
#define QCA_PATCH_UPDATED 0x80
|
||||
#define QCA_DFU_TIMEOUT 3000
|
||||
#define QCA_FLAG_MULTI_NVM 0x80
|
||||
#define QCA_BT_RESET_WAIT_MS 100
|
||||
|
||||
#define WCN6855_2_0_RAM_VERSION_GF 0x400c1200
|
||||
#define WCN6855_2_1_RAM_VERSION_GF 0x400c1211
|
||||
|
@ -3319,6 +3323,13 @@ static int btusb_setup_qca(struct hci_dev *hdev)
|
|||
err = btusb_setup_qca_load_nvm(hdev, &ver, info);
|
||||
if (err < 0)
|
||||
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;
|
||||
|
|
|
@ -1513,6 +1513,8 @@ static const struct of_device_id bcm_bluetooth_of_match[] = {
|
|||
{ .compatible = "brcm,bcm4330-bt" },
|
||||
{ .compatible = "brcm,bcm4334-bt" },
|
||||
{ .compatible = "brcm,bcm4345c5" },
|
||||
{ .compatible = "brcm,bcm43430a0-bt" },
|
||||
{ .compatible = "brcm,bcm43430a1-bt" },
|
||||
{ .compatible = "brcm,bcm43438-bt", .data = &bcm43438_device_data },
|
||||
{ .compatible = "brcm,bcm43540-bt", .data = &bcm4354_device_data },
|
||||
{ .compatible = "brcm,bcm4335a0" },
|
||||
|
|
|
@ -204,19 +204,21 @@ void bt_err_ratelimited(const char *fmt, ...);
|
|||
#define BT_DBG(fmt, ...) pr_debug(fmt "\n", ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#define bt_dev_name(hdev) ((hdev) ? (hdev)->name : "null")
|
||||
|
||||
#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, ...) \
|
||||
BT_WARN("%s: " fmt, (hdev)->name, ##__VA_ARGS__)
|
||||
BT_WARN("%s: " fmt, bt_dev_name(hdev), ##__VA_ARGS__)
|
||||
#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, ...) \
|
||||
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, ...) \
|
||||
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, ...) \
|
||||
bt_err_ratelimited("%s: " fmt, (hdev)->name, ##__VA_ARGS__)
|
||||
bt_err_ratelimited("%s: " fmt, bt_dev_name(hdev), ##__VA_ARGS__)
|
||||
|
||||
/* Connection and socket states */
|
||||
enum {
|
||||
|
|
|
@ -1112,7 +1112,7 @@ struct mgmt_ev_adv_monitor_device_found {
|
|||
__s8 rssi;
|
||||
__le32 flags;
|
||||
__le16 eir_len;
|
||||
__u8 eir[0];
|
||||
__u8 eir[];
|
||||
} __packed;
|
||||
|
||||
#define MGMT_EV_ADV_MONITOR_DEVICE_LOST 0x0030
|
||||
|
|
|
@ -641,7 +641,6 @@ static struct l2cap_chan *add_peer_chan(struct l2cap_chan *chan,
|
|||
return NULL;
|
||||
|
||||
peer->chan = chan;
|
||||
memset(&peer->peer_addr, 0, sizeof(struct in6_addr));
|
||||
|
||||
baswap((void *)peer->lladdr, &chan->dst);
|
||||
|
||||
|
|
|
@ -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_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,
|
||||
u8 *data, u8 data_len)
|
||||
{
|
||||
|
@ -36,6 +41,21 @@ static inline u16 eir_append_le16(u8 *eir, u16 eir_len, u8 type, u16 data)
|
|||
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,
|
||||
size_t *data_len)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
||||
adv = hci_find_adv_instance(hdev, ev->handle);
|
||||
|
||||
/* The Bluetooth Core 5.3 specification clearly states that this event
|
||||
* shall not be sent when the Host disables the advertising set. So in
|
||||
* 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,
|
|||
return;
|
||||
}
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
adv = hci_find_adv_instance(hdev, ev->handle);
|
||||
|
||||
if (ev->status) {
|
||||
if (!adv)
|
||||
return;
|
||||
goto unlock;
|
||||
|
||||
/* Remove advertising as it has been terminated */
|
||||
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,
|
|||
|
||||
list_for_each_entry_safe(adv, n, &hdev->adv_instances, list) {
|
||||
if (adv->enabled)
|
||||
return;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
/* We are no longer advertising, clear HCI_LE_ADV */
|
||||
hci_dev_clear_flag(hdev, HCI_LE_ADV);
|
||||
return;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (adv)
|
||||
|
@ -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 ||
|
||||
bacmp(&conn->resp_addr, BDADDR_ANY))
|
||||
return;
|
||||
goto unlock;
|
||||
|
||||
if (!ev->handle) {
|
||||
bacpy(&conn->resp_addr, &hdev->random_addr);
|
||||
return;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (adv)
|
||||
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,
|
||||
|
|
|
@ -4428,7 +4428,7 @@ static int hci_disconnect_all_sync(struct hci_dev *hdev, u8 reason)
|
|||
return err;
|
||||
}
|
||||
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This function perform power off HCI command sequence as follows:
|
||||
|
|
|
@ -1436,6 +1436,7 @@ static void l2cap_ecred_connect(struct l2cap_chan *chan)
|
|||
|
||||
l2cap_ecred_init(chan, 0);
|
||||
|
||||
memset(&data, 0, sizeof(data));
|
||||
data.pdu.req.psm = chan->psm;
|
||||
data.pdu.req.mtu = cpu_to_le16(chan->imtu);
|
||||
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,
|
|||
struct mgmt_cp_remove_uuid *cp = data;
|
||||
struct mgmt_pending_cmd *cmd;
|
||||
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;
|
||||
|
||||
bt_dev_dbg(hdev, "sock %p", sk);
|
||||
|
@ -8077,7 +8079,7 @@ static int add_advertising(struct sock *sk, struct hci_dev *hdev,
|
|||
u32 flags;
|
||||
u8 status;
|
||||
u16 timeout, duration;
|
||||
unsigned int prev_instance_cnt = hdev->adv_instance_cnt;
|
||||
unsigned int prev_instance_cnt;
|
||||
u8 schedule_instance = 0;
|
||||
struct adv_info *next_instance;
|
||||
int err;
|
||||
|
@ -8128,6 +8130,8 @@ static int add_advertising(struct sock *sk, struct hci_dev *hdev,
|
|||
goto unlock;
|
||||
}
|
||||
|
||||
prev_instance_cnt = hdev->adv_instance_cnt;
|
||||
|
||||
err = hci_add_adv_instance(hdev, cp->instance, flags,
|
||||
cp->adv_data_len, cp->data,
|
||||
cp->scan_rsp_len,
|
||||
|
@ -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_rp_get_adv_size_info rp;
|
||||
u32 flags, supported_flags;
|
||||
int err;
|
||||
|
||||
bt_dev_dbg(hdev, "sock %p", sk);
|
||||
|
||||
|
@ -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_scan_rsp_len = tlv_data_max_len(hdev, flags, false);
|
||||
|
||||
err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_ADV_SIZE_INFO,
|
||||
MGMT_STATUS_SUCCESS, &rp, sizeof(rp));
|
||||
|
||||
return err;
|
||||
return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_ADV_SIZE_INFO,
|
||||
MGMT_STATUS_SUCCESS, &rp, sizeof(rp));
|
||||
}
|
||||
|
||||
static const struct hci_mgmt_handler mgmt_handlers[] = {
|
||||
|
@ -9088,12 +9089,14 @@ void mgmt_device_connected(struct hci_dev *hdev, struct hci_conn *conn,
|
|||
u16 eir_len = 0;
|
||||
u32 flags = 0;
|
||||
|
||||
/* allocate buff for LE or BR/EDR adv */
|
||||
if (conn->le_adv_data_len > 0)
|
||||
skb = mgmt_alloc_skb(hdev, MGMT_EV_DEVICE_CONNECTED,
|
||||
conn->le_adv_data_len);
|
||||
sizeof(*ev) + conn->le_adv_data_len);
|
||||
else
|
||||
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));
|
||||
bacpy(&ev->addr.bdaddr, &conn->dst);
|
||||
|
@ -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);
|
||||
eir_len = conn->le_adv_data_len;
|
||||
} else {
|
||||
if (name_len > 0) {
|
||||
eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE,
|
||||
name, name_len);
|
||||
skb_put(skb, eir_len);
|
||||
}
|
||||
if (name)
|
||||
eir_len += eir_skb_put_data(skb, EIR_NAME_COMPLETE, name, name_len);
|
||||
|
||||
if (memcmp(conn->dev_class, "\0\0\0", 3) != 0) {
|
||||
eir_len = eir_append_data(ev->eir, eir_len,
|
||||
EIR_CLASS_OF_DEV,
|
||||
conn->dev_class, 3);
|
||||
skb_put(skb, 5);
|
||||
}
|
||||
if (memcmp(conn->dev_class, "\0\0\0", sizeof(conn->dev_class)))
|
||||
eir_len += eir_skb_put_data(skb, EIR_CLASS_OF_DEV,
|
||||
conn->dev_class, sizeof(conn->dev_class));
|
||||
}
|
||||
|
||||
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,
|
|||
{
|
||||
struct sk_buff *skb;
|
||||
struct mgmt_ev_device_found *ev;
|
||||
u16 eir_len;
|
||||
u32 flags;
|
||||
u16 eir_len = 0;
|
||||
u32 flags = 0;
|
||||
|
||||
if (name_len)
|
||||
skb = mgmt_alloc_skb(hdev, MGMT_EV_DEVICE_FOUND, 2 + name_len);
|
||||
else
|
||||
skb = mgmt_alloc_skb(hdev, MGMT_EV_DEVICE_FOUND, 0);
|
||||
skb = mgmt_alloc_skb(hdev, MGMT_EV_DEVICE_FOUND,
|
||||
sizeof(*ev) + (name ? eir_precalc_len(name_len) : 0));
|
||||
|
||||
ev = skb_put(skb, sizeof(*ev));
|
||||
bacpy(&ev->addr.bdaddr, bdaddr);
|
||||
ev->addr.type = link_to_bdaddr(link_type, addr_type);
|
||||
ev->rssi = rssi;
|
||||
|
||||
if (name) {
|
||||
eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE, name,
|
||||
name_len);
|
||||
flags = 0;
|
||||
skb_put(skb, eir_len);
|
||||
} else {
|
||||
eir_len = 0;
|
||||
if (name)
|
||||
eir_len += eir_skb_put_data(skb, EIR_NAME_COMPLETE, name, name_len);
|
||||
else
|
||||
flags = MGMT_DEV_FOUND_NAME_REQUEST_FAILED;
|
||||
}
|
||||
|
||||
ev->eir_len = cpu_to_le16(eir_len);
|
||||
ev->flags = cpu_to_le32(flags);
|
||||
|
|
Загрузка…
Ссылка в новой задаче