Skip to content

Commit bcac463

Browse files
committed
Merge: Bluetooth: btintel_pcie: Firmware upload fixes
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/6150 JIRA: https://issues.redhat.com/browse/RHEL-71257 Signed-off-by: Bastien Nocera <bnocera@redhat.com> Approved-by: David Marlin <dmarlin@redhat.com> Approved-by: Desnes Nunes <desnesn@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Patrick Talbert <ptalbert@redhat.com>
2 parents 7441e2c + 5bc5404 commit bcac463

File tree

4 files changed

+427
-51
lines changed

4 files changed

+427
-51
lines changed

drivers/bluetooth/btintel.c

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,6 +1252,12 @@ static void btintel_reset_to_bootloader(struct hci_dev *hdev)
12521252
struct intel_reset params;
12531253
struct sk_buff *skb;
12541254

1255+
/* PCIe transport uses shared hardware reset mechanism for recovery
1256+
* which gets triggered in pcie *setup* function on error.
1257+
*/
1258+
if (hdev->bus == HCI_PCI)
1259+
return;
1260+
12551261
/* Send Intel Reset command. This will result in
12561262
* re-enumeration of BT controller.
12571263
*
@@ -1267,6 +1273,7 @@ static void btintel_reset_to_bootloader(struct hci_dev *hdev)
12671273
* boot_param: Boot address
12681274
*
12691275
*/
1276+
12701277
params.reset_type = 0x01;
12711278
params.patch_enable = 0x01;
12721279
params.ddc_reload = 0x01;
@@ -1841,6 +1848,37 @@ static int btintel_boot_wait(struct hci_dev *hdev, ktime_t calltime, int msec)
18411848
return 0;
18421849
}
18431850

1851+
static int btintel_boot_wait_d0(struct hci_dev *hdev, ktime_t calltime,
1852+
int msec)
1853+
{
1854+
ktime_t delta, rettime;
1855+
unsigned long long duration;
1856+
int err;
1857+
1858+
bt_dev_info(hdev, "Waiting for device transition to d0");
1859+
1860+
err = btintel_wait_on_flag_timeout(hdev, INTEL_WAIT_FOR_D0,
1861+
TASK_INTERRUPTIBLE,
1862+
msecs_to_jiffies(msec));
1863+
if (err == -EINTR) {
1864+
bt_dev_err(hdev, "Device d0 move interrupted");
1865+
return -EINTR;
1866+
}
1867+
1868+
if (err) {
1869+
bt_dev_err(hdev, "Device d0 move timeout");
1870+
return -ETIMEDOUT;
1871+
}
1872+
1873+
rettime = ktime_get();
1874+
delta = ktime_sub(rettime, calltime);
1875+
duration = (unsigned long long)ktime_to_ns(delta) >> 10;
1876+
1877+
bt_dev_info(hdev, "Device moved to D0 in %llu usecs", duration);
1878+
1879+
return 0;
1880+
}
1881+
18441882
static int btintel_boot(struct hci_dev *hdev, u32 boot_addr)
18451883
{
18461884
ktime_t calltime;
@@ -1849,6 +1887,7 @@ static int btintel_boot(struct hci_dev *hdev, u32 boot_addr)
18491887
calltime = ktime_get();
18501888

18511889
btintel_set_flag(hdev, INTEL_BOOTING);
1890+
btintel_set_flag(hdev, INTEL_WAIT_FOR_D0);
18521891

18531892
err = btintel_send_intel_reset(hdev, boot_addr);
18541893
if (err) {
@@ -1861,13 +1900,28 @@ static int btintel_boot(struct hci_dev *hdev, u32 boot_addr)
18611900
* is done by the operational firmware sending bootup notification.
18621901
*
18631902
* Booting into operational firmware should not take longer than
1864-
* 1 second. However if that happens, then just fail the setup
1903+
* 5 second. However if that happens, then just fail the setup
18651904
* since something went wrong.
18661905
*/
1867-
err = btintel_boot_wait(hdev, calltime, 1000);
1868-
if (err == -ETIMEDOUT)
1906+
err = btintel_boot_wait(hdev, calltime, 5000);
1907+
if (err == -ETIMEDOUT) {
18691908
btintel_reset_to_bootloader(hdev);
1909+
goto exit_error;
1910+
}
18701911

1912+
if (hdev->bus == HCI_PCI) {
1913+
/* In case of PCIe, after receiving bootup event, driver performs
1914+
* D0 entry by writing 0 to sleep control register (check
1915+
* btintel_pcie_recv_event())
1916+
* Firmware acks with alive interrupt indicating host is full ready to
1917+
* perform BT operation. Lets wait here till INTEL_WAIT_FOR_D0
1918+
* bit is cleared.
1919+
*/
1920+
calltime = ktime_get();
1921+
err = btintel_boot_wait_d0(hdev, calltime, 2000);
1922+
}
1923+
1924+
exit_error:
18711925
return err;
18721926
}
18731927

@@ -2761,6 +2815,13 @@ int btintel_bootloader_setup_tlv(struct hci_dev *hdev,
27612815
*/
27622816
boot_param = 0x00000000;
27632817

2818+
/* In case of PCIe, this function might get called multiple times with
2819+
* same hdev instance if there is any error on firmware download.
2820+
* Need to clear stale bits of previous firmware download attempt.
2821+
*/
2822+
for (int i = 0; i < __INTEL_NUM_FLAGS; i++)
2823+
btintel_clear_flag(hdev, i);
2824+
27642825
btintel_set_flag(hdev, INTEL_BOOTLOADER);
27652826

27662827
err = btintel_prepare_fw_download_tlv(hdev, ver, &boot_param);
@@ -3285,7 +3346,7 @@ int btintel_configure_setup(struct hci_dev *hdev, const char *driver_name)
32853346
}
32863347
EXPORT_SYMBOL_GPL(btintel_configure_setup);
32873348

3288-
static int btintel_diagnostics(struct hci_dev *hdev, struct sk_buff *skb)
3349+
int btintel_diagnostics(struct hci_dev *hdev, struct sk_buff *skb)
32893350
{
32903351
struct intel_tlv *tlv = (void *)&skb->data[5];
32913352

@@ -3313,6 +3374,7 @@ static int btintel_diagnostics(struct hci_dev *hdev, struct sk_buff *skb)
33133374
recv_frame:
33143375
return hci_recv_frame(hdev, skb);
33153376
}
3377+
EXPORT_SYMBOL_GPL(btintel_diagnostics);
33163378

33173379
int btintel_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
33183380
{
@@ -3332,15 +3394,17 @@ int btintel_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
33323394
* indicating that the bootup completed.
33333395
*/
33343396
btintel_bootup(hdev, ptr, len);
3335-
break;
3397+
kfree_skb(skb);
3398+
return 0;
33363399
case 0x06:
33373400
/* When the firmware loading completes the
33383401
* device sends out a vendor specific event
33393402
* indicating the result of the firmware
33403403
* loading.
33413404
*/
33423405
btintel_secure_send_result(hdev, ptr, len);
3343-
break;
3406+
kfree_skb(skb);
3407+
return 0;
33443408
}
33453409
}
33463410

drivers/bluetooth/btintel.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ enum {
181181
INTEL_ROM_LEGACY,
182182
INTEL_ROM_LEGACY_NO_WBS_SUPPORT,
183183
INTEL_ACPI_RESET_ACTIVE,
184+
INTEL_WAIT_FOR_D0,
184185

185186
__INTEL_NUM_FLAGS,
186187
};
@@ -252,6 +253,7 @@ int btintel_bootloader_setup_tlv(struct hci_dev *hdev,
252253
int btintel_shutdown_combined(struct hci_dev *hdev);
253254
void btintel_hw_error(struct hci_dev *hdev, u8 code);
254255
void btintel_print_fseq_info(struct hci_dev *hdev);
256+
int btintel_diagnostics(struct hci_dev *hdev, struct sk_buff *skb);
255257
#else
256258

257259
static inline int btintel_check_bdaddr(struct hci_dev *hdev)
@@ -385,4 +387,9 @@ static inline void btintel_hw_error(struct hci_dev *hdev, u8 code)
385387
static inline void btintel_print_fseq_info(struct hci_dev *hdev)
386388
{
387389
}
390+
391+
static inline int btintel_diagnostics(struct hci_dev *hdev, struct sk_buff *skb)
392+
{
393+
return -EOPNOTSUPP;
394+
}
388395
#endif

0 commit comments

Comments
 (0)