Bluetooth: btintel: Add helper function to download firmware
PATCH 1/2 Bluetooth: btintel: Add helper function to download firmware
1) ddd a helper function to download firmware for new generation Intel controllers
2) ddd a function to construct firmware / ddc file name for new generation Intel controllers
Signed-off-by Kiran K <[email protected]>
Signed-off-by Amit K Bag <[email protected]>
Signed-off-by Raghuram Hegde <[email protected]>
Reviewed-by Sathish Narasimman <[email protected]>
Reviewed-by Chethan T N <[email protected]>
Reviewed-by Srivatsa Ravishankar <[email protected]>
--- drivers/bluetooth/btintel.h | 6 ++ drivers/bluetooth/btusb.c | 183 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 189 insertions(+)
drivers/bluetooth/btintel.h +6 -0
@@ -132,6 +132,12 @@ struct intel_debug_features {__u8 page1[16 ]; } __packed; +#define INTEL_HW_PLATFORM (cnvx_bt) ((u8)(((cnvx_bt) & 0x0000ff00) >> 8)) +#define INTEL_HW_VARIANT (cnvx_bt) ((u8)(((cnvx_bt) & 0x003f0000) >> 16)) +#define INTEL_CNVX_TOP_TYPE (cnvx_top) ((cnvx_top) & 0x00000fff) +#define INTEL_CNVX_TOP_STEP (cnvx_top) (((cnvx_top) & 0x0f000000) >> 24) +#define INTEL_CNVX_TOP_PACK_SWAB (t, s) __swab16(((__u16)(((t) << 4) | (s)))) +#if IS_ENABLED (CONFIG_BT_INTEL )int btintel_check_bdaddr (struct hci_dev *hdev);
drivers/bluetooth/btusb.c +183 -0
189 lines not on this page · raw message
Signature · 1 line
2.7.4
PATCH 2/2 Bluetooth: btintel: Add *setup* function for new generation Intel controllers
1) add a flag to identify new geneeration Intel controllers
2) define *setup* and hook it up for new genertion Intel controllers
3) map Typhoon Peak controller (PID:0x0032) to new generation controller
Signed-off-by Kiran K <[email protected]>
Signed-off-by Amit K Bag <[email protected]>
Signed-off-by Raghuram Hegde <[email protected]>
Reviewed-by Sathish Narasimman <[email protected]>
Reviewed-by Chethan T N <[email protected]>
Reviewed-by Srivatsa Ravishankar <[email protected]>
--- drivers/bluetooth/btusb.c | 145 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 142 insertions(+), 3 deletions(-)
drivers/bluetooth/btusb.c +142 -3
@@ -59,6 +59,7 @@ static struct usb_driver btusb_driver;#define BTUSB_MEDIATEK 0x200000#define BTUSB_WIDEBAND_SPEECH 0x400000#define BTUSB_VALID_LE_STATES 0x800000 +#define BTUSB_INTEL_NEWGEN 0x1000000static const struct usb_device_id btusb_table[] = {/* Generic Bluetooth USB device */
@@ -360,7 +361,7 @@ static const struct usb_device_id blacklist_table[] = { BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x8087, 0x0029), .driver_info = BTUSB_INTEL_NEW | BTUSB_WIDEBAND_SPEECH }, - { USB_DEVICE(0x8087, 0x0032), .driver_info = BTUSB_INTEL_NEW | + { USB_DEVICE(0x8087, 0x0032), .driver_info = BTUSB_INTEL_NEWGEN | BTUSB_WIDEBAND_SPEECH}, { USB_DEVICE(0x8087, 0x07da), .driver_info = BTUSB_CSR }, { USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL },
@@ -2871,6 +2872,138 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)return 0 ; } +static int btusb_setup_intel_newgen (struct hci_dev *hdev) +{ +struct btusb_data *data =hci_get_drvdata (hdev); +u32 boot_param; +char ddcname[64 ]; +ktime_t calltime, delta, rettime; +unsigned long long duration; +int err; +struct intel_debug_features features; +struct intel_version_tlv version; + +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 +* is in bootloader mode or if it already has operational firmware +* loaded. +*/ + err =btintel_read_version_tlv (hdev, &version); +if (err) { +bt_dev_err (hdev,"Intel Read version failed (%d)" , err); +btintel_reset_to_bootloader (hdev); +return err; + } + +btintel_version_info_tlv (hdev, &version); + + err =btusb_intel_download_firmware_newgen (hdev, &version, &boot_param); +if (err) +return err; + +/* check if controller is already having an operational firmware */ +if (version.img_type ==0x03 ) + goto finish; + + 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); + + calltime =ktime_get (); + +set_bit (BTUSB_BOOTING , &data->flags); + + err =btintel_send_intel_reset (hdev, boot_param); +if (err) { +bt_dev_err (hdev,"Intel Soft Reset failed (%d)" , err); +btintel_reset_to_bootloader (hdev); +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 =wait_on_bit_timeout (&data->flags,BTUSB_BOOTING , +TASK_INTERRUPTIBLE , +msecs_to_jiffies (1000 )); + +if (err == -EINTR ) { +bt_dev_err (hdev,"Device boot interrupted" ); +return -EINTR ; + } + +if (err) { +bt_dev_err (hdev,"Device boot timeout" ); +btintel_reset_to_bootloader (hdev); +return -ETIMEDOUT ; + } + + 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); + +clear_bit (BTUSB_BOOTLOADER , &data->flags); + + err =btusb_setup_intel_newgen_get_fw_name (&version, ddcname, +sizeof (ddcname),"ddc" ); +if (!err) { +bt_dev_err (hdev,"Unsupported Intel firmware naming" ); + }else { +/* Once the device is running in operational mode, it needs to +* apply the device configuration (DDC) parameters. +* +* The device can work without DDC parameters, so even if it +* fails to load the file, no need to fail the setup. +*/ +btintel_load_ddc_config (hdev, ddcname); + } + +/* Read the Intel supported features and if new exception formats +* supported, need to load the additional DDC config to enable. +*/ +btintel_read_debug_features (hdev, &features); + +/* Set DDC mask for available debug features */ +btintel_set_debug_features (hdev, &features); + +/* Read the Intel version information after loading the FW */ + err =btintel_read_version_tlv (hdev, &version); +if (err) +return err; + +btintel_version_info_tlv (hdev, &version); + +finish: +/* Set the event mask for Intel specific vendor events. This enables +* a few extra events that are useful during general operation. It +* does not enable any debugging related events. +* +* The device will function correctly without these events enabled +* and thus no need to fail the setup. +*/ +btintel_set_event_mask (hdev, false); + +return 0 ; +}static int btusb_shutdown_intel (struct hci_dev *hdev) {struct sk_buff *skb;
@@ -4119,7 +4252,8 @@ static int btusb_probe(struct usb_interface *intf,init_usb_anchor (&data->ctrl_anchor);spin_lock_init (&data->rxlock); -if (id->driver_info &BTUSB_INTEL_NEW ) { +if ((id->driver_info &BTUSB_INTEL_NEW ) || + (id->driver_info &BTUSB_INTEL_NEWGEN )) { data->recv_event = btusb_recv_event_intel; data->recv_bulk = btusb_recv_bulk_intel;set_bit (BTUSB_BOOTLOADER , &data->flags);
@@ -4214,7 +4348,8 @@ static int btusb_probe(struct usb_interface *intf,set_bit (HCI_QUIRK_NON_PERSISTENT_DIAG , &hdev->quirks); } -if (id->driver_info &BTUSB_INTEL_NEW ) { +if ((id->driver_info &BTUSB_INTEL_NEW ) || + (id->driver_info &BTUSB_INTEL_NEWGEN )) { hdev->manufacturer =2 ; hdev->send = btusb_send_frame_intel; hdev->setup = btusb_setup_intel_new;
@@ -4228,6 +4363,10 @@ static int btusb_probe(struct usb_interface *intf,set_bit (HCI_QUIRK_NON_PERSISTENT_DIAG , &hdev->quirks); } +/* Overload only setup function for new generation Intel controllers */ +if (id->driver_info &BTUSB_INTEL_NEWGEN ) + hdev->setup = btusb_setup_intel_newgen; +if (id->driver_info &BTUSB_MARVELL ) hdev->set_bdaddr = btusb_set_bdaddr_marvell;
Signature · 1 line
2.7.4