Skip to content

Commit 5ea7c81

Browse files
kirankrishnappa-intelholtmann
authored andcommitted
Bluetooth: btusb: Refactor of firmware download flow for Intel conrollers
Address the scalability to support new generation Intel controller with respect to readability and enhancement to new firmware download sequence Signed-off-by: Kiran K <[email protected]> Reviewed-by: Chethan T N <[email protected]> Signed-off-by: Marcel Holtmann <[email protected]>
1 parent 3a0377d commit 5ea7c81

File tree

1 file changed

+80
-65
lines changed

1 file changed

+80
-65
lines changed

drivers/bluetooth/btusb.c

Lines changed: 80 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,6 @@ struct btusb_data {
511511
unsigned cmd_timeout_cnt;
512512
};
513513

514-
515514
static void btusb_intel_cmd_timeout(struct hci_dev *hdev)
516515
{
517516
struct btusb_data *data = hci_get_drvdata(hdev);
@@ -2278,46 +2277,25 @@ static bool btusb_setup_intel_new_get_fw_name(struct intel_version *ver,
22782277
return true;
22792278
}
22802279

2281-
static int btusb_setup_intel_new(struct hci_dev *hdev)
2280+
static int btusb_intel_download_firmware(struct hci_dev *hdev,
2281+
struct intel_version *ver,
2282+
struct intel_boot_params *params)
22822283
{
2283-
struct btusb_data *data = hci_get_drvdata(hdev);
2284-
struct intel_version ver;
2285-
struct intel_boot_params params;
2286-
struct intel_debug_features features;
22872284
const struct firmware *fw;
22882285
u32 boot_param;
22892286
char fwname[64];
2290-
ktime_t calltime, delta, rettime;
2291-
unsigned long long duration;
22922287
int err;
2288+
struct btusb_data *data = hci_get_drvdata(hdev);
22932289

2294-
BT_DBG("%s", hdev->name);
2295-
2296-
/* Set the default boot parameter to 0x0 and it is updated to
2297-
* SKU specific boot parameter after reading Intel_Write_Boot_Params
2298-
* command while downloading the firmware.
2299-
*/
2300-
boot_param = 0x00000000;
2301-
2302-
calltime = ktime_get();
2303-
2304-
/* Read the Intel version information to determine if the device
2305-
* is in bootloader mode or if it already has operational firmware
2306-
* loaded.
2307-
*/
2308-
err = btintel_read_version(hdev, &ver);
2309-
if (err) {
2310-
bt_dev_err(hdev, "Intel Read version failed (%d)", err);
2311-
btintel_reset_to_bootloader(hdev);
2312-
return err;
2313-
}
2290+
if (!ver || !params)
2291+
return -EINVAL;
23142292

23152293
/* The hardware platform number has a fixed value of 0x37 and
23162294
* for now only accept this single value.
23172295
*/
2318-
if (ver.hw_platform != 0x37) {
2296+
if (ver->hw_platform != 0x37) {
23192297
bt_dev_err(hdev, "Unsupported Intel hardware platform (%u)",
2320-
ver.hw_platform);
2298+
ver->hw_platform);
23212299
return -EINVAL;
23222300
}
23232301

@@ -2327,7 +2305,7 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
23272305
* This check has been put in place to ensure correct forward
23282306
* compatibility options when newer hardware variants come along.
23292307
*/
2330-
switch (ver.hw_variant) {
2308+
switch (ver->hw_variant) {
23312309
case 0x0b: /* SfP */
23322310
case 0x0c: /* WsP */
23332311
case 0x11: /* JfP */
@@ -2337,11 +2315,11 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
23372315
break;
23382316
default:
23392317
bt_dev_err(hdev, "Unsupported Intel hardware variant (%u)",
2340-
ver.hw_variant);
2318+
ver->hw_variant);
23412319
return -EINVAL;
23422320
}
23432321

2344-
btintel_version_info(hdev, &ver);
2322+
btintel_version_info(hdev, ver);
23452323

23462324
/* The firmware variant determines if the device is in bootloader
23472325
* mode or is running operational firmware. The value 0x06 identifies
@@ -2356,42 +2334,42 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
23562334
* It is not possible to use the Secure Boot Parameters in this
23572335
* case since that command is only available in bootloader mode.
23582336
*/
2359-
if (ver.fw_variant == 0x23) {
2337+
if (ver->fw_variant == 0x23) {
23602338
clear_bit(BTUSB_BOOTLOADER, &data->flags);
23612339
btintel_check_bdaddr(hdev);
2362-
goto finish;
2340+
return 0;
23632341
}
23642342

23652343
/* If the device is not in bootloader mode, then the only possible
23662344
* choice is to return an error and abort the device initialization.
23672345
*/
2368-
if (ver.fw_variant != 0x06) {
2346+
if (ver->fw_variant != 0x06) {
23692347
bt_dev_err(hdev, "Unsupported Intel firmware variant (%u)",
2370-
ver.fw_variant);
2348+
ver->fw_variant);
23712349
return -ENODEV;
23722350
}
23732351

23742352
/* Read the secure boot parameters to identify the operating
23752353
* details of the bootloader.
23762354
*/
2377-
err = btintel_read_boot_params(hdev, &params);
2355+
err = btintel_read_boot_params(hdev, params);
23782356
if (err)
23792357
return err;
23802358

23812359
/* It is required that every single firmware fragment is acknowledged
23822360
* with a command complete event. If the boot parameters indicate
23832361
* that this bootloader does not send them, then abort the setup.
23842362
*/
2385-
if (params.limited_cce != 0x00) {
2363+
if (params->limited_cce != 0x00) {
23862364
bt_dev_err(hdev, "Unsupported Intel firmware loading method (%u)",
2387-
params.limited_cce);
2365+
params->limited_cce);
23882366
return -EINVAL;
23892367
}
23902368

23912369
/* If the OTP has no valid Bluetooth device address, then there will
23922370
* also be no valid address for the operational firmware.
23932371
*/
2394-
if (!bacmp(&params.otp_bdaddr, BDADDR_ANY)) {
2372+
if (!bacmp(&params->otp_bdaddr, BDADDR_ANY)) {
23952373
bt_dev_info(hdev, "No device address configured");
23962374
set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
23972375
}
@@ -2417,7 +2395,7 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
24172395
* ibt-<hw_variant>-<hw_revision>-<fw_revision>.sfi.
24182396
*
24192397
*/
2420-
err = btusb_setup_intel_new_get_fw_name(&ver, &params, fwname,
2398+
err = btusb_setup_intel_new_get_fw_name(ver, params, fwname,
24212399
sizeof(fwname), "sfi");
24222400
if (!err) {
24232401
bt_dev_err(hdev, "Unsupported Intel firmware naming");
@@ -2432,16 +2410,6 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
24322410

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

2435-
/* Save the DDC file name for later use to apply once the firmware
2436-
* downloading is done.
2437-
*/
2438-
err = btusb_setup_intel_new_get_fw_name(&ver, &params, fwname,
2439-
sizeof(fwname), "ddc");
2440-
if (!err) {
2441-
bt_dev_err(hdev, "Unsupported Intel firmware naming");
2442-
return -EINVAL;
2443-
}
2444-
24452413
if (fw->size < 644) {
24462414
bt_dev_err(hdev, "Invalid size of firmware file (%zu)",
24472415
fw->size);
@@ -2496,18 +2464,58 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
24962464
goto done;
24972465
}
24982466

2467+
done:
2468+
release_firmware(fw);
2469+
return err;
2470+
}
2471+
2472+
static int btusb_setup_intel_new(struct hci_dev *hdev)
2473+
{
2474+
struct btusb_data *data = hci_get_drvdata(hdev);
2475+
struct intel_version ver;
2476+
struct intel_boot_params params;
2477+
u32 boot_param;
2478+
char ddcname[64];
2479+
ktime_t calltime, delta, rettime;
2480+
unsigned long long duration;
2481+
int err;
2482+
struct intel_debug_features features;
2483+
2484+
BT_DBG("%s", hdev->name);
2485+
2486+
/* Set the default boot parameter to 0x0 and it is updated to
2487+
* SKU specific boot parameter after reading Intel_Write_Boot_Params
2488+
* command while downloading the firmware.
2489+
*/
2490+
boot_param = 0x00000000;
2491+
2492+
calltime = ktime_get();
2493+
2494+
/* Read the Intel version information to determine if the device
2495+
* is in bootloader mode or if it already has operational firmware
2496+
* loaded.
2497+
*/
2498+
err = btintel_read_version(hdev, &ver);
2499+
if (err) {
2500+
bt_dev_err(hdev, "Intel Read version failed (%d)", err);
2501+
btintel_reset_to_bootloader(hdev);
2502+
return err;
2503+
}
2504+
2505+
err = btusb_intel_download_firmware(hdev, &ver, &params);
2506+
if (err)
2507+
return err;
2508+
2509+
/* controller is already having an operational firmware */
2510+
if (ver.fw_variant == 0x23)
2511+
goto finish;
2512+
24992513
rettime = ktime_get();
25002514
delta = ktime_sub(rettime, calltime);
25012515
duration = (unsigned long long) ktime_to_ns(delta) >> 10;
25022516

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

2505-
done:
2506-
release_firmware(fw);
2507-
2508-
if (err < 0)
2509-
return err;
2510-
25112519
calltime = ktime_get();
25122520

25132521
set_bit(BTUSB_BOOTING, &data->flags);
@@ -2551,13 +2559,20 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
25512559

25522560
clear_bit(BTUSB_BOOTLOADER, &data->flags);
25532561

2554-
/* Once the device is running in operational mode, it needs to apply
2555-
* the device configuration (DDC) parameters.
2556-
*
2557-
* The device can work without DDC parameters, so even if it fails
2558-
* to load the file, no need to fail the setup.
2559-
*/
2560-
btintel_load_ddc_config(hdev, fwname);
2562+
err = btusb_setup_intel_new_get_fw_name(&ver, &params, ddcname,
2563+
sizeof(ddcname), "ddc");
2564+
2565+
if (!err) {
2566+
bt_dev_err(hdev, "Unsupported Intel firmware naming");
2567+
} else {
2568+
/* Once the device is running in operational mode, it needs to
2569+
* apply the device configuration (DDC) parameters.
2570+
*
2571+
* The device can work without DDC parameters, so even if it
2572+
* fails to load the file, no need to fail the setup.
2573+
*/
2574+
btintel_load_ddc_config(hdev, ddcname);
2575+
}
25612576

25622577
/* Read the Intel supported features and if new exception formats
25632578
* supported, need to load the additional DDC config to enable.

0 commit comments

Comments
 (0)