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

Merge tag 'for-net-next-2026-04-13' of...

Merge tag 'for-net-next-2026-04-13' 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:

core:
 - hci_core: Rate limit the logging of invalid ISO handle
 - hci_sync: make hci_cmd_sync_run_once return -EEXIST if exists
 - hci_event: fix locking in hci_conn_request_evt() with HCI_PROTO_DEFER
 - hci_event: fix potential UAF in SSP passkey handlers
 - HCI: Avoid a couple -Wflex-array-member-not-at-end warnings
 - L2CAP: CoC: Disconnect if received packet size exceeds MPS
 - L2CAP: Add missing chan lock in l2cap_ecred_reconf_rsp
 - L2CAP: Fix printing wrong information if SDU length exceeds MTU
 - SCO: check for codecs->num_codecs == 1 before assigning to sco_pi(sk)->codec

drivers:
 - btusb: MT7922: Add VID/PID 0489/e174
 - btusb: Add Lite-On 04ca:3807 for MediaTek MT7921
 - btusb: Add MT7927 IDs ASUS ROG Crosshair X870E Hero, Lenovo Legion Pro 7
          16ARX9, Gigabyte Z790 AORUS MASTER X, MSI X870E Ace Max, TP-Link
          Archer TBE550E, ASUS X870E / ProArt X870E-Creator.
 - btusb: Add MT7902 IDs 13d3/3579, 13d3/3580, 13d3/3594, 13d3/3596, 0e8d/1ede
 - btusb: Add MT7902 IDs 13d3/3579, 13d3/3580, 13d3/3594, 13d3/3596, 0e8d/1ede
 - btusb: MediaTek MT7922: Add VID 0489 & PID e11d
 - btintel: Add support for Scorpious Peak2 support
 - btintel: Add support for Scorpious Peak2F support
 - btintel_pcie: Add device id of Scorpius Peak2, Nova Lake-PCD-H
 - btintel_pcie: Add device id of Scorpious2, Nova Lake-PCD-S
 - btmtk: Add reset mechanism if downloading firmware failed
 - btmtk: Add MT6639 (MT7927) Bluetooth support
 - btmtk: fix ISO interface setup for single alt setting
 - btmtk: add MT7902 SDIO support
 - Bluetooth: btmtk: add MT7902 MCU support
 - btbcm: Add entry for BCM4343A2 UART Bluetooth
 - qca: enable pwrseq support for wcn39xx devices
 - hci_qca: Fix BT not getting powered-off on rmmod
 - hci_qca: disable power control for WCN7850 when bt_en is not defined
 - hci_qca: Fix missing wakeup during SSR memdump handling
 - hci_ldisc: Clear HCI_UART_PROTO_INIT on error
 - mmc: sdio: add MediaTek MT7902 SDIO device ID
 - hci_ll: Enable BROKEN_ENHANCED_SETUP_SYNC_CONN for WL183x

* tag 'for-net-next-2026-04-13' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next: (59 commits)
  Bluetooth: hci_qca: Fix missing wakeup during SSR memdump handling
  Bluetooth: btintel_pcie: use strscpy to copy plain strings
  Bluetooth: hci_event: fix potential UAF in SSP passkey handlers
  Bluetooth: hci.h: Avoid a couple -Wflex-array-member-not-at-end warnings
  Bluetooth: SCO: check for codecs->num_codecs == 1 before assigning to sco_pi(sk)->codec
  Bluetooth: btintel_pcie: Align shared DMA memory to 128 bytes
  Bluetooth: l2cap: Add missing chan lock in l2cap_ecred_reconf_rsp
  Bluetooth: hci_ll: Enable BROKEN_ENHANCED_SETUP_SYNC_CONN for WL183x
  Bluetooth: btusb: MediaTek MT7922: Add VID 0489 & PID e11d
  Bluetooth: btmtk: hide unused btmtk_mt6639_devs[] array
  Bluetooth: btusb: Add MT7927 ID for ASUS X870E / ProArt X870E-Creator
  Bluetooth: btusb: Add MT7927 ID for TP-Link Archer TBE550E
  Bluetooth: btusb: Add MT7927 ID for MSI X870E Ace Max
  Bluetooth: btusb: Add MT7927 ID for Gigabyte Z790 AORUS MASTER X
  Bluetooth: btusb: Add MT7927 ID for Lenovo Legion Pro 7 16ARX9
  Bluetooth: btusb: Add MT7927 ID for ASUS ROG Crosshair X870E Hero
  Bluetooth: btmtk: fix ISO interface setup for single alt setting
  Bluetooth: btmtk: Add MT6639 (MT7927) Bluetooth support
  Bluetooth: fix locking in hci_conn_request_evt() with HCI_PROTO_DEFER
  Bluetooth: btmtk: refactor endpoint lookup
  ...
====================

Link: https://patch.msgid.link/20260413132247.320961-1-luiz.dentz@gmail.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents bc174d05 c347ca17
Loading
Loading
Loading
Loading
+5 −6
Original line number Diff line number Diff line
@@ -223,7 +223,7 @@ int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw)
		err = PTR_ERR(skb);
		bt_dev_err(hdev, "BCM: Download Minidrv command failed (%d)",
			   err);
		goto done;
		return err;
	}
	kfree_skb(skb);

@@ -242,8 +242,7 @@ int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw)

		if (fw_size < cmd->plen) {
			bt_dev_err(hdev, "BCM: Patch is corrupted");
			err = -EINVAL;
			goto done;
			return -EINVAL;
		}

		cmd_param = fw_ptr;
@@ -258,7 +257,7 @@ int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw)
			err = PTR_ERR(skb);
			bt_dev_err(hdev, "BCM: Patch command %04x failed (%d)",
				   opcode, err);
			goto done;
			return err;
		}
		kfree_skb(skb);
	}
@@ -266,8 +265,7 @@ int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw)
	/* 250 msec delay after Launch Ram completes */
	msleep(250);

done:
	return err;
	return 0;
}
EXPORT_SYMBOL(btbcm_patchram);

@@ -507,6 +505,7 @@ static const struct bcm_subver_table bcm_uart_subver_table[] = {
	{ 0x6119, "BCM4345C0"	},	/* 003.001.025 */
	{ 0x6606, "BCM4345C5"	},	/* 003.006.006 */
	{ 0x230f, "BCM4356A2"	},	/* 001.003.015 */
	{ 0x2310, "BCM4343A2"	},	/* 001.003.016 */
	{ 0x220e, "BCM20702A1"  },	/* 001.002.014 */
	{ 0x420d, "BCM4349B1"	},	/* 002.002.013 */
	{ 0x420e, "BCM4349B1"	},	/* 002.002.014 */
+92 −17
Original line number Diff line number Diff line
@@ -35,6 +35,19 @@ enum {
	DSM_SET_RESET_METHOD = 3,
};

/* Hybrid ECDSA + LMS */
#define BTINTEL_RSA_HEADER_VER		0x00010000
#define BTINTEL_ECDSA_HEADER_VER	0x00020000
#define BTINTEL_HYBRID_HEADER_VER	0x00069700
#define BTINTEL_ECDSA_OFFSET		128
#define BTINTEL_CSS_HEADER_SIZE		128
#define BTINTEL_ECDSA_PUB_KEY_SIZE	96
#define BTINTEL_ECDSA_SIG_SIZE		96
#define BTINTEL_LMS_OFFSET		320
#define BTINTEL_LMS_PUB_KEY_SIZE	52
#define BTINTEL_LMS_SIG_SIZE		1744
#define BTINTEL_CMD_BUFFER_OFFSET	2116

#define BTINTEL_BT_DOMAIN		0x12
#define BTINTEL_SAR_LEGACY		0
#define BTINTEL_SAR_INC_PWR		1
@@ -489,6 +502,8 @@ int btintel_version_info_tlv(struct hci_dev *hdev,
	case 0x1d:	/* BlazarU (BzrU) */
	case 0x1e:	/* BlazarI (Bzr) */
	case 0x1f:      /* Scorpious Peak */
	case 0x20:	/* Scorpious Peak2 */
	case 0x21:	/* Scorpious Peak2 F */
	case 0x22:	/* BlazarIW (BzrIW) */
		break;
	default:
@@ -510,8 +525,8 @@ int btintel_version_info_tlv(struct hci_dev *hdev,
			return -EINVAL;
		}

		/* Secure boot engine type should be either 1 (ECDSA) or 0 (RSA) */
		if (version->sbe_type > 0x01) {
		/* Secure boot engine type can be 0 (RSA), 1 (ECDSA), 2 (LMS), 3 (ECDSA + LMS) */
		if (version->sbe_type > 0x03) {
			bt_dev_err(hdev, "Unsupported Intel secure boot engine type (0x%x)",
				   version->sbe_type);
			return -EINVAL;
@@ -1030,6 +1045,48 @@ static int btintel_sfi_ecdsa_header_secure_send(struct hci_dev *hdev,
	return 0;
}

static int btintel_sfi_hybrid_header_secure_send(struct hci_dev *hdev,
						 const struct firmware *fw)
{
	int err;

	err = btintel_secure_send(hdev, 0x00, BTINTEL_CSS_HEADER_SIZE, fw->data);
	if (err < 0) {
		bt_dev_err(hdev, "Failed to send firmware CSS header (%d)", err);
		return err;
	}

	err = btintel_secure_send(hdev, 0x03, BTINTEL_ECDSA_PUB_KEY_SIZE,
				  fw->data + BTINTEL_ECDSA_OFFSET);
	if (err < 0) {
		bt_dev_err(hdev, "Failed to send firmware ECDSA pkey (%d)", err);
		return err;
	}

	err = btintel_secure_send(hdev, 0x02, BTINTEL_ECDSA_SIG_SIZE,
				  fw->data + BTINTEL_ECDSA_OFFSET + BTINTEL_ECDSA_PUB_KEY_SIZE);
	if (err < 0) {
		bt_dev_err(hdev, "Failed to send firmware ECDSA signature (%d)", err);
		return err;
	}

	err = btintel_secure_send(hdev, 0x05, BTINTEL_LMS_PUB_KEY_SIZE,
				  fw->data + BTINTEL_LMS_OFFSET);
	if (err < 0) {
		bt_dev_err(hdev, "Failed to send firmware LMS pkey (%d)", err);
		return err;
	}

	err = btintel_secure_send(hdev, 0x04, BTINTEL_LMS_SIG_SIZE,
				  fw->data + BTINTEL_LMS_OFFSET + BTINTEL_LMS_PUB_KEY_SIZE);
	if (err < 0) {
		bt_dev_err(hdev, "Failed to send firmware LMS signature (%d)", err);
		return err;
	}

	return 0;
}

static int btintel_download_firmware_payload(struct hci_dev *hdev,
					     const struct firmware *fw,
					     size_t offset)
@@ -1203,11 +1260,12 @@ static int btintel_download_fw_tlv(struct hci_dev *hdev,
	 * Command Buffer.
	 *
	 * CSS Header byte positions 0x08 to 0x0B represent the CSS Header
	 * version: RSA(0x00010000) , ECDSA (0x00020000)
	 * version: RSA(0x00010000) , ECDSA (0x00020000) , HYBRID (0x00069700)
	 */
	css_header_ver = get_unaligned_le32(fw->data + CSS_HEADER_OFFSET);
	if (css_header_ver != 0x00010000) {
		bt_dev_err(hdev, "Invalid CSS Header version");
	if (css_header_ver != BTINTEL_RSA_HEADER_VER &&
	    css_header_ver != BTINTEL_HYBRID_HEADER_VER) {
		bt_dev_err(hdev, "Invalid CSS Header version: 0x%8.8x", css_header_ver);
		return -EINVAL;
	}

@@ -1225,15 +1283,15 @@ static int btintel_download_fw_tlv(struct hci_dev *hdev,
		err = btintel_download_firmware_payload(hdev, fw, RSA_HEADER_LEN);
		if (err)
			return err;
	} else if (hw_variant >= 0x17) {
	} else if (hw_variant >= 0x17 && css_header_ver == BTINTEL_RSA_HEADER_VER) {
		/* Check if CSS header for ECDSA follows the RSA header */
		if (fw->data[ECDSA_OFFSET] != 0x06)
			return -EINVAL;

		/* Check if the CSS Header version is ECDSA(0x00020000) */
		css_header_ver = get_unaligned_le32(fw->data + ECDSA_OFFSET + CSS_HEADER_OFFSET);
		if (css_header_ver != 0x00020000) {
			bt_dev_err(hdev, "Invalid CSS Header version");
		if (css_header_ver != BTINTEL_ECDSA_HEADER_VER) {
			bt_dev_err(hdev, "Invalid CSS Header version: 0x%8.8x", css_header_ver);
			return -EINVAL;
		}

@@ -1256,6 +1314,14 @@ static int btintel_download_fw_tlv(struct hci_dev *hdev,
			if (err)
				return err;
		}
	} else if (hw_variant >= 0x20 && css_header_ver == BTINTEL_HYBRID_HEADER_VER) {
		err = btintel_sfi_hybrid_header_secure_send(hdev, fw);
		if (err)
			return err;

		err = btintel_download_firmware_payload(hdev, fw, BTINTEL_CMD_BUFFER_OFFSET);
		if (err)
			return err;
	}
	return 0;
}
@@ -2754,35 +2820,40 @@ static int btintel_set_dsbr(struct hci_dev *hdev, struct intel_version_tlv *ver)

	struct btintel_dsbr_cmd cmd;
	struct sk_buff *skb;
	u32 dsbr, cnvi;
	u8 status;
	u32 dsbr;
	u8 status, hw_variant;
	int err;

	cnvi = ver->cnvi_top & 0xfff;
	hw_variant = INTEL_HW_VARIANT(ver->cnvi_bt);
	/* DSBR command needs to be sent for,
	 * 1. BlazarI or BlazarIW + B0 step product in IML image.
	 * 2. Gale Peak2 or BlazarU in OP image.
	 * 3. Scorpious Peak in IML image.
	 * 4. Scorpious Peak2 onwards + PCIe transport in IML image.
	 */

	switch (cnvi) {
	case BTINTEL_CNVI_BLAZARI:
	case BTINTEL_CNVI_BLAZARIW:
	switch (hw_variant) {
	case BTINTEL_HWID_BZRI:
	case BTINTEL_HWID_BZRIW:
		if (ver->img_type == BTINTEL_IMG_IML &&
		    INTEL_CNVX_TOP_STEP(ver->cnvi_top) == 0x01)
			break;
		return 0;
	case BTINTEL_CNVI_GAP:
	case BTINTEL_CNVI_BLAZARU:
	case BTINTEL_HWID_GAP:
	case BTINTEL_HWID_BZRU:
		if (ver->img_type == BTINTEL_IMG_OP &&
		    hdev->bus == HCI_USB)
			break;
		return 0;
	case BTINTEL_CNVI_SCP:
	case BTINTEL_HWID_SCP:
		if (ver->img_type == BTINTEL_IMG_IML)
			break;
		return 0;
	default:
		/* Scorpius Peak2 onwards */
		if (hw_variant >= BTINTEL_HWID_SCP2 && hdev->bus == HCI_PCI
		    && ver->img_type == BTINTEL_IMG_IML)
			break;
		return 0;
	}

@@ -3259,6 +3330,8 @@ void btintel_set_msft_opcode(struct hci_dev *hdev, u8 hw_variant)
	case 0x1d:
	case 0x1e:
	case 0x1f:
	case 0x20:
	case 0x21:
	case 0x22:
		hci_set_msft_opcode(hdev, 0xFC1E);
		break;
@@ -3600,6 +3673,8 @@ static int btintel_setup_combined(struct hci_dev *hdev)
	case 0x1d:
	case 0x1e:
	case 0x1f:
	case 0x20:
	case 0x21:
	case 0x22:
		/* Display version information of TLV type */
		btintel_version_info_tlv(hdev, &ver_tlv);
+15 −5
Original line number Diff line number Diff line
@@ -54,11 +54,13 @@ struct intel_tlv {

#define BTINTEL_HCI_OP_RESET	0xfc01

#define BTINTEL_CNVI_BLAZARI		0x900
#define BTINTEL_CNVI_BLAZARIW		0x901
#define BTINTEL_CNVI_GAP		0x910
#define BTINTEL_CNVI_BLAZARU		0x930
#define BTINTEL_CNVI_SCP		0xA00
#define BTINTEL_CNVI_BLAZARI		0x900	/* BlazarI - Lunar Lake */
#define BTINTEL_CNVI_BLAZARIW		0x901	/* BlazarIW - Wildcat Lake */
#define BTINTEL_CNVI_GAP		0x910	/* Gale Peak2 - Meteor Lake */
#define BTINTEL_CNVI_BLAZARU		0x930	/* BlazarU - Meteor Lake */
#define BTINTEL_CNVI_SCP		0xA00	/* Scorpius Peak - Panther Lake */
#define BTINTEL_CNVI_SCP2		0xA10	/* Scorpius Peak2 - Nova Lake */
#define BTINTEL_CNVI_SCP2F		0xA20	/* Scorpius Peak2F - Nova Lake */

/* CNVR */
#define BTINTEL_CNVR_FMP2		0x910
@@ -69,6 +71,14 @@ struct intel_tlv {

#define BTINTEL_FWID_MAXLEN 64

/* CNVi Hardware variant */
#define BTINTEL_HWID_GAP	0x1c	/* Gale Peak2 - Meteor Lake */
#define BTINTEL_HWID_BZRI	0x1e	/* BlazarI - Lunar Lake */
#define BTINTEL_HWID_BZRU	0x1d	/* BlazarU - Meteor Lake */
#define BTINTEL_HWID_SCP	0x1f	/* Scorpius Peak - Panther Lake */
#define BTINTEL_HWID_SCP2	0x20	/* Scorpius Peak2 - Nova Lake */
#define BTINTEL_HWID_BZRIW	0x22	/* BlazarIW - Wildcat Lake */

struct intel_version_tlv {
	u32	cnvi_top;
	u32	cnvr_top;
+75 −47
Original line number Diff line number Diff line
@@ -9,7 +9,9 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/firmware.h>
#include <linux/overflow.h>
#include <linux/pci.h>
#include <linux/string.h>
#include <linux/wait.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
@@ -35,6 +37,8 @@

#define POLL_INTERVAL_US	10

#define BTINTEL_PCIE_DMA_ALIGN_128B	128 /* 128 byte aligned */

/* Intel Bluetooth PCIe device id table */
static const struct pci_device_id btintel_pcie_table[] = {
	/* BlazarI, Wildcat Lake */
@@ -45,6 +49,10 @@ static const struct pci_device_id btintel_pcie_table[] = {
	{ BTINTEL_PCI_DEVICE(0xE376, PCI_ANY_ID) },
	 /* Scorpious, Panther Lake-H404 */
	{ BTINTEL_PCI_DEVICE(0xE476, PCI_ANY_ID) },
	 /* Scorpious2, Nova Lake-PCD-H */
	{ BTINTEL_PCI_DEVICE(0xD346, PCI_ANY_ID) },
	 /* Scorpious2, Nova Lake-PCD-S */
	{ BTINTEL_PCI_DEVICE(0x6E74, PCI_ANY_ID) },
	{ 0 }
};
MODULE_DEVICE_TABLE(pci, btintel_pcie_table);
@@ -72,6 +80,9 @@ struct btintel_pcie_dev_recovery {
#define BTINTEL_PCIE_SCP_HWEXP_SIZE		4096
#define BTINTEL_PCIE_SCP_HWEXP_DMP_ADDR		0xB030F800

#define BTINTEL_PCIE_SCP2_HWEXP_SIZE		4096
#define BTINTEL_PCIE_SCP2_HWEXP_DMP_ADDR	0xB031D000

#define BTINTEL_PCIE_MAGIC_NUM	0xA5A5A5A5

#define BTINTEL_PCIE_TRIGGER_REASON_USER_TRIGGER	0x17A2
@@ -268,7 +279,7 @@ static inline void btintel_pcie_dump_debug_registers(struct hci_dev *hdev)
	if (!skb)
		return;

	snprintf(buf, sizeof(buf), "%s", "---- Dump of debug registers ---");
	strscpy(buf, "---- Dump of debug registers ---");
	bt_dev_dbg(hdev, "%s", buf);
	skb_put_data(skb, buf, strlen(buf));

@@ -340,7 +351,7 @@ static inline void btintel_pcie_dump_debug_registers(struct hci_dev *hdev)
	snprintf(buf, sizeof(buf), "txq: cr_tia: %u cr_hia: %u", cr_tia, cr_hia);
	skb_put_data(skb, buf, strlen(buf));
	bt_dev_dbg(hdev, "%s", buf);
	snprintf(buf, sizeof(buf), "--------------------------------");
	strscpy(buf, "--------------------------------");
	bt_dev_dbg(hdev, "%s", buf);

	hci_recv_diag(hdev, skb);
@@ -650,7 +661,7 @@ static int btintel_pcie_read_dram_buffers(struct btintel_pcie_data *data)
	else
		return -EINVAL;

	snprintf(vendor, sizeof(vendor), "Vendor: Intel\n");
	strscpy(vendor, "Vendor: Intel\n");
	snprintf(driver, sizeof(driver), "Driver: %s\n",
		 data->dmp_hdr.driver_name);

@@ -1229,6 +1240,11 @@ static void btintel_pcie_read_hwexp(struct btintel_pcie_data *data)
		len = BTINTEL_PCIE_SCP_HWEXP_SIZE;
		addr = BTINTEL_PCIE_SCP_HWEXP_DMP_ADDR;
		break;
	case BTINTEL_CNVI_SCP2:
	case BTINTEL_CNVI_SCP2F:
		len = BTINTEL_PCIE_SCP2_HWEXP_SIZE;
		addr = BTINTEL_PCIE_SCP2_HWEXP_DMP_ADDR;
		break;
	default:
		bt_dev_err(data->hdev, "Unsupported cnvi 0x%8.8x", data->dmp_hdr.cnvi_top);
		return;
@@ -1737,27 +1753,6 @@ static int btintel_pcie_setup_rxq_bufs(struct btintel_pcie_data *data,
	return 0;
}

static void btintel_pcie_setup_ia(struct btintel_pcie_data *data,
				  dma_addr_t p_addr, void *v_addr,
				  struct ia *ia)
{
	/* TR Head Index Array */
	ia->tr_hia_p_addr = p_addr;
	ia->tr_hia = v_addr;

	/* TR Tail Index Array */
	ia->tr_tia_p_addr = p_addr + sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES;
	ia->tr_tia = v_addr + sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES;

	/* CR Head index Array */
	ia->cr_hia_p_addr = p_addr + (sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES * 2);
	ia->cr_hia = v_addr + (sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES * 2);

	/* CR Tail Index Array */
	ia->cr_tia_p_addr = p_addr + (sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES * 3);
	ia->cr_tia = v_addr + (sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES * 3);
}

static void btintel_pcie_free(struct btintel_pcie_data *data)
{
	btintel_pcie_free_rxq_bufs(data, &data->rxq);
@@ -1775,13 +1770,16 @@ static int btintel_pcie_alloc(struct btintel_pcie_data *data)
	size_t total;
	dma_addr_t p_addr;
	void *v_addr;
	size_t tfd_size, frbd_size, ctx_size, ci_size, urbd0_size, urbd1_size;

	/* Allocate the chunk of DMA memory for descriptors, index array, and
	 * context information, instead of allocating individually.
	 * The DMA memory for data buffer is allocated while setting up the
	 * each queue.
	 *
	 * Total size is sum of the following
	 * Total size is sum of the following and each of the individual sizes
	 * are aligned to 128 bytes before adding up.
	 *
	 *  + size of TFD * Number of descriptors in queue
	 *  + size of URBD0 * Number of descriptors in queue
	 *  + size of FRBD * Number of descriptors in queue
@@ -1789,15 +1787,25 @@ static int btintel_pcie_alloc(struct btintel_pcie_data *data)
	 *  + size of index * Number of queues(2) * type of index array(4)
	 *  + size of context information
	 */
	total = (sizeof(struct tfd) + sizeof(struct urbd0)) * BTINTEL_PCIE_TX_DESCS_COUNT;
	total += (sizeof(struct frbd) + sizeof(struct urbd1)) * BTINTEL_PCIE_RX_DESCS_COUNT;
	tfd_size = ALIGN(sizeof(struct tfd) * BTINTEL_PCIE_TX_DESCS_COUNT,
			 BTINTEL_PCIE_DMA_ALIGN_128B);
	urbd0_size = ALIGN(sizeof(struct urbd0) * BTINTEL_PCIE_TX_DESCS_COUNT,
			   BTINTEL_PCIE_DMA_ALIGN_128B);

	frbd_size = ALIGN(sizeof(struct frbd) * BTINTEL_PCIE_RX_DESCS_COUNT,
			  BTINTEL_PCIE_DMA_ALIGN_128B);
	urbd1_size = ALIGN(sizeof(struct urbd1) * BTINTEL_PCIE_RX_DESCS_COUNT,
			   BTINTEL_PCIE_DMA_ALIGN_128B);

	ci_size = ALIGN(sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES,
			BTINTEL_PCIE_DMA_ALIGN_128B);

	/* Add the sum of size of index array and size of ci struct */
	total += (sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES * 4) + sizeof(struct ctx_info);
	ctx_size = ALIGN(sizeof(struct ctx_info), BTINTEL_PCIE_DMA_ALIGN_128B);

	total = tfd_size + urbd0_size + frbd_size + urbd1_size + ctx_size + ci_size * 4;

	/* Allocate DMA Pool */
	data->dma_pool = dma_pool_create(KBUILD_MODNAME, &data->pdev->dev,
					 total, BTINTEL_PCIE_DMA_POOL_ALIGNMENT, 0);
					 total, BTINTEL_PCIE_DMA_ALIGN_128B, 0);
	if (!data->dma_pool) {
		err = -ENOMEM;
		goto exit_error;
@@ -1822,29 +1830,29 @@ static int btintel_pcie_alloc(struct btintel_pcie_data *data)
	data->txq.tfds_p_addr = p_addr;
	data->txq.tfds = v_addr;

	p_addr += (sizeof(struct tfd) * BTINTEL_PCIE_TX_DESCS_COUNT);
	v_addr += (sizeof(struct tfd) * BTINTEL_PCIE_TX_DESCS_COUNT);
	p_addr += tfd_size;
	v_addr += tfd_size;

	/* Setup urbd0 */
	data->txq.urbd0s_p_addr = p_addr;
	data->txq.urbd0s = v_addr;

	p_addr += (sizeof(struct urbd0) * BTINTEL_PCIE_TX_DESCS_COUNT);
	v_addr += (sizeof(struct urbd0) * BTINTEL_PCIE_TX_DESCS_COUNT);
	p_addr += urbd0_size;
	v_addr += urbd0_size;

	/* Setup FRBD*/
	data->rxq.frbds_p_addr = p_addr;
	data->rxq.frbds = v_addr;

	p_addr += (sizeof(struct frbd) * BTINTEL_PCIE_RX_DESCS_COUNT);
	v_addr += (sizeof(struct frbd) * BTINTEL_PCIE_RX_DESCS_COUNT);
	p_addr += frbd_size;
	v_addr += frbd_size;

	/* Setup urbd1 */
	data->rxq.urbd1s_p_addr = p_addr;
	data->rxq.urbd1s = v_addr;

	p_addr += (sizeof(struct urbd1) * BTINTEL_PCIE_RX_DESCS_COUNT);
	v_addr += (sizeof(struct urbd1) * BTINTEL_PCIE_RX_DESCS_COUNT);
	p_addr += urbd1_size;
	v_addr += urbd1_size;

	/* Setup data buffers for txq */
	err = btintel_pcie_setup_txq_bufs(data, &data->txq);
@@ -1856,8 +1864,29 @@ static int btintel_pcie_alloc(struct btintel_pcie_data *data)
	if (err)
		goto exit_error_txq;

	/* Setup Index Array */
	btintel_pcie_setup_ia(data, p_addr, v_addr, &data->ia);
	/* TR Head Index Array */
	data->ia.tr_hia_p_addr = p_addr;
	data->ia.tr_hia = v_addr;
	p_addr += ci_size;
	v_addr += ci_size;

	/* TR Tail Index Array */
	data->ia.tr_tia_p_addr = p_addr;
	data->ia.tr_tia = v_addr;
	p_addr += ci_size;
	v_addr += ci_size;

	/* CR Head index Array */
	data->ia.cr_hia_p_addr = p_addr;
	data->ia.cr_hia = v_addr;
	p_addr += ci_size;
	v_addr += ci_size;

	/* CR Tail Index Array */
	data->ia.cr_tia_p_addr = p_addr;
	data->ia.cr_tia = v_addr;
	p_addr += ci_size;
	v_addr += ci_size;

	/* Setup data buffers for dbgc */
	err = btintel_pcie_setup_dbgc(data);
@@ -1865,9 +1894,6 @@ static int btintel_pcie_alloc(struct btintel_pcie_data *data)
		goto exit_error_txq;

	/* Setup Context Information */
	p_addr += sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES * 4;
	v_addr += sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES * 4;

	data->ci = v_addr;
	data->ci_p_addr = p_addr;

@@ -2093,6 +2119,8 @@ static int btintel_pcie_setup_internal(struct hci_dev *hdev)
	switch (INTEL_HW_VARIANT(ver_tlv.cnvi_bt)) {
	case 0x1e:	/* BzrI */
	case 0x1f:	/* ScP  */
	case 0x20:	/* ScP2 */
	case 0x21:	/* ScP2 F */
	case 0x22:	/* BzrIW */
		/* Display version information of TLV type */
		btintel_version_info_tlv(hdev, &ver_tlv);
@@ -2372,7 +2400,7 @@ static int btintel_pcie_hci_drv_read_info(struct hci_dev *hdev, void *data,
	u16 opcode, num_supported_commands =
		ARRAY_SIZE(btintel_pcie_hci_drv_supported_commands);

	rp_size = sizeof(*rp) + num_supported_commands * 2;
	rp_size = struct_size(rp, supported_commands, num_supported_commands);

	rp = kmalloc(rp_size, GFP_KERNEL);
	if (!rp)
+0 −3
Original line number Diff line number Diff line
@@ -178,9 +178,6 @@ enum {
/* The size of DMA buffer for TX and RX in bytes */
#define BTINTEL_PCIE_BUFFER_SIZE	4096

/* DMA allocation alignment */
#define BTINTEL_PCIE_DMA_POOL_ALIGNMENT	256

#define BTINTEL_PCIE_TX_WAIT_TIMEOUT_MS		500

/* Doorbell vector for TFD */
Loading