Commit b1e6738a authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge tag 'for-net-next-2022-05-23' of...

Merge tag 'for-net-next-2022-05-23' 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 support for Realtek 8761BUV
 - Add HCI_QUIRK_BROKEN_ENHANCED_SETUP_SYNC_CONN quirk
 - Add support for RTL8852C
 - Add a new PID/VID 0489/e0c8 for MT7921
 - Add support for Qualcomm WCN785x

* tag 'for-net-next-2022-05-23' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next: (26 commits)
  Bluetooth: hci_sync: use hci_skb_event() helper
  Bluetooth: eir: Add helpers for managing service data
  Bluetooth: hci_sync: Fix attempting to suspend with unfiltered passive scan
  Bluetooth: MGMT: Add conditions for setting HCI_CONN_FLAG_REMOTE_WAKEUP
  Bluetooth: btmtksdio: fix the reset takes too long
  Bluetooth: btmtksdio: fix possible FW initialization failure
  Bluetooth: btmtksdio: fix use-after-free at btmtksdio_recv_event
  Bluetooth: btbcm: Add entry for BCM4373A0 UART Bluetooth
  Bluetooth: btusb: Add a new PID/VID 0489/e0c8 for MT7921
  Bluetooth: btusb: Add 0x0bda:0x8771 Realtek 8761BUV devices
  Bluetooth: btusb: Set HCI_QUIRK_BROKEN_ERR_DATA_REPORTING for QCA
  Bluetooth: core: Fix missing power_on work cancel on HCI close
  Bluetooth: btusb: add support for Qualcomm WCN785x
  Bluetooth: protect le accept and resolv lists with hdev->lock
  Bluetooth: use hdev lock for accept_list and reject_list in conn req
  Bluetooth: use hdev lock in activate_scan for hci_is_adv_monitoring
  Bluetooth: btrtl: Add support for RTL8852C
  Bluetooth: btusb: Set HCI_QUIRK_BROKEN_ENHANCED_SETUP_SYNC_CONN for QCA
  Bluetooth: Print broken quirks
  Bluetooth: HCI: Add HCI_QUIRK_BROKEN_ENHANCED_SETUP_SYNC_CONN quirk
  ...
====================

Link: https://lore.kernel.org/r/20220523204151.3327345-1-luiz.dentz@gmail.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents fe7324b9 edcb185f
Loading
Loading
Loading
Loading
+52 −1
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
#include <linux/module.h>
#include <linux/firmware.h>
#include <linux/dmi.h>
#include <linux/of.h>
#include <asm/unaligned.h>

#include <net/bluetooth/bluetooth.h>
@@ -29,7 +30,7 @@
#define BDADDR_BCM43341B (&(bdaddr_t) {{0xac, 0x1f, 0x00, 0x1b, 0x34, 0x43}})

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

@@ -457,6 +458,7 @@ static const struct bcm_subver_table bcm_uart_subver_table[] = {
	{ 0x6106, "BCM4359C0"	},	/* 003.001.006 */
	{ 0x4106, "BCM4335A0"	},	/* 002.001.006 */
	{ 0x410c, "BCM43430B0"	},	/* 002.001.012 */
	{ 0x2119, "BCM4373A0"	},	/* 001.001.025 */
	{ }
};

@@ -476,6 +478,42 @@ static const struct bcm_subver_table bcm_usb_subver_table[] = {
	{ }
};

/*
 * This currently only looks up the device tree board appendix,
 * but can be expanded to other mechanisms.
 */
static const char *btbcm_get_board_name(struct device *dev)
{
#ifdef CONFIG_OF
	struct device_node *root;
	char *board_type;
	const char *tmp;
	int len;
	int i;

	root = of_find_node_by_path("/");
	if (!root)
		return NULL;

	if (of_property_read_string_index(root, "compatible", 0, &tmp))
		return NULL;

	/* get rid of any '/' in the compatible string */
	len = strlen(tmp) + 1;
	board_type = devm_kzalloc(dev, len, GFP_KERNEL);
	strscpy(board_type, tmp, len);
	for (i = 0; i < board_type[i]; i++) {
		if (board_type[i] == '/')
			board_type[i] = '-';
	}
	of_node_put(root);

	return board_type;
#else
	return NULL;
#endif
}

int btbcm_initialize(struct hci_dev *hdev, bool *fw_load_done)
{
	u16 subver, rev, pid, vid;
@@ -483,12 +521,15 @@ int btbcm_initialize(struct hci_dev *hdev, bool *fw_load_done)
	struct hci_rp_read_local_version *ver;
	const struct bcm_subver_table *bcm_subver_table;
	const char *hw_name = NULL;
	const char *board_name;
	char postfix[16] = "";
	int fw_name_count = 0;
	bcm_fw_name *fw_name;
	const struct firmware *fw;
	int i, err;

	board_name = btbcm_get_board_name(&hdev->dev);

	/* Reset */
	err = btbcm_reset(hdev);
	if (err)
@@ -549,11 +590,21 @@ int btbcm_initialize(struct hci_dev *hdev, bool *fw_load_done)
		return -ENOMEM;

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

	if (board_name) {
		snprintf(fw_name[fw_name_count], BCM_FW_NAME_LEN,
			 "brcm/BCM%s.%s.hcd", postfix, board_name);
		fw_name_count++;
	}
	snprintf(fw_name[fw_name_count], BCM_FW_NAME_LEN,
		 "brcm/BCM%s.hcd", postfix);
	fw_name_count++;
+1 −1
Original line number Diff line number Diff line
@@ -794,7 +794,7 @@ static void regmap_ibt_free_context(void *context)
	kfree(context);
}

static struct regmap_bus regmap_ibt = {
static const struct regmap_bus regmap_ibt = {
	.read = regmap_ibt_read,
	.write = regmap_ibt_write,
	.gather_write = regmap_ibt_gather_write,
+16 −10
Original line number Diff line number Diff line
@@ -379,6 +379,7 @@ static int btmtksdio_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
{
	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
	struct hci_event_hdr *hdr = (void *)skb->data;
	u8 evt = hdr->evt;
	int err;

	/* When someone waits for the WMT event, the skb is being cloned
@@ -396,7 +397,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_WMT) {
	if (evt == HCI_EV_WMT) {
		if (test_and_clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT,
				       &bdev->tx_state)) {
			/* Barrier to sync with other CPUs */
@@ -863,6 +864,14 @@ static int mt79xx_setup(struct hci_dev *hdev, const char *fwname)
		return err;
	}

	err = btmtksdio_fw_pmctrl(bdev);
	if (err < 0)
		return err;

	err = btmtksdio_drv_pmctrl(bdev);
	if (err < 0)
		return err;

	/* Enable Bluetooth protocol */
	wmt_params.op = BTMTK_WMT_FUNC_CTRL;
	wmt_params.flag = 0;
@@ -961,7 +970,7 @@ static int btmtksdio_get_codec_config_data(struct hci_dev *hdev,
	}

	*ven_data = kmalloc(sizeof(__u8), GFP_KERNEL);
	if (!ven_data) {
	if (!*ven_data) {
		err = -ENOMEM;
		goto error;
	}
@@ -1108,14 +1117,6 @@ static int btmtksdio_setup(struct hci_dev *hdev)
		if (err < 0)
			return err;

		err = btmtksdio_fw_pmctrl(bdev);
		if (err < 0)
			return err;

		err = btmtksdio_drv_pmctrl(bdev);
		if (err < 0)
			return err;

		/* Enable SCO over I2S/PCM */
		err = btmtksdio_sco_setting(hdev);
		if (err < 0) {
@@ -1188,6 +1189,10 @@ static int btmtksdio_shutdown(struct hci_dev *hdev)
	 */
	pm_runtime_get_sync(bdev->dev);

	/* wmt command only works until the reset is complete */
	if (test_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state))
		goto ignore_wmt_cmd;

	/* Disable the device */
	wmt_params.op = BTMTK_WMT_FUNC_CTRL;
	wmt_params.flag = 0;
@@ -1201,6 +1206,7 @@ static int btmtksdio_shutdown(struct hci_dev *hdev)
		return err;
	}

ignore_wmt_cmd:
	pm_runtime_put_noidle(bdev->dev);
	pm_runtime_disable(bdev->dev);

+13 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ enum btrtl_chip_id {
	CHIP_ID_8761B,
	CHIP_ID_8852A = 18,
	CHIP_ID_8852B = 20,
	CHIP_ID_8852C = 25,
};

struct id_table {
@@ -196,6 +197,14 @@ static const struct id_table ic_id_table[] = {
	  .has_msft_ext = true,
	  .fw_name  = "rtl_bt/rtl8852bu_fw.bin",
	  .cfg_name = "rtl_bt/rtl8852bu_config" },

	/* 8852C */
	{ IC_INFO(RTL_ROM_LMP_8852A, 0xc, 0xc, HCI_USB),
	  .config_needed = false,
	  .has_rom_version = true,
	  .has_msft_ext = true,
	  .fw_name  = "rtl_bt/rtl8852cu_fw.bin",
	  .cfg_name = "rtl_bt/rtl8852cu_config" },
	};

static const struct id_table *btrtl_match_ic(u16 lmp_subver, u16 hci_rev,
@@ -305,6 +314,7 @@ static int rtlbt_parse_firmware(struct hci_dev *hdev,
		{ RTL_ROM_LMP_8761A, 14 },	/* 8761B */
		{ RTL_ROM_LMP_8852A, 18 },	/* 8852A */
		{ RTL_ROM_LMP_8852A, 20 },	/* 8852B */
		{ RTL_ROM_LMP_8852A, 25 },	/* 8852C */
	};

	min_size = sizeof(struct rtl_epatch_header) + sizeof(extension_sig) + 3;
@@ -768,6 +778,7 @@ void btrtl_set_quirks(struct hci_dev *hdev, struct btrtl_device_info *btrtl_dev)
	case CHIP_ID_8822C:
	case CHIP_ID_8852A:
	case CHIP_ID_8852B:
	case CHIP_ID_8852C:
		set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
		set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
		hci_set_aosp_capable(hdev);
@@ -947,3 +958,5 @@ MODULE_FIRMWARE("rtl_bt/rtl8852au_fw.bin");
MODULE_FIRMWARE("rtl_bt/rtl8852au_config.bin");
MODULE_FIRMWARE("rtl_bt/rtl8852bu_fw.bin");
MODULE_FIRMWARE("rtl_bt/rtl8852bu_config.bin");
MODULE_FIRMWARE("rtl_bt/rtl8852cu_fw.bin");
MODULE_FIRMWARE("rtl_bt/rtl8852cu_config.bin");
+21 −2
Original line number Diff line number Diff line
@@ -317,6 +317,11 @@ static const struct usb_device_id blacklist_table[] = {
						     BTUSB_WIDEBAND_SPEECH |
						     BTUSB_VALID_LE_STATES },

	/* QCA WCN785x chipset */
	{ USB_DEVICE(0x0cf3, 0xe700), .driver_info = BTUSB_QCA_WCN6855 |
						     BTUSB_WIDEBAND_SPEECH |
						     BTUSB_VALID_LE_STATES },

	/* Broadcom BCM2035 */
	{ USB_DEVICE(0x0a5c, 0x2009), .driver_info = BTUSB_BCM92035 },
	{ USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU },
@@ -446,6 +451,9 @@ static const struct usb_device_id blacklist_table[] = {
						     BTUSB_VALID_LE_STATES },

	/* Additional MediaTek MT7921 Bluetooth devices */
	{ USB_DEVICE(0x0489, 0xe0c8), .driver_info = BTUSB_MEDIATEK |
						     BTUSB_WIDEBAND_SPEECH |
						     BTUSB_VALID_LE_STATES },
	{ USB_DEVICE(0x04ca, 0x3802), .driver_info = BTUSB_MEDIATEK |
						     BTUSB_WIDEBAND_SPEECH |
						     BTUSB_VALID_LE_STATES },
@@ -500,6 +508,10 @@ static const struct usb_device_id blacklist_table[] = {
	{ USB_DEVICE(0x2550, 0x8761), .driver_info = BTUSB_REALTEK |
						     BTUSB_WIDEBAND_SPEECH },

	/* Additional Realtek 8761BUV Bluetooth devices */
	{ USB_DEVICE(0x0bda, 0x8771), .driver_info = BTUSB_REALTEK |
						     BTUSB_WIDEBAND_SPEECH },

	/* Additional Realtek 8821AE Bluetooth devices */
	{ USB_DEVICE(0x0b05, 0x17dc), .driver_info = BTUSB_REALTEK },
	{ USB_DEVICE(0x13d3, 0x3414), .driver_info = BTUSB_REALTEK },
@@ -3037,6 +3049,7 @@ static const struct qca_device_info qca_devices_table[] = {
	{ 0x00130100, 40, 4, 16 }, /* WCN6855 1.0 */
	{ 0x00130200, 40, 4, 16 }, /* WCN6855 2.0 */
	{ 0x00130201, 40, 4, 16 }, /* WCN6855 2.1 */
	{ 0x00190200, 40, 4, 16 }, /* WCN785x 2.0 */
};

static int btusb_qca_send_vendor_req(struct usb_device *udev, u8 request,
@@ -3327,14 +3340,20 @@ static int btusb_setup_qca(struct hci_dev *hdev)
		if (err < 0)
			return err;

		/* WCN6855 2.1 will reset to apply firmware downloaded here, so
		/* WCN6855 2.1 and later 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)
		if (info->rom_version >= 0x00130201)
			msleep(QCA_BT_RESET_WAIT_MS);
	}

	/* Mark HCI_OP_ENHANCED_SETUP_SYNC_CONN as broken as it doesn't seem to
	 * work with the likes of HSP/HFP mSBC.
	 */
	set_bit(HCI_QUIRK_BROKEN_ENHANCED_SETUP_SYNC_CONN, &hdev->quirks);
	set_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks);

	return 0;
}

Loading