mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-20 04:44:26 +08:00
bluetooth-next pull request for net-next:
- Add a new VID/PID 0489/e0f2 for MT7922 - Add Realtek RTL8852BE support ID 0x0cb8:0xc559 - Add a new PID/VID 13d3/3549 for RTL8822CU - Add support for broadcom BCM43430A0 & BCM43430A1 - Add CONFIG_BT_HCIBTUSB_POLL_SYNC - Add CONFIG_BT_LE_L2CAP_ECRED - Add support for CYW4373A0 - Add support for RTL8723DS - Add more device IDs for WCN6855 - Add Broadcom BCM4377 family PCIe Bluetooth -----BEGIN PGP SIGNATURE----- iQJNBAABCAA3FiEE7E6oRXp8w05ovYr/9JCA4xAyCykFAmOXqQYZHGx1aXoudm9u LmRlbnR6QGludGVsLmNvbQAKCRD0kIDjEDILKa4LEACMpjtWb7IhfSt42FC+p7sf gXLZ1GOEZnP3x+rJUXfHRdVfRvkpABixnEFuqbzkCZLQMy6W01abtBJ0xC7mADIu CKvef5IjUdEQJWbbAE5ZwFPxdWbWjoBnO39crl9W1hlpxatLy0QEFfC0SqZRpiiZ Jo2BZ8g6eFP5l1GARhW+B1idjxaXI7JIg41s43PFFHOK/TkfpQxCVCeg4bv36wTD Pp14oixAmJKXsxQoozWJcY9zLy6/6KEedfBzj0mKrOG5/v0O8YyXKoe2T0yjx1d8 t/VSV+XquYiyJ6FA9FsW8spS5GFxGjuEvKagGn11t+in9GIb8t1ve4oAL+y43nC8 br/Sx8FVbFRWu5UA0Xv4issEMp/s/1Zty7U15CHiaFwv6VNZuyXDDLZVzvgUULLl 3ikBrM1JG/AKdoHiIjwmv4qLpteZ7WWOqb3qT3cPMdnUaGBd9fMJ17qCRYs8roW7 9QoGcHUfsPUUAiM6OyBz5L2HbfZuZTdVWvPVqoeaQ7LEmGeqKe4KnGeep0fVpVe8 viKGtLbpi4+S/2IKQvEVvulmsXOved2uJef/x+leH8HShPDceQU9c+TG8RgxOygy f8dhAgn5wV+AgaKzLDJj2xT3xb+0j9jctTWX5SDjvHUPmu23bcNcsA0jv+dknMFh VhOZTE+Qze08ZVGfnRT4uw== =Oj2B -----END PGP SIGNATURE----- Merge tag 'for-net-next-2022-12-12' 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 a new VID/PID 0489/e0f2 for MT7922 - Add Realtek RTL8852BE support ID 0x0cb8:0xc559 - Add a new PID/VID 13d3/3549 for RTL8822CU - Add support for broadcom BCM43430A0 & BCM43430A1 - Add CONFIG_BT_HCIBTUSB_POLL_SYNC - Add CONFIG_BT_LE_L2CAP_ECRED - Add support for CYW4373A0 - Add support for RTL8723DS - Add more device IDs for WCN6855 - Add Broadcom BCM4377 family PCIe Bluetooth * tag 'for-net-next-2022-12-12' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next: (51 commits) Bluetooth: Wait for HCI_OP_WRITE_AUTH_PAYLOAD_TO to complete Bluetooth: ISO: Avoid circular locking dependency Bluetooth: RFCOMM: don't call kfree_skb() under spin_lock_irqsave() Bluetooth: hci_core: don't call kfree_skb() under spin_lock_irqsave() Bluetooth: hci_bcsp: don't call kfree_skb() under spin_lock_irqsave() Bluetooth: hci_h5: don't call kfree_skb() under spin_lock_irqsave() Bluetooth: hci_ll: don't call kfree_skb() under spin_lock_irqsave() Bluetooth: hci_qca: don't call kfree_skb() under spin_lock_irqsave() Bluetooth: btusb: don't call kfree_skb() under spin_lock_irqsave() Bluetooth: btintel: Fix missing free skb in btintel_setup_combined() Bluetooth: hci_conn: Fix crash on hci_create_cis_sync Bluetooth: btintel: Fix existing sparce warnings Bluetooth: btusb: Fix existing sparce warning Bluetooth: btusb: Fix new sparce warnings Bluetooth: btusb: Add a new PID/VID 13d3/3549 for RTL8822CU Bluetooth: btusb: Add Realtek RTL8852BE support ID 0x0cb8:0xc559 dt-bindings: net: realtek-bluetooth: Add RTL8723DS Bluetooth: btusb: Add a new VID/PID 0489/e0f2 for MT7922 dt-bindings: bluetooth: broadcom: add BCM43430A0 & BCM43430A1 Bluetooth: hci_bcm4377: Fix missing pci_disable_device() on error in bcm4377_probe() ... ==================== Link: https://lore.kernel.org/r/20221212222322.1690780-1-luiz.dentz@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
4cc58a087d
@ -1,5 +0,0 @@
|
||||
The following properties are common to the Bluetooth controllers:
|
||||
|
||||
- local-bd-address: array of 6 bytes, specifies the BD address that was
|
||||
uniquely assigned to the Bluetooth device, formatted with least significant
|
||||
byte first (little-endian).
|
@ -0,0 +1,29 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/bluetooth/bluetooth-controller.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Bluetooth Controller Generic Binding
|
||||
|
||||
maintainers:
|
||||
- Marcel Holtmann <marcel@holtmann.org>
|
||||
- Johan Hedberg <johan.hedberg@gmail.com>
|
||||
- Luiz Augusto von Dentz <luiz.dentz@gmail.com>
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^bluetooth(@.*)?$"
|
||||
|
||||
local-bd-address:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
maxItems: 6
|
||||
description:
|
||||
Specifies the BD address that was uniquely assigned to the Bluetooth
|
||||
device. Formatted with least significant byte first (little-endian), e.g.
|
||||
in order to assign the address 00:11:22:33:44:55 this property must have
|
||||
the value [55 44 33 22 11 00].
|
||||
|
||||
additionalProperties: true
|
||||
|
||||
...
|
@ -0,0 +1,81 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/bluetooth/brcm,bcm4377-bluetooth.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Broadcom BCM4377 family PCIe Bluetooth Chips
|
||||
|
||||
maintainers:
|
||||
- Sven Peter <sven@svenpeter.dev>
|
||||
|
||||
description:
|
||||
This binding describes Broadcom BCM4377 family PCIe-attached bluetooth chips
|
||||
usually found in Apple machines. The Wi-Fi part of the chip is described in
|
||||
bindings/net/wireless/brcm,bcm4329-fmac.yaml.
|
||||
|
||||
allOf:
|
||||
- $ref: bluetooth-controller.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- pci14e4,5fa0 # BCM4377
|
||||
- pci14e4,5f69 # BCM4378
|
||||
- pci14e4,5f71 # BCM4387
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
brcm,board-type:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
description: Board type of the Bluetooth chip. This is used to decouple
|
||||
the overall system board from the Bluetooth module and used to construct
|
||||
firmware and calibration data filenames.
|
||||
On Apple platforms, this should be the Apple module-instance codename
|
||||
prefixed by "apple,", e.g. "apple,atlantisb".
|
||||
pattern: '^apple,.*'
|
||||
|
||||
brcm,taurus-cal-blob:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
description: A per-device calibration blob for the Bluetooth radio. This
|
||||
should be filled in by the bootloader from platform configuration
|
||||
data, if necessary, and will be uploaded to the device.
|
||||
This blob is used if the chip stepping of the Bluetooth module does not
|
||||
support beamforming.
|
||||
|
||||
brcm,taurus-bf-cal-blob:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
description: A per-device calibration blob for the Bluetooth radio. This
|
||||
should be filled in by the bootloader from platform configuration
|
||||
data, if necessary, and will be uploaded to the device.
|
||||
This blob is used if the chip stepping of the Bluetooth module supports
|
||||
beamforming.
|
||||
|
||||
local-bd-address: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- local-bd-address
|
||||
- brcm,board-type
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
pcie@a0000000 {
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
reg = <0xa0000000 0x1000000>;
|
||||
device_type = "pci";
|
||||
ranges = <0x43000000 0x6 0xa0000000 0xa0000000 0x0 0x20000000>;
|
||||
|
||||
bluetooth@0,1 {
|
||||
compatible = "pci14e4,5f69";
|
||||
reg = <0x100 0x0 0x0 0x0 0x0>;
|
||||
brcm,board-type = "apple,honshu";
|
||||
/* To be filled by the bootloader */
|
||||
local-bd-address = [00 00 00 00 00 00];
|
||||
};
|
||||
};
|
@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/qualcomm-bluetooth.yaml#
|
||||
$id: http://devicetree.org/schemas/net/bluetooth/qualcomm-bluetooth.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Bluetooth Chips
|
||||
@ -79,8 +79,7 @@ properties:
|
||||
firmware-name:
|
||||
description: specify the name of nvm firmware to load
|
||||
|
||||
local-bd-address:
|
||||
description: see Documentation/devicetree/bindings/net/bluetooth.txt
|
||||
local-bd-address: true
|
||||
|
||||
|
||||
required:
|
||||
@ -89,6 +88,7 @@ required:
|
||||
additionalProperties: false
|
||||
|
||||
allOf:
|
||||
- $ref: bluetooth-controller.yaml#
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
@ -19,11 +19,14 @@ properties:
|
||||
- brcm,bcm4329-bt
|
||||
- brcm,bcm4330-bt
|
||||
- brcm,bcm4334-bt
|
||||
- brcm,bcm43430a0-bt
|
||||
- brcm,bcm43430a1-bt
|
||||
- brcm,bcm43438-bt
|
||||
- brcm,bcm4345c5
|
||||
- brcm,bcm43540-bt
|
||||
- brcm,bcm4335a0
|
||||
- brcm,bcm4349-bt
|
||||
- cypress,cyw4373a0-bt
|
||||
- infineon,cyw55572-bt
|
||||
|
||||
shutdown-gpios:
|
||||
|
@ -20,6 +20,7 @@ properties:
|
||||
enum:
|
||||
- realtek,rtl8723bs-bt
|
||||
- realtek,rtl8723cs-bt
|
||||
- realtek,rtl8723ds-bt
|
||||
- realtek,rtl8822cs-bt
|
||||
|
||||
device-wake-gpios:
|
||||
|
@ -42,15 +42,13 @@ properties:
|
||||
bluetooth:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
allOf:
|
||||
- $ref: /schemas/net/bluetooth/bluetooth-controller.yaml#
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,wcnss-bt
|
||||
|
||||
local-bd-address:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
maxItems: 6
|
||||
description:
|
||||
See Documentation/devicetree/bindings/net/bluetooth.txt
|
||||
local-bd-address: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
@ -1903,6 +1903,7 @@ F: Documentation/devicetree/bindings/interrupt-controller/apple,*
|
||||
F: Documentation/devicetree/bindings/iommu/apple,dart.yaml
|
||||
F: Documentation/devicetree/bindings/iommu/apple,sart.yaml
|
||||
F: Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml
|
||||
F: Documentation/devicetree/bindings/net/bluetooth/brcm,bcm4377-bluetooth.yaml
|
||||
F: Documentation/devicetree/bindings/nvme/apple,nvme-ans.yaml
|
||||
F: Documentation/devicetree/bindings/nvmem/apple,efuses.yaml
|
||||
F: Documentation/devicetree/bindings/pci/apple,pcie.yaml
|
||||
@ -1910,6 +1911,7 @@ F: Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml
|
||||
F: Documentation/devicetree/bindings/power/apple*
|
||||
F: Documentation/devicetree/bindings/watchdog/apple,wdt.yaml
|
||||
F: arch/arm64/boot/dts/apple/
|
||||
F: drivers/bluetooth/hci_bcm4377.c
|
||||
F: drivers/clk/clk-apple-nco.c
|
||||
F: drivers/dma/apple-admac.c
|
||||
F: drivers/i2c/busses/i2c-pasemi-core.c
|
||||
|
@ -21,6 +21,10 @@
|
||||
};
|
||||
};
|
||||
|
||||
&bluetooth0 {
|
||||
brcm,board-type = "apple,atlantisb";
|
||||
};
|
||||
|
||||
&wifi0 {
|
||||
brcm,board-type = "apple,atlantisb";
|
||||
};
|
||||
|
@ -17,6 +17,10 @@
|
||||
model = "Apple MacBook Pro (13-inch, M1, 2020)";
|
||||
};
|
||||
|
||||
&bluetooth0 {
|
||||
brcm,board-type = "apple,honshu";
|
||||
};
|
||||
|
||||
&wifi0 {
|
||||
brcm,board-type = "apple,honshu";
|
||||
};
|
||||
|
@ -17,6 +17,10 @@
|
||||
model = "Apple MacBook Air (M1, 2020)";
|
||||
};
|
||||
|
||||
&bluetooth0 {
|
||||
brcm,board-type = "apple,shikoku";
|
||||
};
|
||||
|
||||
&wifi0 {
|
||||
brcm,board-type = "apple,shikoku";
|
||||
};
|
||||
|
@ -21,6 +21,10 @@
|
||||
};
|
||||
};
|
||||
|
||||
&bluetooth0 {
|
||||
brcm,board-type = "apple,capri";
|
||||
};
|
||||
|
||||
&wifi0 {
|
||||
brcm,board-type = "apple,capri";
|
||||
};
|
||||
|
@ -21,6 +21,10 @@
|
||||
};
|
||||
};
|
||||
|
||||
&bluetooth0 {
|
||||
brcm,board-type = "apple,santorini";
|
||||
};
|
||||
|
||||
&wifi0 {
|
||||
brcm,board-type = "apple,santorini";
|
||||
};
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
/ {
|
||||
aliases {
|
||||
bluetooth0 = &bluetooth0;
|
||||
serial0 = &serial0;
|
||||
serial2 = &serial2;
|
||||
wifi0 = &wifi0;
|
||||
@ -77,4 +78,11 @@
|
||||
local-mac-address = [00 00 00 00 00 00];
|
||||
apple,antenna-sku = "XX";
|
||||
};
|
||||
|
||||
bluetooth0: bluetooth@0,1 {
|
||||
compatible = "pci14e4,5f69";
|
||||
reg = <0x10100 0x0 0x0 0x0 0x0>;
|
||||
/* To be filled by the loader */
|
||||
local-bd-address = [00 00 00 00 00 00];
|
||||
};
|
||||
};
|
||||
|
@ -45,6 +45,17 @@ config BT_HCIBTUSB_AUTOSUSPEND
|
||||
This can be overridden by passing btusb.enable_autosuspend=[y|n]
|
||||
on the kernel commandline.
|
||||
|
||||
config BT_HCIBTUSB_POLL_SYNC
|
||||
bool "Enable USB poll_sync for Bluetooth USB devices by default"
|
||||
depends on BT_HCIBTUSB
|
||||
default y
|
||||
help
|
||||
poll_sync synchronizes the USB data and event endpoints by
|
||||
prioritizing the later.
|
||||
|
||||
Say Y here to enable USB poll_sync for Bluetooth USB devices by
|
||||
default.
|
||||
|
||||
config BT_HCIBTUSB_BCM
|
||||
bool "Broadcom protocol support"
|
||||
depends on BT_HCIBTUSB
|
||||
@ -274,6 +285,18 @@ config BT_HCIBCM203X
|
||||
Say Y here to compile support for HCI BCM203x devices into the
|
||||
kernel or say M to compile it as module (bcm203x).
|
||||
|
||||
|
||||
config BT_HCIBCM4377
|
||||
tristate "HCI BCM4377/4378/4387 PCIe driver"
|
||||
depends on PCI
|
||||
select FW_LOADER
|
||||
help
|
||||
Support for Broadcom BCM4377/4378/4387 Bluetooth chipsets attached via
|
||||
PCIe. These are usually found in Apple machines.
|
||||
|
||||
Say Y here to compile support for HCI BCM4377 family devices into the
|
||||
kernel or say M to compile it as module (hci_bcm4377).
|
||||
|
||||
config BT_HCIBPA10X
|
||||
tristate "HCI BPA10x USB driver"
|
||||
depends on USB
|
||||
|
@ -6,6 +6,7 @@
|
||||
obj-$(CONFIG_BT_HCIVHCI) += hci_vhci.o
|
||||
obj-$(CONFIG_BT_HCIUART) += hci_uart.o
|
||||
obj-$(CONFIG_BT_HCIBCM203X) += bcm203x.o
|
||||
obj-$(CONFIG_BT_HCIBCM4377) += hci_bcm4377.o
|
||||
obj-$(CONFIG_BT_HCIBPA10X) += bpa10x.o
|
||||
obj-$(CONFIG_BT_HCIBFUSB) += bfusb.o
|
||||
obj-$(CONFIG_BT_HCIDTL1) += dtl1_cs.o
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
#define CMD_WRITE_BOOT_PARAMS 0xfc0e
|
||||
struct cmd_write_boot_params {
|
||||
u32 boot_addr;
|
||||
__le32 boot_addr;
|
||||
u8 fw_build_num;
|
||||
u8 fw_build_ww;
|
||||
u8 fw_build_yy;
|
||||
@ -1783,19 +1783,19 @@ static int btintel_get_fw_name(struct intel_version *ver,
|
||||
case 0x0b: /* SfP */
|
||||
case 0x0c: /* WsP */
|
||||
snprintf(fw_name, len, "intel/ibt-%u-%u.%s",
|
||||
le16_to_cpu(ver->hw_variant),
|
||||
le16_to_cpu(params->dev_revid),
|
||||
suffix);
|
||||
ver->hw_variant,
|
||||
le16_to_cpu(params->dev_revid),
|
||||
suffix);
|
||||
break;
|
||||
case 0x11: /* JfP */
|
||||
case 0x12: /* ThP */
|
||||
case 0x13: /* HrP */
|
||||
case 0x14: /* CcP */
|
||||
snprintf(fw_name, len, "intel/ibt-%u-%u-%u.%s",
|
||||
le16_to_cpu(ver->hw_variant),
|
||||
le16_to_cpu(ver->hw_revision),
|
||||
le16_to_cpu(ver->fw_revision),
|
||||
suffix);
|
||||
ver->hw_variant,
|
||||
ver->hw_revision,
|
||||
ver->fw_revision,
|
||||
suffix);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
@ -2524,7 +2524,7 @@ static int btintel_setup_combined(struct hci_dev *hdev)
|
||||
*/
|
||||
err = btintel_read_version(hdev, &ver);
|
||||
if (err)
|
||||
return err;
|
||||
break;
|
||||
|
||||
/* Apply the device specific HCI quirks
|
||||
*
|
||||
@ -2566,7 +2566,8 @@ static int btintel_setup_combined(struct hci_dev *hdev)
|
||||
default:
|
||||
bt_dev_err(hdev, "Unsupported Intel hw variant (%u)",
|
||||
INTEL_HW_VARIANT(ver_tlv.cnvi_bt));
|
||||
return -EINVAL;
|
||||
err = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
exit_error:
|
||||
|
@ -781,6 +781,13 @@ void btrtl_set_quirks(struct hci_dev *hdev, struct btrtl_device_info *btrtl_dev)
|
||||
case CHIP_ID_8852C:
|
||||
set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
|
||||
set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
|
||||
|
||||
/* RTL8852C needs to transmit mSBC data continuously without
|
||||
* the zero length of USB packets for the ALT 6 supported chips
|
||||
*/
|
||||
if (btrtl_dev->project_id == CHIP_ID_8852C)
|
||||
btrealtek_set_flag(hdev, REALTEK_ALT6_CONTINUOUS_TX_CHIP);
|
||||
|
||||
hci_set_aosp_capable(hdev);
|
||||
break;
|
||||
default:
|
||||
|
@ -47,6 +47,27 @@ struct rtl_vendor_config {
|
||||
struct rtl_vendor_config_entry entry[];
|
||||
} __packed;
|
||||
|
||||
enum {
|
||||
REALTEK_ALT6_CONTINUOUS_TX_CHIP,
|
||||
|
||||
__REALTEK_NUM_FLAGS,
|
||||
};
|
||||
|
||||
struct btrealtek_data {
|
||||
DECLARE_BITMAP(flags, __REALTEK_NUM_FLAGS);
|
||||
};
|
||||
|
||||
#define btrealtek_set_flag(hdev, nr) \
|
||||
do { \
|
||||
struct btrealtek_data *realtek = hci_get_priv((hdev)); \
|
||||
set_bit((nr), realtek->flags); \
|
||||
} while (0)
|
||||
|
||||
#define btrealtek_get_flag(hdev) \
|
||||
(((struct btrealtek_data *)hci_get_priv(hdev))->flags)
|
||||
|
||||
#define btrealtek_test_flag(hdev, nr) test_bit((nr), btrealtek_get_flag(hdev))
|
||||
|
||||
#if IS_ENABLED(CONFIG_BT_RTL)
|
||||
|
||||
struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev,
|
||||
|
@ -32,6 +32,7 @@
|
||||
static bool disable_scofix;
|
||||
static bool force_scofix;
|
||||
static bool enable_autosuspend = IS_ENABLED(CONFIG_BT_HCIBTUSB_AUTOSUSPEND);
|
||||
static bool enable_poll_sync = IS_ENABLED(CONFIG_BT_HCIBTUSB_POLL_SYNC);
|
||||
static bool reset = true;
|
||||
|
||||
static struct usb_driver btusb_driver;
|
||||
@ -316,6 +317,90 @@ static const struct usb_device_id blacklist_table[] = {
|
||||
{ USB_DEVICE(0x0489, 0xe0d0), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
{ USB_DEVICE(0x10ab, 0x9108), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
{ USB_DEVICE(0x10ab, 0x9109), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
{ USB_DEVICE(0x10ab, 0x9208), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
{ USB_DEVICE(0x10ab, 0x9209), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
{ USB_DEVICE(0x10ab, 0x9308), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
{ USB_DEVICE(0x10ab, 0x9408), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
{ USB_DEVICE(0x10ab, 0x9508), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
{ USB_DEVICE(0x10ab, 0x9509), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
{ USB_DEVICE(0x10ab, 0x9608), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
{ USB_DEVICE(0x10ab, 0x9609), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
{ USB_DEVICE(0x10ab, 0x9f09), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
{ USB_DEVICE(0x04ca, 0x3022), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
{ USB_DEVICE(0x0489, 0xe0c7), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
{ USB_DEVICE(0x0489, 0xe0c9), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
{ USB_DEVICE(0x0489, 0xe0ca), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
{ USB_DEVICE(0x0489, 0xe0cb), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
{ USB_DEVICE(0x0489, 0xe0ce), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
{ USB_DEVICE(0x0489, 0xe0de), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
{ USB_DEVICE(0x0489, 0xe0df), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
{ USB_DEVICE(0x0489, 0xe0e1), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
{ USB_DEVICE(0x0489, 0xe0ea), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
{ USB_DEVICE(0x0489, 0xe0ec), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
{ USB_DEVICE(0x04ca, 0x3023), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
{ USB_DEVICE(0x04ca, 0x3024), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
{ USB_DEVICE(0x04ca, 0x3a22), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
{ USB_DEVICE(0x04ca, 0x3a24), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
{ USB_DEVICE(0x04ca, 0x3a26), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
{ USB_DEVICE(0x04ca, 0x3a27), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
|
||||
/* QCA WCN785x chipset */
|
||||
{ USB_DEVICE(0x0cf3, 0xe700), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
@ -413,6 +498,10 @@ static const struct usb_device_id blacklist_table[] = {
|
||||
{ USB_DEVICE(0x0bda, 0xc822), .driver_info = BTUSB_REALTEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
|
||||
/* Realtek 8822CU Bluetooth devices */
|
||||
{ USB_DEVICE(0x13d3, 0x3549), .driver_info = BTUSB_REALTEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
|
||||
/* Realtek 8852AE Bluetooth devices */
|
||||
{ USB_DEVICE(0x0bda, 0x2852), .driver_info = BTUSB_REALTEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
@ -443,6 +532,10 @@ static const struct usb_device_id blacklist_table[] = {
|
||||
{ USB_DEVICE(0x13d3, 0x3592), .driver_info = BTUSB_REALTEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
|
||||
/* Realtek 8852BE Bluetooth devices */
|
||||
{ USB_DEVICE(0x0cb8, 0xc559), .driver_info = BTUSB_REALTEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
|
||||
/* Realtek Bluetooth devices */
|
||||
{ USB_VENDOR_AND_INTERFACE_INFO(0x0bda, 0xe0, 0x01, 0x01),
|
||||
.driver_info = BTUSB_REALTEK },
|
||||
@ -511,6 +604,9 @@ static const struct usb_device_id blacklist_table[] = {
|
||||
{ USB_DEVICE(0x0489, 0xe0e2), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
{ USB_DEVICE(0x0489, 0xe0f2), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
|
||||
/* Additional Realtek 8723AE Bluetooth devices */
|
||||
{ USB_DEVICE(0x0930, 0x021d), .driver_info = BTUSB_REALTEK },
|
||||
@ -543,6 +639,8 @@ static const struct usb_device_id blacklist_table[] = {
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x7392, 0xc611), .driver_info = BTUSB_REALTEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x2b89, 0x8761), .driver_info = BTUSB_REALTEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
|
||||
/* Additional Realtek 8821AE Bluetooth devices */
|
||||
{ USB_DEVICE(0x0b05, 0x17dc), .driver_info = BTUSB_REALTEK },
|
||||
@ -632,6 +730,7 @@ static const struct dmi_system_id btusb_needs_reset_resume_table[] = {
|
||||
#define BTUSB_TX_WAIT_VND_EVT 13
|
||||
#define BTUSB_WAKEUP_AUTOSUSPEND 14
|
||||
#define BTUSB_USE_ALT3_FOR_WBS 15
|
||||
#define BTUSB_ALT6_CONTINUOUS_TX 16
|
||||
|
||||
struct btusb_data {
|
||||
struct hci_dev *hdev;
|
||||
@ -696,6 +795,28 @@ struct btusb_data {
|
||||
unsigned cmd_timeout_cnt;
|
||||
};
|
||||
|
||||
static void btusb_reset(struct hci_dev *hdev)
|
||||
{
|
||||
struct btusb_data *data;
|
||||
int err;
|
||||
|
||||
if (hdev->reset) {
|
||||
hdev->reset(hdev);
|
||||
return;
|
||||
}
|
||||
|
||||
data = hci_get_drvdata(hdev);
|
||||
/* This is not an unbalanced PM reference since the device will reset */
|
||||
err = usb_autopm_get_interface(data->intf);
|
||||
if (err) {
|
||||
bt_dev_err(hdev, "Failed usb_autopm_get_interface: %d", err);
|
||||
return;
|
||||
}
|
||||
|
||||
bt_dev_err(hdev, "Resetting usb device.");
|
||||
usb_queue_reset_device(data->intf);
|
||||
}
|
||||
|
||||
static void btusb_intel_cmd_timeout(struct hci_dev *hdev)
|
||||
{
|
||||
struct btusb_data *data = hci_get_drvdata(hdev);
|
||||
@ -705,7 +826,7 @@ static void btusb_intel_cmd_timeout(struct hci_dev *hdev)
|
||||
return;
|
||||
|
||||
if (!reset_gpio) {
|
||||
bt_dev_err(hdev, "No way to reset. Ignoring and continuing");
|
||||
btusb_reset(hdev);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -736,7 +857,7 @@ static void btusb_rtl_cmd_timeout(struct hci_dev *hdev)
|
||||
return;
|
||||
|
||||
if (!reset_gpio) {
|
||||
bt_dev_err(hdev, "No gpio to reset Realtek device, ignoring");
|
||||
btusb_reset(hdev);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -761,7 +882,6 @@ static void btusb_qca_cmd_timeout(struct hci_dev *hdev)
|
||||
{
|
||||
struct btusb_data *data = hci_get_drvdata(hdev);
|
||||
struct gpio_desc *reset_gpio = data->reset_gpio;
|
||||
int err;
|
||||
|
||||
if (++data->cmd_timeout_cnt < 5)
|
||||
return;
|
||||
@ -787,13 +907,7 @@ static void btusb_qca_cmd_timeout(struct hci_dev *hdev)
|
||||
return;
|
||||
}
|
||||
|
||||
bt_dev_err(hdev, "Multiple cmd timeouts seen. Resetting usb device.");
|
||||
/* This is not an unbalanced PM reference since the device will reset */
|
||||
err = usb_autopm_get_interface(data->intf);
|
||||
if (!err)
|
||||
usb_queue_reset_device(data->intf);
|
||||
else
|
||||
bt_dev_err(hdev, "Failed usb_autopm_get_interface with %d", err);
|
||||
btusb_reset(hdev);
|
||||
}
|
||||
|
||||
static inline void btusb_free_frags(struct btusb_data *data)
|
||||
@ -802,13 +916,13 @@ static inline void btusb_free_frags(struct btusb_data *data)
|
||||
|
||||
spin_lock_irqsave(&data->rxlock, flags);
|
||||
|
||||
kfree_skb(data->evt_skb);
|
||||
dev_kfree_skb_irq(data->evt_skb);
|
||||
data->evt_skb = NULL;
|
||||
|
||||
kfree_skb(data->acl_skb);
|
||||
dev_kfree_skb_irq(data->acl_skb);
|
||||
data->acl_skb = NULL;
|
||||
|
||||
kfree_skb(data->sco_skb);
|
||||
dev_kfree_skb_irq(data->sco_skb);
|
||||
data->sco_skb = NULL;
|
||||
|
||||
spin_unlock_irqrestore(&data->rxlock, flags);
|
||||
@ -962,6 +1076,34 @@ static int btusb_recv_bulk(struct btusb_data *data, void *buffer, int count)
|
||||
return err;
|
||||
}
|
||||
|
||||
static bool btusb_validate_sco_handle(struct hci_dev *hdev,
|
||||
struct hci_sco_hdr *hdr)
|
||||
{
|
||||
__u16 handle;
|
||||
|
||||
if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL))
|
||||
// Can't validate, userspace controls everything.
|
||||
return true;
|
||||
|
||||
/*
|
||||
* USB isochronous transfers are not designed to be reliable and may
|
||||
* lose fragments. When this happens, the next first fragment
|
||||
* encountered might actually be a continuation fragment.
|
||||
* Validate the handle to detect it and drop it, or else the upper
|
||||
* layer will get garbage for a while.
|
||||
*/
|
||||
|
||||
handle = hci_handle(__le16_to_cpu(hdr->handle));
|
||||
|
||||
switch (hci_conn_lookup_type(hdev, handle)) {
|
||||
case SCO_LINK:
|
||||
case ESCO_LINK:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static int btusb_recv_isoc(struct btusb_data *data, void *buffer, int count)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
@ -994,9 +1136,12 @@ static int btusb_recv_isoc(struct btusb_data *data, void *buffer, int count)
|
||||
|
||||
if (skb->len == HCI_SCO_HDR_SIZE) {
|
||||
/* Complete SCO header */
|
||||
hci_skb_expect(skb) = hci_sco_hdr(skb)->dlen;
|
||||
struct hci_sco_hdr *hdr = hci_sco_hdr(skb);
|
||||
|
||||
if (skb_tailroom(skb) < hci_skb_expect(skb)) {
|
||||
hci_skb_expect(skb) = hdr->dlen;
|
||||
|
||||
if (skb_tailroom(skb) < hci_skb_expect(skb) ||
|
||||
!btusb_validate_sco_handle(data->hdev, hdr)) {
|
||||
kfree_skb(skb);
|
||||
skb = NULL;
|
||||
|
||||
@ -1276,11 +1421,17 @@ static void btusb_isoc_complete(struct urb *urb)
|
||||
static inline void __fill_isoc_descriptor_msbc(struct urb *urb, int len,
|
||||
int mtu, struct btusb_data *data)
|
||||
{
|
||||
int i, offset = 0;
|
||||
int i = 0, offset = 0;
|
||||
unsigned int interval;
|
||||
|
||||
BT_DBG("len %d mtu %d", len, mtu);
|
||||
|
||||
/* For mSBC ALT 6 settings some chips need to transmit the data
|
||||
* continuously without the zero length of USB packets.
|
||||
*/
|
||||
if (test_bit(BTUSB_ALT6_CONTINUOUS_TX, &data->flags))
|
||||
goto ignore_usb_alt6_packet_flow;
|
||||
|
||||
/* For mSBC ALT 6 setting the host will send the packet at continuous
|
||||
* flow. As per core spec 5, vol 4, part B, table 2.1. For ALT setting
|
||||
* 6 the HCI PACKET INTERVAL should be 7.5ms for every usb packets.
|
||||
@ -1300,6 +1451,7 @@ static inline void __fill_isoc_descriptor_msbc(struct urb *urb, int len,
|
||||
urb->iso_frame_desc[i].length = offset;
|
||||
}
|
||||
|
||||
ignore_usb_alt6_packet_flow:
|
||||
if (len && i < BTUSB_MAX_ISOC_FRAMES) {
|
||||
urb->iso_frame_desc[i].offset = offset;
|
||||
urb->iso_frame_desc[i].length = len;
|
||||
@ -1981,10 +2133,11 @@ static void btusb_work(struct work_struct *work)
|
||||
if (btusb_switch_alt_setting(hdev, new_alts) < 0)
|
||||
bt_dev_err(hdev, "set USB alt:(%d) failed!", new_alts);
|
||||
} else {
|
||||
clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
|
||||
usb_kill_anchored_urbs(&data->isoc_anchor);
|
||||
|
||||
__set_isoc_interface(hdev, 0);
|
||||
if (test_and_clear_bit(BTUSB_ISOC_RUNNING, &data->flags))
|
||||
__set_isoc_interface(hdev, 0);
|
||||
|
||||
if (test_and_clear_bit(BTUSB_DID_ISO_RESUME, &data->flags))
|
||||
usb_autopm_put_interface(data->isoc ? data->isoc : data->intf);
|
||||
}
|
||||
@ -2048,18 +2201,19 @@ static int btusb_setup_csr(struct hci_dev *hdev)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (skb->len != sizeof(struct hci_rp_read_local_version)) {
|
||||
rp = skb_pull_data(skb, sizeof(*rp));
|
||||
if (!rp) {
|
||||
bt_dev_err(hdev, "CSR: Local version length mismatch");
|
||||
kfree_skb(skb);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
rp = (struct hci_rp_read_local_version *)skb->data;
|
||||
bt_dev_info(hdev, "CSR: Setting up dongle with HCI ver=%u rev=%04x",
|
||||
rp->hci_ver, le16_to_cpu(rp->hci_rev));
|
||||
|
||||
bt_dev_info(hdev, "CSR: Setting up dongle with HCI ver=%u rev=%04x; LMP ver=%u subver=%04x; manufacturer=%u",
|
||||
le16_to_cpu(rp->hci_ver), le16_to_cpu(rp->hci_rev),
|
||||
le16_to_cpu(rp->lmp_ver), le16_to_cpu(rp->lmp_subver),
|
||||
le16_to_cpu(rp->manufacturer));
|
||||
bt_dev_info(hdev, "LMP ver=%u subver=%04x; manufacturer=%u",
|
||||
rp->lmp_ver, le16_to_cpu(rp->lmp_subver),
|
||||
le16_to_cpu(rp->manufacturer));
|
||||
|
||||
/* Detect a wide host of Chinese controllers that aren't CSR.
|
||||
*
|
||||
@ -2089,29 +2243,29 @@ static int btusb_setup_csr(struct hci_dev *hdev)
|
||||
* third-party BT 4.0 dongle reuses it.
|
||||
*/
|
||||
else if (le16_to_cpu(rp->lmp_subver) <= 0x034e &&
|
||||
le16_to_cpu(rp->hci_ver) > BLUETOOTH_VER_1_1)
|
||||
rp->hci_ver > BLUETOOTH_VER_1_1)
|
||||
is_fake = true;
|
||||
|
||||
else if (le16_to_cpu(rp->lmp_subver) <= 0x0529 &&
|
||||
le16_to_cpu(rp->hci_ver) > BLUETOOTH_VER_1_2)
|
||||
rp->hci_ver > BLUETOOTH_VER_1_2)
|
||||
is_fake = true;
|
||||
|
||||
else if (le16_to_cpu(rp->lmp_subver) <= 0x0c5c &&
|
||||
le16_to_cpu(rp->hci_ver) > BLUETOOTH_VER_2_0)
|
||||
rp->hci_ver > BLUETOOTH_VER_2_0)
|
||||
is_fake = true;
|
||||
|
||||
else if (le16_to_cpu(rp->lmp_subver) <= 0x1899 &&
|
||||
le16_to_cpu(rp->hci_ver) > BLUETOOTH_VER_2_1)
|
||||
rp->hci_ver > BLUETOOTH_VER_2_1)
|
||||
is_fake = true;
|
||||
|
||||
else if (le16_to_cpu(rp->lmp_subver) <= 0x22bb &&
|
||||
le16_to_cpu(rp->hci_ver) > BLUETOOTH_VER_4_0)
|
||||
rp->hci_ver > BLUETOOTH_VER_4_0)
|
||||
is_fake = true;
|
||||
|
||||
/* Other clones which beat all the above checks */
|
||||
else if (bcdDevice == 0x0134 &&
|
||||
le16_to_cpu(rp->lmp_subver) == 0x0c5c &&
|
||||
le16_to_cpu(rp->hci_ver) == BLUETOOTH_VER_2_0)
|
||||
rp->hci_ver == BLUETOOTH_VER_2_0)
|
||||
is_fake = true;
|
||||
|
||||
if (is_fake) {
|
||||
@ -2321,6 +2475,19 @@ static int btusb_send_frame_intel(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
return -EILSEQ;
|
||||
}
|
||||
|
||||
static int btusb_setup_realtek(struct hci_dev *hdev)
|
||||
{
|
||||
struct btusb_data *data = hci_get_drvdata(hdev);
|
||||
int ret;
|
||||
|
||||
ret = btrtl_setup_realtek(hdev);
|
||||
|
||||
if (btrealtek_test_flag(data->hdev, REALTEK_ALT6_CONTINUOUS_TX_CHIP))
|
||||
set_bit(BTUSB_ALT6_CONTINUOUS_TX, &data->flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* UHW CR mapping */
|
||||
#define MTK_BT_MISC 0x70002510
|
||||
#define MTK_BT_SUBSYS_RST 0x70002610
|
||||
@ -3256,7 +3423,7 @@ static int btusb_setup_qca_load_rampatch(struct hci_dev *hdev,
|
||||
|
||||
if (ver_rom & ~0xffffU) {
|
||||
rver_rom_high = le16_to_cpu(rver->rom_version_high);
|
||||
rver_rom = le32_to_cpu(rver_rom_high << 16 | rver_rom_low);
|
||||
rver_rom = rver_rom_high << 16 | rver_rom_low;
|
||||
} else {
|
||||
rver_rom = rver_rom_low;
|
||||
}
|
||||
@ -3761,6 +3928,9 @@ static int btusb_probe(struct usb_interface *intf,
|
||||
/* Override the rx handlers */
|
||||
data->recv_event = btusb_recv_event_intel;
|
||||
data->recv_bulk = btusb_recv_bulk_intel;
|
||||
} else if (id->driver_info & BTUSB_REALTEK) {
|
||||
/* Allocate extra space for Realtek device */
|
||||
priv_size += sizeof(struct btrealtek_data);
|
||||
}
|
||||
|
||||
data->recv_acl = hci_recv_frame;
|
||||
@ -3919,7 +4089,7 @@ static int btusb_probe(struct usb_interface *intf,
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_HCIBTUSB_RTL) &&
|
||||
(id->driver_info & BTUSB_REALTEK)) {
|
||||
hdev->setup = btrtl_setup_realtek;
|
||||
hdev->setup = btusb_setup_realtek;
|
||||
hdev->shutdown = btrtl_shutdown_realtek;
|
||||
hdev->cmd_timeout = btusb_rtl_cmd_timeout;
|
||||
|
||||
@ -4004,6 +4174,8 @@ static int btusb_probe(struct usb_interface *intf,
|
||||
if (enable_autosuspend)
|
||||
usb_enable_autosuspend(data->udev);
|
||||
|
||||
data->poll_sync = enable_poll_sync;
|
||||
|
||||
err = hci_register_dev(hdev);
|
||||
if (err < 0)
|
||||
goto out_free_dev;
|
||||
|
@ -53,11 +53,13 @@
|
||||
* struct bcm_device_data - device specific data
|
||||
* @no_early_set_baudrate: Disallow set baudrate before driver setup()
|
||||
* @drive_rts_on_open: drive RTS signal on ->open() when platform requires it
|
||||
* @no_uart_clock_set: UART clock set command for >3Mbps mode is unavailable
|
||||
* @max_autobaud_speed: max baudrate supported by device in autobaud mode
|
||||
*/
|
||||
struct bcm_device_data {
|
||||
bool no_early_set_baudrate;
|
||||
bool drive_rts_on_open;
|
||||
bool no_uart_clock_set;
|
||||
u32 max_autobaud_speed;
|
||||
};
|
||||
|
||||
@ -100,6 +102,7 @@ struct bcm_device_data {
|
||||
* @is_suspended: whether flow control is currently disabled
|
||||
* @no_early_set_baudrate: don't set_baudrate before setup()
|
||||
* @drive_rts_on_open: drive RTS signal on ->open() when platform requires it
|
||||
* @no_uart_clock_set: UART clock set command for >3Mbps mode is unavailable
|
||||
* @pcm_int_params: keep the initial PCM configuration
|
||||
* @use_autobaud_mode: start Bluetooth device in autobaud mode
|
||||
* @max_autobaud_speed: max baudrate supported by device in autobaud mode
|
||||
@ -140,6 +143,7 @@ struct bcm_device {
|
||||
#endif
|
||||
bool no_early_set_baudrate;
|
||||
bool drive_rts_on_open;
|
||||
bool no_uart_clock_set;
|
||||
bool use_autobaud_mode;
|
||||
u8 pcm_int_params[5];
|
||||
u32 max_autobaud_speed;
|
||||
@ -172,10 +176,11 @@ static inline void host_set_baudrate(struct hci_uart *hu, unsigned int speed)
|
||||
static int bcm_set_baudrate(struct hci_uart *hu, unsigned int speed)
|
||||
{
|
||||
struct hci_dev *hdev = hu->hdev;
|
||||
struct bcm_data *bcm = hu->priv;
|
||||
struct sk_buff *skb;
|
||||
struct bcm_update_uart_baud_rate param;
|
||||
|
||||
if (speed > 3000000) {
|
||||
if (speed > 3000000 && !bcm->dev->no_uart_clock_set) {
|
||||
struct bcm_write_uart_clock_setting clock;
|
||||
|
||||
clock.type = BCM_UART_CLOCK_48MHZ;
|
||||
@ -1529,6 +1534,7 @@ static int bcm_serdev_probe(struct serdev_device *serdev)
|
||||
bcmdev->max_autobaud_speed = data->max_autobaud_speed;
|
||||
bcmdev->no_early_set_baudrate = data->no_early_set_baudrate;
|
||||
bcmdev->drive_rts_on_open = data->drive_rts_on_open;
|
||||
bcmdev->no_uart_clock_set = data->no_uart_clock_set;
|
||||
}
|
||||
|
||||
return hci_uart_register_device(&bcmdev->serdev_hu, &bcm_proto);
|
||||
@ -1550,6 +1556,10 @@ static struct bcm_device_data bcm43438_device_data = {
|
||||
.drive_rts_on_open = true,
|
||||
};
|
||||
|
||||
static struct bcm_device_data cyw4373a0_device_data = {
|
||||
.no_uart_clock_set = true,
|
||||
};
|
||||
|
||||
static struct bcm_device_data cyw55572_device_data = {
|
||||
.max_autobaud_speed = 921600,
|
||||
};
|
||||
@ -1566,6 +1576,7 @@ static const struct of_device_id bcm_bluetooth_of_match[] = {
|
||||
{ .compatible = "brcm,bcm4349-bt", .data = &bcm43438_device_data },
|
||||
{ .compatible = "brcm,bcm43540-bt", .data = &bcm4354_device_data },
|
||||
{ .compatible = "brcm,bcm4335a0" },
|
||||
{ .compatible = "cypress,cyw4373a0-bt", .data = &cyw4373a0_device_data },
|
||||
{ .compatible = "infineon,cyw55572-bt", .data = &cyw55572_device_data },
|
||||
{ },
|
||||
};
|
||||
|
2514
drivers/bluetooth/hci_bcm4377.c
Normal file
2514
drivers/bluetooth/hci_bcm4377.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -378,7 +378,7 @@ static void bcsp_pkt_cull(struct bcsp_struct *bcsp)
|
||||
i++;
|
||||
|
||||
__skb_unlink(skb, &bcsp->unack);
|
||||
kfree_skb(skb);
|
||||
dev_kfree_skb_irq(skb);
|
||||
}
|
||||
|
||||
if (skb_queue_empty(&bcsp->unack))
|
||||
|
@ -313,7 +313,7 @@ static void h5_pkt_cull(struct h5 *h5)
|
||||
break;
|
||||
|
||||
__skb_unlink(skb, &h5->unack);
|
||||
kfree_skb(skb);
|
||||
dev_kfree_skb_irq(skb);
|
||||
}
|
||||
|
||||
if (skb_queue_empty(&h5->unack))
|
||||
|
@ -345,7 +345,7 @@ static int ll_enqueue(struct hci_uart *hu, struct sk_buff *skb)
|
||||
default:
|
||||
BT_ERR("illegal hcill state: %ld (losing packet)",
|
||||
ll->hcill_state);
|
||||
kfree_skb(skb);
|
||||
dev_kfree_skb_irq(skb);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -912,7 +912,7 @@ static int qca_enqueue(struct hci_uart *hu, struct sk_buff *skb)
|
||||
default:
|
||||
BT_ERR("Illegal tx state: %d (losing packet)",
|
||||
qca->tx_ibs_state);
|
||||
kfree_skb(skb);
|
||||
dev_kfree_skb_irq(skb);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1765,7 +1765,8 @@ retry:
|
||||
qca_debugfs_init(hdev);
|
||||
hu->hdev->hw_error = qca_hw_error;
|
||||
hu->hdev->cmd_timeout = qca_cmd_timeout;
|
||||
hu->hdev->wakeup = qca_wakeup;
|
||||
if (device_can_wakeup(hu->serdev->ctrl->dev.parent))
|
||||
hu->hdev->wakeup = qca_wakeup;
|
||||
} else if (ret == -ENOENT) {
|
||||
/* No patch/nvm-config found, run with original fw/config */
|
||||
set_bit(QCA_ROM_FW, &qca->flags);
|
||||
|
@ -50,8 +50,11 @@ static int virtbt_add_inbuf(struct virtio_bluetooth *vbt)
|
||||
|
||||
static int virtbt_open(struct hci_dev *hdev)
|
||||
{
|
||||
struct virtio_bluetooth *vbt = hci_get_drvdata(hdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int virtbt_open_vdev(struct virtio_bluetooth *vbt)
|
||||
{
|
||||
if (virtbt_add_inbuf(vbt) < 0)
|
||||
return -EIO;
|
||||
|
||||
@ -61,7 +64,11 @@ static int virtbt_open(struct hci_dev *hdev)
|
||||
|
||||
static int virtbt_close(struct hci_dev *hdev)
|
||||
{
|
||||
struct virtio_bluetooth *vbt = hci_get_drvdata(hdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int virtbt_close_vdev(struct virtio_bluetooth *vbt)
|
||||
{
|
||||
int i;
|
||||
|
||||
cancel_work_sync(&vbt->rx);
|
||||
@ -306,7 +313,12 @@ static int virtbt_probe(struct virtio_device *vdev)
|
||||
if (virtio_has_feature(vdev, VIRTIO_BT_F_VND_HCI)) {
|
||||
__u16 vendor;
|
||||
|
||||
virtio_cread(vdev, struct virtio_bt_config, vendor, &vendor);
|
||||
if (virtio_has_feature(vdev, VIRTIO_BT_F_CONFIG_V2))
|
||||
virtio_cread(vdev, struct virtio_bt_config_v2,
|
||||
vendor, &vendor);
|
||||
else
|
||||
virtio_cread(vdev, struct virtio_bt_config,
|
||||
vendor, &vendor);
|
||||
|
||||
switch (vendor) {
|
||||
case VIRTIO_BT_CONFIG_VENDOR_ZEPHYR:
|
||||
@ -339,8 +351,12 @@ static int virtbt_probe(struct virtio_device *vdev)
|
||||
if (virtio_has_feature(vdev, VIRTIO_BT_F_MSFT_EXT)) {
|
||||
__u16 msft_opcode;
|
||||
|
||||
virtio_cread(vdev, struct virtio_bt_config,
|
||||
msft_opcode, &msft_opcode);
|
||||
if (virtio_has_feature(vdev, VIRTIO_BT_F_CONFIG_V2))
|
||||
virtio_cread(vdev, struct virtio_bt_config_v2,
|
||||
msft_opcode, &msft_opcode);
|
||||
else
|
||||
virtio_cread(vdev, struct virtio_bt_config,
|
||||
msft_opcode, &msft_opcode);
|
||||
|
||||
hci_set_msft_opcode(hdev, msft_opcode);
|
||||
}
|
||||
@ -354,8 +370,15 @@ static int virtbt_probe(struct virtio_device *vdev)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
virtio_device_ready(vdev);
|
||||
err = virtbt_open_vdev(vbt);
|
||||
if (err)
|
||||
goto open_failed;
|
||||
|
||||
return 0;
|
||||
|
||||
open_failed:
|
||||
hci_free_dev(hdev);
|
||||
failed:
|
||||
vdev->config->del_vqs(vdev);
|
||||
return err;
|
||||
@ -368,6 +391,7 @@ static void virtbt_remove(struct virtio_device *vdev)
|
||||
|
||||
hci_unregister_dev(hdev);
|
||||
virtio_reset_device(vdev);
|
||||
virtbt_close_vdev(vbt);
|
||||
|
||||
hci_free_dev(hdev);
|
||||
vbt->hdev = NULL;
|
||||
@ -387,6 +411,7 @@ static const unsigned int virtbt_features[] = {
|
||||
VIRTIO_BT_F_VND_HCI,
|
||||
VIRTIO_BT_F_MSFT_EXT,
|
||||
VIRTIO_BT_F_AOSP_EXT,
|
||||
VIRTIO_BT_F_CONFIG_V2,
|
||||
};
|
||||
|
||||
static struct virtio_driver virtbt_driver = {
|
||||
|
@ -274,6 +274,26 @@ enum {
|
||||
* during the hdev->setup vendor callback.
|
||||
*/
|
||||
HCI_QUIRK_BROKEN_ENHANCED_SETUP_SYNC_CONN,
|
||||
|
||||
/*
|
||||
* When this quirk is set, the HCI_OP_LE_SET_EXT_SCAN_ENABLE command is
|
||||
* disabled. This is required for some Broadcom controllers which
|
||||
* erroneously claim to support extended scanning.
|
||||
*
|
||||
* This quirk can be set before hci_register_dev is called or
|
||||
* during the hdev->setup vendor callback.
|
||||
*/
|
||||
HCI_QUIRK_BROKEN_EXT_SCAN,
|
||||
|
||||
/*
|
||||
* When this quirk is set, the HCI_OP_GET_MWS_TRANSPORT_CONFIG command is
|
||||
* disabled. This is required for some Broadcom controllers which
|
||||
* erroneously claim to support MWS Transport Layer Configuration.
|
||||
*
|
||||
* This quirk can be set before hci_register_dev is called or
|
||||
* during the hdev->setup vendor callback.
|
||||
*/
|
||||
HCI_QUIRK_BROKEN_MWS_TRANSPORT_CONFIG,
|
||||
};
|
||||
|
||||
/* HCI device flags */
|
||||
@ -2590,6 +2610,7 @@ struct hci_ev_le_conn_complete {
|
||||
#define LE_EXT_ADV_DIRECT_IND 0x0004
|
||||
#define LE_EXT_ADV_SCAN_RSP 0x0008
|
||||
#define LE_EXT_ADV_LEGACY_PDU 0x0010
|
||||
#define LE_EXT_ADV_EVT_TYPE_MASK 0x007f
|
||||
|
||||
#define ADDR_LE_DEV_PUBLIC 0x00
|
||||
#define ADDR_LE_DEV_RANDOM 0x01
|
||||
|
@ -659,6 +659,7 @@ struct hci_dev {
|
||||
int (*set_diag)(struct hci_dev *hdev, bool enable);
|
||||
int (*set_bdaddr)(struct hci_dev *hdev, const bdaddr_t *bdaddr);
|
||||
void (*cmd_timeout)(struct hci_dev *hdev);
|
||||
void (*reset)(struct hci_dev *hdev);
|
||||
bool (*wakeup)(struct hci_dev *hdev);
|
||||
int (*set_quality_report)(struct hci_dev *hdev, bool enable);
|
||||
int (*get_data_path_id)(struct hci_dev *hdev, __u8 *data_path);
|
||||
@ -1689,7 +1690,9 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
|
||||
|
||||
/* Use ext scanning if set ext scan param and ext scan enable is supported */
|
||||
#define use_ext_scan(dev) (((dev)->commands[37] & 0x20) && \
|
||||
((dev)->commands[37] & 0x40))
|
||||
((dev)->commands[37] & 0x40) && \
|
||||
!test_bit(HCI_QUIRK_BROKEN_EXT_SCAN, &(dev)->quirks))
|
||||
|
||||
/* Use ext create connection if command is supported */
|
||||
#define use_ext_conn(dev) ((dev)->commands[37] & 0x80)
|
||||
|
||||
@ -1717,6 +1720,9 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
|
||||
((dev)->le_features[3] & HCI_LE_CIS_PERIPHERAL)
|
||||
#define bis_capable(dev) ((dev)->le_features[3] & HCI_LE_ISO_BROADCASTER)
|
||||
|
||||
#define mws_transport_config_capable(dev) (((dev)->commands[30] & 0x08) && \
|
||||
(!test_bit(HCI_QUIRK_BROKEN_MWS_TRANSPORT_CONFIG, &(dev)->quirks)))
|
||||
|
||||
/* ----- HCI protocols ----- */
|
||||
#define HCI_PROTO_DEFER 0x01
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#define VIRTIO_BT_F_VND_HCI 0 /* Indicates vendor command support */
|
||||
#define VIRTIO_BT_F_MSFT_EXT 1 /* Indicates MSFT vendor support */
|
||||
#define VIRTIO_BT_F_AOSP_EXT 2 /* Indicates AOSP vendor support */
|
||||
#define VIRTIO_BT_F_CONFIG_V2 3 /* Use second version configuration */
|
||||
|
||||
enum virtio_bt_config_type {
|
||||
VIRTIO_BT_CONFIG_TYPE_PRIMARY = 0,
|
||||
@ -28,4 +29,11 @@ struct virtio_bt_config {
|
||||
__u16 msft_opcode;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct virtio_bt_config_v2 {
|
||||
__u8 type;
|
||||
__u8 alignment;
|
||||
__u16 vendor;
|
||||
__u16 msft_opcode;
|
||||
};
|
||||
|
||||
#endif /* _UAPI_LINUX_VIRTIO_BT_H */
|
||||
|
@ -78,6 +78,17 @@ config BT_LE
|
||||
Bluetooth Low Energy includes support low-energy physical
|
||||
layer available with Bluetooth version 4.0 or later.
|
||||
|
||||
config BT_LE_L2CAP_ECRED
|
||||
bool "Bluetooth L2CAP Enhanced Credit Flow Control"
|
||||
depends on BT_LE
|
||||
default y
|
||||
help
|
||||
Bluetooth Low Energy L2CAP Enhanced Credit Flow Control available with
|
||||
Bluetooth version 5.2 or later.
|
||||
|
||||
This can be overridden by passing bluetooth.enable_ecred=[1|0]
|
||||
on the kernel commandline.
|
||||
|
||||
config BT_6LOWPAN
|
||||
tristate "Bluetooth 6LoWPAN support"
|
||||
depends on BT_LE && 6LOWPAN
|
||||
|
@ -824,11 +824,10 @@ static int hci_le_terminate_big(struct hci_dev *hdev, u8 big, u8 bis)
|
||||
|
||||
bt_dev_dbg(hdev, "big 0x%2.2x bis 0x%2.2x", big, bis);
|
||||
|
||||
d = kmalloc(sizeof(*d), GFP_KERNEL);
|
||||
d = kzalloc(sizeof(*d), GFP_KERNEL);
|
||||
if (!d)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(d, 0, sizeof(*d));
|
||||
d->big = big;
|
||||
d->bis = bis;
|
||||
|
||||
@ -861,11 +860,10 @@ static int hci_le_big_terminate(struct hci_dev *hdev, u8 big, u16 sync_handle)
|
||||
|
||||
bt_dev_dbg(hdev, "big 0x%2.2x sync_handle 0x%4.4x", big, sync_handle);
|
||||
|
||||
d = kmalloc(sizeof(*d), GFP_KERNEL);
|
||||
d = kzalloc(sizeof(*d), GFP_KERNEL);
|
||||
if (!d)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(d, 0, sizeof(*d));
|
||||
d->big = big;
|
||||
d->sync_handle = sync_handle;
|
||||
|
||||
@ -1881,7 +1879,7 @@ static int hci_create_cis_sync(struct hci_dev *hdev, void *data)
|
||||
continue;
|
||||
|
||||
/* Check if all CIS(s) belonging to a CIG are ready */
|
||||
if (conn->link->state != BT_CONNECTED ||
|
||||
if (!conn->link || conn->link->state != BT_CONNECTED ||
|
||||
conn->state != BT_CONNECT) {
|
||||
cmd.cp.num_cis = 0;
|
||||
break;
|
||||
@ -2046,19 +2044,12 @@ int hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst, __u8 dst_type,
|
||||
if (hci_dev_test_and_set_flag(hdev, HCI_PA_SYNC))
|
||||
return -EBUSY;
|
||||
|
||||
cp = kmalloc(sizeof(*cp), GFP_KERNEL);
|
||||
cp = kzalloc(sizeof(*cp), GFP_KERNEL);
|
||||
if (!cp) {
|
||||
hci_dev_clear_flag(hdev, HCI_PA_SYNC);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Convert from ISO socket address type to HCI address type */
|
||||
if (dst_type == BDADDR_LE_PUBLIC)
|
||||
dst_type = ADDR_LE_DEV_PUBLIC;
|
||||
else
|
||||
dst_type = ADDR_LE_DEV_RANDOM;
|
||||
|
||||
memset(cp, 0, sizeof(*cp));
|
||||
cp->sid = sid;
|
||||
cp->addr_type = dst_type;
|
||||
bacpy(&cp->addr, dst);
|
||||
|
@ -2660,7 +2660,7 @@ int hci_register_dev(struct hci_dev *hdev)
|
||||
|
||||
error = hci_register_suspend_notifier(hdev);
|
||||
if (error)
|
||||
goto err_wqueue;
|
||||
BT_WARN("register suspend notifier failed error:%d\n", error);
|
||||
|
||||
queue_work(hdev->req_workqueue, &hdev->power_on);
|
||||
|
||||
@ -3985,7 +3985,7 @@ void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status,
|
||||
*req_complete_skb = bt_cb(skb)->hci.req_complete_skb;
|
||||
else
|
||||
*req_complete = bt_cb(skb)->hci.req_complete;
|
||||
kfree_skb(skb);
|
||||
dev_kfree_skb_irq(skb);
|
||||
}
|
||||
spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
|
||||
}
|
||||
|
@ -757,7 +757,7 @@ static ssize_t force_static_address_write(struct file *file,
|
||||
bool enable;
|
||||
int err;
|
||||
|
||||
if (test_bit(HCI_UP, &hdev->flags))
|
||||
if (hdev_is_powered(hdev))
|
||||
return -EBUSY;
|
||||
|
||||
err = kstrtobool_from_user(user_buf, count, &enable);
|
||||
|
@ -801,9 +801,6 @@ static u8 hci_cc_write_auth_payload_timeout(struct hci_dev *hdev, void *data,
|
||||
|
||||
bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
|
||||
|
||||
if (rp->status)
|
||||
return rp->status;
|
||||
|
||||
sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_PAYLOAD_TO);
|
||||
if (!sent)
|
||||
return rp->status;
|
||||
@ -811,9 +808,17 @@ static u8 hci_cc_write_auth_payload_timeout(struct hci_dev *hdev, void *data,
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
|
||||
if (conn)
|
||||
if (!conn) {
|
||||
rp->status = 0xff;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (!rp->status)
|
||||
conn->auth_payload_timeout = get_unaligned_le16(sent + 2);
|
||||
|
||||
hci_encrypt_cfm(conn, 0);
|
||||
|
||||
unlock:
|
||||
hci_dev_unlock(hdev);
|
||||
|
||||
return rp->status;
|
||||
@ -3680,8 +3685,13 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, void *data,
|
||||
|
||||
cp.handle = cpu_to_le16(conn->handle);
|
||||
cp.timeout = cpu_to_le16(hdev->auth_payload_timeout);
|
||||
hci_send_cmd(conn->hdev, HCI_OP_WRITE_AUTH_PAYLOAD_TO,
|
||||
sizeof(cp), &cp);
|
||||
if (hci_send_cmd(conn->hdev, HCI_OP_WRITE_AUTH_PAYLOAD_TO,
|
||||
sizeof(cp), &cp)) {
|
||||
bt_dev_err(hdev, "write auth payload timeout failed");
|
||||
goto notify;
|
||||
}
|
||||
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
notify:
|
||||
@ -6494,7 +6504,7 @@ static void hci_le_ext_adv_report_evt(struct hci_dev *hdev, void *data,
|
||||
info->length))
|
||||
break;
|
||||
|
||||
evt_type = __le16_to_cpu(info->type);
|
||||
evt_type = __le16_to_cpu(info->type) & LE_EXT_ADV_EVT_TYPE_MASK;
|
||||
legacy_evt_type = ext_evt_type_to_legacy(hdev, evt_type);
|
||||
if (legacy_evt_type != LE_ADV_INVALID) {
|
||||
process_adv_report(hdev, legacy_evt_type, &info->bdaddr,
|
||||
|
@ -3055,6 +3055,7 @@ int hci_update_name_sync(struct hci_dev *hdev)
|
||||
* Enable Authentication
|
||||
* lmp_bredr_capable(Set Fast Connectable -> Set Scan Type -> Set Class ->
|
||||
* Set Name -> Set EIR)
|
||||
* HCI_FORCE_STATIC_ADDR | BDADDR_ANY && !HCI_BREDR_ENABLED (Set Static Address)
|
||||
*/
|
||||
int hci_powered_update_sync(struct hci_dev *hdev)
|
||||
{
|
||||
@ -3094,6 +3095,23 @@ int hci_powered_update_sync(struct hci_dev *hdev)
|
||||
hci_update_eir_sync(hdev);
|
||||
}
|
||||
|
||||
/* If forcing static address is in use or there is no public
|
||||
* address use the static address as random address (but skip
|
||||
* the HCI command if the current random address is already the
|
||||
* static one.
|
||||
*
|
||||
* In case BR/EDR has been disabled on a dual-mode controller
|
||||
* and a static address has been configured, then use that
|
||||
* address instead of the public BR/EDR address.
|
||||
*/
|
||||
if (hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) ||
|
||||
(!bacmp(&hdev->bdaddr, BDADDR_ANY) &&
|
||||
!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))) {
|
||||
if (bacmp(&hdev->static_addr, BDADDR_ANY))
|
||||
return hci_set_random_addr_sync(hdev,
|
||||
&hdev->static_addr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -4261,7 +4279,7 @@ static int hci_read_local_pairing_opts_sync(struct hci_dev *hdev)
|
||||
/* Get MWS transport configuration if the HCI command is supported */
|
||||
static int hci_get_mws_transport_config_sync(struct hci_dev *hdev)
|
||||
{
|
||||
if (!(hdev->commands[30] & 0x08))
|
||||
if (!mws_transport_config_capable(hdev))
|
||||
return 0;
|
||||
|
||||
return __hci_cmd_sync_status(hdev, HCI_OP_GET_MWS_TRANSPORT_CONFIG,
|
||||
@ -4703,6 +4721,7 @@ int hci_dev_open_sync(struct hci_dev *hdev)
|
||||
hdev->flush(hdev);
|
||||
|
||||
if (hdev->sent_cmd) {
|
||||
cancel_delayed_work_sync(&hdev->cmd_timer);
|
||||
kfree_skb(hdev->sent_cmd);
|
||||
hdev->sent_cmd = NULL;
|
||||
}
|
||||
|
@ -261,36 +261,42 @@ static int iso_connect_bis(struct sock *sk)
|
||||
|
||||
if (!bis_capable(hdev)) {
|
||||
err = -EOPNOTSUPP;
|
||||
goto done;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
/* Fail if out PHYs are marked as disabled */
|
||||
if (!iso_pi(sk)->qos.out.phy) {
|
||||
err = -EINVAL;
|
||||
goto done;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
hcon = hci_connect_bis(hdev, &iso_pi(sk)->dst, iso_pi(sk)->dst_type,
|
||||
hcon = hci_connect_bis(hdev, &iso_pi(sk)->dst,
|
||||
le_addr_type(iso_pi(sk)->dst_type),
|
||||
&iso_pi(sk)->qos, iso_pi(sk)->base_len,
|
||||
iso_pi(sk)->base);
|
||||
if (IS_ERR(hcon)) {
|
||||
err = PTR_ERR(hcon);
|
||||
goto done;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
conn = iso_conn_add(hcon);
|
||||
if (!conn) {
|
||||
hci_conn_drop(hcon);
|
||||
err = -ENOMEM;
|
||||
goto done;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
hci_dev_unlock(hdev);
|
||||
hci_dev_put(hdev);
|
||||
|
||||
lock_sock(sk);
|
||||
|
||||
/* Update source addr of the socket */
|
||||
bacpy(&iso_pi(sk)->src, &hcon->src);
|
||||
|
||||
err = iso_chan_add(conn, sk, NULL);
|
||||
if (err)
|
||||
goto done;
|
||||
goto release;
|
||||
|
||||
if (hcon->state == BT_CONNECTED) {
|
||||
iso_sock_clear_timer(sk);
|
||||
@ -300,7 +306,11 @@ static int iso_connect_bis(struct sock *sk)
|
||||
iso_sock_set_timer(sk, sk->sk_sndtimeo);
|
||||
}
|
||||
|
||||
done:
|
||||
release:
|
||||
release_sock(sk);
|
||||
return err;
|
||||
|
||||
unlock:
|
||||
hci_dev_unlock(hdev);
|
||||
hci_dev_put(hdev);
|
||||
return err;
|
||||
@ -324,13 +334,13 @@ static int iso_connect_cis(struct sock *sk)
|
||||
|
||||
if (!cis_central_capable(hdev)) {
|
||||
err = -EOPNOTSUPP;
|
||||
goto done;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
/* Fail if either PHYs are marked as disabled */
|
||||
if (!iso_pi(sk)->qos.in.phy && !iso_pi(sk)->qos.out.phy) {
|
||||
err = -EINVAL;
|
||||
goto done;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
/* Just bind if DEFER_SETUP has been set */
|
||||
@ -340,7 +350,7 @@ static int iso_connect_cis(struct sock *sk)
|
||||
&iso_pi(sk)->qos);
|
||||
if (IS_ERR(hcon)) {
|
||||
err = PTR_ERR(hcon);
|
||||
goto done;
|
||||
goto unlock;
|
||||
}
|
||||
} else {
|
||||
hcon = hci_connect_cis(hdev, &iso_pi(sk)->dst,
|
||||
@ -348,7 +358,7 @@ static int iso_connect_cis(struct sock *sk)
|
||||
&iso_pi(sk)->qos);
|
||||
if (IS_ERR(hcon)) {
|
||||
err = PTR_ERR(hcon);
|
||||
goto done;
|
||||
goto unlock;
|
||||
}
|
||||
}
|
||||
|
||||
@ -356,15 +366,20 @@ static int iso_connect_cis(struct sock *sk)
|
||||
if (!conn) {
|
||||
hci_conn_drop(hcon);
|
||||
err = -ENOMEM;
|
||||
goto done;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
hci_dev_unlock(hdev);
|
||||
hci_dev_put(hdev);
|
||||
|
||||
lock_sock(sk);
|
||||
|
||||
/* Update source addr of the socket */
|
||||
bacpy(&iso_pi(sk)->src, &hcon->src);
|
||||
|
||||
err = iso_chan_add(conn, sk, NULL);
|
||||
if (err)
|
||||
goto done;
|
||||
goto release;
|
||||
|
||||
if (hcon->state == BT_CONNECTED) {
|
||||
iso_sock_clear_timer(sk);
|
||||
@ -377,7 +392,11 @@ static int iso_connect_cis(struct sock *sk)
|
||||
iso_sock_set_timer(sk, sk->sk_sndtimeo);
|
||||
}
|
||||
|
||||
done:
|
||||
release:
|
||||
release_sock(sk);
|
||||
return err;
|
||||
|
||||
unlock:
|
||||
hci_dev_unlock(hdev);
|
||||
hci_dev_put(hdev);
|
||||
return err;
|
||||
@ -831,20 +850,23 @@ static int iso_sock_connect(struct socket *sock, struct sockaddr *addr,
|
||||
bacpy(&iso_pi(sk)->dst, &sa->iso_bdaddr);
|
||||
iso_pi(sk)->dst_type = sa->iso_bdaddr_type;
|
||||
|
||||
release_sock(sk);
|
||||
|
||||
if (bacmp(&iso_pi(sk)->dst, BDADDR_ANY))
|
||||
err = iso_connect_cis(sk);
|
||||
else
|
||||
err = iso_connect_bis(sk);
|
||||
|
||||
if (err)
|
||||
goto done;
|
||||
return err;
|
||||
|
||||
lock_sock(sk);
|
||||
|
||||
if (!test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
|
||||
err = bt_sock_wait_state(sk, BT_CONNECTED,
|
||||
sock_sndtimeo(sk, flags & O_NONBLOCK));
|
||||
}
|
||||
|
||||
done:
|
||||
release_sock(sk);
|
||||
return err;
|
||||
}
|
||||
@ -875,7 +897,8 @@ static int iso_listen_bis(struct sock *sk)
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
err = hci_pa_create_sync(hdev, &iso_pi(sk)->dst, iso_pi(sk)->dst_type,
|
||||
err = hci_pa_create_sync(hdev, &iso_pi(sk)->dst,
|
||||
le_addr_type(iso_pi(sk)->dst_type),
|
||||
iso_pi(sk)->bc_sid);
|
||||
|
||||
hci_dev_unlock(hdev);
|
||||
@ -1099,28 +1122,22 @@ static int iso_sock_recvmsg(struct socket *sock, struct msghdr *msg,
|
||||
{
|
||||
struct sock *sk = sock->sk;
|
||||
struct iso_pinfo *pi = iso_pi(sk);
|
||||
int err;
|
||||
|
||||
BT_DBG("sk %p", sk);
|
||||
|
||||
lock_sock(sk);
|
||||
|
||||
if (test_and_clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
|
||||
switch (sk->sk_state) {
|
||||
case BT_CONNECT2:
|
||||
lock_sock(sk);
|
||||
iso_conn_defer_accept(pi->conn->hcon);
|
||||
sk->sk_state = BT_CONFIG;
|
||||
release_sock(sk);
|
||||
return 0;
|
||||
case BT_CONNECT:
|
||||
err = iso_connect_cis(sk);
|
||||
release_sock(sk);
|
||||
return err;
|
||||
return iso_connect_cis(sk);
|
||||
}
|
||||
}
|
||||
|
||||
release_sock(sk);
|
||||
|
||||
return bt_sock_recvmsg(sock, msg, len, flags);
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@
|
||||
#define LE_FLOWCTL_MAX_CREDITS 65535
|
||||
|
||||
bool disable_ertm;
|
||||
bool enable_ecred;
|
||||
bool enable_ecred = IS_ENABLED(CONFIG_BT_LE_L2CAP_ECRED);
|
||||
|
||||
static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN | L2CAP_FEAT_UCD;
|
||||
|
||||
|
@ -170,7 +170,7 @@ __u8 bt_status(int err)
|
||||
case -EMLINK:
|
||||
return 0x09;
|
||||
|
||||
case EALREADY:
|
||||
case -EALREADY:
|
||||
return 0x0b;
|
||||
|
||||
case -EBUSY:
|
||||
@ -191,7 +191,7 @@ __u8 bt_status(int err)
|
||||
case -ECONNABORTED:
|
||||
return 0x16;
|
||||
|
||||
case ELOOP:
|
||||
case -ELOOP:
|
||||
return 0x17;
|
||||
|
||||
case -EPROTONOSUPPORT:
|
||||
|
@ -8859,7 +8859,7 @@ static int add_ext_adv_params(struct sock *sk, struct hci_dev *hdev,
|
||||
* extra parameters we don't know about will be ignored in this request.
|
||||
*/
|
||||
if (data_len < MGMT_ADD_EXT_ADV_PARAMS_MIN_SIZE)
|
||||
return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING,
|
||||
return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_EXT_ADV_PARAMS,
|
||||
MGMT_STATUS_INVALID_PARAMS);
|
||||
|
||||
flags = __le32_to_cpu(cp->flags);
|
||||
|
@ -590,7 +590,7 @@ int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb)
|
||||
|
||||
ret = rfcomm_dlc_send_frag(d, frag);
|
||||
if (ret < 0) {
|
||||
kfree_skb(frag);
|
||||
dev_kfree_skb_irq(frag);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user