Commit 43a1ce8f authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge tag 'for-net-next-2025-05-22' of...

Merge tag 'for-net-next-2025-05-22' 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:
 - Add support for SIOCETHTOOL ETHTOOL_GET_TS_INFO
 - Separate CIS_LINK and BIS_LINK link types
 - Introduce HCI Driver protocol

drivers:
 - btintel_pcie: Do not generate coredump for diagnostic events
 - btusb: Add HCI Drv commands for configuring altsetting
 - btusb: Add RTL8851BE device 0x0bda:0xb850
 - btusb: Add new VID/PID 13d3/3584 for MT7922
 - btusb: Add new VID/PID 13d3/3630 and 13d3/3613 for MT7925
 - btnxpuart: Implement host-wakeup feature

* tag 'for-net-next-2025-05-22' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next: (23 commits)
  Bluetooth: btintel: Check dsbr size from EFI variable
  Bluetooth: MGMT: iterate over mesh commands in mgmt_mesh_foreach()
  Bluetooth: btusb: Add new VID/PID 13d3/3584 for MT7922
  Bluetooth: btusb: use skb_pull to avoid unsafe access in QCA dump handling
  Bluetooth: L2CAP: Fix not checking l2cap_chan security level
  Bluetooth: separate CIS_LINK and BIS_LINK link types
  Bluetooth: btusb: Add new VID/PID 13d3/3630 for MT7925
  Bluetooth: add support for SIOCETHTOOL ETHTOOL_GET_TS_INFO
  Bluetooth: btintel_pcie: Dump debug registers on error
  Bluetooth: ISO: Fix getpeername not returning sockaddr_iso_bc fields
  Bluetooth: ISO: Fix not using SID from adv report
  Revert "Bluetooth: btusb: add sysfs attribute to control USB alt setting"
  Revert "Bluetooth: btusb: Configure altsetting for HCI_USER_CHANNEL"
  Bluetooth: btusb: Add HCI Drv commands for configuring altsetting
  Bluetooth: Introduce HCI Driver protocol
  Bluetooth: btnxpuart: Implement host-wakeup feature
  dt-bindings: net: bluetooth: nxp: Add support for host-wakeup
  Bluetooth: btusb: Add RTL8851BE device 0x0bda:0xb850
  Bluetooth: hci_uart: Remove unnecessary NULL check before release_firmware()
  Bluetooth: btmtksdio: Fix wakeup source leaks on device unbind
  ...
====================

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


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 33e1b1b3 3aa1dc3c
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -48,6 +48,18 @@ properties:
    description:
      The GPIO number of the NXP chipset used for BT_WAKE_IN.

  interrupts:
    maxItems: 1
    description:
      Host wakeup by falling edge interrupt on this pin which is
      connected to BT_WAKE_OUT pin of the NXP chipset.

  interrupt-names:
    items:
      - const: wakeup

  wakeup-source: true

  nxp,wakeout-pin:
    $ref: /schemas/types.yaml#/definitions/uint8
    description:
@@ -61,6 +73,7 @@ unevaluatedProperties: false
examples:
  - |
    #include <dt-bindings/gpio/gpio.h>
    #include <dt-bindings/interrupt-controller/irq.h>
    serial {
        bluetooth {
            compatible = "nxp,88w8987-bt";
@@ -70,5 +83,9 @@ examples:
            nxp,wakein-pin = /bits/ 8 <18>;
            nxp,wakeout-pin = /bits/ 8 <19>;
            local-bd-address = [66 55 44 33 22 11];
            interrupt-parent = <&gpio>;
            interrupts = <8 IRQ_TYPE_EDGE_FALLING>;
            interrupt-names = "wakeup";
            wakeup-source;
        };
    };
+0 −12
Original line number Diff line number Diff line
@@ -56,18 +56,6 @@ config BT_HCIBTUSB_POLL_SYNC
	  Say Y here to enable USB poll_sync for Bluetooth USB devices by
	  default.

config BT_HCIBTUSB_AUTO_ISOC_ALT
	bool "Automatically adjust alternate setting for Isoc endpoints"
	depends on BT_HCIBTUSB
	default y if CHROME_PLATFORMS
	help
	  Say Y here to automatically adjusting the alternate setting for
	  HCI_USER_CHANNEL whenever a SCO link is established.

	  When enabled, btusb intercepts the HCI_EV_SYNC_CONN_COMPLETE packets
	  and configures isoc endpoint alternate setting automatically when
	  HCI_USER_CHANNEL is in use.

config BT_HCIBTUSB_BCM
	bool "Broadcom protocol support"
	depends on BT_HCIBTUSB
+3 −10
Original line number Diff line number Diff line
@@ -2719,7 +2719,7 @@ static int btintel_uefi_get_dsbr(u32 *dsbr_var)
	} __packed data;

	efi_status_t status;
	unsigned long data_size = 0;
	unsigned long data_size = sizeof(data);
	efi_guid_t guid = EFI_GUID(0xe65d8884, 0xd4af, 0x4b20, 0x8d, 0x03,
				   0x77, 0x2e, 0xcc, 0x3d, 0xa5, 0x31);

@@ -2729,16 +2729,10 @@ static int btintel_uefi_get_dsbr(u32 *dsbr_var)
	if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE))
		return -EOPNOTSUPP;

	status = efi.get_variable(BTINTEL_EFI_DSBR, &guid, NULL, &data_size,
				  NULL);

	if (status != EFI_BUFFER_TOO_SMALL || !data_size)
		return -EIO;

	status = efi.get_variable(BTINTEL_EFI_DSBR, &guid, NULL, &data_size,
				  &data);

	if (status != EFI_SUCCESS)
	if (status != EFI_SUCCESS || data_size != sizeof(data))
		return -ENXIO;

	*dsbr_var = data.dsbr;
@@ -3688,7 +3682,7 @@ int btintel_configure_setup(struct hci_dev *hdev, const char *driver_name)
}
EXPORT_SYMBOL_GPL(btintel_configure_setup);

int btintel_diagnostics(struct hci_dev *hdev, struct sk_buff *skb)
static int btintel_diagnostics(struct hci_dev *hdev, struct sk_buff *skb)
{
	struct intel_tlv *tlv = (void *)&skb->data[5];

@@ -3716,7 +3710,6 @@ int btintel_diagnostics(struct hci_dev *hdev, struct sk_buff *skb)
recv_frame:
	return hci_recv_frame(hdev, skb);
}
EXPORT_SYMBOL_GPL(btintel_diagnostics);

int btintel_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
{
+0 −6
Original line number Diff line number Diff line
@@ -277,7 +277,6 @@ int btintel_bootloader_setup_tlv(struct hci_dev *hdev,
int btintel_shutdown_combined(struct hci_dev *hdev);
void btintel_hw_error(struct hci_dev *hdev, u8 code);
void btintel_print_fseq_info(struct hci_dev *hdev);
int btintel_diagnostics(struct hci_dev *hdev, struct sk_buff *skb);
#else

static inline int btintel_check_bdaddr(struct hci_dev *hdev)
@@ -411,9 +410,4 @@ static inline void btintel_hw_error(struct hci_dev *hdev, u8 code)
static inline void btintel_print_fseq_info(struct hci_dev *hdev)
{
}

static inline int btintel_diagnostics(struct hci_dev *hdev, struct sk_buff *skb)
{
	return -EOPNOTSUPP;
}
#endif
+130 −11
Original line number Diff line number Diff line
@@ -208,6 +208,96 @@ static void btintel_pcie_prepare_tx(struct txq *txq, u16 tfd_index,
	memcpy(buf->data, skb->data, tfd->size);
}

static inline void btintel_pcie_dump_debug_registers(struct hci_dev *hdev)
{
	struct btintel_pcie_data *data = hci_get_drvdata(hdev);
	u16 cr_hia, cr_tia;
	u32 reg, mbox_reg;
	struct sk_buff *skb;
	u8 buf[80];

	skb = alloc_skb(1024, GFP_ATOMIC);
	if (!skb)
		return;

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

	reg = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_BOOT_STAGE_REG);
	snprintf(buf, sizeof(buf), "boot stage: 0x%8.8x", reg);
	bt_dev_dbg(hdev, "%s", buf);
	skb_put_data(skb, buf, strlen(buf));
	data->boot_stage_cache = reg;

	reg = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_IPC_STATUS_REG);
	snprintf(buf, sizeof(buf), "ipc status: 0x%8.8x", reg);
	skb_put_data(skb, buf, strlen(buf));
	bt_dev_dbg(hdev, "%s", buf);

	reg = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_IPC_CONTROL_REG);
	snprintf(buf, sizeof(buf), "ipc control: 0x%8.8x", reg);
	skb_put_data(skb, buf, strlen(buf));
	bt_dev_dbg(hdev, "%s", buf);

	reg = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_IPC_SLEEP_CTL_REG);
	snprintf(buf, sizeof(buf), "ipc sleep control: 0x%8.8x", reg);
	skb_put_data(skb, buf, strlen(buf));
	bt_dev_dbg(hdev, "%s", buf);

	/*Read the Mail box status and registers*/
	reg = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_MBOX_STATUS_REG);
	snprintf(buf, sizeof(buf), "mbox status: 0x%8.8x", reg);
	skb_put_data(skb, buf, strlen(buf));
	if (reg & BTINTEL_PCIE_CSR_MBOX_STATUS_MBOX1) {
		mbox_reg = btintel_pcie_rd_reg32(data,
						 BTINTEL_PCIE_CSR_MBOX_1_REG);
		snprintf(buf, sizeof(buf), "mbox_1: 0x%8.8x", mbox_reg);
		skb_put_data(skb, buf, strlen(buf));
		bt_dev_dbg(hdev, "%s", buf);
	}

	if (reg & BTINTEL_PCIE_CSR_MBOX_STATUS_MBOX2) {
		mbox_reg = btintel_pcie_rd_reg32(data,
						 BTINTEL_PCIE_CSR_MBOX_2_REG);
		snprintf(buf, sizeof(buf), "mbox_2: 0x%8.8x", mbox_reg);
		skb_put_data(skb, buf, strlen(buf));
		bt_dev_dbg(hdev, "%s", buf);
	}

	if (reg & BTINTEL_PCIE_CSR_MBOX_STATUS_MBOX3) {
		mbox_reg = btintel_pcie_rd_reg32(data,
						 BTINTEL_PCIE_CSR_MBOX_3_REG);
		snprintf(buf, sizeof(buf), "mbox_3: 0x%8.8x", mbox_reg);
		skb_put_data(skb, buf, strlen(buf));
		bt_dev_dbg(hdev, "%s", buf);
	}

	if (reg & BTINTEL_PCIE_CSR_MBOX_STATUS_MBOX4) {
		mbox_reg = btintel_pcie_rd_reg32(data,
						 BTINTEL_PCIE_CSR_MBOX_4_REG);
		snprintf(buf, sizeof(buf), "mbox_4: 0x%8.8x", mbox_reg);
		skb_put_data(skb, buf, strlen(buf));
		bt_dev_dbg(hdev, "%s", buf);
	}

	cr_hia = data->ia.cr_hia[BTINTEL_PCIE_RXQ_NUM];
	cr_tia = data->ia.cr_tia[BTINTEL_PCIE_RXQ_NUM];
	snprintf(buf, sizeof(buf), "rxq: cr_tia: %u cr_hia: %u", cr_tia, cr_hia);
	skb_put_data(skb, buf, strlen(buf));
	bt_dev_dbg(hdev, "%s", buf);

	cr_hia = data->ia.cr_hia[BTINTEL_PCIE_TXQ_NUM];
	cr_tia = data->ia.cr_tia[BTINTEL_PCIE_TXQ_NUM];
	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), "--------------------------------");
	bt_dev_dbg(hdev, "%s", buf);

	hci_recv_diag(hdev, skb);
}

static int btintel_pcie_send_sync(struct btintel_pcie_data *data,
				  struct sk_buff *skb)
{
@@ -237,8 +327,11 @@ static int btintel_pcie_send_sync(struct btintel_pcie_data *data,
	/* Wait for the complete interrupt - URBD0 */
	ret = wait_event_timeout(data->tx_wait_q, data->tx_wait_done,
				 msecs_to_jiffies(BTINTEL_PCIE_TX_WAIT_TIMEOUT_MS));
	if (!ret)
	if (!ret) {
		bt_dev_err(data->hdev, "tx completion timeout");
		btintel_pcie_dump_debug_registers(data->hdev);
		return -ETIME;
	}

	return 0;
}
@@ -756,6 +849,26 @@ static int btintel_pcie_read_device_mem(struct btintel_pcie_data *data,
	return 0;
}

static inline bool btintel_pcie_in_lockdown(struct btintel_pcie_data *data)
{
	return (data->boot_stage_cache &
		BTINTEL_PCIE_CSR_BOOT_STAGE_ROM_LOCKDOWN) ||
		(data->boot_stage_cache &
		 BTINTEL_PCIE_CSR_BOOT_STAGE_IML_LOCKDOWN);
}

static inline bool btintel_pcie_in_error(struct btintel_pcie_data *data)
{
	return (data->boot_stage_cache & BTINTEL_PCIE_CSR_BOOT_STAGE_DEVICE_ERR) ||
		(data->boot_stage_cache & BTINTEL_PCIE_CSR_BOOT_STAGE_ABORT_HANDLER);
}

static void btintel_pcie_msix_gp1_handler(struct btintel_pcie_data *data)
{
	bt_dev_err(data->hdev, "Received gp1 mailbox interrupt");
	btintel_pcie_dump_debug_registers(data->hdev);
}

/* This function handles the MSI-X interrupt for gp0 cause (bit 0 in
 * BTINTEL_PCIE_CSR_MSIX_HW_INT_CAUSES) which is sent for boot stage and image response.
 */
@@ -779,6 +892,18 @@ static void btintel_pcie_msix_gp0_handler(struct btintel_pcie_data *data)
	if (reg != data->img_resp_cache)
		data->img_resp_cache = reg;

	if (btintel_pcie_in_error(data)) {
		bt_dev_err(data->hdev, "Controller in error state");
		btintel_pcie_dump_debug_registers(data->hdev);
		return;
	}

	if (btintel_pcie_in_lockdown(data)) {
		bt_dev_err(data->hdev, "Controller in lockdown state");
		btintel_pcie_dump_debug_registers(data->hdev);
		return;
	}

	data->gp0_received = true;

	old_ctxt = data->alive_intr_ctxt;
@@ -889,7 +1014,6 @@ static void btintel_pcie_msix_tx_handle(struct btintel_pcie_data *data)
static int btintel_pcie_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
{
	struct hci_event_hdr *hdr = (void *)skb->data;
	const char diagnostics_hdr[] = { 0x87, 0x80, 0x03 };
	struct btintel_pcie_data *data = hci_get_drvdata(hdev);

	if (skb->len > HCI_EVENT_HDR_SIZE && hdr->evt == 0xff &&
@@ -945,15 +1069,6 @@ static int btintel_pcie_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
			}
		}

		/* Handle all diagnostics events separately. May still call
		 * hci_recv_frame.
		 */
		if (len >= sizeof(diagnostics_hdr) &&
		    memcmp(&skb->data[2], diagnostics_hdr,
			   sizeof(diagnostics_hdr)) == 0) {
			return btintel_diagnostics(hdev, skb);
		}

		/* This is a debug event that comes from IML and OP image when it
		 * starts execution. There is no need pass this event to stack.
		 */
@@ -1343,6 +1458,9 @@ static irqreturn_t btintel_pcie_irq_msix_handler(int irq, void *dev_id)
	if (intr_hw & BTINTEL_PCIE_MSIX_HW_INT_CAUSES_HWEXP)
		btintel_pcie_msix_hw_exp_handler(data);

	if (intr_hw & BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP1)
		btintel_pcie_msix_gp1_handler(data);

	/* This interrupt is triggered by the firmware after updating
	 * boot_stage register and image_response register
	 */
@@ -2028,6 +2146,7 @@ static int btintel_pcie_setup(struct hci_dev *hdev)
	while ((err = btintel_pcie_setup_internal(hdev)) && fw_dl_retry++ < 1) {
		bt_dev_err(hdev, "Firmware download retry count: %d",
			   fw_dl_retry);
		btintel_pcie_dump_debug_registers(hdev);
		err = btintel_pcie_reset_bt(data);
		if (err) {
			bt_dev_err(hdev, "Failed to do shr reset: %d", err);
Loading