linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "An, Tedd" <tedd.an@intel.com>
To: Marcel Holtmann <marcel@holtmann.org>
Cc: "linux-bluetooth@vger.kernel.org"
	<linux-bluetooth@vger.kernel.org>,
	Johan Hedberg <johan.hedberg@gmail.com>
Subject: Re: [RFC v2 4/4] Bluetooth: Add support Intel Bluetooth bootloader device
Date: Wed, 10 Dec 2014 01:57:53 +0000	[thread overview]
Message-ID: <D0ACDE57.44B1%tedd.an@intel.com> (raw)
In-Reply-To: <91440EF0-0729-4962-AFC6-56E322B48183@holtmann.org>

Hi Marcel,

On 12/8/14, 10:11 PM, "Marcel Holtmann" <marcel@holtmann.org> wrote:

>Hi Tedd,
>
>> +		if (ret < 0) {
>> +			BT_ERR("%s: sending DATA section failed", hdev->name);
>> +			return ret;
>> +		}
>> +
>> +		fw_ptr +=3D read_len;
>> +		remain -=3D read_len;
>> +	}
>
>And here you already have the fragmentation as a more generic approach.
>As I said, lets put that all into btusb_setup_intel_send_sec. Then this
>becomes nice and simple code.
>
>I even get the feeling that btusb_setup_intel_sec_patching can then be
>removed and the handling of the 4 sections folded into
>btusb_setup_intel_boot2 directly.

Got it. I will try above approach first then try to see if I can remove
btusb_setup_intel_sec_patching.

>
>> +
>> +	return 0;
>> +}
>> +
>> +/*
>> + * Send Intel Reset command to the device to enable the operational
>>firmware.
>> + * Because the device will not send CC event for Intel Reset command,
>> + * the command is sent with btusb_send_frame() instead of
>>__hci_cmd_sync() so
>> + * the host won't wait for event.
>> + */
>
>Why :(
>
>These are the things that does frustrate me sometimes. Is it too much to
>ask from the bootloader to acknowledge that it received the command and
>only then go and reset everything in the device.
>
>I mean you start using a well defined transport protocol and then you
>start violating it whenever you please because it is some tiny shortcut.
>It means that the host stack now has to do extra work and we can never
>tell when the device actually does a reset or if something fails. I mean
>how would we know if some of the firmware verification fails?

I knew that you won=B9t like it. :)
This is currently on discussion and this implementation is based on the
current spec and firmware design.
I will update you in a few days.

>
>> +static int btusb_setup_intel_send_reset(struct hci_dev *hdev)
>> +{
>> +	int ret;
>
>Use int err and normally we have these last in the variable list.
>
>> +	int len, plen;
>> +	struct hci_command_hdr *hdr;
>> +	struct sk_buff *skb;
>> +
>> +	u8 intel_reset[] =3D { 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x04, 0x00 =
};
>
>Make these const at least.
>
>> +
>> +	plen =3D sizeof(intel_reset);
>> +
>> +	len =3D HCI_COMMAND_HDR_SIZE + plen;
>> +	skb =3D bt_skb_alloc(len, GFP_ATOMIC);
>> +	if (!skb) {
>> +		BT_ERR("%s: failed to allocate sk_buff", hdev->name);
>> +		return -ENOMEM;
>> +	}
>> +
>> +	hdr =3D (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
>> +	hdr->opcode =3D cpu_to_le16(0xfc01);
>> +	hdr->plen   =3D plen;
>> +
>> +	memcpy(skb_put(skb, plen), intel_reset, plen);
>> +
>> +	bt_cb(skb)->pkt_type =3D HCI_COMMAND_PKT;
>> +	bt_cb(skb)->opcode =3D 0xfc01;
>> +
>> +	ret =3D btusb_send_frame(hdev, skb);
>> +	if (ret < 0) {
>> +		BT_ERR("%s: sending Intel Reset failed (%d)", hdev->name, ret);
>> +		return ret;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static int btusb_setup_intel_boot2(struct hci_dev *hdev)
>> +{
>> +	struct btusb_data *data =3D hci_get_drvdata(hdev);
>> +	const struct firmware *fw;
>> +	int err;
>> +
>> +	BT_DBG("%s", hdev->name);
>> +
>> +	/*
>> +	 * During the setup, the specific HCI command (INTE_SEC_SEND) and its
>> +	 * correspond event are sending/receiving via bulk endpoint instead of
>> +	 * control ep and interrupt in order to improve the FW downlaoding
>> +	 * speed. So, it sending and receiving routines needs to be set to
>> +	 * custom ones during this time and it will set back to generic ones
>> +	 * after.
>> +	 */
>> +	hdev->send =3D btusb_send_frame_intel;
>> +	data->recv_bulk =3D btusb_recv_bulk_intel;
>
>I actually prefer that we do not mess with these pointers in a registered
>device. These should be set in the probe function and then stay there.
>
>> +
>> +	fw =3D btusb_setup_intel_get_fw(hdev, INTEL_FW_MODE_BL);
>> +	if (!fw) {
>> +		err =3D 0;
>> +		goto exit_error;
>> +	}
>> +
>> +	/* Start to download the firmware */
>> +	err =3D btusb_setup_intel_sec_patching(hdev, fw);
>> +	if (err < 0) {
>> +		BT_ERR("%s: downloading firmware failed (%d)", hdev->name, err);
>> +		goto exit_release;
>> +	}
>> +
>> +	/* Send Intel Reset to enable the downloaded operational firmware */
>> +	err =3D btusb_setup_intel_send_reset(hdev);
>> +	if (err < 0) {
>> +		BT_ERR("%s: sending Intel Reset failed (%d)", hdev->name, err);
>> +		goto exit_release;
>> +	}
>> +
>> +	BT_INFO("%s: Intel firmware downloading is completed", hdev->name);
>> +
>> +exit_release:
>> +	release_firmware(fw);
>> +
>> +	/* extra time after resetting the device */
>> +	msleep(200);
>
>So this now gets execute as generic error path. I think this timeout
>should be actually in the btusb_setup_intel_send_reset function. Since
>that is the only time it needs to wait for some magic time to turn the
>device back.
>
>> +
>> +	/*
>> +	 * Once the device is running with operational firmware, send device
>> +	 * specific configuration parameter with legacy way.
>> +	 */
>> +	err =3D btusb_setup_intel(hdev);
>> +	if (err < 0) {
>> +		BT_ERR("%s: configuring Intel BT device failed (%d)",
>> +		       hdev->name, err);
>> +		goto exit_error;
>> +	}
>> +
>> +	BT_INFO("%s: Intel Bluetooth device configuration is completed",
>> +		hdev->name);
>> +
>> +exit_error:
>> +	/*
>> +	 * After this point, All events will come from interrupt endpoint.
>> +	 * So, put back the bulk_recv routine to generic one
>> +	 */
>> +	BT_INFO("%s: Reset the send and receive routines", hdev->name);
>> +
>> +	data->recv_bulk =3D btusb_recv_bulk;
>> +	hdev->send =3D btusb_send_frame;
>> +
>> +	return err;
>> +}
>> +
>> +
>> static int btusb_set_bdaddr_intel(struct hci_dev *hdev, const bdaddr_t
>>*bdaddr)
>> {
>> 	struct sk_buff *skb;
>> @@ -2079,6 +2432,9 @@ static int btusb_probe(struct usb_interface *intf,
>> 		hdev->set_bdaddr =3D btusb_set_bdaddr_intel;
>> 	}
>>=20
>> +	if (id->driver_info & BTUSB_INTEL_BOOT2)
>> +		hdev->setup =3D btusb_setup_intel_boot2;
>> +
>
>This should include btusb_set_bdaddr_intel as well.
>
>And you also want to set the special btusb_send_frame_intel here as well.
>And same for the internal bulk handler.
>
>> 	if (id->driver_info & BTUSB_MARVELL)
>> 		hdev->set_bdaddr =3D btusb_set_bdaddr_marvell;
>
>Regards
>
>Marcel
>
>--
>To unsubscribe from this list: send the line "unsubscribe
>linux-bluetooth" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at  http://vger.kernel.org/majordomo-info.html

Regards,
Tedd

  reply	other threads:[~2014-12-10  1:57 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-12-08 23:25 [RFC v2 4/4] Bluetooth: Add support Intel Bluetooth bootloader device Tedd Ho-Jeong An
2014-12-09  6:11 ` Marcel Holtmann
2014-12-10  1:57   ` An, Tedd [this message]
2014-12-10 11:31     ` Marcel Holtmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=D0ACDE57.44B1%tedd.an@intel.com \
    --to=tedd.an@intel.com \
    --cc=johan.hedberg@gmail.com \
    --cc=linux-bluetooth@vger.kernel.org \
    --cc=marcel@holtmann.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).