diff mbox series

[v2] Bluetooth: btusb: Add support different nvm to distinguish different factory for WCN6855 controller

Message ID 1628152661-5669-1-git-send-email-zijuhu@codeaurora.org (mailing list archive)
State Superseded
Headers show
Series [v2] Bluetooth: btusb: Add support different nvm to distinguish different factory for WCN6855 controller | expand

Commit Message

Zijun Hu Aug. 5, 2021, 8:37 a.m. UTC
From: Tim Jiang <tjiang@codeaurora.org>

we have different factory to produce wcn6855 soc chip, so we should
use different nvm file with suffix to distinguish them.

Signed-off-by: Tim Jiang <tjiang@codeaurora.org>
---
 drivers/bluetooth/btusb.c | 60 +++++++++++++++++++++++++++++++++++++----------
 1 file changed, 47 insertions(+), 13 deletions(-)

Comments

bluez.test.bot@gmail.com Aug. 5, 2021, 9:05 a.m. UTC | #1
This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=526805

---Test result---

Test Summary:
CheckPatch                    PASS      0.57 seconds
GitLint                       FAIL      0.12 seconds
BuildKernel                   FAIL      391.29 seconds
TestRunner: Setup             PASS      407.20 seconds
TestRunner: l2cap-tester      PASS      2.86 seconds
TestRunner: bnep-tester       PASS      2.15 seconds
TestRunner: mgmt-tester       PASS      31.82 seconds
TestRunner: rfcomm-tester     PASS      2.40 seconds
TestRunner: sco-tester        PASS      2.22 seconds
TestRunner: smp-tester        FAIL      2.34 seconds
TestRunner: userchan-tester   PASS      2.21 seconds

Details
##############################
Test: CheckPatch - PASS - 0.57 seconds
Run checkpatch.pl script with rule in .checkpatch.conf


##############################
Test: GitLint - FAIL - 0.12 seconds
Run gitlint with rule in .gitlint
Bluetooth: btusb: Add support different nvm to distinguish different factory for WCN6855 controller
1: T1 Title exceeds max length (99>72): "Bluetooth: btusb: Add support different nvm to distinguish different factory for WCN6855 controller"


##############################
Test: BuildKernel - FAIL - 391.29 seconds
Build Kernel with minimal configuration supports Bluetooth
drivers/bluetooth/btusb.c: In function ‘btusb_setup_qca_form_nvm_name’:
drivers/bluetooth/btusb.c:4391:1: error: no return statement in function returning non-void [-Werror=return-type]
 4391 | }
      | ^
drivers/bluetooth/btusb.c: In function ‘btusb_setup_qca_load_nvm’:
drivers/bluetooth/btusb.c:4404:33: error: passing argument 1 of ‘btusb_setup_qca_form_nvm_name’ from incompatible pointer type [-Werror=incompatible-pointer-types]
 4404 |   btusb_setup_qca_form_nvm_name(&fwname, sizeof(fwname), ver, "gf");
      |                                 ^~~~~~~
      |                                 |
      |                                 char (*)[64]
drivers/bluetooth/btusb.c:4357:49: note: expected ‘char **’ but argument is of type ‘char (*)[64]’
 4357 | static int btusb_setup_qca_form_nvm_name(char **fwname,
      |                                          ~~~~~~~^~~~~~
drivers/bluetooth/btusb.c:4407:33: error: passing argument 1 of ‘btusb_setup_qca_form_nvm_name’ from incompatible pointer type [-Werror=incompatible-pointer-types]
 4407 |   btusb_setup_qca_form_nvm_name(&fwname, sizeof(fwname), ver, NULL);
      |                                 ^~~~~~~
      |                                 |
      |                                 char (*)[64]
drivers/bluetooth/btusb.c:4357:49: note: expected ‘char **’ but argument is of type ‘char (*)[64]’
 4357 | static int btusb_setup_qca_form_nvm_name(char **fwname,
      |                                          ~~~~~~~^~~~~~
drivers/bluetooth/btusb.c: In function ‘btusb_recv_acl_mtk’:
drivers/bluetooth/btusb.c:4033:3: warning: this statement may fall through [-Wimplicit-fallthrough=]
 4033 |   usb_disable_autosuspend(data->udev);
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/bluetooth/btusb.c:4034:2: note: here
 4034 |  case 0x05ff:  /* Firmware debug logging 1 */
      |  ^~~~
cc1: some warnings being treated as errors
make[2]: *** [scripts/Makefile.build:271: drivers/bluetooth/btusb.o] Error 1
make[1]: *** [scripts/Makefile.build:514: drivers/bluetooth] Error 2
make: *** [Makefile:1841: drivers] Error 2


##############################
Test: TestRunner: Setup - PASS - 407.20 seconds
Setup environment for running Test Runner


##############################
Test: TestRunner: l2cap-tester - PASS - 2.86 seconds
Run test-runner with l2cap-tester
Total: 40, Passed: 40 (100.0%), Failed: 0, Not Run: 0

##############################
Test: TestRunner: bnep-tester - PASS - 2.15 seconds
Run test-runner with bnep-tester
Total: 1, Passed: 1 (100.0%), Failed: 0, Not Run: 0

##############################
Test: TestRunner: mgmt-tester - PASS - 31.82 seconds
Run test-runner with mgmt-tester
Total: 448, Passed: 445 (99.3%), Failed: 0, Not Run: 3

##############################
Test: TestRunner: rfcomm-tester - PASS - 2.40 seconds
Run test-runner with rfcomm-tester
Total: 9, Passed: 9 (100.0%), Failed: 0, Not Run: 0

##############################
Test: TestRunner: sco-tester - PASS - 2.22 seconds
Run test-runner with sco-tester
Total: 8, Passed: 8 (100.0%), Failed: 0, Not Run: 0

##############################
Test: TestRunner: smp-tester - FAIL - 2.34 seconds
Run test-runner with smp-tester
Total: 8, Passed: 7 (87.5%), Failed: 1, Not Run: 0

Failed Test Cases
SMP Client - SC Request 2                            Failed       0.032 seconds

##############################
Test: TestRunner: userchan-tester - PASS - 2.21 seconds
Run test-runner with userchan-tester
Total: 3, Passed: 3 (100.0%), Failed: 0, Not Run: 0



---
Regards,
Linux Bluetooth
kernel test robot Aug. 5, 2021, 11:28 a.m. UTC | #2
Hi Zijun,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on bluetooth-next/master]
[also build test ERROR on linus/master v5.14-rc4 next-20210804]
[cannot apply to bluetooth/master linux/master]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Zijun-Hu/Bluetooth-btusb-Add-support-different-nvm-to-distinguish-different-factory-for-WCN6855-controller/20210805-164035
base:   https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git master
config: m68k-randconfig-r013-20210804 (attached as .config)
compiler: m68k-linux-gcc (GCC) 10.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/7af6ba1121380c4ee146896c833b7ecb7716d82e
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Zijun-Hu/Bluetooth-btusb-Add-support-different-nvm-to-distinguish-different-factory-for-WCN6855-controller/20210805-164035
        git checkout 7af6ba1121380c4ee146896c833b7ecb7716d82e
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-10.3.0 make.cross ARCH=m68k 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   drivers/bluetooth/btusb.c: In function 'btusb_setup_qca_form_nvm_name':
   drivers/bluetooth/btusb.c:4391:1: error: no return statement in function returning non-void [-Werror=return-type]
    4391 | }
         | ^
   drivers/bluetooth/btusb.c: In function 'btusb_setup_qca_load_nvm':
>> drivers/bluetooth/btusb.c:4404:33: error: passing argument 1 of 'btusb_setup_qca_form_nvm_name' from incompatible pointer type [-Werror=incompatible-pointer-types]
    4404 |   btusb_setup_qca_form_nvm_name(&fwname, sizeof(fwname), ver, "gf");
         |                                 ^~~~~~~
         |                                 |
         |                                 char (*)[64]
   drivers/bluetooth/btusb.c:4357:49: note: expected 'char **' but argument is of type 'char (*)[64]'
    4357 | static int btusb_setup_qca_form_nvm_name(char **fwname,
         |                                          ~~~~~~~^~~~~~
   drivers/bluetooth/btusb.c:4407:33: error: passing argument 1 of 'btusb_setup_qca_form_nvm_name' from incompatible pointer type [-Werror=incompatible-pointer-types]
    4407 |   btusb_setup_qca_form_nvm_name(&fwname, sizeof(fwname), ver, NULL);
         |                                 ^~~~~~~
         |                                 |
         |                                 char (*)[64]
   drivers/bluetooth/btusb.c:4357:49: note: expected 'char **' but argument is of type 'char (*)[64]'
    4357 | static int btusb_setup_qca_form_nvm_name(char **fwname,
         |                                          ~~~~~~~^~~~~~
   cc1: some warnings being treated as errors


vim +/btusb_setup_qca_form_nvm_name +4404 drivers/bluetooth/btusb.c

  4356	
  4357	static int btusb_setup_qca_form_nvm_name(char **fwname,
  4358						int max_size,
  4359						struct qca_version *ver,
  4360						char *factory)
  4361	{
  4362		if (((ver->flag >> 8) & 0xff) == QCA_FLAG_MULTI_NVM) {
  4363			/* if boardid equal 0, use default nvm without suffix */
  4364			if (le16_to_cpu(ver->board_id) == 0x0) {
  4365				/* we add suffix factory to distinguish with different factory. */
  4366				if (factory != NULL) {
  4367					snprintf(*fwname, max_size, "qca/nvm_usb_%08x_%s.bin",
  4368						 le32_to_cpu(ver->rom_version),
  4369						 factory);
  4370				} else {
  4371					snprintf(*fwname, max_size, "qca/nvm_usb_%08x.bin",
  4372						 le32_to_cpu(ver->rom_version));
  4373				}
  4374			} else {
  4375				if (factory != NULL) {
  4376					snprintf(*fwname, max_size, "qca/nvm_usb_%08x_%s_%04x.bin",
  4377						le32_to_cpu(ver->rom_version),
  4378						factory,
  4379						le16_to_cpu(ver->board_id));
  4380				} else {
  4381					snprintf(*fwname, max_size, "qca/nvm_usb_%08x_%04x.bin",
  4382						le32_to_cpu(ver->rom_version),
  4383						le16_to_cpu(ver->board_id));
  4384				}
  4385			}
  4386		} else {
  4387			snprintf(*fwname, max_size, "qca/nvm_usb_%08x.bin",
  4388				 le32_to_cpu(ver->rom_version));
  4389		}
  4390	
> 4391	}
  4392	
  4393	static int btusb_setup_qca_load_nvm(struct hci_dev *hdev,
  4394					    struct qca_version *ver,
  4395					    const struct qca_device_info *info)
  4396	{
  4397		const struct firmware *fw;
  4398		char fwname[64];
  4399		int err;
  4400	
  4401		switch (ver->ram_version) {
  4402		case WCN6855_2_0_RAM_VERSION_GF:
  4403		case WCN6855_2_1_RAM_VERSION_GF:
> 4404			btusb_setup_qca_form_nvm_name(&fwname, sizeof(fwname), ver, "gf");
  4405			break;
  4406		default:
  4407			btusb_setup_qca_form_nvm_name(&fwname, sizeof(fwname), ver, NULL);
  4408		}
  4409	
  4410		err = request_firmware(&fw, fwname, &hdev->dev);
  4411		if (err) {
  4412			bt_dev_err(hdev, "failed to request NVM file: %s (%d)",
  4413				   fwname, err);
  4414			return err;
  4415		}
  4416	
  4417		bt_dev_info(hdev, "using NVM file: %s", fwname);
  4418	
  4419		err = btusb_setup_qca_download_fw(hdev, fw, info->nvm_hdr);
  4420	
  4421		release_firmware(fw);
  4422	
  4423		return err;
  4424	}
  4425	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Marcel Holtmann Aug. 5, 2021, 2:09 p.m. UTC | #3
Hi Zijun,

> we have different factory to produce wcn6855 soc chip, so we should
> use different nvm file with suffix to distinguish them.
> 
> Signed-off-by: Tim Jiang <tjiang@codeaurora.org>
> ---
> drivers/bluetooth/btusb.c | 60 +++++++++++++++++++++++++++++++++++++----------
> 1 file changed, 47 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
> index b1a05bb9f4bf..18b1ef2497ec 100644
> --- a/drivers/bluetooth/btusb.c
> +++ b/drivers/bluetooth/btusb.c
> @@ -4013,6 +4013,9 @@ static int btusb_set_bdaddr_wcn6855(struct hci_dev *hdev,
> #define QCA_DFU_TIMEOUT		3000
> #define QCA_FLAG_MULTI_NVM      0x80
> 
> +#define WCN6855_2_0_RAM_VERSION_GF 0x400c1200
> +#define WCN6855_2_1_RAM_VERSION_GF 0x400c1211
> +
> struct qca_version {
> 	__le32	rom_version;
> 	__le32	patch_version;
> @@ -4044,6 +4047,7 @@ static const struct qca_device_info qca_devices_table[] = {
> 	{ 0x00000302, 28, 4, 16 }, /* Rome 3.2 */
> 	{ 0x00130100, 40, 4, 16 }, /* WCN6855 1.0 */
> 	{ 0x00130200, 40, 4, 16 }, /* WCN6855 2.0 */
> +	{ 0x00130201, 40, 4, 16 }, /* WCN6855 2.1 */
> };
> 
> static int btusb_qca_send_vendor_req(struct usb_device *udev, u8 request,
> @@ -4198,6 +4202,42 @@ static int btusb_setup_qca_load_rampatch(struct hci_dev *hdev,
> 	return err;
> }
> 
> +static int btusb_setup_qca_form_nvm_name(char **fwname,
> +					int max_size,
> +					struct qca_version *ver,
> +					char *factory)
> +{
> +	if (((ver->flag >> 8) & 0xff) == QCA_FLAG_MULTI_NVM) {
> +		/* if boardid equal 0, use default nvm without suffix */
> +		if (le16_to_cpu(ver->board_id) == 0x0) {
> +			/* we add suffix factory to distinguish with different factory. */
> +			if (factory != NULL) {

the coding style is if (!factory) btw.

> +				snprintf(*fwname, max_size, "qca/nvm_usb_%08x_%s.bin",
> +					 le32_to_cpu(ver->rom_version),
> +					 factory);
> +			} else {
> +				snprintf(*fwname, max_size, "qca/nvm_usb_%08x.bin",
> +					 le32_to_cpu(ver->rom_version));
> +			}
> +		} else {
> +			if (factory != NULL) {
> +				snprintf(*fwname, max_size, "qca/nvm_usb_%08x_%s_%04x.bin",
> +					le32_to_cpu(ver->rom_version),
> +					factory,
> +					le16_to_cpu(ver->board_id));
> +			} else {
> +				snprintf(*fwname, max_size, "qca/nvm_usb_%08x_%04x.bin",
> +					le32_to_cpu(ver->rom_version),
> +					le16_to_cpu(ver->board_id));
> +			}
> +		}
> +	} else {
> +		snprintf(*fwname, max_size, "qca/nvm_usb_%08x.bin",
> +			 le32_to_cpu(ver->rom_version));
> +	}
> +
> +}
> +

I still don’t like the nested ifs here. Can you not just figure out something simpler. Something like a table as I mentioned in my previous review.

> static int btusb_setup_qca_load_nvm(struct hci_dev *hdev,
> 				    struct qca_version *ver,
> 				    const struct qca_device_info *info)
> @@ -4206,19 +4246,13 @@ static int btusb_setup_qca_load_nvm(struct hci_dev *hdev,
> 	char fwname[64];
> 	int err;
> 
> -	if (((ver->flag >> 8) & 0xff) == QCA_FLAG_MULTI_NVM) {
> -		/* if boardid equal 0, use default nvm without surfix */
> -		if (le16_to_cpu(ver->board_id) == 0x0) {
> -			snprintf(fwname, sizeof(fwname), "qca/nvm_usb_%08x.bin",
> -				 le32_to_cpu(ver->rom_version));
> -		} else {
> -			snprintf(fwname, sizeof(fwname), "qca/nvm_usb_%08x_%04x.bin",
> -				le32_to_cpu(ver->rom_version),
> -				le16_to_cpu(ver->board_id));
> -		}
> -	} else {
> -		snprintf(fwname, sizeof(fwname), "qca/nvm_usb_%08x.bin",
> -			 le32_to_cpu(ver->rom_version));
> +	switch (ver->ram_version) {
> +	case WCN6855_2_0_RAM_VERSION_GF:
> +	case WCN6855_2_1_RAM_VERSION_GF:
> +		btusb_setup_qca_form_nvm_name(&fwname, sizeof(fwname), ver, "gf");
> +		break;
> +	default:
> +		btusb_setup_qca_form_nvm_name(&fwname, sizeof(fwname), ver, NULL);

This is missing a break.

> 	}
> 
> 	err = request_firmware(&fw, fwname, &hdev->dev);

Regards

Marcel
kernel test robot Aug. 5, 2021, 3:51 p.m. UTC | #4
Hi Zijun,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on bluetooth-next/master]
[also build test ERROR on linus/master v5.14-rc4 next-20210804]
[cannot apply to bluetooth/master linux/master]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Zijun-Hu/Bluetooth-btusb-Add-support-different-nvm-to-distinguish-different-factory-for-WCN6855-controller/20210805-164035
base:   https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git master
config: hexagon-randconfig-r004-20210805 (attached as .config)
compiler: clang version 12.0.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/7af6ba1121380c4ee146896c833b7ecb7716d82e
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Zijun-Hu/Bluetooth-btusb-Add-support-different-nvm-to-distinguish-different-factory-for-WCN6855-controller/20210805-164035
        git checkout 7af6ba1121380c4ee146896c833b7ecb7716d82e
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=hexagon 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> drivers/bluetooth/btusb.c:4391:1: error: non-void function does not return a value [-Werror,-Wreturn-type]
   }
   ^
>> drivers/bluetooth/btusb.c:4404:33: error: incompatible pointer types passing 'char (*)[64]' to parameter of type 'char **' [-Werror,-Wincompatible-pointer-types]
                   btusb_setup_qca_form_nvm_name(&fwname, sizeof(fwname), ver, "gf");
                                                 ^~~~~~~
   drivers/bluetooth/btusb.c:4357:49: note: passing argument to parameter 'fwname' here
   static int btusb_setup_qca_form_nvm_name(char **fwname,
                                                   ^
   drivers/bluetooth/btusb.c:4407:33: error: incompatible pointer types passing 'char (*)[64]' to parameter of type 'char **' [-Werror,-Wincompatible-pointer-types]
                   btusb_setup_qca_form_nvm_name(&fwname, sizeof(fwname), ver, NULL);
                                                 ^~~~~~~
   drivers/bluetooth/btusb.c:4357:49: note: passing argument to parameter 'fwname' here
   static int btusb_setup_qca_form_nvm_name(char **fwname,
                                                   ^
   3 errors generated.


vim +4391 drivers/bluetooth/btusb.c

  4356	
  4357	static int btusb_setup_qca_form_nvm_name(char **fwname,
  4358						int max_size,
  4359						struct qca_version *ver,
  4360						char *factory)
  4361	{
  4362		if (((ver->flag >> 8) & 0xff) == QCA_FLAG_MULTI_NVM) {
  4363			/* if boardid equal 0, use default nvm without suffix */
  4364			if (le16_to_cpu(ver->board_id) == 0x0) {
  4365				/* we add suffix factory to distinguish with different factory. */
  4366				if (factory != NULL) {
  4367					snprintf(*fwname, max_size, "qca/nvm_usb_%08x_%s.bin",
  4368						 le32_to_cpu(ver->rom_version),
  4369						 factory);
  4370				} else {
  4371					snprintf(*fwname, max_size, "qca/nvm_usb_%08x.bin",
  4372						 le32_to_cpu(ver->rom_version));
  4373				}
  4374			} else {
  4375				if (factory != NULL) {
  4376					snprintf(*fwname, max_size, "qca/nvm_usb_%08x_%s_%04x.bin",
  4377						le32_to_cpu(ver->rom_version),
  4378						factory,
  4379						le16_to_cpu(ver->board_id));
  4380				} else {
  4381					snprintf(*fwname, max_size, "qca/nvm_usb_%08x_%04x.bin",
  4382						le32_to_cpu(ver->rom_version),
  4383						le16_to_cpu(ver->board_id));
  4384				}
  4385			}
  4386		} else {
  4387			snprintf(*fwname, max_size, "qca/nvm_usb_%08x.bin",
  4388				 le32_to_cpu(ver->rom_version));
  4389		}
  4390	
> 4391	}
  4392	
  4393	static int btusb_setup_qca_load_nvm(struct hci_dev *hdev,
  4394					    struct qca_version *ver,
  4395					    const struct qca_device_info *info)
  4396	{
  4397		const struct firmware *fw;
  4398		char fwname[64];
  4399		int err;
  4400	
  4401		switch (ver->ram_version) {
  4402		case WCN6855_2_0_RAM_VERSION_GF:
  4403		case WCN6855_2_1_RAM_VERSION_GF:
> 4404			btusb_setup_qca_form_nvm_name(&fwname, sizeof(fwname), ver, "gf");
  4405			break;
  4406		default:
  4407			btusb_setup_qca_form_nvm_name(&fwname, sizeof(fwname), ver, NULL);
  4408		}
  4409	
  4410		err = request_firmware(&fw, fwname, &hdev->dev);
  4411		if (err) {
  4412			bt_dev_err(hdev, "failed to request NVM file: %s (%d)",
  4413				   fwname, err);
  4414			return err;
  4415		}
  4416	
  4417		bt_dev_info(hdev, "using NVM file: %s", fwname);
  4418	
  4419		err = btusb_setup_qca_download_fw(hdev, fw, info->nvm_hdr);
  4420	
  4421		release_firmware(fw);
  4422	
  4423		return err;
  4424	}
  4425	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff mbox series

Patch

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index b1a05bb9f4bf..18b1ef2497ec 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -4013,6 +4013,9 @@  static int btusb_set_bdaddr_wcn6855(struct hci_dev *hdev,
 #define QCA_DFU_TIMEOUT		3000
 #define QCA_FLAG_MULTI_NVM      0x80
 
+#define WCN6855_2_0_RAM_VERSION_GF 0x400c1200
+#define WCN6855_2_1_RAM_VERSION_GF 0x400c1211
+
 struct qca_version {
 	__le32	rom_version;
 	__le32	patch_version;
@@ -4044,6 +4047,7 @@  static const struct qca_device_info qca_devices_table[] = {
 	{ 0x00000302, 28, 4, 16 }, /* Rome 3.2 */
 	{ 0x00130100, 40, 4, 16 }, /* WCN6855 1.0 */
 	{ 0x00130200, 40, 4, 16 }, /* WCN6855 2.0 */
+	{ 0x00130201, 40, 4, 16 }, /* WCN6855 2.1 */
 };
 
 static int btusb_qca_send_vendor_req(struct usb_device *udev, u8 request,
@@ -4198,6 +4202,42 @@  static int btusb_setup_qca_load_rampatch(struct hci_dev *hdev,
 	return err;
 }
 
+static int btusb_setup_qca_form_nvm_name(char **fwname,
+					int max_size,
+					struct qca_version *ver,
+					char *factory)
+{
+	if (((ver->flag >> 8) & 0xff) == QCA_FLAG_MULTI_NVM) {
+		/* if boardid equal 0, use default nvm without suffix */
+		if (le16_to_cpu(ver->board_id) == 0x0) {
+			/* we add suffix factory to distinguish with different factory. */
+			if (factory != NULL) {
+				snprintf(*fwname, max_size, "qca/nvm_usb_%08x_%s.bin",
+					 le32_to_cpu(ver->rom_version),
+					 factory);
+			} else {
+				snprintf(*fwname, max_size, "qca/nvm_usb_%08x.bin",
+					 le32_to_cpu(ver->rom_version));
+			}
+		} else {
+			if (factory != NULL) {
+				snprintf(*fwname, max_size, "qca/nvm_usb_%08x_%s_%04x.bin",
+					le32_to_cpu(ver->rom_version),
+					factory,
+					le16_to_cpu(ver->board_id));
+			} else {
+				snprintf(*fwname, max_size, "qca/nvm_usb_%08x_%04x.bin",
+					le32_to_cpu(ver->rom_version),
+					le16_to_cpu(ver->board_id));
+			}
+		}
+	} else {
+		snprintf(*fwname, max_size, "qca/nvm_usb_%08x.bin",
+			 le32_to_cpu(ver->rom_version));
+	}
+
+}
+
 static int btusb_setup_qca_load_nvm(struct hci_dev *hdev,
 				    struct qca_version *ver,
 				    const struct qca_device_info *info)
@@ -4206,19 +4246,13 @@  static int btusb_setup_qca_load_nvm(struct hci_dev *hdev,
 	char fwname[64];
 	int err;
 
-	if (((ver->flag >> 8) & 0xff) == QCA_FLAG_MULTI_NVM) {
-		/* if boardid equal 0, use default nvm without surfix */
-		if (le16_to_cpu(ver->board_id) == 0x0) {
-			snprintf(fwname, sizeof(fwname), "qca/nvm_usb_%08x.bin",
-				 le32_to_cpu(ver->rom_version));
-		} else {
-			snprintf(fwname, sizeof(fwname), "qca/nvm_usb_%08x_%04x.bin",
-				le32_to_cpu(ver->rom_version),
-				le16_to_cpu(ver->board_id));
-		}
-	} else {
-		snprintf(fwname, sizeof(fwname), "qca/nvm_usb_%08x.bin",
-			 le32_to_cpu(ver->rom_version));
+	switch (ver->ram_version) {
+	case WCN6855_2_0_RAM_VERSION_GF:
+	case WCN6855_2_1_RAM_VERSION_GF:
+		btusb_setup_qca_form_nvm_name(&fwname, sizeof(fwname), ver, "gf");
+		break;
+	default:
+		btusb_setup_qca_form_nvm_name(&fwname, sizeof(fwname), ver, NULL);
 	}
 
 	err = request_firmware(&fw, fwname, &hdev->dev);