Commit 6cd35888 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'for-upstream' of...

Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next



Johan Hedberg says:

====================
pull request: bluetooth-next 2020-05-13

Here's a second attempt at a bluetooth-next pull request which
supercedes the one dated 2020-05-09. This should have the issues
discovered by Jakub fixed.

 - Add support for Intel Typhoon Peak device (8087:0032)
 - Add device tree bindings for Realtek RTL8723BS device
 - Add device tree bindings for Qualcomm QCA9377 device
 - Add support for experimental features configuration through mgmt
 - Add driver hook to prevent wake from suspend
 - Add support for waiting for L2CAP disconnection response
 - Multiple fixes & cleanups to the btbcm driver
 - Add support for LE scatternet topology for selected devices
 - A few other smaller fixes & cleanups

Please let me know if there are any issues pulling. Thanks.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents b41dc4ae 5b440676
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@ device the slave device is attached to.
Required properties:
 - compatible: should contain one of the following:
   * "qcom,qca6174-bt"
   * "qcom,qca9377-bt"
   * "qcom,wcn3990-bt"
   * "qcom,wcn3991-bt"
   * "qcom,wcn3998-bt"
@@ -21,6 +22,10 @@ Optional properties for compatible string qcom,qca6174-bt:
 - clocks: clock provided to the controller (SUSCLK_32KHZ)
 - firmware-name: specify the name of nvm firmware to load

Optional properties for compatible string qcom,qca9377-bt:

 - max-speed: see Documentation/devicetree/bindings/serial/serial.yaml

Required properties for compatible string qcom,wcn399x-bt:

 - vddio-supply: VDD_IO supply regulator handle.
+54 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/net/realtek-bluetooth.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: RTL8723BS/RTL8723CS/RTL8822CS Bluetooth Device Tree Bindings

maintainers:
  - Vasily Khoruzhick <anarsoul@gmail.com>
  - Alistair Francis <alistair@alistair23.me>

description:
  RTL8723CS/RTL8723CS/RTL8822CS is WiFi + BT chip. WiFi part is connected over
  SDIO, while BT is connected over serial. It speaks H5 protocol with few
  extra commands to upload firmware and change module speed.

properties:
  compatible:
    oneOf:
      - const: "realtek,rtl8723bs-bt"
      - const: "realtek,rtl8723cs-bt"
      - const: "realtek,rtl8822cs-bt"

  device-wake-gpios:
    maxItems: 1
    description: GPIO specifier, used to wakeup the BT module

  enable-gpios:
    maxItems: 1
    description: GPIO specifier, used to enable the BT module

  host-wake-gpios:
    maxItems: 1
    description: GPIO specifier, used to wakeup the host processor

required:
  - compatible

examples:
  - |
    #include <dt-bindings/gpio/gpio.h>

    uart1 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
        uart-has-rtscts = <1>;

        bluetooth {
            compatible = "realtek,rtl8723bs-bt";
            device-wake-gpios = <&r_pio 0 5 GPIO_ACTIVE_HIGH>; /* PL5 */
            host-wakeup-gpios = <&r_pio 0 6 GPIO_ACTIVE_HIGH>; /* PL6 */
        };
    };
+79 −60
Original line number Diff line number Diff line
@@ -27,6 +27,11 @@
#define BDADDR_BCM4345C5 (&(bdaddr_t) {{0xac, 0x1f, 0x00, 0xc5, 0x45, 0x43}})
#define BDADDR_BCM43341B (&(bdaddr_t) {{0xac, 0x1f, 0x00, 0x1b, 0x34, 0x43}})

#define BCM_FW_NAME_LEN			64
#define BCM_FW_NAME_COUNT_MAX		2
/* For kmalloc-ing the fw-name array instead of putting it on the stack */
typedef char bcm_fw_name[BCM_FW_NAME_LEN];

int btbcm_check_bdaddr(struct hci_dev *hdev)
{
	struct hci_rp_read_bd_addr *bda;
@@ -358,6 +363,13 @@ static int btbcm_read_info(struct hci_dev *hdev)
	bt_dev_info(hdev, "BCM: features 0x%2.2x", skb->data[1]);
	kfree_skb(skb);

	return 0;
}

static int btbcm_print_local_name(struct hci_dev *hdev)
{
	struct sk_buff *skb;

	/* Read Local Name */
	skb = btbcm_read_local_name(hdev);
	if (IS_ERR(skb))
@@ -380,6 +392,7 @@ static const struct bcm_subver_table bcm_uart_subver_table[] = {
	{ 0x410e, "BCM43341B0"	},	/* 002.001.014 */
	{ 0x4204, "BCM2076B1"	},	/* 002.002.004 */
	{ 0x4406, "BCM4324B3"	},	/* 002.004.006 */
	{ 0x4606, "BCM4324B5"	},	/* 002.006.006 */
	{ 0x6109, "BCM4335C0"	},	/* 003.001.009 */
	{ 0x610c, "BCM4354"	},	/* 003.001.012 */
	{ 0x2122, "BCM4343A0"	},	/* 001.001.034 */
@@ -395,6 +408,7 @@ static const struct bcm_subver_table bcm_uart_subver_table[] = {
};

static const struct bcm_subver_table bcm_usb_subver_table[] = {
	{ 0x2105, "BCM20703A1"	},	/* 001.001.005 */
	{ 0x210b, "BCM43142A0"	},	/* 001.001.011 */
	{ 0x2112, "BCM4314A0"	},	/* 001.001.018 */
	{ 0x2118, "BCM20702A0"	},	/* 001.001.024 */
@@ -408,14 +422,17 @@ static const struct bcm_subver_table bcm_usb_subver_table[] = {
	{ }
};

int btbcm_initialize(struct hci_dev *hdev, char *fw_name, size_t len,
		     bool reinit)
int btbcm_initialize(struct hci_dev *hdev, bool *fw_load_done)
{
	u16 subver, rev, pid, vid;
	const char *hw_name = "BCM";
	struct sk_buff *skb;
	struct hci_rp_read_local_version *ver;
	const struct bcm_subver_table *bcm_subver_table;
	const char *hw_name = NULL;
	char postfix[16] = "";
	int fw_name_count = 0;
	bcm_fw_name *fw_name;
	const struct firmware *fw;
	int i, err;

	/* Reset */
@@ -434,15 +451,14 @@ int btbcm_initialize(struct hci_dev *hdev, char *fw_name, size_t len,
	kfree_skb(skb);

	/* Read controller information */
	if (!reinit) {
	if (!(*fw_load_done)) {
		err = btbcm_read_info(hdev);
		if (err)
			return err;
	}

	/* Upper nibble of rev should be between 0 and 3? */
	if (((rev & 0xf000) >> 12) > 3)
		return 0;
	err = btbcm_print_local_name(hdev);
	if (err)
		return err;

	bcm_subver_table = (hdev->bus == HCI_USB) ? bcm_usb_subver_table :
						    bcm_uart_subver_table;
@@ -454,6 +470,13 @@ int btbcm_initialize(struct hci_dev *hdev, char *fw_name, size_t len,
		}
	}

	bt_dev_info(hdev, "%s (%3.3u.%3.3u.%3.3u) build %4.4u",
		    hw_name ? hw_name : "BCM", (subver & 0xe000) >> 13,
		    (subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff);

	if (*fw_load_done)
		return 0;

	if (hdev->bus == HCI_USB) {
		/* Read USB Product Info */
		skb = btbcm_read_usb_product(hdev);
@@ -464,85 +487,81 @@ int btbcm_initialize(struct hci_dev *hdev, char *fw_name, size_t len,
		pid = get_unaligned_le16(skb->data + 3);
		kfree_skb(skb);

		snprintf(fw_name, len, "brcm/%s-%4.4x-%4.4x.hcd",
			 hw_name, vid, pid);
	} else {
		snprintf(fw_name, len, "brcm/%s.hcd", hw_name);
		snprintf(postfix, sizeof(postfix), "-%4.4x-%4.4x", vid, pid);
	}

	bt_dev_info(hdev, "%s (%3.3u.%3.3u.%3.3u) build %4.4u",
		    hw_name, (subver & 0xe000) >> 13,
		    (subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff);
	fw_name = kmalloc(BCM_FW_NAME_COUNT_MAX * BCM_FW_NAME_LEN, GFP_KERNEL);
	if (!fw_name)
		return -ENOMEM;

	if (hw_name) {
		snprintf(fw_name[fw_name_count], BCM_FW_NAME_LEN,
			 "brcm/%s%s.hcd", hw_name, postfix);
		fw_name_count++;
	}

	snprintf(fw_name[fw_name_count], BCM_FW_NAME_LEN,
		 "brcm/BCM%s.hcd", postfix);
	fw_name_count++;

	for (i = 0; i < fw_name_count; i++) {
		err = firmware_request_nowarn(&fw, fw_name[i], &hdev->dev);
		if (err == 0) {
			bt_dev_info(hdev, "%s '%s' Patch",
				    hw_name ? hw_name : "BCM", fw_name[i]);
			*fw_load_done = true;
			break;
		}
	}

	if (*fw_load_done) {
		err = btbcm_patchram(hdev, fw);
		if (err)
			bt_dev_info(hdev, "BCM: Patch failed (%d)", err);

		release_firmware(fw);
	} else {
		bt_dev_err(hdev, "BCM: firmware Patch file not found, tried:");
		for (i = 0; i < fw_name_count; i++)
			bt_dev_err(hdev, "BCM: '%s'", fw_name[i]);
	}

	kfree(fw_name);
	return 0;
}
EXPORT_SYMBOL_GPL(btbcm_initialize);

int btbcm_finalize(struct hci_dev *hdev)
int btbcm_finalize(struct hci_dev *hdev, bool *fw_load_done)
{
	char fw_name[64];
	int err;

	/* Re-initialize */
	err = btbcm_initialize(hdev, fw_name, sizeof(fw_name), true);
	/* Re-initialize if necessary */
	if (*fw_load_done) {
		err = btbcm_initialize(hdev, fw_load_done);
		if (err)
			return err;
	}

	btbcm_check_bdaddr(hdev);

	set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);

	/* Some devices ship with the controller default address.
	 * Allow the bootloader to set a valid address through the
	 * device tree.
	 */
	set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks);

	return 0;
}
EXPORT_SYMBOL_GPL(btbcm_finalize);

int btbcm_setup_patchram(struct hci_dev *hdev)
{
	char fw_name[64];
	const struct firmware *fw;
	struct sk_buff *skb;
	bool fw_load_done = false;
	int err;

	/* Initialize */
	err = btbcm_initialize(hdev, fw_name, sizeof(fw_name), false);
	if (err)
		return err;

	err = request_firmware(&fw, fw_name, &hdev->dev);
	if (err < 0) {
		bt_dev_info(hdev, "BCM: Patch %s not found", fw_name);
		goto done;
	}

	btbcm_patchram(hdev, fw);

	release_firmware(fw);

	/* Re-initialize */
	err = btbcm_initialize(hdev, fw_name, sizeof(fw_name), true);
	err = btbcm_initialize(hdev, &fw_load_done);
	if (err)
		return err;

	/* Read Local Name */
	skb = btbcm_read_local_name(hdev);
	if (IS_ERR(skb))
		return PTR_ERR(skb);

	bt_dev_info(hdev, "%s", (char *)(skb->data + 1));
	kfree_skb(skb);

done:
	btbcm_check_bdaddr(hdev);

	set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);

	return 0;
	/* Re-initialize after loading Patch */
	return btbcm_finalize(hdev, &fw_load_done);
}
EXPORT_SYMBOL_GPL(btbcm_setup_patchram);

+4 −6
Original line number Diff line number Diff line
@@ -62,9 +62,8 @@ int btbcm_write_pcm_int_params(struct hci_dev *hdev,
int btbcm_setup_patchram(struct hci_dev *hdev);
int btbcm_setup_apple(struct hci_dev *hdev);

int btbcm_initialize(struct hci_dev *hdev, char *fw_name, size_t len,
		     bool reinit);
int btbcm_finalize(struct hci_dev *hdev);
int btbcm_initialize(struct hci_dev *hdev, bool *fw_load_done);
int btbcm_finalize(struct hci_dev *hdev, bool *fw_load_done);

#else

@@ -105,13 +104,12 @@ static inline int btbcm_setup_apple(struct hci_dev *hdev)
	return 0;
}

static inline int btbcm_initialize(struct hci_dev *hdev, char *fw_name,
				   size_t len, bool reinit)
static inline int btbcm_initialize(struct hci_dev *hdev, bool *fw_load_done)
{
	return 0;
}

static inline int btbcm_finalize(struct hci_dev *hdev)
static inline int btbcm_finalize(struct hci_dev *hdev, bool *fw_load_done)
{
	return 0;
}
+18 −2
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ static struct usb_driver btusb_driver;
#define BTUSB_CW6622		0x100000
#define BTUSB_MEDIATEK		0x200000
#define BTUSB_WIDEBAND_SPEECH	0x400000
#define BTUSB_VALID_LE_STATES   0x800000

static const struct usb_device_id btusb_table[] = {
	/* Generic Bluetooth USB device */
@@ -335,11 +336,14 @@ static const struct usb_device_id blacklist_table[] = {

	/* Intel Bluetooth devices */
	{ USB_DEVICE(0x8087, 0x0025), .driver_info = BTUSB_INTEL_NEW |
						     BTUSB_WIDEBAND_SPEECH },
						     BTUSB_WIDEBAND_SPEECH |
						     BTUSB_VALID_LE_STATES },
	{ USB_DEVICE(0x8087, 0x0026), .driver_info = BTUSB_INTEL_NEW |
						     BTUSB_WIDEBAND_SPEECH },
	{ USB_DEVICE(0x8087, 0x0029), .driver_info = BTUSB_INTEL_NEW |
						     BTUSB_WIDEBAND_SPEECH },
	{ USB_DEVICE(0x8087, 0x0032), .driver_info = BTUSB_INTEL_NEW |
						     BTUSB_WIDEBAND_SPEECH},
	{ USB_DEVICE(0x8087, 0x07da), .driver_info = BTUSB_CSR },
	{ USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL },
	{ USB_DEVICE(0x8087, 0x0a2a), .driver_info = BTUSB_INTEL },
@@ -348,7 +352,8 @@ static const struct usb_device_id blacklist_table[] = {
	{ USB_DEVICE(0x8087, 0x0aa7), .driver_info = BTUSB_INTEL |
						     BTUSB_WIDEBAND_SPEECH },
	{ USB_DEVICE(0x8087, 0x0aaa), .driver_info = BTUSB_INTEL_NEW |
						     BTUSB_WIDEBAND_SPEECH },
						     BTUSB_WIDEBAND_SPEECH |
						     BTUSB_VALID_LE_STATES },

	/* Other Intel Bluetooth devices */
	{ USB_VENDOR_AND_INTERFACE_INFO(0x8087, 0xe0, 0x01, 0x01),
@@ -3695,6 +3700,13 @@ static void btusb_check_needs_reset_resume(struct usb_interface *intf)
		interface_to_usbdev(intf)->quirks |= USB_QUIRK_RESET_RESUME;
}

static bool btusb_prevent_wake(struct hci_dev *hdev)
{
	struct btusb_data *data = hci_get_drvdata(hdev);

	return !device_may_wakeup(&data->udev->dev);
}

static int btusb_probe(struct usb_interface *intf,
		       const struct usb_device_id *id)
{
@@ -3828,6 +3840,7 @@ static int btusb_probe(struct usb_interface *intf,
	hdev->flush  = btusb_flush;
	hdev->send   = btusb_send_frame;
	hdev->notify = btusb_notify;
	hdev->prevent_wake = btusb_prevent_wake;

#ifdef CONFIG_PM
	err = btusb_config_oob_wake(hdev);
@@ -3972,6 +3985,9 @@ static int btusb_probe(struct usb_interface *intf,
	if (id->driver_info & BTUSB_WIDEBAND_SPEECH)
		set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);

	if (id->driver_info & BTUSB_VALID_LE_STATES)
		set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);

	if (id->driver_info & BTUSB_DIGIANSWER) {
		data->cmdreq_type = USB_TYPE_VENDOR;
		set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
Loading