static int intel_setup()

in hci_intel.c [523:865]


static int intel_setup(struct hci_uart *hu)
{
	struct intel_data *intel = hu->priv;
	struct hci_dev *hdev = hu->hdev;
	struct sk_buff *skb;
	struct intel_version ver;
	struct intel_boot_params params;
	struct intel_device *idev;
	const struct firmware *fw;
	char fwname[64];
	u32 boot_param;
	ktime_t calltime, delta, rettime;
	unsigned long long duration;
	unsigned int init_speed, oper_speed;
	int speed_change = 0;
	int err;

	bt_dev_dbg(hdev, "start intel_setup");

	hu->hdev->set_diag = btintel_set_diag;
	hu->hdev->set_bdaddr = btintel_set_bdaddr;

	/* 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();

	if (hu->init_speed)
		init_speed = hu->init_speed;
	else
		init_speed = hu->proto->init_speed;

	if (hu->oper_speed)
		oper_speed = hu->oper_speed;
	else
		oper_speed = hu->proto->oper_speed;

	if (oper_speed && init_speed && oper_speed != init_speed)
		speed_change = 1;

	/* Check that the controller is ready */
	err = intel_wait_booting(hu);

	clear_bit(STATE_BOOTING, &intel->flags);

	/* In case of timeout, try to continue anyway */
	if (err && err != -ETIMEDOUT)
		return err;

	set_bit(STATE_BOOTLOADER, &intel->flags);

	/* Read the Intel version information to determine if the device
	 * is in bootloader mode or if it already has operational firmware
	 * loaded.
	 */
	err = btintel_read_version(hdev, &ver);
	if (err)
		return err;

	/* The hardware platform number has a fixed value of 0x37 and
	 * for now only accept this single value.
	 */
	if (ver.hw_platform != 0x37) {
		bt_dev_err(hdev, "Unsupported Intel hardware platform (%u)",
			   ver.hw_platform);
		return -EINVAL;
	}

        /* Check for supported iBT hardware variants of this firmware
         * loading method.
         *
         * This check has been put in place to ensure correct forward
         * compatibility options when newer hardware variants come along.
         */
	switch (ver.hw_variant) {
	case 0x0b:	/* LnP */
	case 0x0c:	/* WsP */
	case 0x12:	/* ThP */
		break;
	default:
		bt_dev_err(hdev, "Unsupported Intel hardware variant (%u)",
			   ver.hw_variant);
		return -EINVAL;
	}

	btintel_version_info(hdev, &ver);

	/* The firmware variant determines if the device is in bootloader
	 * mode or is running operational firmware. The value 0x06 identifies
	 * the bootloader and the value 0x23 identifies the operational
	 * firmware.
	 *
	 * When the operational firmware is already present, then only
	 * the check for valid Bluetooth device address is needed. This
	 * determines if the device will be added as configured or
	 * unconfigured controller.
	 *
	 * It is not possible to use the Secure Boot Parameters in this
	 * case since that command is only available in bootloader mode.
	 */
	if (ver.fw_variant == 0x23) {
		clear_bit(STATE_BOOTLOADER, &intel->flags);
		btintel_check_bdaddr(hdev);
		return 0;
	}

	/* If the device is not in bootloader mode, then the only possible
	 * choice is to return an error and abort the device initialization.
	 */
	if (ver.fw_variant != 0x06) {
		bt_dev_err(hdev, "Unsupported Intel firmware variant (%u)",
			   ver.fw_variant);
		return -ENODEV;
	}

	/* Read the secure boot parameters to identify the operating
	 * details of the bootloader.
	 */
	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) {
		bt_dev_err(hdev, "Unsupported Intel firmware loading method (%u)",
			   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)) {
		bt_dev_info(hdev, "No device address configured");
		set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
	}

	/* With this Intel bootloader only the hardware variant and device
	 * revision information are used to select the right firmware for SfP
	 * and WsP.
	 *
	 * The firmware filename is ibt-<hw_variant>-<dev_revid>.sfi.
	 *
	 * Currently the supported hardware variants are:
	 *   11 (0x0b) for iBT 3.0 (LnP/SfP)
	 *   12 (0x0c) for iBT 3.5 (WsP)
	 *
	 * For ThP/JfP and for future SKU's, the FW name varies based on HW
	 * variant, HW revision and FW revision, as these are dependent on CNVi
	 * and RF Combination.
	 *
	 *   18 (0x12) for iBT3.5 (ThP/JfP)
	 *
	 * The firmware file name for these will be
	 * ibt-<hw_variant>-<hw_revision>-<fw_revision>.sfi.
	 *
	 */
	switch (ver.hw_variant) {
	case 0x0b:      /* SfP */
	case 0x0c:      /* WsP */
		snprintf(fwname, sizeof(fwname), "intel/ibt-%u-%u.sfi",
			 ver.hw_variant, le16_to_cpu(params.dev_revid));
		break;
	case 0x12:      /* ThP */
		snprintf(fwname, sizeof(fwname), "intel/ibt-%u-%u-%u.sfi",
			 ver.hw_variant, ver.hw_revision, ver.fw_revision);
		break;
	default:
		bt_dev_err(hdev, "Unsupported Intel hardware variant (%u)",
			   ver.hw_variant);
		return -EINVAL;
	}

	err = request_firmware(&fw, fwname, &hdev->dev);
	if (err < 0) {
		bt_dev_err(hdev, "Failed to load Intel firmware file (%d)",
			   err);
		return err;
	}

	bt_dev_info(hdev, "Found device firmware: %s", fwname);

	/* Save the DDC file name for later */
	switch (ver.hw_variant) {
	case 0x0b:      /* SfP */
	case 0x0c:      /* WsP */
		snprintf(fwname, sizeof(fwname), "intel/ibt-%u-%u.ddc",
			 ver.hw_variant, le16_to_cpu(params.dev_revid));
		break;
	case 0x12:      /* ThP */
		snprintf(fwname, sizeof(fwname), "intel/ibt-%u-%u-%u.ddc",
			 ver.hw_variant, ver.hw_revision, ver.fw_revision);
		break;
	default:
		bt_dev_err(hdev, "Unsupported Intel hardware variant (%u)",
			   ver.hw_variant);
		return -EINVAL;
	}

	if (fw->size < 644) {
		bt_dev_err(hdev, "Invalid size of firmware file (%zu)",
			   fw->size);
		err = -EBADF;
		goto done;
	}

	set_bit(STATE_DOWNLOADING, &intel->flags);

	/* Start firmware downloading and get boot parameter */
	err = btintel_download_firmware(hdev, &ver, fw, &boot_param);
	if (err < 0)
		goto done;

	set_bit(STATE_FIRMWARE_LOADED, &intel->flags);

	bt_dev_info(hdev, "Waiting for firmware download to complete");

	/* Before switching the device into operational mode and with that
	 * booting the loaded firmware, wait for the bootloader notification
	 * that all fragments have been successfully received.
	 *
	 * When the event processing receives the notification, then the
	 * STATE_DOWNLOADING flag will be cleared.
	 *
	 * The firmware loading should not take longer than 5 seconds
	 * and thus just timeout if that happens and fail the setup
	 * of this device.
	 */
	err = wait_on_bit_timeout(&intel->flags, STATE_DOWNLOADING,
				  TASK_INTERRUPTIBLE,
				  msecs_to_jiffies(5000));
	if (err == -EINTR) {
		bt_dev_err(hdev, "Firmware loading interrupted");
		err = -EINTR;
		goto done;
	}

	if (err) {
		bt_dev_err(hdev, "Firmware loading timeout");
		err = -ETIMEDOUT;
		goto done;
	}

	if (test_bit(STATE_FIRMWARE_FAILED, &intel->flags)) {
		bt_dev_err(hdev, "Firmware loading failed");
		err = -ENOEXEC;
		goto done;
	}

	rettime = ktime_get();
	delta = ktime_sub(rettime, calltime);
	duration = (unsigned long long) ktime_to_ns(delta) >> 10;

	bt_dev_info(hdev, "Firmware loaded in %llu usecs", duration);

done:
	release_firmware(fw);

	/* Check if there was an error and if is not -EALREADY which means the
	 * firmware has already been loaded.
	 */
	if (err < 0 && err != -EALREADY)
		return err;

	/* We need to restore the default speed before Intel reset */
	if (speed_change) {
		err = intel_set_baudrate(hu, init_speed);
		if (err)
			return err;
	}

	calltime = ktime_get();

	set_bit(STATE_BOOTING, &intel->flags);

	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.
	 *
	 * Booting into operational firmware should not take longer than
	 * 1 second. However if that happens, then just fail the setup
	 * since something went wrong.
	 */
	bt_dev_info(hdev, "Waiting for device to boot");

	err = intel_wait_booting(hu);
	if (err)
		return err;

	clear_bit(STATE_BOOTING, &intel->flags);

	rettime = ktime_get();
	delta = ktime_sub(rettime, calltime);
	duration = (unsigned long long) ktime_to_ns(delta) >> 10;

	bt_dev_info(hdev, "Device booted in %llu usecs", duration);

	/* Enable LPM if matching pdev with wakeup enabled, set TX active
	 * until further LPM TX notification.
	 */
	mutex_lock(&intel_device_list_lock);
	list_for_each_entry(idev, &intel_device_list, list) {
		if (!hu->tty->dev)
			break;
		if (hu->tty->dev->parent == idev->pdev->dev.parent) {
			if (device_may_wakeup(&idev->pdev->dev)) {
				set_bit(STATE_LPM_ENABLED, &intel->flags);
				set_bit(STATE_TX_ACTIVE, &intel->flags);
			}
			break;
		}
	}
	mutex_unlock(&intel_device_list_lock);

	/* Ignore errors, device can work without DDC parameters */
	btintel_load_ddc_config(hdev, fwname);

	skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_CMD_TIMEOUT);
	if (IS_ERR(skb))
		return PTR_ERR(skb);
	kfree_skb(skb);

	if (speed_change) {
		err = intel_set_baudrate(hu, oper_speed);
		if (err)
			return err;
	}

	bt_dev_info(hdev, "Setup complete");

	clear_bit(STATE_BOOTLOADER, &intel->flags);

	return 0;
}