Re: [PATCH v2] Bluetooth: btusb: Allow firmware re-download when version matches

From: makro-kernel

Date: Wed May 13 2026 - 22:45:38 EST


Hi Shuai, Luiz,

I sent a patch earlier today touching the same function for a related
but distinct failure mode in the same family of chips, and only just
saw this thread.

https://lore.kernel.org/linux-bluetooth/aD_Lix2EVXOHmbZ4L1CunlWiLqfiKlU_1_FcVh4CBuIgud4kmE_544xjW2zFKsmh4pNAo9yIQ7q8_GZ4YcmgAXPp8LgW9rfWKqnu06WSjgk=@proton.me/T/#u

In my case the *outer* check fails first: on Foxconn USB 0489:e10a
(Qualcomm WCN6855/WCN785x, ROM 0x00190200) the chip reports
QCA_CHECK_STATUS = 0xe0 (PATCH_UPDATED | SYSCFG_UPDATED) on every
probe, so btusb_setup_qca() never reaches load_rampatch() or
load_nvm(), returns 0, and the controller runs unpatched firmware.

AVDTP setup later fails on Acquire and A2DP audio cannot stream. The
PATCH_UPDATED bit appears to persist across cold boots somewhere on
chip -- originally set by Windows on dual-boot-then-Linux systems
we've seen, but the bit sticks even after a successful Linux firmware
upload, so subsequent boots also see 0xe0 and skip.

The rampatch itself also persists on this silicon at least across
suspend/hibernate resume cycles and driver reload (whether it
survives a true cold boot I haven't isolated). Either way, once an
upload has succeeded the chip reports patch_version equal to the
file's version on subsequent probes, which is exactly the condition
your patch addresses. With my outer bypass in place but without your
inner change, the second and subsequent probes hit the existing
`rver_patch <= ver_patch` check, return -EINVAL, and controller
setup aborts entirely:

Bluetooth: hci0: using rampatch file: qca/rampatch_usb_00190200.bin
Bluetooth: hci0: QCA: patch rome 0x190200 build 0x8567, firmware rome 0x190200 build 0x8567
Bluetooth: hci0: rampatch file version did not match with firmware
(btusb_setup_qca returns -EINVAL, hci0 never finishes registering)

So your fix is doing the right thing here, and on this hardware both
sides are needed together for the chip to come up cleanly across
reload / reboot cycles.

In my local tree I skip reuploading on equal versions rather than
re-uploading on every probe:

if (rver_rom != ver_rom) {
bt_dev_err(hdev, "rampatch file ROM did not match controller");
err = -EINVAL;
goto done;
}

if (rver_patch <= ver_patch) {
bt_dev_info(hdev, "QCA: rampatch already current, skipping download");
err = 0;
goto done;
}

err = btusb_setup_qca_download_fw(hdev, fw, info->rampatch_hdr);

Best,
Makro