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

Merge tag 'for-net-next-2023-02-09' of...

Merge tag 'for-net-next-2023-02-09' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next

Luiz Augusto von Dentz says:

====================
pull-request: bluetooth-next

 - Add new PID/VID 0489:e0f2 for MT7921
 - Add VID:PID 13d3:3529 for Realtek RTL8821CE
 - Add CIS feature bits to controller information
 - Set Per Platform Antenna Gain(PPAG) for Intel controllers

* tag 'for-net-next-2023-02-09' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next:
  Bluetooth: btintel: Set Per Platform Antenna Gain(PPAG)
  Bluetooth: Make sure LE create conn cancel is sent when timeout
  Bluetooth: Free potentially unfreed SCO connection
  Bluetooth: hci_qca: get wakeup status from serdev device handle
  Bluetooth: L2CAP: Fix potential user-after-free
  Bluetooth: MGMT: add CIS feature bits to controller information
  Bluetooth: hci_conn: Refactor hci_bind_bis() since it always succeeds
  Bluetooth: HCI: Replace zero-length arrays with flexible-array members
  Bluetooth: qca: Fix sparse warnings
  Bluetooth: btusb: Add VID:PID 13d3:3529 for Realtek RTL8821CE
  Bluetooth: btusb: Add new PID/VID 0489:e0f2 for MT7921
  Bluetooth: Fix issue with Actions Semi ATS2851 based devices
====================

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


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents de428733 c585a92b
Loading
Loading
Loading
Loading
+116 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
#include <linux/module.h>
#include <linux/firmware.h>
#include <linux/regmap.h>
#include <linux/acpi.h>
#include <asm/unaligned.h>

#include <net/bluetooth/bluetooth.h>
@@ -24,6 +25,9 @@
#define ECDSA_OFFSET		644
#define ECDSA_HEADER_LEN	320

#define BTINTEL_PPAG_NAME   "PPAG"
#define BTINTEL_PPAG_PREFIX "\\_SB_.PCI0.XHCI.RHUB"

#define CMD_WRITE_BOOT_PARAMS	0xfc0e
struct cmd_write_boot_params {
	__le32 boot_addr;
@@ -1278,6 +1282,63 @@ static int btintel_read_debug_features(struct hci_dev *hdev,
	return 0;
}

static acpi_status btintel_ppag_callback(acpi_handle handle, u32 lvl, void *data,
					 void **ret)
{
	acpi_status status;
	size_t len;
	struct btintel_ppag *ppag = data;
	union acpi_object *p, *elements;
	struct acpi_buffer string = {ACPI_ALLOCATE_BUFFER, NULL};
	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
	struct hci_dev *hdev = ppag->hdev;

	status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
	if (ACPI_FAILURE(status)) {
		bt_dev_warn(hdev, "ACPI Failure: %s", acpi_format_exception(status));
		return status;
	}

	if (strncmp(BTINTEL_PPAG_PREFIX, string.pointer,
		    strlen(BTINTEL_PPAG_PREFIX))) {
		kfree(string.pointer);
		return AE_OK;
	}

	len = strlen(string.pointer);
	if (strncmp((char *)string.pointer + len - 4, BTINTEL_PPAG_NAME, 4)) {
		kfree(string.pointer);
		return AE_OK;
	}
	kfree(string.pointer);

	status = acpi_evaluate_object(handle, NULL, NULL, &buffer);
	if (ACPI_FAILURE(status)) {
		bt_dev_warn(hdev, "ACPI Failure: %s", acpi_format_exception(status));
		return status;
	}

	p = buffer.pointer;
	ppag = (struct btintel_ppag *)data;

	if (p->type != ACPI_TYPE_PACKAGE || p->package.count != 2) {
		kfree(buffer.pointer);
		bt_dev_warn(hdev, "Invalid object type: %d or package count: %d",
			    p->type, p->package.count);
		return AE_ERROR;
	}

	elements = p->package.elements;

	/* PPAG table is located at element[1] */
	p = &elements[1];

	ppag->domain = (u32)p->package.elements[0].integer.value;
	ppag->mode = (u32)p->package.elements[1].integer.value;
	kfree(buffer.pointer);
	return AE_CTRL_TERMINATE;
}

static int btintel_set_debug_features(struct hci_dev *hdev,
			       const struct intel_debug_features *features)
{
@@ -2251,6 +2312,58 @@ static int btintel_configure_offload(struct hci_dev *hdev)
	return err;
}

static void btintel_set_ppag(struct hci_dev *hdev, struct intel_version_tlv *ver)
{
	acpi_status status;
	struct btintel_ppag ppag;
	struct sk_buff *skb;
	struct btintel_loc_aware_reg ppag_cmd;

    /* PPAG is not supported if CRF is HrP2, Jfp2, JfP1 */
	switch (ver->cnvr_top & 0xFFF) {
	case 0x504:     /* Hrp2 */
	case 0x202:     /* Jfp2 */
	case 0x201:     /* Jfp1 */
		return;
	}

	memset(&ppag, 0, sizeof(ppag));

	ppag.hdev = hdev;
	status = acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
				     ACPI_UINT32_MAX, NULL,
				     btintel_ppag_callback, &ppag, NULL);

	if (ACPI_FAILURE(status)) {
		/* Do not log warning message if ACPI entry is not found */
		if (status == AE_NOT_FOUND)
			return;
		bt_dev_warn(hdev, "PPAG: ACPI Failure: %s", acpi_format_exception(status));
		return;
	}

	if (ppag.domain != 0x12) {
		bt_dev_warn(hdev, "PPAG-BT Domain disabled");
		return;
	}

	/* PPAG mode, BIT0 = 0 Disabled, BIT0 = 1 Enabled */
	if (!(ppag.mode & BIT(0))) {
		bt_dev_dbg(hdev, "PPAG disabled");
		return;
	}

	ppag_cmd.mcc = cpu_to_le32(0);
	ppag_cmd.sel = cpu_to_le32(0); /* 0 - Enable , 1 - Disable, 2 - Testing mode */
	ppag_cmd.delta = cpu_to_le32(0);
	skb = __hci_cmd_sync(hdev, 0xfe19, sizeof(ppag_cmd), &ppag_cmd, HCI_CMD_TIMEOUT);
	if (IS_ERR(skb)) {
		bt_dev_warn(hdev, "Failed to send PPAG Enable (%ld)", PTR_ERR(skb));
		return;
	}
	kfree_skb(skb);
}

static int btintel_bootloader_setup_tlv(struct hci_dev *hdev,
					struct intel_version_tlv *ver)
{
@@ -2297,6 +2410,9 @@ static int btintel_bootloader_setup_tlv(struct hci_dev *hdev,

	hci_dev_clear_flag(hdev, HCI_QUALITY_REPORT);

	/* Set PPAG feature */
	btintel_set_ppag(hdev, ver);

	/* Read the Intel version information after loading the FW  */
	err = btintel_read_version_tlv(hdev, &new_ver);
	if (err)
+13 −0
Original line number Diff line number Diff line
@@ -137,6 +137,19 @@ struct intel_offload_use_cases {
	__u8	preset[8];
} __packed;

/* structure to store the PPAG data read from ACPI table */
struct btintel_ppag {
	u32	domain;
	u32     mode;
	struct hci_dev *hdev;
};

struct btintel_loc_aware_reg {
	__le32 mcc;
	__le32 sel;
	__le32 delta;
} __packed;

#define INTEL_HW_PLATFORM(cnvx_bt)	((u8)(((cnvx_bt) & 0x0000ff00) >> 8))
#define INTEL_HW_VARIANT(cnvx_bt)	((u8)(((cnvx_bt) & 0x003f0000) >> 16))
#define INTEL_CNVX_TOP_TYPE(cnvx_top)	((cnvx_top) & 0x00000fff)
+16 −0
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ static struct usb_driver btusb_driver;
#define BTUSB_INTEL_BROKEN_SHUTDOWN_LED	BIT(24)
#define BTUSB_INTEL_BROKEN_INITIAL_NCMD BIT(25)
#define BTUSB_INTEL_NO_WBS_SUPPORT	BIT(26)
#define BTUSB_ACTIONS_SEMI		BIT(27)

static const struct usb_device_id btusb_table[] = {
	/* Generic Bluetooth USB device */
@@ -492,6 +493,10 @@ static const struct usb_device_id blacklist_table[] = {
	{ USB_VENDOR_AND_INTERFACE_INFO(0x8087, 0xe0, 0x01, 0x01),
	  .driver_info = BTUSB_IGNORE },

	/* Realtek 8821CE Bluetooth devices */
	{ USB_DEVICE(0x13d3, 0x3529), .driver_info = BTUSB_REALTEK |
						     BTUSB_WIDEBAND_SPEECH },

	/* Realtek 8822CE Bluetooth devices */
	{ USB_DEVICE(0x0bda, 0xb00c), .driver_info = BTUSB_REALTEK |
						     BTUSB_WIDEBAND_SPEECH },
@@ -566,6 +571,9 @@ static const struct usb_device_id blacklist_table[] = {
	{ USB_DEVICE(0x0489, 0xe0e0), .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 },
	{ USB_DEVICE(0x04ca, 0x3802), .driver_info = BTUSB_MEDIATEK |
						     BTUSB_WIDEBAND_SPEECH |
						     BTUSB_VALID_LE_STATES },
@@ -677,6 +685,9 @@ static const struct usb_device_id blacklist_table[] = {
	{ USB_DEVICE(0x0cb5, 0xc547), .driver_info = BTUSB_REALTEK |
						     BTUSB_WIDEBAND_SPEECH },

	/* Actions Semiconductor ATS2851 based devices */
	{ USB_DEVICE(0x10d7, 0xb012), .driver_info = BTUSB_ACTIONS_SEMI },

	/* Silicon Wave based devices */
	{ USB_DEVICE(0x0c10, 0x0000), .driver_info = BTUSB_SWAVE },

@@ -4098,6 +4109,11 @@ static int btusb_probe(struct usb_interface *intf,
		set_bit(BTUSB_USE_ALT3_FOR_WBS, &data->flags);
	}

	if (id->driver_info & BTUSB_ACTIONS_SEMI) {
		/* Support is advertised, but not implemented */
		set_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks);
	}

	if (!reset)
		set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);

+6 −5
Original line number Diff line number Diff line
@@ -128,13 +128,13 @@ struct qca_memdump_event_hdr {
	__u8    evt;
	__u8    plen;
	__u16   opcode;
	__u16   seq_no;
	__le16   seq_no;
	__u8    reserved;
} __packed;


struct qca_dump_size {
	u32 dump_size;
	__le32 dump_size;
} __packed;

struct qca_data {
@@ -1588,10 +1588,11 @@ static bool qca_wakeup(struct hci_dev *hdev)
	struct hci_uart *hu = hci_get_drvdata(hdev);
	bool wakeup;

	/* UART driver handles the interrupt from BT SoC.So we need to use
	 * device handle of UART driver to get the status of device may wakeup.
	/* BT SoC attached through the serial bus is handled by the serdev driver.
	 * So we need to use the device handle of the serdev driver to get the
	 * status of device may wakeup.
	 */
	wakeup = device_may_wakeup(hu->serdev->ctrl->dev.parent);
	wakeup = device_may_wakeup(&hu->serdev->ctrl->dev);
	bt_dev_dbg(hu->hdev, "wakeup status : %d", wakeup);

	return wakeup;
+2 −2
Original line number Diff line number Diff line
@@ -2156,7 +2156,7 @@ struct hci_cp_le_big_create_sync {
	__u8    mse;
	__le16  timeout;
	__u8    num_bis;
	__u8    bis[0];
	__u8    bis[];
} __packed;

#define HCI_OP_LE_BIG_TERM_SYNC			0x206c
@@ -2174,7 +2174,7 @@ struct hci_cp_le_setup_iso_path {
	__le16  codec_vid;
	__u8    delay[3];
	__u8    codec_cfg_len;
	__u8    codec_cfg[0];
	__u8    codec_cfg[];
} __packed;

struct hci_rp_le_setup_iso_path {
Loading