]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
Bluetooth: btusb: QCA: Fix downloading wrong NVM for WCN6855 GF variant without board ID
authorZijun Hu <zijun.hu@oss.qualcomm.com>
Tue, 15 Jul 2025 12:40:13 +0000 (20:40 +0800)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Wed, 16 Jul 2025 19:38:15 +0000 (15:38 -0400)
For GF variant of WCN6855 without board ID programmed
btusb_generate_qca_nvm_name() will chose wrong NVM
'qca/nvm_usb_00130201.bin' to download.

Fix by choosing right NVM 'qca/nvm_usb_00130201_gf.bin'.
Also simplify NVM choice logic of btusb_generate_qca_nvm_name().

Fixes: d6cba4e6d0e2 ("Bluetooth: btusb: Add support using different nvm for variant WCN6855 controller")
Signed-off-by: Zijun Hu <zijun.hu@oss.qualcomm.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
drivers/bluetooth/btusb.c

index 64509f5bfc994e58990bec7d8e0931f27e951626..f9eeec0aed57dae4a1c589c9cc83a6407e174832 100644 (file)
@@ -3192,6 +3192,32 @@ static const struct qca_device_info qca_devices_table[] = {
        { 0x00190200, 40, 4, 16 }, /* WCN785x 2.0 */
 };
 
+static u16 qca_extract_board_id(const struct qca_version *ver)
+{
+       u16 flag = le16_to_cpu(ver->flag);
+       u16 board_id = 0;
+
+       if (((flag >> 8) & 0xff) == QCA_FLAG_MULTI_NVM) {
+               /* The board_id should be split into two bytes
+                * The 1st byte is chip ID, and the 2nd byte is platform ID
+                * For example, board ID 0x010A, 0x01 is platform ID. 0x0A is chip ID
+                * we have several platforms, and platform IDs are continuously added
+                * Platform ID:
+                * 0x00 is for Mobile
+                * 0x01 is for X86
+                * 0x02 is for Automotive
+                * 0x03 is for Consumer electronic
+                */
+               board_id = (ver->chip_id << 8) + ver->platform_id;
+       }
+
+       /* Take 0xffff as invalid board ID */
+       if (board_id == 0xffff)
+               board_id = 0;
+
+       return board_id;
+}
+
 static int btusb_qca_send_vendor_req(struct usb_device *udev, u8 request,
                                     void *data, u16 size)
 {
@@ -3348,44 +3374,28 @@ static void btusb_generate_qca_nvm_name(char *fwname, size_t max_size,
                                        const struct qca_version *ver)
 {
        u32 rom_version = le32_to_cpu(ver->rom_version);
-       u16 flag = le16_to_cpu(ver->flag);
+       const char *variant;
+       int len;
+       u16 board_id;
 
-       if (((flag >> 8) & 0xff) == QCA_FLAG_MULTI_NVM) {
-               /* The board_id should be split into two bytes
-                * The 1st byte is chip ID, and the 2nd byte is platform ID
-                * For example, board ID 0x010A, 0x01 is platform ID. 0x0A is chip ID
-                * we have several platforms, and platform IDs are continuously added
-                * Platform ID:
-                * 0x00 is for Mobile
-                * 0x01 is for X86
-                * 0x02 is for Automotive
-                * 0x03 is for Consumer electronic
-                */
-               u16 board_id = (ver->chip_id << 8) + ver->platform_id;
-               const char *variant;
+       board_id = qca_extract_board_id(ver);
 
-               switch (le32_to_cpu(ver->ram_version)) {
-               case WCN6855_2_0_RAM_VERSION_GF:
-               case WCN6855_2_1_RAM_VERSION_GF:
-                       variant = "_gf";
-                       break;
-               default:
-                       variant = "";
-                       break;
-               }
-
-               if (board_id == 0) {
-                       snprintf(fwname, max_size, "qca/nvm_usb_%08x%s.bin",
-                               rom_version, variant);
-               } else {
-                       snprintf(fwname, max_size, "qca/nvm_usb_%08x%s_%04x.bin",
-                               rom_version, variant, board_id);
-               }
-       } else {
-               snprintf(fwname, max_size, "qca/nvm_usb_%08x.bin",
-                       rom_version);
+       switch (le32_to_cpu(ver->ram_version)) {
+       case WCN6855_2_0_RAM_VERSION_GF:
+       case WCN6855_2_1_RAM_VERSION_GF:
+               variant = "_gf";
+               break;
+       default:
+               variant = NULL;
+               break;
        }
 
+       len = snprintf(fwname, max_size, "qca/nvm_usb_%08x", rom_version);
+       if (variant)
+               len += snprintf(fwname + len, max_size - len, "%s", variant);
+       if (board_id)
+               len += snprintf(fwname + len, max_size - len, "_%04x", board_id);
+       len += snprintf(fwname + len, max_size - len, ".bin");
 }
 
 static int btusb_setup_qca_load_nvm(struct hci_dev *hdev,