Commit 2f901582 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge tag 'for-net-next-2024-03-08' of...

Merge tag 'for-net-next-2024-03-08' 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:

 - hci_conn: Only do ACL connections sequentially
 - hci_core: Cancel request on command timeout
 - Remove CONFIG_BT_HS
 - btrtl: Add the support for RTL8852BT/RTL8852BE-VT
 - btusb: Add support Mediatek MT7920
 - btusb: Add new VID/PID 13d3/3602 for MT7925
 - Add new quirk for broken read key length on ATS2851

* tag 'for-net-next-2024-03-08' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next: (52 commits)
  Bluetooth: hci_sync: Fix UAF in hci_acl_create_conn_sync
  Bluetooth: Fix eir name length
  Bluetooth: ISO: Align broadcast sync_timeout with connection timeout
  Bluetooth: Add new quirk for broken read key length on ATS2851
  Bluetooth: mgmt: remove NULL check in add_ext_adv_params_complete()
  Bluetooth: mgmt: remove NULL check in mgmt_set_connectable_complete()
  Bluetooth: btusb: Add support Mediatek MT7920
  Bluetooth: btmtk: Add MODULE_FIRMWARE() for MT7922
  Bluetooth: btnxpuart: Fix btnxpuart_close
  Bluetooth: ISO: Clean up returns values in iso_connect_ind()
  Bluetooth: fix use-after-free in accessing skb after sending it
  Bluetooth: af_bluetooth: Fix deadlock
  Bluetooth: bnep: Fix out-of-bound access
  Bluetooth: btusb: Fix memory leak
  Bluetooth: msft: Fix memory leak
  Bluetooth: hci_core: Fix possible buffer overflow
  Bluetooth: btrtl: fix out of bounds memory access
  Bluetooth: hci_h5: Add ability to allocate memory for private data
  Bluetooth: hci_sync: Fix overwriting request callback
  Bluetooth: hci_sync: Use QoS to determine which PHY to scan
  ...
====================

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


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 2612b9f1 3d1c16e9
Loading
Loading
Loading
Loading
+3 −9
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#include <linux/firmware.h>
#include <linux/dmi.h>
#include <linux/of.h>
#include <linux/string.h>
#include <asm/unaligned.h>

#include <net/bluetooth/bluetooth.h>
@@ -543,8 +544,6 @@ static const char *btbcm_get_board_name(struct device *dev)
	struct device_node *root;
	char *board_type;
	const char *tmp;
	int len;
	int i;

	root = of_find_node_by_path("/");
	if (!root)
@@ -554,13 +553,8 @@ static const char *btbcm_get_board_name(struct device *dev)
		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 < len; i++) {
		if (board_type[i] == '/')
			board_type[i] = '-';
	}
	board_type = devm_kstrdup(dev, tmp, GFP_KERNEL);
	strreplace(board_type, '/', '-');
	of_node_put(root);

	return board_type;
+115 −1
Original line number Diff line number Diff line
@@ -441,7 +441,7 @@ int btintel_read_version(struct hci_dev *hdev, struct intel_version *ver)
		return PTR_ERR(skb);
	}

	if (skb->len != sizeof(*ver)) {
	if (!skb || skb->len != sizeof(*ver)) {
		bt_dev_err(hdev, "Intel version event size mismatch");
		kfree_skb(skb);
		return -EILSEQ;
@@ -2670,6 +2670,119 @@ static void btintel_set_msft_opcode(struct hci_dev *hdev, u8 hw_variant)
	}
}

static void btintel_print_fseq_info(struct hci_dev *hdev)
{
	struct sk_buff *skb;
	u8 *p;
	u32 val;
	const char *str;

	skb = __hci_cmd_sync(hdev, 0xfcb3, 0, NULL, HCI_CMD_TIMEOUT);
	if (IS_ERR(skb)) {
		bt_dev_dbg(hdev, "Reading fseq status command failed (%ld)",
			   PTR_ERR(skb));
		return;
	}

	if (skb->len < (sizeof(u32) * 16 + 2)) {
		bt_dev_dbg(hdev, "Malformed packet of length %u received",
			   skb->len);
		kfree_skb(skb);
		return;
	}

	p = skb_pull_data(skb, 1);
	if (*p) {
		bt_dev_dbg(hdev, "Failed to get fseq status (0x%2.2x)", *p);
		kfree_skb(skb);
		return;
	}

	p = skb_pull_data(skb, 1);
	switch (*p) {
	case 0:
		str = "Success";
		break;
	case 1:
		str = "Fatal error";
		break;
	case 2:
		str = "Semaphore acquire error";
		break;
	default:
		str = "Unknown error";
		break;
	}

	if (*p) {
		bt_dev_err(hdev, "Fseq status: %s (0x%2.2x)", str, *p);
		kfree_skb(skb);
		return;
	}

	bt_dev_info(hdev, "Fseq status: %s (0x%2.2x)", str, *p);

	val = get_unaligned_le32(skb_pull_data(skb, 4));
	bt_dev_dbg(hdev, "Reason: 0x%8.8x", val);

	val = get_unaligned_le32(skb_pull_data(skb, 4));
	bt_dev_dbg(hdev, "Global version: 0x%8.8x", val);

	val = get_unaligned_le32(skb_pull_data(skb, 4));
	bt_dev_dbg(hdev, "Installed version: 0x%8.8x", val);

	p = skb->data;
	skb_pull_data(skb, 4);
	bt_dev_info(hdev, "Fseq executed: %2.2u.%2.2u.%2.2u.%2.2u", p[0], p[1],
		    p[2], p[3]);

	p = skb->data;
	skb_pull_data(skb, 4);
	bt_dev_info(hdev, "Fseq BT Top: %2.2u.%2.2u.%2.2u.%2.2u", p[0], p[1],
		    p[2], p[3]);

	val = get_unaligned_le32(skb_pull_data(skb, 4));
	bt_dev_dbg(hdev, "Fseq Top init version: 0x%8.8x", val);

	val = get_unaligned_le32(skb_pull_data(skb, 4));
	bt_dev_dbg(hdev, "Fseq Cnvio init version: 0x%8.8x", val);

	val = get_unaligned_le32(skb_pull_data(skb, 4));
	bt_dev_dbg(hdev, "Fseq MBX Wifi file version: 0x%8.8x", val);

	val = get_unaligned_le32(skb_pull_data(skb, 4));
	bt_dev_dbg(hdev, "Fseq BT version: 0x%8.8x", val);

	val = get_unaligned_le32(skb_pull_data(skb, 4));
	bt_dev_dbg(hdev, "Fseq Top reset address: 0x%8.8x", val);

	val = get_unaligned_le32(skb_pull_data(skb, 4));
	bt_dev_dbg(hdev, "Fseq MBX timeout: 0x%8.8x", val);

	val = get_unaligned_le32(skb_pull_data(skb, 4));
	bt_dev_dbg(hdev, "Fseq MBX ack: 0x%8.8x", val);

	val = get_unaligned_le32(skb_pull_data(skb, 4));
	bt_dev_dbg(hdev, "Fseq CNVi id: 0x%8.8x", val);

	val = get_unaligned_le32(skb_pull_data(skb, 4));
	bt_dev_dbg(hdev, "Fseq CNVr id: 0x%8.8x", val);

	val = get_unaligned_le32(skb_pull_data(skb, 4));
	bt_dev_dbg(hdev, "Fseq Error handle: 0x%8.8x", val);

	val = get_unaligned_le32(skb_pull_data(skb, 4));
	bt_dev_dbg(hdev, "Fseq Magic noalive indication: 0x%8.8x", val);

	val = get_unaligned_le32(skb_pull_data(skb, 4));
	bt_dev_dbg(hdev, "Fseq OTP version: 0x%8.8x", val);

	val = get_unaligned_le32(skb_pull_data(skb, 4));
	bt_dev_dbg(hdev, "Fseq MBX otp version: 0x%8.8x", val);

	kfree_skb(skb);
}

static int btintel_setup_combined(struct hci_dev *hdev)
{
	const u8 param[1] = { 0xFF };
@@ -2902,6 +3015,7 @@ static int btintel_setup_combined(struct hci_dev *hdev)

		err = btintel_bootloader_setup_tlv(hdev, &ver_tlv);
		btintel_register_devcoredump_support(hdev);
		btintel_print_fseq_info(hdev);
		break;
	default:
		bt_dev_err(hdev, "Unsupported Intel hw variant (%u)",
+4 −1
Original line number Diff line number Diff line
@@ -372,8 +372,10 @@ int btmtk_process_coredump(struct hci_dev *hdev, struct sk_buff *skb)
	struct btmediatek_data *data = hci_get_priv(hdev);
	int err;

	if (!IS_ENABLED(CONFIG_DEV_COREDUMP))
	if (!IS_ENABLED(CONFIG_DEV_COREDUMP)) {
		kfree_skb(skb);
		return 0;
	}

	switch (data->cd_info.state) {
	case HCI_DEVCOREDUMP_IDLE:
@@ -420,5 +422,6 @@ MODULE_LICENSE("GPL");
MODULE_FIRMWARE(FIRMWARE_MT7622);
MODULE_FIRMWARE(FIRMWARE_MT7663);
MODULE_FIRMWARE(FIRMWARE_MT7668);
MODULE_FIRMWARE(FIRMWARE_MT7922);
MODULE_FIRMWARE(FIRMWARE_MT7961);
MODULE_FIRMWARE(FIRMWARE_MT7925);
+1 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@
#define FIRMWARE_MT7622		"mediatek/mt7622pr2h.bin"
#define FIRMWARE_MT7663		"mediatek/mt7663pr2h.bin"
#define FIRMWARE_MT7668		"mediatek/mt7668pr2h.bin"
#define FIRMWARE_MT7922		"mediatek/BT_RAM_CODE_MT7922_1_1_hdr.bin"
#define FIRMWARE_MT7961		"mediatek/BT_RAM_CODE_MT7961_1_2_hdr.bin"
#define FIRMWARE_MT7925		"mediatek/mt7925/BT_RAM_CODE_MT7925_1_1_hdr.bin"

+24 −3
Original line number Diff line number Diff line
@@ -126,6 +126,7 @@ struct ps_data {
	struct hci_dev *hdev;
	struct work_struct work;
	struct timer_list ps_timer;
	struct mutex ps_lock;
};

struct wakeup_cmd_payload {
@@ -317,6 +318,9 @@ static void ps_start_timer(struct btnxpuart_dev *nxpdev)

	if (psdata->cur_psmode == PS_MODE_ENABLE)
		mod_timer(&psdata->ps_timer, jiffies + msecs_to_jiffies(psdata->h2c_ps_interval));

	if (psdata->ps_state == PS_STATE_AWAKE && psdata->ps_cmd == PS_CMD_ENTER_PS)
		cancel_work_sync(&psdata->work);
}

static void ps_cancel_timer(struct btnxpuart_dev *nxpdev)
@@ -337,6 +341,7 @@ static void ps_control(struct hci_dev *hdev, u8 ps_state)
	    !test_bit(BTNXPUART_SERDEV_OPEN, &nxpdev->tx_state))
		return;

	mutex_lock(&psdata->ps_lock);
	switch (psdata->cur_h2c_wakeupmode) {
	case WAKEUP_METHOD_DTR:
		if (ps_state == PS_STATE_AWAKE)
@@ -350,12 +355,15 @@ static void ps_control(struct hci_dev *hdev, u8 ps_state)
			status = serdev_device_break_ctl(nxpdev->serdev, 0);
		else
			status = serdev_device_break_ctl(nxpdev->serdev, -1);
		msleep(20); /* Allow chip to detect UART-break and enter sleep */
		bt_dev_dbg(hdev, "Set UART break: %s, status=%d",
			   str_on_off(ps_state == PS_STATE_SLEEP), status);
		break;
	}
	if (!status)
		psdata->ps_state = ps_state;
	mutex_unlock(&psdata->ps_lock);

	if (ps_state == PS_STATE_AWAKE)
		btnxpuart_tx_wakeup(nxpdev);
}
@@ -391,17 +399,25 @@ static void ps_setup(struct hci_dev *hdev)

	psdata->hdev = hdev;
	INIT_WORK(&psdata->work, ps_work_func);
	mutex_init(&psdata->ps_lock);
	timer_setup(&psdata->ps_timer, ps_timeout_func, 0);
}

static void ps_wakeup(struct btnxpuart_dev *nxpdev)
static bool ps_wakeup(struct btnxpuart_dev *nxpdev)
{
	struct ps_data *psdata = &nxpdev->psdata;
	u8 ps_state;

	mutex_lock(&psdata->ps_lock);
	ps_state = psdata->ps_state;
	mutex_unlock(&psdata->ps_lock);

	if (psdata->ps_state != PS_STATE_AWAKE) {
	if (ps_state != PS_STATE_AWAKE) {
		psdata->ps_cmd = PS_CMD_EXIT_PS;
		schedule_work(&psdata->work);
		return true;
	}
	return false;
}

static int send_ps_cmd(struct hci_dev *hdev, void *data)
@@ -1171,7 +1187,6 @@ static struct sk_buff *nxp_dequeue(void *data)
{
	struct btnxpuart_dev *nxpdev = (struct btnxpuart_dev *)data;

	ps_wakeup(nxpdev);
	ps_start_timer(nxpdev);
	return skb_dequeue(&nxpdev->txq);
}
@@ -1186,6 +1201,9 @@ static void btnxpuart_tx_work(struct work_struct *work)
	struct sk_buff *skb;
	int len;

	if (ps_wakeup(nxpdev))
		return;

	while ((skb = nxp_dequeue(nxpdev))) {
		len = serdev_device_write_buf(serdev, skb->data, skb->len);
		hdev->stat.byte_tx += len;
@@ -1234,6 +1252,9 @@ static int btnxpuart_close(struct hci_dev *hdev)

	ps_wakeup(nxpdev);
	serdev_device_close(nxpdev->serdev);
	skb_queue_purge(&nxpdev->txq);
	kfree_skb(nxpdev->rx_skb);
	nxpdev->rx_skb = NULL;
	clear_bit(BTNXPUART_SERDEV_OPEN, &nxpdev->tx_state);
	return 0;
}
Loading