Commit 2e63a2df authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files
Luiz Augusto von Dentz says:

====================
bluetooth pull request for net:

 - Fix MGMT add advmon with RSSI command
 - L2CAP: Fix responding with wrong PDU type
 - Fix race condition in hci_cmd_sync_clear
 - ISO: Fix timestamped HCI ISO data packet parsing
 - HCI: Fix global-out-of-bounds
 - hci_sync: Resume adv with no RPA when active scan

* tag 'for-net-2023-03-23' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth:
  Bluetooth: HCI: Fix global-out-of-bounds
  Bluetooth: mgmt: Fix MGMT add advmon with RSSI command
  Bluetooth: btsdio: fix use after free bug in btsdio_remove due to unfinished work
  Bluetooth: L2CAP: Fix responding with wrong PDU type
  Bluetooth: btqcomsmd: Fix command timeout after setting BD address
  Bluetooth: btinel: Check ACPI handle for NULL before accessing
  Bluetooth: Remove "Power-on" check from Mesh feature
  Bluetooth: Fix race condition in hci_cmd_sync_clear
  Bluetooth: btintel: Iterate only bluetooth device ACPI entries
  Bluetooth: ISO: fix timestamped HCI ISO data packet parsing
  Bluetooth: btusb: Remove detection of ISO packets over bulk
  Bluetooth: hci_core: Detect if an ACL packet is in fact an ISO packet
  Bluetooth: hci_sync: Resume adv with no RPA when active scan
====================

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


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 4f44d326 bce56405
Loading
Loading
Loading
Loading
+33 −18
Original line number Diff line number Diff line
@@ -26,7 +26,14 @@
#define ECDSA_HEADER_LEN	320

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

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

#define CMD_WRITE_BOOT_PARAMS	0xfc0e
struct cmd_write_boot_params {
@@ -1295,17 +1302,16 @@ static acpi_status btintel_ppag_callback(acpi_handle handle, u32 lvl, void *data

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

	if (strncmp(BTINTEL_PPAG_PREFIX, string.pointer,
		    strlen(BTINTEL_PPAG_PREFIX))) {
	len = strlen(string.pointer);
	if (len < strlen(BTINTEL_PPAG_NAME)) {
		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;
@@ -1314,7 +1320,8 @@ static acpi_status btintel_ppag_callback(acpi_handle handle, u32 lvl, void *data

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

@@ -1323,8 +1330,9 @@ static acpi_status btintel_ppag_callback(acpi_handle handle, u32 lvl, void *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",
		bt_dev_warn(hdev, "PPAG-BT: Invalid object type: %d or package count: %d",
			    p->type, p->package.count);
		ppag->status = AE_ERROR;
		return AE_ERROR;
	}

@@ -1335,6 +1343,7 @@ static acpi_status btintel_ppag_callback(acpi_handle handle, u32 lvl, void *data

	ppag->domain = (u32)p->package.elements[0].integer.value;
	ppag->mode = (u32)p->package.elements[1].integer.value;
	ppag->status = AE_OK;
	kfree(buffer.pointer);
	return AE_CTRL_TERMINATE;
}
@@ -2314,10 +2323,10 @@ static int btintel_configure_offload(struct hci_dev *hdev)

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;
	acpi_handle handle;

	/* PPAG is not supported if CRF is HrP2, Jfp2, JfP1 */
	switch (ver->cnvr_top & 0xFFF) {
@@ -2327,29 +2336,35 @@ static void btintel_set_ppag(struct hci_dev *hdev, struct intel_version_tlv *ver
		return;
	}

	handle = ACPI_HANDLE(GET_HCIDEV_DEV(hdev));
	if (!handle) {
		bt_dev_info(hdev, "No support for BT device in ACPI firmware");
		return;
	}

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

	ppag.hdev = hdev;
	status = acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
				     ACPI_UINT32_MAX, NULL,
	ppag.status = AE_NOT_FOUND;
	acpi_walk_namespace(ACPI_TYPE_PACKAGE, handle, 1, 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)
	if (ACPI_FAILURE(ppag.status)) {
		if (ppag.status == AE_NOT_FOUND) {
			bt_dev_dbg(hdev, "PPAG-BT: ACPI entry 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");
		bt_dev_warn(hdev, "PPAG-BT: domain is not bluetooth");
		return;
	}

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

+0 −7
Original line number Diff line number Diff line
@@ -137,13 +137,6 @@ 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;
+16 −1
Original line number Diff line number Diff line
@@ -122,6 +122,21 @@ static int btqcomsmd_setup(struct hci_dev *hdev)
	return 0;
}

static int btqcomsmd_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
{
	int ret;

	ret = qca_set_bdaddr_rome(hdev, bdaddr);
	if (ret)
		return ret;

	/* The firmware stops responding for a while after setting the bdaddr,
	 * causing timeouts for subsequent commands. Sleep a bit to avoid this.
	 */
	usleep_range(1000, 10000);
	return 0;
}

static int btqcomsmd_probe(struct platform_device *pdev)
{
	struct btqcomsmd *btq;
@@ -162,7 +177,7 @@ static int btqcomsmd_probe(struct platform_device *pdev)
	hdev->close = btqcomsmd_close;
	hdev->send = btqcomsmd_send;
	hdev->setup = btqcomsmd_setup;
	hdev->set_bdaddr = qca_set_bdaddr_rome;
	hdev->set_bdaddr = btqcomsmd_set_bdaddr;

	ret = hci_register_dev(hdev);
	if (ret < 0)
+1 −0
Original line number Diff line number Diff line
@@ -354,6 +354,7 @@ static void btsdio_remove(struct sdio_func *func)

	BT_DBG("func %p", func);

	cancel_work_sync(&data->work);
	if (!data)
		return;

+0 −10
Original line number Diff line number Diff line
@@ -1050,21 +1050,11 @@ static int btusb_recv_bulk(struct btusb_data *data, void *buffer, int count)
		hci_skb_expect(skb) -= len;

		if (skb->len == HCI_ACL_HDR_SIZE) {
			__u16 handle = __le16_to_cpu(hci_acl_hdr(skb)->handle);
			__le16 dlen = hci_acl_hdr(skb)->dlen;
			__u8 type;

			/* Complete ACL header */
			hci_skb_expect(skb) = __le16_to_cpu(dlen);

			/* Detect if ISO packet has been sent over bulk */
			if (hci_conn_num(data->hdev, ISO_LINK)) {
				type = hci_conn_lookup_type(data->hdev,
							    hci_handle(handle));
				if (type == ISO_LINK)
					hci_skb_pkt_type(skb) = HCI_ISODATA_PKT;
			}

			if (skb_tailroom(skb) < hci_skb_expect(skb)) {
				kfree_skb(skb);
				skb = NULL;
Loading