Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 525d0ae7 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'for-upstream' of...

Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next



Johan Hedberg says:

====================
pull request: bluetooth-next 2018-01-25

Here's one last bluetooth-next pull request for the 4.16 kernel:

 - Improved support for Intel controllers
 - New set_parity method to serdev (agreed with maintainers to be taken
   through bluetooth-next)
 - Fix error path in hci_bcm (missing call to serdev close)
 - New ID for BCM4343A0 UART controller

Please let me know if there are any issues pulling. Thanks.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents d9ac2d99 fbbe83c5
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -323,6 +323,7 @@ static const struct {
	{ 0x410e, "BCM43341B0"	},	/* 002.001.014 */
	{ 0x4406, "BCM4324B3"	},	/* 002.004.006 */
	{ 0x610c, "BCM4354"	},	/* 003.001.012 */
	{ 0x2122, "BCM4343A0"	},	/* 001.001.034 */
	{ 0x2209, "BCM43430A1"  },	/* 001.002.009 */
	{ 0x6119, "BCM4345C0"	},	/* 003.001.025 */
	{ 0x230f, "BCM4356A2"	},	/* 001.003.015 */
+155 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include <linux/module.h>
#include <linux/firmware.h>
#include <linux/regmap.h>
#include <asm/unaligned.h>

#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
@@ -569,6 +570,160 @@ struct regmap *btintel_regmap_init(struct hci_dev *hdev, u16 opcode_read,
}
EXPORT_SYMBOL_GPL(btintel_regmap_init);

int btintel_send_intel_reset(struct hci_dev *hdev, u32 boot_param)
{
	struct intel_reset params = { 0x00, 0x01, 0x00, 0x01, 0x00000000 };
	struct sk_buff *skb;

	params.boot_param = cpu_to_le32(boot_param);

	skb = __hci_cmd_sync(hdev, 0xfc01, sizeof(params), &params,
			     HCI_INIT_TIMEOUT);
	if (IS_ERR(skb)) {
		bt_dev_err(hdev, "Failed to send Intel Reset command");
		return PTR_ERR(skb);
	}

	kfree_skb(skb);

	return 0;
}
EXPORT_SYMBOL_GPL(btintel_send_intel_reset);

int btintel_read_boot_params(struct hci_dev *hdev,
			     struct intel_boot_params *params)
{
	struct sk_buff *skb;

	skb = __hci_cmd_sync(hdev, 0xfc0d, 0, NULL, HCI_INIT_TIMEOUT);
	if (IS_ERR(skb)) {
		bt_dev_err(hdev, "Reading Intel boot parameters failed (%ld)",
			   PTR_ERR(skb));
		return PTR_ERR(skb);
	}

	if (skb->len != sizeof(*params)) {
		bt_dev_err(hdev, "Intel boot parameters size mismatch");
		kfree_skb(skb);
		return -EILSEQ;
	}

	memcpy(params, skb->data, sizeof(*params));

	kfree_skb(skb);

	if (params->status) {
		bt_dev_err(hdev, "Intel boot parameters command failed (%02x)",
			   params->status);
		return -bt_to_errno(params->status);
	}

	bt_dev_info(hdev, "Device revision is %u",
		    le16_to_cpu(params->dev_revid));

	bt_dev_info(hdev, "Secure boot is %s",
		    params->secure_boot ? "enabled" : "disabled");

	bt_dev_info(hdev, "OTP lock is %s",
		    params->otp_lock ? "enabled" : "disabled");

	bt_dev_info(hdev, "API lock is %s",
		    params->api_lock ? "enabled" : "disabled");

	bt_dev_info(hdev, "Debug lock is %s",
		    params->debug_lock ? "enabled" : "disabled");

	bt_dev_info(hdev, "Minimum firmware build %u week %u %u",
		    params->min_fw_build_nn, params->min_fw_build_cw,
		    2000 + params->min_fw_build_yy);

	return 0;
}
EXPORT_SYMBOL_GPL(btintel_read_boot_params);

int btintel_download_firmware(struct hci_dev *hdev, const struct firmware *fw,
			      u32 *boot_param)
{
	int err;
	const u8 *fw_ptr;
	u32 frag_len;

	/* Start the firmware download transaction with the Init fragment
	 * represented by the 128 bytes of CSS header.
	 */
	err = btintel_secure_send(hdev, 0x00, 128, fw->data);
	if (err < 0) {
		bt_dev_err(hdev, "Failed to send firmware header (%d)", err);
		goto done;
	}

	/* Send the 256 bytes of public key information from the firmware
	 * as the PKey fragment.
	 */
	err = btintel_secure_send(hdev, 0x03, 256, fw->data + 128);
	if (err < 0) {
		bt_dev_err(hdev, "Failed to send firmware pkey (%d)", err);
		goto done;
	}

	/* Send the 256 bytes of signature information from the firmware
	 * as the Sign fragment.
	 */
	err = btintel_secure_send(hdev, 0x02, 256, fw->data + 388);
	if (err < 0) {
		bt_dev_err(hdev, "Failed to send firmware signature (%d)", err);
		goto done;
	}

	fw_ptr = fw->data + 644;
	frag_len = 0;

	while (fw_ptr - fw->data < fw->size) {
		struct hci_command_hdr *cmd = (void *)(fw_ptr + frag_len);

		/* Each SKU has a different reset parameter to use in the
		 * HCI_Intel_Reset command and it is embedded in the firmware
		 * data. So, instead of using static value per SKU, check
		 * the firmware data and save it for later use.
		 */
		if (le16_to_cpu(cmd->opcode) == 0xfc0e) {
			/* The boot parameter is the first 32-bit value
			 * and rest of 3 octets are reserved.
			 */
			*boot_param = get_unaligned_le32(fw_ptr + sizeof(*cmd));

			bt_dev_dbg(hdev, "boot_param=0x%x", *boot_param);
		}

		frag_len += sizeof(*cmd) + cmd->plen;

		/* The parameter length of the secure send command requires
		 * a 4 byte alignment. It happens so that the firmware file
		 * contains proper Intel_NOP commands to align the fragments
		 * as needed.
		 *
		 * Send set of commands with 4 byte alignment from the
		 * firmware data buffer as a single Data fragement.
		 */
		if (!(frag_len % 4)) {
			err = btintel_secure_send(hdev, 0x01, frag_len, fw_ptr);
			if (err < 0) {
				bt_dev_err(hdev,
					   "Failed to send firmware data (%d)",
					   err);
				goto done;
			}

			fw_ptr += frag_len;
			frag_len = 0;
		}
	}

done:
	return err;
}
EXPORT_SYMBOL_GPL(btintel_download_firmware);

MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Bluetooth support for Intel devices ver " VERSION);
MODULE_VERSION(VERSION);
+32 −1
Original line number Diff line number Diff line
@@ -69,6 +69,14 @@ struct intel_secure_send_result {
	__u8     status;
} __packed;

struct intel_reset {
	__u8     reset_type;
	__u8     patch_enable;
	__u8     ddc_reload;
	__u8     boot_option;
	__le32   boot_param;
} __packed;

#if IS_ENABLED(CONFIG_BT_INTEL)

int btintel_check_bdaddr(struct hci_dev *hdev);
@@ -89,7 +97,11 @@ int btintel_read_version(struct hci_dev *hdev, struct intel_version *ver);

struct regmap *btintel_regmap_init(struct hci_dev *hdev, u16 opcode_read,
				   u16 opcode_write);

int btintel_send_intel_reset(struct hci_dev *hdev, u32 boot_param);
int btintel_read_boot_params(struct hci_dev *hdev,
			     struct intel_boot_params *params);
int btintel_download_firmware(struct hci_dev *dev, const struct firmware *fw,
			      u32 *boot_param);
#else

static inline int btintel_check_bdaddr(struct hci_dev *hdev)
@@ -165,4 +177,23 @@ static inline struct regmap *btintel_regmap_init(struct hci_dev *hdev,
{
	return ERR_PTR(-EINVAL);
}

static inline int btintel_send_intel_reset(struct hci_dev *hdev,
					   u32 reset_param)
{
	return -EOPNOTSUPP;
}

static inline int btintel_read_boot_params(struct hci_dev *hdev,
					   struct intel_boot_params *params)
{
	return -EOPNOTSUPP;
}

static inline int btintel_download_firmware(struct hci_dev *dev,
					    const struct firmware *fw,
					    u32 *boot_param)
{
	return -EOPNOTSUPP;
}
#endif
+22 −111
Original line number Diff line number Diff line
@@ -2009,15 +2009,11 @@ static int btusb_send_frame_intel(struct hci_dev *hdev, struct sk_buff *skb)

static int btusb_setup_intel_new(struct hci_dev *hdev)
{
	static const u8 reset_param[] = { 0x00, 0x01, 0x00, 0x01,
					  0x00, 0x08, 0x04, 0x00 };
	struct btusb_data *data = hci_get_drvdata(hdev);
	struct sk_buff *skb;
	struct intel_version ver;
	struct intel_boot_params *params;
	struct intel_boot_params params;
	const struct firmware *fw;
	const u8 *fw_ptr;
	u32 frag_len;
	u32 boot_param;
	char fwname[64];
	ktime_t calltime, delta, rettime;
	unsigned long long duration;
@@ -2025,6 +2021,12 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)

	BT_DBG("%s", hdev->name);

	/* Set the default boot parameter to 0x0 and it is updated to
	 * SKU specific boot parameter after reading Intel_Write_Boot_Params
	 * command while downloading the firmware.
	 */
	boot_param = 0x00000000;

	calltime = ktime_get();

	/* Read the Intel version information to determine if the device
@@ -2095,55 +2097,24 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
	/* Read the secure boot parameters to identify the operating
	 * details of the bootloader.
	 */
	skb = __hci_cmd_sync(hdev, 0xfc0d, 0, NULL, HCI_INIT_TIMEOUT);
	if (IS_ERR(skb)) {
		BT_ERR("%s: Reading Intel boot parameters failed (%ld)",
		       hdev->name, PTR_ERR(skb));
		return PTR_ERR(skb);
	}

	if (skb->len != sizeof(*params)) {
		BT_ERR("%s: Intel boot parameters size mismatch", hdev->name);
		kfree_skb(skb);
		return -EILSEQ;
	}

	params = (struct intel_boot_params *)skb->data;

	bt_dev_info(hdev, "Device revision is %u",
		    le16_to_cpu(params->dev_revid));

	bt_dev_info(hdev, "Secure boot is %s",
		    params->secure_boot ? "enabled" : "disabled");

	bt_dev_info(hdev, "OTP lock is %s",
		    params->otp_lock ? "enabled" : "disabled");

	bt_dev_info(hdev, "API lock is %s",
		    params->api_lock ? "enabled" : "disabled");

	bt_dev_info(hdev, "Debug lock is %s",
		    params->debug_lock ? "enabled" : "disabled");

	bt_dev_info(hdev, "Minimum firmware build %u week %u %u",
		    params->min_fw_build_nn, params->min_fw_build_cw,
		    2000 + params->min_fw_build_yy);
	err = btintel_read_boot_params(hdev, &params);
	if (err)
		return err;

	/* It is required that every single firmware fragment is acknowledged
	 * with a command complete event. If the boot parameters indicate
	 * that this bootloader does not send them, then abort the setup.
	 */
	if (params->limited_cce != 0x00) {
	if (params.limited_cce != 0x00) {
		BT_ERR("%s: Unsupported Intel firmware loading method (%u)",
		       hdev->name, params->limited_cce);
		kfree_skb(skb);
		       hdev->name, params.limited_cce);
		return -EINVAL;
	}

	/* If the OTP has no valid Bluetooth device address, then there will
	 * also be no valid address for the operational firmware.
	 */
	if (!bacmp(&params->otp_bdaddr, BDADDR_ANY)) {
	if (!bacmp(&params.otp_bdaddr, BDADDR_ANY)) {
		bt_dev_info(hdev, "No device address configured");
		set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
	}
@@ -2174,7 +2145,7 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
	case 0x0c:	/* WsP */
		snprintf(fwname, sizeof(fwname), "intel/ibt-%u-%u.sfi",
			 le16_to_cpu(ver.hw_variant),
			 le16_to_cpu(params->dev_revid));
			 le16_to_cpu(params.dev_revid));
		break;
	case 0x11:	/* JfP */
	case 0x12:	/* ThP */
@@ -2192,7 +2163,6 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
	if (err < 0) {
		BT_ERR("%s: Failed to load Intel firmware file (%d)",
		       hdev->name, err);
		kfree_skb(skb);
		return err;
	}

@@ -2206,7 +2176,7 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
	case 0x0c:	/* WsP */
		snprintf(fwname, sizeof(fwname), "intel/ibt-%u-%u.ddc",
			 le16_to_cpu(ver.hw_variant),
			 le16_to_cpu(params->dev_revid));
			 le16_to_cpu(params.dev_revid));
		break;
	case 0x11:	/* JfP */
	case 0x12:	/* ThP */
@@ -2220,8 +2190,6 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
		return -EINVAL;
	}

	kfree_skb(skb);

	if (fw->size < 644) {
		BT_ERR("%s: Invalid size of firmware file (%zu)",
		       hdev->name, fw->size);
@@ -2231,64 +2199,10 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)

	set_bit(BTUSB_DOWNLOADING, &data->flags);

	/* Start the firmware download transaction with the Init fragment
	 * represented by the 128 bytes of CSS header.
	 */
	err = btintel_secure_send(hdev, 0x00, 128, fw->data);
	if (err < 0) {
		BT_ERR("%s: Failed to send firmware header (%d)",
		       hdev->name, err);
		goto done;
	}

	/* Send the 256 bytes of public key information from the firmware
	 * as the PKey fragment.
	 */
	err = btintel_secure_send(hdev, 0x03, 256, fw->data + 128);
	if (err < 0) {
		BT_ERR("%s: Failed to send firmware public key (%d)",
		       hdev->name, err);
		goto done;
	}

	/* Send the 256 bytes of signature information from the firmware
	 * as the Sign fragment.
	 */
	err = btintel_secure_send(hdev, 0x02, 256, fw->data + 388);
	if (err < 0) {
		BT_ERR("%s: Failed to send firmware signature (%d)",
		       hdev->name, err);
		goto done;
	}

	fw_ptr = fw->data + 644;
	frag_len = 0;

	while (fw_ptr - fw->data < fw->size) {
		struct hci_command_hdr *cmd = (void *)(fw_ptr + frag_len);

		frag_len += sizeof(*cmd) + cmd->plen;

		/* The parameter length of the secure send command requires
		 * a 4 byte alignment. It happens so that the firmware file
		 * contains proper Intel_NOP commands to align the fragments
		 * as needed.
		 *
		 * Send set of commands with 4 byte alignment from the
		 * firmware data buffer as a single Data fragement.
		 */
		if (!(frag_len % 4)) {
			err = btintel_secure_send(hdev, 0x01, frag_len, fw_ptr);
			if (err < 0) {
				BT_ERR("%s: Failed to send firmware data (%d)",
				       hdev->name, err);
	/* Start firmware downloading and get boot parameter */
	err = btintel_download_firmware(hdev, fw, &boot_param);
	if (err < 0)
		goto done;
			}

			fw_ptr += frag_len;
			frag_len = 0;
		}
	}

	set_bit(BTUSB_FIRMWARE_LOADED, &data->flags);

@@ -2341,12 +2255,9 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)

	set_bit(BTUSB_BOOTING, &data->flags);

	skb = __hci_cmd_sync(hdev, 0xfc01, sizeof(reset_param), reset_param,
			     HCI_INIT_TIMEOUT);
	if (IS_ERR(skb))
		return PTR_ERR(skb);

	kfree_skb(skb);
	err = btintel_send_intel_reset(hdev, boot_param);
	if (err)
		return err;

	/* The bootloader will not indicate when the device is ready. This
	 * is done by the operational firmware sending bootup notification.
+4 −1
Original line number Diff line number Diff line
@@ -412,7 +412,10 @@ static int bcm_open(struct hci_uart *hu)
	return 0;

err_unset_hu:
	if (hu->serdev)
		serdev_device_close(hu->serdev);
#ifdef CONFIG_PM
	else
		bcm->dev->hu = NULL;
#endif
err_free:
Loading