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

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

 - btmtk: Fix failed to send func ctrl for MediaTek devices.
 - hci_sync: Fix not setting Random Address when required
 - MGMT: Fix Add Device to responding before completing
 - btnxpuart: Fix driver sending truncated data

* tag 'for-net-2025-01-08' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth:
  Bluetooth: btmtk: Fix failed to send func ctrl for MediaTek devices.
  Bluetooth: btnxpuart: Fix driver sending truncated data
  Bluetooth: MGMT: Fix Add Device to responding before completing
  Bluetooth: hci_sync: Fix not setting Random Address when required
====================

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


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents f552b303 67dba2c2
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -1472,10 +1472,15 @@ EXPORT_SYMBOL_GPL(btmtk_usb_setup);

int btmtk_usb_shutdown(struct hci_dev *hdev)
{
	struct btmtk_data *data = hci_get_priv(hdev);
	struct btmtk_hci_wmt_params wmt_params;
	u8 param = 0;
	int err;

	err = usb_autopm_get_interface(data->intf);
	if (err < 0)
		return err;

	/* Disable the device */
	wmt_params.op = BTMTK_WMT_FUNC_CTRL;
	wmt_params.flag = 0;
@@ -1486,9 +1491,11 @@ int btmtk_usb_shutdown(struct hci_dev *hdev)
	err = btmtk_usb_hci_wmt_sync(hdev, &wmt_params);
	if (err < 0) {
		bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
		usb_autopm_put_interface(data->intf);
		return err;
	}

	usb_autopm_put_interface(data->intf);
	return 0;
}
EXPORT_SYMBOL_GPL(btmtk_usb_shutdown);
+1 −0
Original line number Diff line number Diff line
@@ -1381,6 +1381,7 @@ static void btnxpuart_tx_work(struct work_struct *work)

	while ((skb = nxp_dequeue(nxpdev))) {
		len = serdev_device_write_buf(serdev, skb->data, skb->len);
		serdev_device_wait_until_sent(serdev, 0);
		hdev->stat.byte_tx += len;

		skb_pull(skb, len);
+6 −5
Original line number Diff line number Diff line
@@ -1031,9 +1031,9 @@ static bool adv_use_rpa(struct hci_dev *hdev, uint32_t flags)

static int hci_set_random_addr_sync(struct hci_dev *hdev, bdaddr_t *rpa)
{
	/* If we're advertising or initiating an LE connection we can't
	 * go ahead and change the random address at this time. This is
	 * because the eventual initiator address used for the
	/* If a random_addr has been set we're advertising or initiating an LE
	 * connection we can't go ahead and change the random address at this
	 * time. This is because the eventual initiator address used for the
	 * subsequently created connection will be undefined (some
	 * controllers use the new address and others the one we had
	 * when the operation started).
@@ -1041,8 +1041,9 @@ static int hci_set_random_addr_sync(struct hci_dev *hdev, bdaddr_t *rpa)
	 * In this kind of scenario skip the update and let the random
	 * address be updated at the next cycle.
	 */
	if (hci_dev_test_flag(hdev, HCI_LE_ADV) ||
	    hci_lookup_le_connect(hdev)) {
	if (bacmp(&hdev->random_addr, BDADDR_ANY) &&
	    (hci_dev_test_flag(hdev, HCI_LE_ADV) ||
	    hci_lookup_le_connect(hdev))) {
		bt_dev_dbg(hdev, "Deferring random address update");
		hci_dev_set_flag(hdev, HCI_RPA_EXPIRED);
		return 0;
+36 −2
Original line number Diff line number Diff line
@@ -7655,6 +7655,24 @@ static void device_added(struct sock *sk, struct hci_dev *hdev,
	mgmt_event(MGMT_EV_DEVICE_ADDED, hdev, &ev, sizeof(ev), sk);
}

static void add_device_complete(struct hci_dev *hdev, void *data, int err)
{
	struct mgmt_pending_cmd *cmd = data;
	struct mgmt_cp_add_device *cp = cmd->param;

	if (!err) {
		device_added(cmd->sk, hdev, &cp->addr.bdaddr, cp->addr.type,
			     cp->action);
		device_flags_changed(NULL, hdev, &cp->addr.bdaddr,
				     cp->addr.type, hdev->conn_flags,
				     PTR_UINT(cmd->user_data));
	}

	mgmt_cmd_complete(cmd->sk, hdev->id, MGMT_OP_ADD_DEVICE,
			  mgmt_status(err), &cp->addr, sizeof(cp->addr));
	mgmt_pending_free(cmd);
}

static int add_device_sync(struct hci_dev *hdev, void *data)
{
	return hci_update_passive_scan_sync(hdev);
@@ -7663,6 +7681,7 @@ static int add_device_sync(struct hci_dev *hdev, void *data)
static int add_device(struct sock *sk, struct hci_dev *hdev,
		      void *data, u16 len)
{
	struct mgmt_pending_cmd *cmd;
	struct mgmt_cp_add_device *cp = data;
	u8 auto_conn, addr_type;
	struct hci_conn_params *params;
@@ -7743,8 +7762,23 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
			current_flags = params->flags;
	}

	err = hci_cmd_sync_queue(hdev, add_device_sync, NULL, NULL);
	if (err < 0)
	cmd = mgmt_pending_new(sk, MGMT_OP_ADD_DEVICE, hdev, data, len);
	if (!cmd) {
		err = -ENOMEM;
		goto unlock;
	}

	cmd->user_data = UINT_PTR(current_flags);

	err = hci_cmd_sync_queue(hdev, add_device_sync, cmd,
				 add_device_complete);
	if (err < 0) {
		err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE,
					MGMT_STATUS_FAILED, &cp->addr,
					sizeof(cp->addr));
		mgmt_pending_free(cmd);
	}

	goto unlock;

added:
+2 −2
Original line number Diff line number Diff line
@@ -201,14 +201,14 @@ static ssize_t address_show(struct device *tty_dev,
			    struct device_attribute *attr, char *buf)
{
	struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
	return sprintf(buf, "%pMR\n", &dev->dst);
	return sysfs_emit(buf, "%pMR\n", &dev->dst);
}

static ssize_t channel_show(struct device *tty_dev,
			    struct device_attribute *attr, char *buf)
{
	struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
	return sprintf(buf, "%d\n", dev->channel);
	return sysfs_emit(buf, "%d\n", dev->channel);
}

static DEVICE_ATTR_RO(address);